【问题标题】:FabricJS weird line animation with pageSnap带有pageSnap的FabricJS奇怪的线条动画
【发布时间】:2017-01-15 08:13:33
【问题描述】:

我正在使用 FabricJS 创建 JS 线条动画并使用 PageSnapJS 创建捕捉部分。但是,线条动画行为是非常随机的。如果您慢慢滚动彩色页面,您会看到红线动画。第 1 到 2 页通常很好,但第 2 到 3 页失败。我的计算不正确吗?如何纠正它?

这是我的代码(JSFiddle 在问题的末尾):

var canvas;
var current_page = 1;
var is_animating = false;
var line_options = {
    stroke: 'red',
    strokeWidth: 3
};
$(document).ready(function() {
    canvas = new fabric.Canvas('line_effect');
    canvas.setHeight($('.indicator').height());
    canvas.setWidth(50);
    canvas.renderAll();
    var section_h = $('.section').height();

    var startPts = [
        {x: 48, y: 0},
        {x: 48, y: $('.section').height()}
    ];
    var endPts = [
        {x: 48, y: $('.section').height() * 2},
        {x: 48, y: $('.section').height()}
    ];

    var line = new fabric.Polyline(startPts, line_options);
    canvas.add(line);

    function animateLine(i, prop, endPts) {
        fabric.util.animate({
            startValue: line.points[i][prop],
            endValue: endPts[i][prop],
            duration: 1000,
            easing: fabric.util.ease.easeInOutCubic,
            onChange: function(value) {
                line.points[i][prop] = value;
                if(i === startPts.length - 1 && prop == 'y') {
                    canvas.renderAll();
                }
            },
            onComplete: function() {
                line.setCoords();
                if(i === startPts.length - 1 && prop == 'y') {
                    even = !even;
                    animateLine(i, prop, endPts);
                }
            }
        });
    }
    function animate(startPage, endPage) {
        if(is_animating) {
            return;
        } else if(startPage == endPage) {
            return;
        } else if(Math.abs(startPage - endPage) > 1) {
            // Jump to that section immediately.
            console.log('Jump to Page ' + endPage);
            canvas.remove(line);
            if(endPage == 1) {
                line = new fabric.Line([48, section_h * 0, 48, section_h * 1], line_options);
            } else if(endPage == 2) {
                line = new fabric.Line([48, section_h * 1, 48, section_h * 2], line_options);
            } else if(endPage == 3) {
                line = new fabric.Line([48, section_h * 2, 48, section_h * 3], line_options);
            } else if(endPage == 4) {
                line = new fabric.Line([48, section_h * 3, 48, section_h * 4], line_options);
            } 
            canvas.add(line);
        } else {
            is_animating = true;
            if(startPage == 1 && endPage == 2) {
                console.log('Page 1 > 2');
                startPts = [
                    {x: 48, y: section_h * 0},
                    {x: 48, y: section_h * 1}
                ];
                endPts = [
                    {x: 48, y: section_h * 2},
                    {x: 48, y: section_h * 1}
                ];
            } else if(startPage == 2 && endPage == 3) {
                console.log('Page 2 > 3');
                startPts = [
                    {x: 48, y: section_h * 1},
                    {x: 48, y: section_h * 2}
                ];
                endPts = [
                    {x: 48, y: section_h * 3},
                    {x: 48, y: section_h * 2}
                ];
            } else if(startPage == 3 && endPage == 4) {
                console.log('Page 3 > 4');
                startPts = [
                    {x: 48, y: section_h * 2},
                    {x: 48, y: section_h * 3}
                ];
                endPts = [
                    {x: 48, y: section_h * 4},
                    {x: 48, y: section_h * 3}
                ];
            } else if(startPage == 4 && endPage == 3) {
                console.log('Page 4 > 3');
                startPts = [
                    {x: 48, y: section_h * 4},
                    {x: 48, y: section_h * 3}
                ];
                endPts = [
                    {x: 48, y: section_h * 2},
                    {x: 48, y: section_h * 3}
                ];
            } else if(startPage == 3 && endPage == 2) {
                console.log('Page 3 > 2');
                startPts = [
                    {x: 48, y: section_h * 2},
                    {x: 48, y: section_h * 3}
                ];
                endPts = [
                    {x: 48, y: section_h * 2},
                    {x: 48, y: section_h * 1}
                ];
            } else if(startPage == 2 && endPage == 1) {
                console.log('Page 2 > 1');
                startPts = [
                    {x: 48, y: section_h * 2},
                    {x: 48, y: section_h * 1}
                ];
                endPts = [
                    {x: 48, y: section_h * 0},
                    {x: 48, y: section_h * 1}
                ];
            } else {
                console.log('Others: ' + startPage + ' > ' + endPage);
            }
            canvas.remove(line);
            line = new fabric.Polyline(startPts, line_options);
            canvas.add(line);
            for(var i = 0, len = startPts.length; i < len; i++) {
                animateLine(i, 'y', even ? endPts : startPts); 
            }
            is_animating = false;
        }
    }

    var even = true;
    $('.contents').panelSnap({
        $menu: false, // the menu DOM object
        onSnapStart: function($target) {
            if($target.data('panel') == 'page2') {
                animate(current_page, 2);
            } else if($target.data('panel') == 'page3') {
                animate(current_page, 3);
            } else if($target.data('panel') == 'page4') {
                animate(current_page, 4);
            } else if($target.data('panel') == 'page1') {
                animate(current_page, 1);
            } 
        },
        onSnapFinish: function($target) {
            current_page = parseInt($target.data('panel').replace('page', ''));
            console.log('Current Page: ' + current_page);
        }

    });
});

这里是JSFiddle

【问题讨论】:

    标签: javascript jquery animation fabricjs


    【解决方案1】:

    我已经看到其他框架中的动画在使用相对尺寸时会失败,但在使用绝对尺寸值时会成功。我开始玩你的小提琴,使用一些额外的 js 开始将高度和宽度的值设置为 px 值而不是 % 值,它看起来很有希望。

    这适用于 JSFiddle 容器。

    $('html, body').css({'height':$('.contents').height()+'px','width':$('.contents').width()+'px'});
      $('.indicator .section').css({'height':$('.contents').height/4+'px'});
    

    如果您需要响应式设计,您可以尝试朝这个方向前进。我怀疑你正在做的事情会有几个这样的调整来确定事情。

    【讨论】:

    • 谢谢。会朝这个方向努力。我有问题的代码已经修复了&lt;canvas&gt; 的宽度和高度,因为 100% 的高度会使画布内容变得模糊。
    猜你喜欢
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多