Snap.svg: 动画使用 mina() 沿着螺旋画线
Snap.svg: Animation using mina() to draw lines along spiral
我有一个动画对象,AnimateJS,在下面的例子中。它的功能是沿着螺旋线画线。
我想将其转换为 Snap 的 mina()。我在应用各种 mina 属性来实现这一点时遇到了一些困难。
如有任何帮助,我们将不胜感激。
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="http://svgDiscovery.com/_SNP/snap.svg-min.js"></script>
</head>
<body onload="setTimeout(runAnimLinear,1000)" >
<h4>Draw Spiraled Lines</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
Use Snap to animate lines drawn along a spiral </div>
<table><tr>
<td>
<table>
<tr><td colspan=2><b>This Example's AnimateJS Settings:</b></td></tr>
<tr><td>1. Smoothness</td><td>80 frames per second</td></tr>
<tr><td>2. Duration</td><td>3000 - runtime in ms</td></tr>
<tr><td>3. Range</td><td> 720 degrees : ending/maximum value</td></tr>
<tr><td>4. Output Equation</td><td><span style=color:blue>function</span> linear(p){return p} </td></tr>
<tr><td>5. Application Output </td><td><span style=color:blue>function</span> addToSpiral(angle)</td></tr>
</table><p></p>
The above values to be used in <b>mina(a, A, b, B, get, set, [easing])</b> <br>
<textarea style=border-width:0px;width:400px;height:180px;>
Parameters:
a - start slave number
A - end slave number
b - start master number (start time in general case)
B - end master number (end time in general case)
get - getter of master number (see mina.time)
set - setter of slave number
easing - oneasing function, default is mina.linear
</textarea>
</td>
<td>
<div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400">
</svg>
</div>
<center><button disabled id=runAgainButton onClick=clearLines();runAnimLinear();this.disabled=true>run again</button></center>
</td>
</tr> </table>
</center>
<script>
var SNPsvg = Snap("#mySVG");
var SpiralG = SNPsvg.g().attr({id:'SpiralG',strokeWidth:1,stroke:'black' });
/*---generalized animate core function
Allows progress/output to follow a specific/customized equation(delta)
by: Ilya Kantor - http://javascript.info/tutorial/animation
*/
var AnimateJS=function(options){
this.options=options
var start = new Date
var iT = setInterval(
function(){
var timePassed = new Date - start
var progress = timePassed / options.duration
if (progress > 1) progress = 1
this.progress=progress
var delta = options.delta(progress)
options.output(delta)
if (progress == 1)clearInterval(iT);
},options.delay)
}
//--onload, and 'run again' button---
function runAnimLinear()
{
var range=720 //--degrees: 2 revs---
var FPS=80 //---Frames Per Second = smoothness--
var delay=1000/FPS //---delay---
var duration=3000 //---duration ms, 3 seconds---
var delta=function linear(p){return p}//---linear---
//---this animation---
new AnimateJS({delay:delay,duration:duration,delta:delta,output:
function(delta)//---output: delta=0.0 thru 1.0---
{
addToSpiral(range * delta )
if(progress==1) //---finished---
{
runAgainButton.disabled=false
}
}})
}
//---fired at each output request---
function addToSpiral(angle)
{
radius = Constant*angle;
offsetX = radius*Math.cos(angle*Math.PI/180);
offsetY = radius*Math.sin(angle*Math.PI/180);
currentX = basePointX+offsetX;
currentY = basePointY-offsetY;
// add perpendicular line segments...
lineX = lineHHLength*Math.cos(
branches*angle*Math.PI/180);
lineY = lineHHLength*Math.sin(
branches*angle*Math.PI/180);
fromX = currentX-lineX;
fromY = currentY+lineY;
destX = currentX+lineX;
destY = currentY-lineY;
lineNode = SNPsvg.line(fromX,fromY,destX,destY)
SpiralG.append(lineNode);
lineX = lineHHLength*Math.cos(
branches*(angle+90)*Math.PI/180);
lineY = lineHHLength*Math.sin(
branches*(angle+90)*Math.PI/180);
fromX = currentX-lineX;
fromY = currentY+lineY;
destX = currentX+lineX;
destY = currentY-lineY;
lineNode = SNPsvg.line(fromX,fromY,destX,destY)
SpiralG.append(lineNode);
}
//--fired on 'run again' ---
function clearLines()
{
SpiralG.clear()
}
//----spiral variables---
var basePointX = 180.;
var basePointY = 170.;
var currentX = 0.;
var currentY = 0.;
var offsetX = 0.;
var offsetY = 0.;
var radius = 0.;
var minorAxis = 12;
var majorAxis = 20.;
var Constant = 0.25;
var fromX = 0.;
var fromY = 0.;
var destX = 0.;
var destY = 0.;
var lineX = 0.;
var lineY = 0.;
var branches = 3.;
var lineHVLength = 2*minorAxis;
var lineHHLength = 2*majorAxis;
var lineNode = null;
</script>
</body>
</html>
你真的需要米娜吗? Snap 有一个名为 Snap.animate() 的通用动画方法(文档 here)。这不会作用于特定元素(与 element.animate() 不同);因此,您很少需要专门与 mina 相处(我认为我从来不需要这样做),但请注意,这并没有专门回答您的问题。
前两个参数是起始值和结束值(注意,它也可以采用值数组,我认为可以在它们之间进行插值)。这些将在两者之间进行插值(就像我在原始代码中认为的增量)。
第三个参数是每次调用的函数。 val/delta 被传递给这个函数。
第四个参数是缓动(所以 mina.linear 这里需要)。
第 5 个参数是回调(因此如果需要,我们再次将按钮重置为 运行 动画)
主要核心就是这个转换函数..
function runAnimLinear() {
var range=720 //--degrees: 2 revs---
var duration=3000 //---duration ms, 3 seconds---
Snap.animate(0, 1, function( delta ) {
addToSpiral( range * delta )
}, duration, mina.linear, function() { runAgainButton.disabled=false } );
}
其余的我保留原样。
但是,现在这里有一些问题,取决于是否真的需要平滑度之类的东西,所以不太一样。如果是这样,我 'think' 它需要另一种解决方案,这会稍微复杂一些,我不确定是否有足够的理由不使用原始方案。如果这是您需要使用 mina 的特定原因,可以将其添加到问题中。
这里使用 mina 来说明它是如何工作的。
var anim = mina( 0, 1, mina.time(), mina.time() + duration, mina.time,
function( delta ) { addToSpiral( range * delta )})
//callback using eve, referencing the id of the animation from above
eve.once("mina.finish." + anim.id, function () {
runAgainButton.disabled=false
});
我有一个动画对象,AnimateJS,在下面的例子中。它的功能是沿着螺旋线画线。
我想将其转换为 Snap 的 mina()。我在应用各种 mina 属性来实现这一点时遇到了一些困难。
如有任何帮助,我们将不胜感激。
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="http://svgDiscovery.com/_SNP/snap.svg-min.js"></script>
</head>
<body onload="setTimeout(runAnimLinear,1000)" >
<h4>Draw Spiraled Lines</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
Use Snap to animate lines drawn along a spiral </div>
<table><tr>
<td>
<table>
<tr><td colspan=2><b>This Example's AnimateJS Settings:</b></td></tr>
<tr><td>1. Smoothness</td><td>80 frames per second</td></tr>
<tr><td>2. Duration</td><td>3000 - runtime in ms</td></tr>
<tr><td>3. Range</td><td> 720 degrees : ending/maximum value</td></tr>
<tr><td>4. Output Equation</td><td><span style=color:blue>function</span> linear(p){return p} </td></tr>
<tr><td>5. Application Output </td><td><span style=color:blue>function</span> addToSpiral(angle)</td></tr>
</table><p></p>
The above values to be used in <b>mina(a, A, b, B, get, set, [easing])</b> <br>
<textarea style=border-width:0px;width:400px;height:180px;>
Parameters:
a - start slave number
A - end slave number
b - start master number (start time in general case)
B - end master number (end time in general case)
get - getter of master number (see mina.time)
set - setter of slave number
easing - oneasing function, default is mina.linear
</textarea>
</td>
<td>
<div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400">
</svg>
</div>
<center><button disabled id=runAgainButton onClick=clearLines();runAnimLinear();this.disabled=true>run again</button></center>
</td>
</tr> </table>
</center>
<script>
var SNPsvg = Snap("#mySVG");
var SpiralG = SNPsvg.g().attr({id:'SpiralG',strokeWidth:1,stroke:'black' });
/*---generalized animate core function
Allows progress/output to follow a specific/customized equation(delta)
by: Ilya Kantor - http://javascript.info/tutorial/animation
*/
var AnimateJS=function(options){
this.options=options
var start = new Date
var iT = setInterval(
function(){
var timePassed = new Date - start
var progress = timePassed / options.duration
if (progress > 1) progress = 1
this.progress=progress
var delta = options.delta(progress)
options.output(delta)
if (progress == 1)clearInterval(iT);
},options.delay)
}
//--onload, and 'run again' button---
function runAnimLinear()
{
var range=720 //--degrees: 2 revs---
var FPS=80 //---Frames Per Second = smoothness--
var delay=1000/FPS //---delay---
var duration=3000 //---duration ms, 3 seconds---
var delta=function linear(p){return p}//---linear---
//---this animation---
new AnimateJS({delay:delay,duration:duration,delta:delta,output:
function(delta)//---output: delta=0.0 thru 1.0---
{
addToSpiral(range * delta )
if(progress==1) //---finished---
{
runAgainButton.disabled=false
}
}})
}
//---fired at each output request---
function addToSpiral(angle)
{
radius = Constant*angle;
offsetX = radius*Math.cos(angle*Math.PI/180);
offsetY = radius*Math.sin(angle*Math.PI/180);
currentX = basePointX+offsetX;
currentY = basePointY-offsetY;
// add perpendicular line segments...
lineX = lineHHLength*Math.cos(
branches*angle*Math.PI/180);
lineY = lineHHLength*Math.sin(
branches*angle*Math.PI/180);
fromX = currentX-lineX;
fromY = currentY+lineY;
destX = currentX+lineX;
destY = currentY-lineY;
lineNode = SNPsvg.line(fromX,fromY,destX,destY)
SpiralG.append(lineNode);
lineX = lineHHLength*Math.cos(
branches*(angle+90)*Math.PI/180);
lineY = lineHHLength*Math.sin(
branches*(angle+90)*Math.PI/180);
fromX = currentX-lineX;
fromY = currentY+lineY;
destX = currentX+lineX;
destY = currentY-lineY;
lineNode = SNPsvg.line(fromX,fromY,destX,destY)
SpiralG.append(lineNode);
}
//--fired on 'run again' ---
function clearLines()
{
SpiralG.clear()
}
//----spiral variables---
var basePointX = 180.;
var basePointY = 170.;
var currentX = 0.;
var currentY = 0.;
var offsetX = 0.;
var offsetY = 0.;
var radius = 0.;
var minorAxis = 12;
var majorAxis = 20.;
var Constant = 0.25;
var fromX = 0.;
var fromY = 0.;
var destX = 0.;
var destY = 0.;
var lineX = 0.;
var lineY = 0.;
var branches = 3.;
var lineHVLength = 2*minorAxis;
var lineHHLength = 2*majorAxis;
var lineNode = null;
</script>
</body>
</html>
你真的需要米娜吗? Snap 有一个名为 Snap.animate() 的通用动画方法(文档 here)。这不会作用于特定元素(与 element.animate() 不同);因此,您很少需要专门与 mina 相处(我认为我从来不需要这样做),但请注意,这并没有专门回答您的问题。
前两个参数是起始值和结束值(注意,它也可以采用值数组,我认为可以在它们之间进行插值)。这些将在两者之间进行插值(就像我在原始代码中认为的增量)。
第三个参数是每次调用的函数。 val/delta 被传递给这个函数。
第四个参数是缓动(所以 mina.linear 这里需要)。
第 5 个参数是回调(因此如果需要,我们再次将按钮重置为 运行 动画)
主要核心就是这个转换函数..
function runAnimLinear() {
var range=720 //--degrees: 2 revs---
var duration=3000 //---duration ms, 3 seconds---
Snap.animate(0, 1, function( delta ) {
addToSpiral( range * delta )
}, duration, mina.linear, function() { runAgainButton.disabled=false } );
}
其余的我保留原样。
但是,现在这里有一些问题,取决于是否真的需要平滑度之类的东西,所以不太一样。如果是这样,我 'think' 它需要另一种解决方案,这会稍微复杂一些,我不确定是否有足够的理由不使用原始方案。如果这是您需要使用 mina 的特定原因,可以将其添加到问题中。
这里使用 mina 来说明它是如何工作的。
var anim = mina( 0, 1, mina.time(), mina.time() + duration, mina.time,
function( delta ) { addToSpiral( range * delta )})
//callback using eve, referencing the id of the animation from above
eve.once("mina.finish." + anim.id, function () {
runAgainButton.disabled=false
});