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

javascript - Making a circle that moves - Stack Overflow

programmeradmin2浏览0评论

Been trying to get something to work in HTML and I haven't been able to nail it down quite yet. Basically, I want to create a canvas and then make a circle inside the canvas that moves from edge of the canvas to edge of the canvas. Any suggestions?

EDIT:

Folks wanted what I have so far, so here it is:

<html> 
<head> 
<script type="text/javascript">   
function draw () {
    var canvas = document.getElementById('circle');
    if (canvas.getContext) {
      var context = canvas.getContext('2d');

      context.fillStyle = "rgb(150,29,28)";
      var startPoint = (Math.PI/180)*0;
      var endPoint = (Math.PI/180)*360;
      context.beginPath(); 
      context.arc(200,200,150,startPoint,endPoint,true);    
      context.fill();
   context.closePath(); 
      }
    }   
} 
</script>
</head>
<body onload="init();"> 
<canvas id="canvas" width="500" height="500"></canvas><br>

</body> 
</html>

I'm not really sure how to get a circle onto the canvas (and I'm still shakey on the implementation thereof) as well as how to make it, y'know, move. I have examples of how to rotate something, but not really how to move it. Sorry for the inexperience guys, trying to learn HTML on my own, but the book I've got doesn't seem really descriptive on this aspect, even though it's a supposed to be teaching me HTML.

Been trying to get something to work in HTML and I haven't been able to nail it down quite yet. Basically, I want to create a canvas and then make a circle inside the canvas that moves from edge of the canvas to edge of the canvas. Any suggestions?

EDIT:

Folks wanted what I have so far, so here it is:

<html> 
<head> 
<script type="text/javascript">   
function draw () {
    var canvas = document.getElementById('circle');
    if (canvas.getContext) {
      var context = canvas.getContext('2d');

      context.fillStyle = "rgb(150,29,28)";
      var startPoint = (Math.PI/180)*0;
      var endPoint = (Math.PI/180)*360;
      context.beginPath(); 
      context.arc(200,200,150,startPoint,endPoint,true);    
      context.fill();
   context.closePath(); 
      }
    }   
} 
</script>
</head>
<body onload="init();"> 
<canvas id="canvas" width="500" height="500"></canvas><br>

</body> 
</html>

I'm not really sure how to get a circle onto the canvas (and I'm still shakey on the implementation thereof) as well as how to make it, y'know, move. I have examples of how to rotate something, but not really how to move it. Sorry for the inexperience guys, trying to learn HTML on my own, but the book I've got doesn't seem really descriptive on this aspect, even though it's a supposed to be teaching me HTML.

Share Improve this question edited Nov 7, 2012 at 15:35 Michael Myers 192k47 gold badges298 silver badges295 bronze badges asked Nov 7, 2012 at 14:08 user1806369user1806369 211 silver badge3 bronze badges 2
  • 7 wele to stackoverflow: what have you tried? – Daniel A. White Commented Nov 7, 2012 at 14:10
  • Online tutorials are your friend - html5canvastutorials./advanced/… – Paul Aldred-Bann Commented Nov 7, 2012 at 14:14
Add a ment  | 

2 Answers 2

Reset to default 5

So up to now you have a code where you're able to draw a circle at a certain position onto the canvas surface, very well, now in order to make it look like it's moving you'll have to keep drawing it again and again with it's position slightly changed to give a smooth motion effect to it, it's a standard to draw things 60 times per second (I think that's because 60 frames per second is the most that the human eye can notice, or whatever). And of course, each time you draw it on another position, it's going to be necessary to clear the older drawing.

Let's change your code just a bit in order to make it animation-friendly:

<script type="text/javascript">   
function init()
{
   canvas = document.getElementById('canvas');
   if(canvas.getContext)
      context = canvas.getContext('2d');
   else return;

   setInterval(draw, 1000 / 60); // 60 times per second
}

function draw()
{
   context.clearRect(0, 0, canvas.width, canvas.height);
   context.fillStyle = "rgb(150,29,28)";
   // var startPoint = (Math.PI/180)*0; Kinda redundant, it's just 0
   // var endPoint = (Math.PI/180)*360; Again, it's just PI times 2
   context.beginPath(); 
   context.arc(200, 200, 150, 0, Math.PI * 2, true);    
   context.fill();
   context.closePath(); 
} 
</script>
</head>
<body onload="init();"> 
<canvas id="canvas" width="500" height="500"></canvas><br>

