最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Canvas line drawing animation - Stack Overflow

programmeradmin5浏览0评论

I am new learner of animation using HTML5 Canvas. I am struggling to create line drawing animation in a canvas with desired length of a line.

Here is the code

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>

I am new learner of animation using HTML5 Canvas. I am struggling to create line drawing animation in a canvas with desired length of a line.

Here is the code

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>

The line is growing on Canvas in the above code. But how to achieve that the 200px wide line and animate the movement in x and y direction. And the same animation with multiple lines using for loop and move them in different direction.

Check the reference image ....

Need to move each line in a different direction

Thanks in advance

Find a new reference image which i want to achieve

Share Improve this question edited Mar 19, 2017 at 14:06 Yesvinkumar asked Mar 18, 2017 at 17:05 YesvinkumarYesvinkumar 55911 silver badges28 bronze badges 1
  • To clarify, if we number the lines in your reference image from 1 to n, then do you want the odd numbered lines to go in one direction (clockwise perhaps) and the even numbered lines to go in the other direction (counter-clockwise) ? – fmacdee Commented Mar 18, 2017 at 17:39
Add a ment  | 

3 Answers 3

Reset to default 5

You need to either use transforms or a bit of trigonometry.

Transforms

For each frame:

  • Reset transforms and translate to center
  • Clear canvas
  • Draw line from center to the right
  • Rotate x angle
  • Repeat from step 2 until all lines are drawn

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);
})();
<canvas id=c></canvas>

You can use transformation different ways, but since you're learning I kept it simple in the above code.

Trigonometry

You can also calculate the line angles manually using trigonometry. Also here you can use different approaches, ie. if you want to use delta values, vectors or brute force using the math implicit.

For each frame:

  • Reset transforms and translate to center
  • Clear canvas
  • Calculate angle and direction for each line
  • Draw line

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);
})();
<canvas id=c></canvas>

Bonus animation to play around with (using the same basis as above):

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);
body {margin:0;background:#222}
<canvas id=c width=640 height=640></canvas>

Here is what I think you are describing...

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();
};
html,
body {
  margin: 0px;
}

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

This is one that is a variable length emerging pattern. It has a length array element for each spoke in the wheel that grows at a different rate. You can play with the settings to vary the results:

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>

发布评论

评论列表(0)

  1. 暂无评论