我想模拟千分表。仪表需要有多个框架才能显示不同的值。在这个jsfiddle示例中,仪表从30开始到80和150.我想运行各种各样的角度(30,80,150,200,90,24 ....)。不幸的是,代码将需要多个不可扩展的功能。
var s = Snap("#svg836");
var textval=s.select("#text846");
var canvasSize = 400,
centre = canvasSize/2,
radius = canvasSize*0.8/2,
s = Snap('.gauge'),
path = "",
startY = centre-radius,
arc = s.path(path);
function fill1(startpoint, endpoint) {
console.log("FILL1");
Snap.animate(startpoint, endpoint, function (val) {
console.log(path);
arc.remove();
var d = val,
dr = d-180;
radians = Math.PI*(dr)/180,
endx = centre + radius*Math.cos(radians),
endy = centre + radius * Math.sin(radians),
largeArc = d>180 ? 1 : 0;
path = "M"+startY+","+centre+" A"+radius+","+radius+" 0 "+largeArc+",1 "+endx+","+endy;
arc = s.path(path);
if (endpoint<=45)
{
arc.attr({
stroke: 'green',
fill: 'none',
strokeWidth: 44,
});
} else if (endpoint<=90){
arc.attr({
stroke: 'blue',
fill: 'none',
strokeWidth: 44,
});
} else if (endpoint<=135){
arc.attr({
stroke: 'yellow',
fill: 'none',
strokeWidth: 44,
});
} else {
arc.attr({
stroke: 'red',
fill: 'none',
strokeWidth: 44,
});
}
}, 1500, mina.backout, function (){
fill2(80,150);
});
}
function fill2(startpoint, endpoint) {
console.log("FILL2");
Snap.animate(startpoint, endpoint, function (val) {
arc.remove();
var d = val,
dr = d-180;
radians = Math.PI*(dr)/180,
endx = centre + radius*Math.cos(radians),
endy = centre + radius * Math.sin(radians),
largeArc = d>180 ? 1 : 0;
path = "M"+startY+","+centre+" A"+radius+","+radius+" 0 "+largeArc+",1 "+endx+","+endy;
console.log(path);
arc = s.path(path);
if (endpoint<=45)
{
arc.attr({
stroke: 'green',
fill: 'none',
strokeWidth: 44,
});
} else if (endpoint<=90){
arc.attr({
stroke: 'blue',
fill: 'none',
strokeWidth: 44,
});
} else if (endpoint<=135){
arc.attr({
stroke: 'yellow',
fill: 'none',
strokeWidth: 44,
});
} else {
arc.attr({
stroke: 'red',
fill: 'none',
strokeWidth: 44,
});
}
}, 1500, mina.backout);
}
startpoint=30;
endpoint=80;
fill1(startpoint, endpoint);
似乎有一种alternate方法来对动画进行排序。但是,我不清楚如何设置多个帧以使用该方法。
更新
基于this代码,jsfiddle已更新为this。我们的想法是创建一个函数数组(称为myFrames),每个函数代表一个序列。不幸的是,myFrames [0]确实运行如console.log所示,但myFrames [1]会立即被触发,因此永远不会绘制myFrames [0]的动画。
任何提示?
Snap.plugin( function( Snap, Element, Paper, global ) {
function nextSequence ( sequenceArray, whichSequence ) {
// we're finished
if( whichSequence >= sequenceArray.length ) { return }
// If we've just got one object and not an array of animations, place it in an array to iterative over. If 2nd param is number, its simple array form
var animations = ((sequenceArray[ whichSequence ].constructor === Array) && ( isNaN(parseFloat(sequenceArray[ whichSequence ][1]))) ) ? sequenceArray[ whichSequence ] : [ sequenceArray[ whichSequence ] ];
// Lets go through the next animation sequence, deal with concurrent/synced animations within a sequence
for( var animCount = 0; animCount < animations.length; animCount++) {
var thisEl = this;
// closure for multiple animations, as we don't want to call the next sequence more than one time
(function(){
var animation = animations[ animCount ];
var el = animation.el || thisEl;
var lastConcurrentAnim = animCount == animations.length - 1 ? 1 : 0;
// deal with a function call returning Snap.animate(0,1....) or something, just must have a dur
if( typeof animation === 'function') {
var animFunc = animation.call( el );
var duration = ( animFunc && animFunc.dur ) ? animFunc.dur : 0;
if( lastConcurrentAnim ) // finally call the next main sequence
setTimeout( nextSequence.bind( el, sequenceArray, whichSequence + 1 ), duration )
} else { // all the other standard possible animation objects and arrays
if( typeof animation.onStart === 'function' ) animation.onStart.call(sequenceArray[ whichSequence ].el)
el.animate(
animation.attr || animation[0],
animation.dur || animation[1],
animation.easing || animation[2] || mina.linear,
function() {
var callback = animation.callback || animation[3];
if( callback ) callback.call( el )
if( lastConcurrentAnim ) // finally call the next main sequence
nextSequence.call( el, sequenceArray, whichSequence + 1 ) // callback after each
}
);
};
})();
}; // end for loop
thisEl = el = null;
};
// Takes an array of sequences..these contain either a Snap animation OR
// el: element (optional), attrs: animations to change (required), dur: duration (required), onStart: function to perform on start, onEnd: function to perform on end
Element.prototype.animateSequence = function( animSequence ) {
nextSequence.call( this, animSequence, 0 );
};
});
var s = Snap("#svg836");
var textval=s.select("#text846");
var canvasSize = 400,
centre = canvasSize/2,
radius = canvasSize*0.8/2,
s = Snap('.gauge'),
path = "",
startY = centre-radius,
arc = s.path(path);
var d = 20,
dr = d-180;
radians = Math.PI*(dr)/180,
endx = centre + radius*Math.cos(radians),
endy = centre + radius * Math.sin(radians),
largeArc = d>180 ? 1 : 0;
path = "M"+startY+","+centre+" A"+radius+","+radius+" 0 "+largeArc+",1 "+endx+","+endy;
arc = s.path(path);
var dur = 2000;
//Create function to draw an arc
function drawarc(startpoint,endpoint) { return Snap.animate( startpoint,endpoint, function (val) {
arc.remove();
var d = val,
dr = d-180;
radians = Math.PI*(dr)/180,
endx = centre + radius*Math.cos(radians),
endy = centre + radius * Math.sin(radians),
largeArc = d>180 ? 1 : 0;
path = "M"+startY+","+centre+" A"+radius+","+radius+" 0 "+largeArc+",1 "+endx+","+endy;
arc = s.path(path);
if (endpoint<=45)
{
arc.attr({
stroke: 'green',
fill: 'none',
strokeWidth: 44,
});
} else if (endpoint<=90){
arc.attr({
stroke: 'blue',
fill: 'none',
strokeWidth: 44,
});
} else if (endpoint<=135){
arc.attr({
stroke: 'yellow',
fill: 'none',
strokeWidth: 44,
});
} else {
arc.attr({
stroke: 'red',
fill: 'none',
strokeWidth: 44,
});
}
}, dur, function() {
console.log("animation step complete with " + endpoint);
}
);
}
//Embed drawarc in another function to create an array of functions
function func(startpoint,endpoint){
return function(){
drawarc(startpoint,endpoint);
}
}
//Create an array of functions
var mypoints=[0,30,150];
var myFrames =[];
var i;
for (i = 1; i < mypoints.length; i++)
{
var startpoint=mypoints[i-1];
var endpoint=mypoints[i];
myFrames.push(func(startpoint, endpoint));
}
var sequence = [
myFrames[0],
myFrames[1]
];
arc.animateSequence( sequence );
答案 0 :(得分:0)
原始的序列代码会占用很多位,而且你能给它的东西并不明显。
如果它是一个函数,它需要至少返回一个带有dur(持续时间)的对象,例如
return { dur: 2000 }
如果是一个Snap.animation调用,这已经返回一个持续时间的对象,所以我认为没有必要。
但是,如果它是一个Snap.animate()调用,我们只通过执行它来知道持续时间。如果我们执行它,动画已经在运行,这是不行的。
因此,如果你想使用一个函数,你需要做类似......
的事情function func2(startpoint,endpoint) {
return function(){ drawarc(startpoint,endpoint);
return { dur: dur };
}
}
它可能看起来不直观,因为动画本身已经有了持续时间,但由于你在函数中做其他事情(例如调用drawarc),它不知道这个持续时间。