Я намерен включить в свой проект ускорение, основанное на времени, и мне может потребоваться некоторая помощь для этого.
В настоящее время я использую простую формулу x пикселей в секунду.
...
speed: 100,
now: undefined,
delta: undefined,
then: undefined,
setDelta: function() {
this.now = Date.now();
this.delta = (this.now - this.then) / 1000;
this.then = this.now;
},
...
var slice = this.speed * this.delta;
this.x += Math.cos(rad) * slice;
this.y += Math.sin(rad) * slice;
При этом мой объект движется со скоростью 100 пикселей в секунду.
Анимация, однако, очень скучная, поэтому идея сделать ее более интересной, заставив ее начать медленно, ускоряться до половины расстояния, а затем снова начинать замедляться, пока не достигнет цели.
Я нашел этот список функций замедления для javascript click .
Я думаю, что тот, который кажется точным, будет иметь некоторый плавный синус, как этот:
easeInOutSin: function (t) {
return (1 + Math.sin(Math.PI * t - Math.PI / 2)) / 2;
}
Однако проблема в том, что я не могу понять, как «связать» эту формулу с моим кодом (представленным выше).
По ссылке ребята утверждают, что t
- это параметр от 0
до 1
, и я думаю, что, вероятно, нужно изменить это speed
. Может быть, кто-то может помочь.
это демонстрационный фрагмент для эксперимента:
let distance = (p) => Math.sqrt((p.x - p.dx) * (p.x - p.dx) + (p.y - p.dy) * (p.y - p.dy)),
rftv = (p) => Math.atan2(p.dy - p.y, p.dx - p.x);
let cvs = document.createElement('canvas'),
ctx = cvs.getContext('2d'),
w = cvs.width = 700,
h = cvs.height = 200,
cx = w / 2,
cy = h / 2;
let obj = {
x: 100,
y: cy,
speed: 100,
dx: 600,
dy: cy,
run: function() {
if(!this.moving) { return; }
let d = distance(this);
if(d < 1) {
this.end();
}
this.setDelta();
var slice = this.speed * this.delta;
let rad = rftv(this);
this.x += Math.cos(rad) * slice;
this.y += Math.sin(rad) * slice;
},
now: undefined,
delta: undefined,
then: undefined,
setDelta: function() {
this.now = Date.now();
this.delta = (this.now - this.then) / 1000;
this.then = this.now;
},
moving: false,
start: function() {
this._started_ = Date.now();
this.then = Date.now();
this.moving = true;
},
end: function() {
this.moving = false;
console.log( Date.now() - this._started_, 'should be close to 5000' );
}
};
let render = () => {
ctx.fillStyle = '#ccc';
ctx.fillRect(0, 0, w, h);
ctx.beginPath();
ctx.arc(obj.x, obj.y, 10, 0, Math.PI * 2);
ctx.closePath();
ctx.strokeStyle = 'red';
ctx.stroke();
obj.run();
requestAnimationFrame(render);
};
document.body.appendChild(cvs);
render();
obj.start();