画布线条画动画

时间:2017-03-18 17:05:35

标签: javascript animation canvas html5-canvas

我是使用HTML5 Canvas的新动画学习者。我正在努力在画布中创建具有所需行长的线条绘制动画。

这是代码



var canvas = document.getElementById("canvas"),
  context = canvas.getContext("2d"),
  width = canvas.width = window.innerWidth,
  height = canvas.height = window.innerHeight;
var x = 200;
var y = 200;
draw();
update();

function draw() {
  context.beginPath();
  context.moveTo(100, 100);
  context.lineTo(x, y);
  context.stroke();
}

function update() {
  context.clearRect(0, 0, width, height);
  x = x + 1;
  y = y + 1;
  draw();
  requestAnimationFrame(update);
}

html,
body {
  margin: 0px;
}

canvas {
  display: block;
}

<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;

以上代码中Canvas上的这条线正在增长。但是如何实现200px宽线并在x和y方向上制作动画。和使用for循环的多行相同的动画并将它们移动到不同的方向。

检查参考图像....
enter image description here

需要沿不同方向移动每一行

提前致谢

enter image description here

找到我想要实现的新参考图像

3 个答案:

答案 0 :(得分:2)

以下是我认为您正在描述的内容......

&#13;
&#13;
window.onload = function() {
  var canvas = document.getElementById("canvas"),
    context = canvas.getContext("2d"),
    width = canvas.width = 400,
    height = canvas.height = 220,
    xcenter = 200,
    ycenter = 110,
    radius = 0,
    radiusmax = 100,
    start_angle1 = 0,
    start_angle2 = 0;

  function toRadians(angle) {
    return angle * (Math.PI / 180);
  }

  function draw(x1, y1, x2, y2) {
    context.beginPath();
    context.moveTo(x1, y1);
    context.lineTo(x2, y2);
    context.stroke();
  }

  function drawWheel(xc, yc, start_angle, count, rad) {
    var inc = 360 / count;
    for (var angle = start_angle; angle < start_angle + 180; angle += inc) {
      var x = Math.cos(toRadians(angle)) * rad;
      var y = Math.sin(toRadians(angle)) * rad;
      draw(xc - x, yc - y, xc + x, yc + y);
    }
  }

  function update() {
    start_angle1 += 0.1;
    start_angle2 -= 0.1;
    if(radius<radiusmax) radius++;
    context.clearRect(0, 0, width, height);
    drawWheel(xcenter, ycenter, start_angle1, 40, radius);
    drawWheel(xcenter, ycenter, start_angle2, 40, radius);
    requestAnimationFrame(update);
  }


  update();
};
&#13;
html,
body {
  margin: 0px;
}

canvas {
  display: block;
}
&#13;
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

您需要使用变换或一些三角函数。

变换

对于每一帧:

  • 重置转换并转换为中心
  • 清除画布
  • 从中间向右画线
  • 旋转x角度
  • 从步骤2开始重复,直到绘制完所有行

&#13;
&#13;
var ctx = c.getContext("2d");
var centerX = c.width>>1;
var centerY = c.height>>1;
var maxLength = Math.min(centerX, centerY); // use the shortest direction for demo
var currentLength = 0;                      // current length, for animation
var lenStep = 1;                            // "speed" of animation

function render() {
  ctx.setTransform(1,0,0,1, centerX, centerY);
  ctx.clearRect(-centerX, -centerY, c.width, c.height);
  ctx.beginPath();
  
  for(var angle = 0, step = 0.1; angle < Math.PI * 2; angle += step) {
    ctx.moveTo(0, 0);
    ctx.lineTo(currentLength, 0);
    ctx.rotate(step);
  }
  ctx.stroke();  // stroke all at once
}

(function loop() {
  render();
  currentLength += lenStep;
  if (currentLength < maxLength) requestAnimationFrame(loop);
})();
&#13;
<canvas id=c></canvas>
&#13;
&#13;
&#13;

您可以通过不同的方式使用转换,但由于您正在学习,我在上面的代码中保持简单。

三角

您还可以使用三角函数手动计算线角度。在这里你可以使用不同的方法,即。如果你想使用数学隐式使用delta值,向量或暴力。

对于每一帧:

  • 重置转换并转换为中心
  • 清除画布
  • 计算每行的角度和方向
  • 画线

&#13;
&#13;
var ctx = c.getContext("2d");
var centerX = c.width>>1;
var centerY = c.height>>1;
var maxLength = Math.min(centerX, centerY); // use the shortest direction for demo
var currentLength = 0;                      // current length, for animation
var lenStep = 1;                            // "speed" of animation

