我正在使用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
答案 0 :(得分:1)
我已经看到其他框架中的动画因相对大小而失败,但是使用绝对大小值成功。我开始玩你的小提琴使用一些额外的js开始设置高度和宽度的值到px值而不是%值,它看起来很有希望。
这适用于JSFiddle容器。
$('html, body').css({'height':$('.contents').height()+'px','width':$('.contents').width()+'px'});
$('.indicator .section').css({'height':$('.contents').height/4+'px'});
如果您需要响应式设计,您可以尝试朝着这个方向前进。我怀疑你正在做什么,会有几个这样的调整,以便把事情固定下来。