绘制并重新绘制图像以模拟动画是行不通的
Drawing and redrawing an image to simulate animation doesnt work
我有一个简单的动画,显示煤气表从绿色变为红色。我只是在计时器上绘制、清除图像,然后重新绘制图像,尝试模拟动画。虽然这是一种工作,但动画滞后,有时只是在本应完成后来回播放。
这是代码:
function meter(){
requestAnimationFrame(meter);
setTimeout(function() {
var radius = 40;
ctx.clearRect(500, 200, 100, 100);
ctx.beginPath();
ctx.arc(550, 250, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'rgba(192, 192, 192, 0.4)';
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#000000';
ctx.stroke();
ctx.fillStyle = "#ffcc4a";
ctx.fillRect(525, 220, 50, 60);
ctx.fillStyle = "#ffffff";
ctx.fillRect(528, 225, 44, 45);
var grd = ctx.createLinearGradient(510, 0, 670, 0);
grd.addColorStop(0, "black");
grd.addColorStop(0.25, "yellow");
grd.addColorStop(0.5, "red");
ctx.fillStyle = grd;
ctx.fillRect(530, 228, 40, 30);
ctx.beginPath();
ctx.fillStyle = "#000000";
ctx.arc(550, 264, 5, 0, 2 * Math.PI, false);
ctx.moveTo(549, 260);
ctx.lineTo(548, 240);
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#000000';
ctx.stroke();
ctx.closePath();
ctx.closePath();
//ctx.clearRect(500, 200, 100, 100);
}, 2000);
setTimeout(function() {
var radius = 40;
ctx.clearRect(500, 200, 100, 100);
ctx.beginPath();
ctx.arc(550, 250, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'rgba(192, 192, 192, 0.4)';
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#000000';
ctx.stroke();
ctx.fillStyle = "#ffcc4a";
ctx.fillRect(525, 220, 50, 60);
ctx.fillStyle = "#ffffff";
ctx.fillRect(528, 225, 44, 45);
var grd = ctx.createLinearGradient(510, 0, 670, 0);
grd.addColorStop(0, "black");
grd.addColorStop(0.25, "yellow");
grd.addColorStop(0.5, "red");
ctx.fillStyle = grd;
ctx.fillRect(530, 228, 40, 30);
ctx.beginPath();
ctx.fillStyle = "#000000";
ctx.arc(550, 264, 5, 0, 2 * Math.PI, false);
ctx.moveTo(549, 260);
ctx.lineTo(558, 240);
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#000000';
ctx.stroke();
ctx.closePath();
ctx.closePath();
//ctx.clearRect(500, 200, 100, 100);
}, 2500);
setTimeout(function() {
var radius = 40;
ctx.clearRect(500, 200, 100, 100);
ctx.beginPath();
ctx.arc(550, 250, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'rgba(192, 192, 192, 0.4)';
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#000000';
ctx.stroke();
ctx.fillStyle = "#ffcc4a";
ctx.fillRect(525, 220, 50, 60);
ctx.fillStyle = "#ffffff";
ctx.fillRect(528, 225, 44, 45);
var grd = ctx.createLinearGradient(510, 0, 670, 0);
grd.addColorStop(0, "black");
grd.addColorStop(0.25, "yellow");
grd.addColorStop(0.5, "red");
ctx.fillStyle = grd;
ctx.fillRect(530, 228, 40, 30);
ctx.beginPath();
ctx.fillStyle = "#000000";
ctx.arc(550, 264, 5, 0, 2 * Math.PI, false);
ctx.moveTo(549, 260);
ctx.lineTo(568, 240);
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#000000';
ctx.stroke();
ctx.closePath();
ctx.closePath();
//ctx.clearRect(500, 200, 100, 100);
}, 3000);
}
在我看来,在第一个setTimeout函数等待激发和绘制内容时,您将有足够的时间多次调用requestAnimationFrame函数。这意味着,在第一个定时器启动之前,您可能会启动setTimeout定时器几次。
这基本上就是你所拥有的:
function meter(){
requestAnimationFrame(meter);
setTimeout(function() {
//drawing stuff
}, 2000);
setTimeout(function() {
//drawing stuff
}, 2500);
setTimeout(function() {
//drawing stuff
}, 3000);
}
你用一个小改动就画了三次同样的东西。相反,把它变成一个带有参数的函数:
function meter(indicatorPosition){
//black circle
var radius = 40;
ctx.clearRect(500, 200, 100, 100);
ctx.beginPath();
ctx.arc(550, 250, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'rgba(192, 192, 192, 0.4)';
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#000000';
ctx.stroke();
//yellow rectangle
ctx.fillStyle = "#ffcc4a";
ctx.fillRect(525, 220, 50, 60);
//white rectangle over yellow
ctx.fillStyle = "#ffffff";
ctx.fillRect(528, 225, 44, 45);
//meter gradient background
var grd = ctx.createLinearGradient(510, 0, 670, 0);
grd.addColorStop(0, "black");
grd.addColorStop(0.25, "yellow");
grd.addColorStop(0.5, "red");
ctx.fillStyle = grd;
ctx.fillRect(530, 228, 40, 30);
//circle and indicator
ctx.beginPath();
ctx.fillStyle = "#000000";
ctx.arc(550, 264, 5, 0, 2 * Math.PI, false);
ctx.moveTo(549, 260);
ctx.lineTo(indicatorPosition, 240); //this is the only variable!
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#000000';
ctx.stroke();
ctx.closePath();
}
现在让它移动:
如果希望它每0.5秒移动一次,最好使用setInterval。
var meterPosition = 548 //your starting position
var myInterval = setInterval(function() {
//each run we draw the meter
meter(meterPosition);
//Then we want to add 10 to the meter position
meterPosition+=10;
//We don't want the meter to go nuts and disappear to the right, so we'll make it reset after 3 moves
if (meterPosition > 568) {
meterPosition = 548;
}
},500);
以下是正在运行的代码:http://jsfiddle.net/Niddro/7jxknwk4/
相关文章:
- 在VanillaJS中模拟模型双向数据绑定
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 有没有一个javascript图形绘制库可以进行气球树布局
- 使用jasmine模拟对服务器的调用
- 模拟谷歌地图中的点击
- 使用相同的数据集绘制各种符号
- 使用onclick绘制SVG路径
- 在谷歌地图上绘制位置数据库
- 用chart.js绘制条形图
- “可绘制地图”设置地图选项“纬度-经度”
- 使用模拟按键在输入框中自动输入文本
- 多维数据集网格未在指定的分区中绘制
- 模拟chrome.storage.local函数使用Jasmine
- 从数据库中检索字段,而不模拟它们
- 使用谷歌图表在x轴上绘制日期
- 使用fabric.js从矩形区域获取对象,并将该区域绘制到画布上
- 如何在React Native中绘制图形
- react testUtils模拟点击单选按钮而不触发onchange
- 绘制并重新绘制图像以模拟动画是行不通的
- 模拟.js第一个程序:屏幕上没有绘制任何内容