ctx.setTransform(1,0,0,1, centerX, centerY);

function render() {
  ctx.clearRect(-centerX, -centerY, c.width, c.height);
  ctx.beginPath();
  
  for(var angle = 0, step = 0.1; angle < Math.PI * 2; angle += step) {
    ctx.moveTo(0, 0);
    ctx.lineTo(currentLength * Math.cos(angle), currentLength * Math.sin(angle));
  }
  ctx.stroke();  // stroke all at once
}

(function loop() {
  render();
  currentLength += lenStep;
  if (currentLength < maxLength) requestAnimationFrame(loop);
})();
&#13;
<canvas id=c></canvas>
&#13;
&#13;
&#13;

要使用的额外动画(使用与上述相同的基础):

&#13;
&#13;
var ctx = c.getContext("2d", {alpha: false});
var centerX = c.width>>1;
var centerY = c.height>>1;

ctx.setTransform(1,0,0,1, centerX, centerY);
ctx.lineWidth = 2;
ctx.strokeStyle = "rgba(0,0,0,0.8)";
ctx.shadowBlur = 16;

function render(time) {
  ctx.globalAlpha=0.77;
  ctx.fillRect(-500, -500, 1000, 1000);
  ctx.globalAlpha=1;
  ctx.beginPath();
  ctx.rotate(0.025);
  ctx.shadowColor = "hsl(" + time*0.1 + ",100%,75%)";
  ctx.shadowBlur = 16;
  
  for(var angle = 0, step = Math.PI / ((time % 200) + 50); angle < Math.PI * 2; angle += step) {
    ctx.moveTo(0, 0);
    var len = 150 + 150 * Math.cos(time*0.0001618*angle*Math.tan(time*0.00025)) * Math.sin(time*0.01);
    ctx.lineTo(len * Math.cos(angle), len * Math.sin(angle));
  }
  ctx.stroke();
  ctx.globalCompositeOperation = "lighter";
  ctx.shadowBlur = 0;
  ctx.drawImage(ctx.canvas, -centerX, -centerY);
  ctx.drawImage(ctx.canvas, -centerX, -centerY);
  ctx.globalCompositeOperation = "source-over";
}

function loop(time) {
  render(time);
  requestAnimationFrame(loop);
};
requestAnimationFrame(loop);
&#13;
body {margin:0;background:#222}
&#13;
<canvas id=c width=640 height=640></canvas>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

这是一个可变长度的新兴模式。它有一个长度数组元素,用于车轮中每个轮辐以不同的速率增长。您可以使用设置来改变结果:

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = canvas.width = window.innerWidth;
var height = canvas.height = window.innerHeight;

var xcenter = width/4;
var ycenter = height/2;
var radius;
var time;

if(width>height) {
    radius = height*0.4;
}
else {
    radius = width*0.4;
}

var start_angle1 = 0;
var start_angle2 = 0;

function toRadians (angle) {
  return angle * (Math.PI / 180);
}
function draw(x1,y1,x2,y2) {
  context.beginPath();
  context.moveTo(x1,y1);
  context.lineTo(x2,y2);
  context.stroke();
}
var radmax=width;
var rads = [];
var radsinc = [];
function drawWheel(xc,yc,start_angle,count,rad) {
    var inc = 360/count;
    var i=0;
    for(var angle=start_angle; angle < start_angle+180; angle +=inc) {
        var x = Math.cos(toRadians(angle)) * rads[rad+i];
        var y = Math.sin(toRadians(angle)) * rads[rad+i];
        draw(xc-x,yc-y,xc+x,yc+y);
        rads[rad+i] += radsinc[i];
        if(rads[rad+i] > radmax) rads[rad+i] = 1;
        i++;
    }
}
function update() {
    var now = new Date().getTime();
    var dt = now - (time || now);
    time = now;
    start_angle1 += (dt/1000) * 10;
    start_angle2 -= (dt/1000) * 10;
    context.clearRect(0,0,width,height);                
    drawWheel(xcenter,ycenter,start_angle1,50,0);     
    drawWheel(xcenter,ycenter,start_angle2,50,50);     
    requestAnimationFrame(update);
}
function init() {
    for(var i=0;i<100;i++) {
        rads[i] = 0;
        radsinc[i] = Math.random() * 10;
    }
}

window.onload = function() {
  init();
  update();
};
html, body {
            margin: 0px;

        }
        canvas {
        width:100%;
        height:200px;
            display: block;
        }
<canvas id="canvas"></canvas>