Now there are lots of funny ways to make an object move towards a fixed point, but the simplest is, of course, moving along a straight line. To do so you'll need

  • A vector containing the object's current position
  • A vector containing the object's target position

Let's change your code so we have those at hand

var canvas, context,
    position = {x: 200, y: 200},
    target = {x: 400, y: 400};

function init()
{
    ...
}

function draw()
{
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.fillStyle = "rgb(150,29,28)";
    context.beginPath(); 
    context.arc(position.x, position.y, 150, 0, Math.PI * 2, true);    
    context.fill();
    context.closePath(); 
}

Good! This way whenever you change one of the values in the position object, the position of your circle is going to be affected.

If you subtract the current position from the target position you'll get another vector which points straight to the target position ing from the current position right? So get that vector and just normalize it, turning it's length to 1, the result will actually be the (cosine, sine) of the angle from the target to the object's position. What that means is if you add that normalized vector to the object's current position, the object will move towards the target position 1 unit at a time.

Normlizing a vector is simply dividing it's ponents by it's length.

function normalize(v)
{
    var length = Math.sqrt(v.x * v.x + v.y * v.y);
    return {x: v.x / length, y: v.y / length};
}

var step = normalize({x: target.x - position.x, y: target.y - position.y});

Ok, now all we need to do is keep adding the step vector to the object's current position until it reaches the target position.

function normalize(v)
{
    var length = Math.sqrt(v.x * v.x + v.y * v.y);
    return {x: v.x / length, y: v.y / length};
}

var canvas, context,
    position = {x: 200, y: 200},
    target = {x: 400, y: 400},
    step = normalize({x: target.x - position.x, y: target.y - position.y});

function init()
{
   canvas = document.getElementById('canvas');
   if(canvas.getContext)
      context = canvas.getContext('2d');
   else return;

   setInterval(draw, 1000 / 60);
}

function draw()
{
    context.clearRect(0, 0, canvas.width, canvas.height);
    context.fillStyle = "rgb(150,29,28)";
    context.beginPath(); 
    context.arc(position.x, position.y, 150, 0, Math.PI * 2, true);    
    context.fill();
    context.closePath(); 

    position.x += step.x;
    position.y += step.y;
}

And there you have it. Of course it's pretty basic code, you'll have to add a codition to check whether or not the object has arrived to the target otherwise it will just keep going past the target. If it's moving too slow, just scale the step vector by an arbitrary speed factor. Also in a real world app you'd have lot's of objects and not only just a circle so you'd have to make it entirely object-oriented since every object would have it's position, target position, color etc etc etc. A library to work with vectors would e in handy. This is one I wrote for myself some time ago: http://pastebin./Hdxg8dxn

Here you go, give this a crack -

<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
function toggleClass(element, newStr)
{
    index=element.className.indexOf(newStr);
    if ( index == -1)
        element.className += ' '+newStr;
    else
    {
        if (index != 0)
            newStr = ' '+newStr;
        element.className = element.className.replace(newStr, '');
    }
}
function forEachNode(nodeList, func)
{
    var i, n = nodeList.length;
    for (i=0; i<n; i++)
    {
        func(nodeList[i], i, nodeList);
    }
}

window.addEventListener('load', mInit, false);

var canvas, hdc;
var posx=50, posy=0, radius=50;

function circle(hdc, x, y, radius)
{
    hdc.beginPath();
    hdc.arc(x, y, radius, 0, 2*Math.PI);
    hdc.stroke();
//arc(x,y,r,start,stop)
}

function mInit()
{
    canvas = byId('tgtCanvas');
    hdc = canvas.getContext('2d');

    //circle(hdc, posx, posy, 50);
    setInterval(animateStep, 50);
}

var velX = 2;
function animateStep()
{
    posx += velX;
    if (posx+radius > canvas.width)
        velX *= -1;
    else if (posx-radius < 0)
        velX *= -1;

    hdc.clearRect(0,0,canvas.width,canvas.height);
    circle(hdc, posx, posy, radius);
}

</script>
<style>
</style>
</head>
<body>

    <canvas id='tgtCanvas' width='256' height='256'></canvas>

</body>
</html>
发布评论

评论列表(0)

  1. 暂无评论