我在javascript画布中制作一个简单的动画,为了完成请求的结果,我需要有一个像这样的对象:
circle: {
x: scene_point.x,
y: scene_point.y,
vel_x: randomFloat(0.100, 0.500),
vel_y: randomFloat(0.100, 0.500),
r: 0,
r_max: 10,
trend: 'up'
}
现在循环中的动画应该是这样的:
这是我上面写的代码:
if(circle.trend === 'up' && circle.r < circle.maxR) { // growing, to reach max
circle.r = parseFloat(circle.r) + parseFloat(circle.decayR);
}
if(circle.trend === 'up' && circle.r >= circle.maxR) { // reached max, starting to decay
circle.trend = 'down';
}
if(circle.trend === 'down' && circle.r >= 1) { // decaying, to reach min
circle.r = parseFloat(circle.r) - parseFloat(circle.decayR);
}
if(circle.trend === 'down' && circle.r < 1) { // reached min, reseting
reset(i);
}
最后绘制对象以获得适当的不透明度:
ctx.fillStyle = 'rgba(210, 210, 210, ' + circle.r / circle.maxR + ')';
问题是,是否有可能在没有“趋势”逻辑的情况下实现上述目标,它只是看起来/感觉不对。我必须使用4条件和额外的“趋势”参数才能上下移动。也许有更友好的方式去做。我只是画布和动画的新手,我还不知道所有的技巧;)
答案 0 :(得分:1)
你可以这样做:
circle.r += circle.decayR;
if(circle.decayR > 0 && circle.r >= circle.maxR)
circle.decayR *= -1;
if(circle.decayR < 0 && circle.r < 1)
reset(i);
基本上,只需翻转decayR
的标志。
工作示例:
var circle, canvas, ctx;
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
function reset() {
circle = {
decayR: 1,
r: 0,
maxR: 20,
x: 50 + Math.random() * 50,
y: 50 + Math.random() * 50
};
}
function update() {
circle.r += circle.decayR;
if (circle.decayR > 0 && circle.r >= circle.maxR)
circle.decayR *= -1;
if (circle.decayR < 0 && circle.r < 1)
reset();
// clear
ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw
ctx.beginPath();
ctx.arc(circle.x, circle.y, circle.r, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
requestAnimationFrame(update);
}
reset();
requestAnimationFrame(update);
#canvas {
width: 200px;
height: 200px;
border: solid 1px black;
}
<canvas id="canvas" width="200" height="200"></canvas>
答案 1 :(得分:0)
我认为可以这样缩短:
if(circle.trend === 'up'){
(circle.r >= circle.maxR) ?
circle.trend = 'down' :
circle.r += circle.decayR;
}else{
(circle.r >= 1) ?
circle.r -= circle.decayR :
reset(i);
}