【问题标题】:Canvas Javascript Looping画布 Javascript 循环
【发布时间】:2018-01-03 11:56:22
【问题描述】:

我正在尝试循环播放我的动画,但无论我做什么,它都不会循环播放。总的来说,我对 canvas、javascript 和代码还是很陌生。

var canvas = document.getElementById("fabrication");
var ctx = canvas.getContext("2d");
var background = new Image();
background.src = 
"C:/Users/dylan/Desktop/ProjectTwo/Images/fabricationbackground.jpg";
background.onload = function(){
}


//Loading all of my canvas

var posi =[];
posi[1] = 20;
posi[2] = 20;
var dx=10;
var dy=10;
var ballRadius = 4;

//Variables for drawing a ball and it's movement

function drawballleft(){


posi =xy(posi[1],posi[2])
}
function xy(x,y){
    ctx.drawImage(background,0,0);
    ctx.beginPath();
    ctx.arc(x, y, ballRadius, 0, Math.PI*2);
    ctx.fillStyle = "#FFFFFFF";
    ctx.fill();
    ctx.closePath();
    var newpos=[];
    newpos[1]= x +dx;
        newpos[2]= y +dy;
    return newpos;

//Drawing the ball, making it move off canvas.

if (newpos[1] > canvas.width) {
newpos[1] = 20;
}
if (newpos[2] > canvas.height) {
newpos[2] = 20;
}
//If statement to detect if the ball moves off the canvas, to make it return to original spot

}
setInterval(drawballleft, 20);
//Looping the function

如果我做错了什么,请告诉我,我真的很想知道我在这里做什么。球应该离开画布,然后循环回到自己身上,但它离开了画布并结束了。

提前致谢!

【问题讨论】:

  • 尝试使用 .push() 设置 newpos 值,就像 newpos.push(20) 一样,并记住数组索引从 0 而不是 1 开始。
  • 不要使用file://。使用真实的静态服务器。大多数 IDE 都内置了此功能。您也可以使用 http-server 模块。

标签: javascript html animation canvas


【解决方案1】:

我对您的代码做了一些更改。

首先我使用requestAnimationFrame 而不是setIntervalhttp://www.javascriptkit.com/javatutors/requestanimationframe.shtml

其次,我没有使用图像,因为我不想遇到 CORS 问题。但是你可以把你的背景图片放回去。

我简化了您的 posi 数组以使用索引 01 而不是 12 来清理您创建数组的方式。

我将您的 return 从两个 ifs 之前移到之后,这样当球离开侧面时,它会移回左侧或顶部。 我认为这是你看到的真正问题

var canvas = document.getElementById("fabrication");
var ctx = canvas.getContext("2d");

//Loading all of my canvas

var posi =[20,20];
var dx=10;
var dy=10;
var ballRadius = 4;

//Variables for drawing a ball and it's movement

function drawballleft(){
  posi = xy(posi[0],posi[1])
  requestAnimationFrame(drawballleft);
}

function xy(x,y){
  ctx.fillStyle = '#FFF';
  ctx.fillRect(0,0,400,300);
  ctx.beginPath();
  ctx.arc(x, y, ballRadius, 0, Math.PI*2);
  ctx.fillStyle = "#000";
  ctx.fill();
  ctx.closePath();
  var newpos=[x+dx,y+dy];

    //Drawing the ball, making it move off canvas.

  if (newpos[0] > canvas.width) {
    newpos[0] = 20;
  }
  if (newpos[1] > canvas.height) {
    newpos[1] = 20;
  }
  //If statement to detect if the ball moves off the canvas, to make it return to original spot

  return newpos;
}

requestAnimationFrame(drawballleft);
canvas {
  outline: 1px solid red;
}
<canvas width="400" height="300" id="fabrication"></canvas>

【讨论】:

  • 它在代码 sn-p 中像预期的那样工作,但它似乎不适用于我的画布 - 一个球自行移动,离开画布,然后停止并没有t 再次出现。
  • 您是否将 return 移到了 to if 语句之后?否则,球会飞离画布边缘,再也不会被看到。
  • 我整理好了!它循环惊人,谢谢!如何让它每次都出现在同一个地方,而不是在画布上循环? IE。出现在它的第一个位置,循环等。
  • 如果你想让它始终从 [0,0] 开始,那么更改if 中的代码,将newpos[0]newpos[1] 都设置为0,而不是只执行一个从屏幕上消失了。如果这不是你的意思,那么让我确切地知道你在追求什么,我会尽力提供帮助。
  • 我设法通过删除 canvas.width 的 if 语句对其进行排序,从而将 canvas.height 设置为 newpos[0] = 0 和 newpos[1] = 0。非常感谢您的帮助 - 现在我必须镜像它,我应该对此感到满意。再次感谢您!
【解决方案2】:

为了让一切变得更简单... 使用外部脚本来处理画布。

一个非常好的一个;): https://github.com/GustavGenberg/handy-front-end#canvasjs

包含在其中

<script type="text/javascript" src="https://gustavgenberg.github.io/handy-front-end/Canvas.js"></script>

那么就这么简单:

// Setup canvas
const canvas = new Canvas('my-canvas', 400, 300).start(function (ctx, handyObject, now) {

    // init
    handyObject.Ball = {};

    handyObject.Ball.position = { x: 20, y: 20 };
    handyObject.Ball.dx = 10;
    handyObject.Ball.dy = 10;
    handyObject.Ball.ballRadius = 4;

  });

// Update loop, runs before draw loop
canvas.on('update', function (handyObject, delta, now) {

    handyObject.Ball.position.x += handyObject.Ball.dx;
    handyObject.Ball.position.y += handyObject.Ball.dy;

    if(handyObject.Ball.position.x > canvas.width)
      handyObject.Ball.position.x = 20;

    if(handyObject.Ball.position.y > canvas.height)
      handyObject.Ball.position.y = 20;

});

// Draw loop
canvas.on('draw', function (ctx, handyObject, delta, now) {

    ctx.clear();

    ctx.beginPath();

    ctx.arc(handyObject.Ball.position.x, handyObject.Ball.position.y, handyObject.Ball.ballRadius, 0, Math.PI * 2);

    ctx.fillStyle = '#000';
    ctx.fill();

    ctx.closePath();

});

我重新构建了您的代码并使用了外部脚本,现在它看起来更简洁,更易于阅读和排除故障!

JSFiddle:https://jsfiddle.net/n7osvt7y/

【讨论】:

    猜你喜欢
    • 2013-03-06
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 2013-02-08
    相关资源
    最近更新 更多