使用JavaScript单击时的Buggy canvas动画
每次用户单击画布时,我都尝试运行一个简单的动画。我肯定我做错了什么,因为动画片有时甚至不会开火。我以前从未使用过画布动画,很难理解如何在使用JavaScript单击时的Buggy canvas动画,javascript,animation,html5-canvas,Javascript,Animation,Html5 Canvas,每次用户单击画布时,我都尝试运行一个简单的动画。我肯定我做错了什么,因为动画片有时甚至不会开火。我以前从未使用过画布动画,很难理解如何在for循环中构造画布动画 fgCanvas.on('mousedown', function(e) { var cX = Math.round((e.offsetX - m) / gS), cY = Math.round((e.offsetY - m) / gS); clickDot({x:cX,y:cY}); }); function
for
循环中构造画布动画
fgCanvas.on('mousedown', function(e) {
var cX = Math.round((e.offsetX - m) / gS),
cY = Math.round((e.offsetY - m) / gS);
clickDot({x:cX,y:cY});
});
function clickDot(data) {
for (var i = 1; i < 100; i++) {
fctx.clearRect(0, 0, pW, pH);
fctx.beginPath();
fctx.arc(data.x * gS + m, data.y * gS + m, i/10, 0, Math.PI * 2);
fctx.strokeStyle = 'rgba(255,255,255,' + i/10 + ')';
fctx.stroke();
}
requestAnimationFrame(clickDot);
}
fgCanvas.on('mousedown',函数(e){
var cX=数学四舍五入((e.offsetX-m)/gS),
cY=数学圆((e.offsetY-m)/gS);
点击点({x:cX,y:cY});
});
功能点击点(数据){
对于(变量i=1;i<100;i++){
fctx.clearRect(0,0,pW,pH);
fctx.beginPath();
fctx.arc(data.x*gS+m,data.y*gS+m,i/10,0,Math.PI*2);
fctx.strokeStyle='rgba(255255255,+i/10+');
fctx.stroke();
}
请求动画帧(点击点);
}
完整代码如下:
另一个问题是如何减慢动画或添加一些缓和,以便在环消失时在接近结束时绘制得更慢?您可以使用
requestAnimationFrame
加上缓和功能来创建所需的效果:
演示:
requestAnimationFrame自己创建一个动画循环——因此不需要在requestAnimationFrame的动画循环中使用for循环
以最简单的形式,此requestAnimationFrame循环将为圆设置动画:
var counter=1;
animate();
function animate(){
// stop the animation after it has run 100 times
if(counter>100){return;}
// there's more animating to do, so request another loop
requestAnimationFrame(animate);
// calc the circle radius
var radius=counter/10;
// draw your circle
}
要使动画加速或减速,可以使用easings
。测量值会随着时间的推移更改一个值(如半径),但它们会不均匀地更改该值。在动画持续时间内加速和减速
罗伯特·彭纳(Robert Penner)提出了一套很棒的放松算法。Dan Rogers用javascript编写了代码:
你可以在这里看到他的放松功能的工作示例:
下面是使用requestAnimationFrame
pluseasings
为圆设置动画的注释代码
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
// set the context styles
ctx.lineWidth=1;
ctx.strokeStyle="gold";
ctx.fillStyle="#888";
// variables used to draw & animate the ring
var PI2=Math.PI*2;
var ringX,ringY,ringRadius,ingCounter,ringCounterVelocity;
// fill the canvas with a background color
ctx.fillRect(0,0,canvas.width,canvas.height);
// tell handleMouseDown to handle all mousedown events
$("#canvas").mousedown(function(e){handleMouseDown(e);});
// set the ring variables and start the animation
function ring(x,y){
ringX=x;
ringY=y;
ringRadius=0;
ringCounter=0;
ringCounterVelocity=4;
requestAnimationFrame(animate);
}
// the animation loop
function animate(){
// return if the animation is complete
if(ringCounter>200){return;}
// otherwise request another animation loop
requestAnimationFrame(animate);
// ringCounter<100 means the ring is expanding
// ringCounter>=100 means the ring is shrinking
if(ringCounter<100){
// expand the ring using easeInCubic easing
ringRadius=easeInCubic(ringCounter,0,15,100);
}else{
// shrink the ring using easeOutCubic easing
ringRadius=easeOutCubic(ringCounter-100,15,-15,100);
}
// draw the ring at the radius set using the easing functions
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.arc(ringX,ringY,ringRadius,0,PI2);
ctx.closePath();
ctx.stroke();
// increment the ringCounter for the next loop
ringCounter+=ringCounterVelocity;
}
// Robert Penner's easing functions coded by Dan Rogers
//
// https://github.com/danro/jquery-easing/blob/master/jquery.easing.js
//
// now=elapsed time,
// startValue=value at start of easing,
// deltaValue=amount the value will change during the easing,
// duration=total time for easing
function easeInCubic(now, startValue, deltaValue, duration) {
return deltaValue*(now/=duration)*now*now + startValue;
}
function easeOutCubic(now, startValue, deltaValue, duration) {
return deltaValue*((now=now/duration-1)*now*now + 1) + startValue;
}
// handle mousedown events
function handleMouseDown(e){
// tell the browser we'll handle this event
e.preventDefault();
e.stopPropagation();
// calc the mouse position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// animate a ring at the mouse position
ring(mouseX,mouseY);
}
}); // end $(function(){});
</script>
</head>
<body>
<h4>Click in the canvas to draw animated circle with easings.</h4>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
#画布{边框:1px纯红;}
$(函数(){
//画布相关变量
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var$canvas=$(“#canvas”);
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
//设置上下文样式
ctx.线宽=1;
ctx.strokeStyle=“黄金”;
ctx.fillStyle=“#888”;
//用于绘制环并设置环动画的变量
var PI2=数学PI*2;
var ringX,ringY,ringRadius,ingCounter,ringCounterVelocity;
//用背景色填充画布
ctx.fillRect(0,0,canvas.width,canvas.height);
//告诉handleMouseDown处理所有mousedown事件
$(“#canvas”).mousedown(函数(e){handleMouseDown(e);});
//设置环变量并启动动画
功能环(x,y){
环x=x;
环形=y;
环半径=0;
响铃计数器=0;
环对速度=4;
请求动画帧(动画);
}
//动画循环
函数animate(){
//如果动画完成,则返回
如果(响铃计数器>200){return;}
//否则,请求另一个动画循环
请求动画帧(动画);
//ringCounter=100表示环正在收缩
很好的回答!谢谢。