如何使用贝塞尔曲线轨迹绘制动画

时间:2014-12-02 17:07:19

标签: javascript html5

如何绘制我的蝴蝶动画:http://jsfiddle.net/38pnog5s/4/,其动作如下图所示:enter image description here

我想画出我的蝴蝶在画布上移动,就像附上的照片一样,但是蝴蝶还在晃动。

我尝试设置不同的变量,1。用于掠过运动的变量,2。用于贝塞尔曲线移动的变量。然后我将我的第二个变量放在第一个变量中但它移动得如此奇怪。

这是蝴蝶随着掠过运动随机移动的代码:

if (x >= 0) {
if (x <= 450) {
    if (y >= 0) {
        if (y <= 450) {
            if (Math.floor(Math.random() * 4) == 0) {
                x = x + Math.random() + 15;
            }
            if (Math.floor(Math.random() * 4) == 2) {
                y = y + Math.random() + 15;
            }
            if (Math.floor(Math.random() * 4) == 1) {
                x = x - Math.random() - 15;

            }
            if (Math.floor(Math.random() * 4) == 3) {
                y = y - Math.random() - 15;

            }
            if (x < 0) {
                x = 0;
            }
            if (y < 0) {
                y = 0;
            }
            if (x > 450) {
                x = 450;
            }
            if (y > 450) {
                y = 450;
            }
            randomly[0] = x;
            randomly[1] = y;

1 个答案:

答案 0 :(得分:1)

[基于已更改问题的新答案]

这里有一个示例,展示如何在保持掠过效果的同时围绕立方贝塞尔曲线移动蝴蝶。请注意,在getCubicBezierXYatT

中完成了围绕曲线的导航

&#13;
&#13;
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var PI=Math.PI;
var PI2=PI*2;

var curve=[
  {x:110,y:150},
  {x:250,y:0},
  {x:50,y:0},
  {x:190,y:150},
];

  var sampleSize=1000;

  //var equiPoints=getEquidistantPointsOnCubicBezierCurve(curve,sampleSize);

  var nextTime=0;
  var delay=16*10;
  var interval=0.00;
  var intervalDelta=1/300;

  var bW=30;
  var bH=30;
  var bFlitX,bFlitY;
  var bNextFlit=0;
  var bFlitDelay=16*10;
  var butterfly=new Image();
  butterfly.onload=start;
  butterfly.src="http://es.fordesigner.com/imguploads/Image/cjbc/zcool/png20080526/1211766513.png";
  function start(){
  requestAnimationFrame(animate);
  }

  function animate(currentTime){
  if(interval<=1.00){requestAnimationFrame(animate);}

  var point=getCubicBezierXYatT(curve[0],curve[1],curve[2],curve[3],interval)

  ctx.clearRect(0,0,cw,ch);

ctx.beginPath();
ctx.moveTo(curve[0].x,curve[0].y);
ctx.bezierCurveTo(curve[1].x,curve[1].y,curve[2].x,curve[2].y,curve[3].x,curve[3].y);
ctx.stroke();

// calc flit
if(currentTime>bNextFlit){
  bNextFlit=currentTime+bFlitDelay;
  bFlitX=Math.random()*10-5;
  bFlitY=Math.random()*10-5;
}

ctx.drawImage(butterfly,point.x+bFlitX-bW/2,point.y+bFlitY-bH/2,bW,bH);

interval+=intervalDelta;

}


//////////////////////////////////////////////


// [x,y] on cubic Bezier at interval T
function getCubicBezierXYatT(startPt,controlPt1,controlPt2,endPt,T){
  var x=CubicN(T,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
  var y=CubicN(T,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
  return({x:x,y:y});
}
// cubic helper formula at T distance
function CubicN(T, a,b,c,d) {
  var t2 = T * T;
  var t3 = t2 * T;
  return a + (-a * 3 + T * (3 * a - a * T)) * T
  + (3 * b + T * (-6 * b + b * 3 * T)) * T
  + (c * 3 - c * 3 * T) * t2
  + d * t3;
}
&#13;
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
&#13;
<canvas id="canvas" width=300 height=300></canvas>
&#13;
&#13;
&#13;