Нужна помощь с анимацией
Написал код с анимацией, хотел чисто на js без css вообщем квадрат стоит по центру экрана потом двигается на верх до конца экрана, потом на права до конца, потом вниз до конца потом налево и вверх обратно на свое место. И проблема у меня такая получилась вверх и направо он у меня идет, а вот вниз не хочет, точнее начинает идти потом проскакивает часть экрана и все, на лево вообще стоит на месте. не знаю что делать помогите
let box=document.getElementById(`red`);
let delay=10; //скорость
let coords=box.getBoundingClientRect(); //координаты в начальной точке
let windowWidth=document.documentElement.clientWidth;//размер экрана
let windowHeight=document.documentElement.clientHeight;//размер экрана
let count=0; //
let countLeft=0; //
let countBottom=0;// Счетчики
let countRight=0; //
function edge()
{
let coords2=box.getBoundingClientRect(); // отслеживаю координаты
if(coords2.y!=0) //двигаюсь вверх пока координата х не станет 0
{
setTimeout(edge,delay);
box.style.bottom= count+'px';
count++;
}else
if(coords2.x!=windowWidth-box.offsetWidth) //на право
{
setTimeout(edge,delay);
box.style.left= countLeft+'px';
countLeft++;
}
/* else
if(coords2.y!=windowHeight-box.offsetHeight) //вниз не работает как надо
{
setTimeout(edge,delay);
box.style.top = countBottom +'px';
countBottom++;
} */
/* else
if(coords2.x==coords.x) //на лево вообще не срабатывает
{
setTimeout(edge,delay);
box.style.right= countRight+'px';
countRight++;
} */
/*Это чисто проверки для себя не влияет на работу кода*/
console.log(coords2.x);
console.log(coords2.y);
console.log('*******');
}
//edge();
console.log(windowWidth,windowHeight);
console.log(coords.x,coords.y);
|
|
|
Анимацию через requestAnimationFrame нужно делать
<!DOCTYPE html>
<html>
<head>
<style>
#red {
position: absolute;
width: 25px;
height: 25px;
background-color: red;
}
body {
height: 100%;
}
</style>
</head>
<body>
<div id="red"></div>
<button id="start">Start</button>
<script>
let box= document.getElementById('red');
const boxrect = box.getBoundingClientRect();
const boxWidth = boxrect.width;
const boxHeight = boxrect.height
const windowWidth=innerWidth;
const windowHeight=innerHeight;
const x0 = (windowWidth - boxWidth)/2;
const y0 = (windowHeight - boxHeight)/2
box.style.left = x0 + 'px';
box.style.top = y0 + 'px';
let direction = 'up';
const rightX = windowWidth - boxWidth;
const bottomY = windowHeight - boxHeight;
const speed = 100; // px/s
let lastT;
let curX = x0;
let curY = y0;
const move = (nowT) => {
if (lastT === undefined) lastT = nowT;
let stop = false;
const dt = nowT - lastT;
const d = speed * dt / 1000;
lastT = nowT;
switch (direction) {
case 'up':
if (curY <= y0) {
curY = Math.max(curY - d, 0);
if (curY == 0) direction = 'right';
} else {
curY = Math.max(curY - d, y0);
if (curY == y0) stop = true;
}
break;
case 'right' :
curX = Math.min(curX + d, rightX);
if (curX == rightX) direction = 'down';
break;
case 'down':
curY = Math.min (curY + d, bottomY);
if (curY == bottomY) direction = 'left';
break
case 'left' :
curX = Math.max(curX - d, x0);
if (curX == x0) direction = 'up';
break;
}
box.style.top = curY + 'px';
box.style.left = curX + 'px';
if (!stop)
requestAnimationFrame(move);
else
lastT = undefined;
}
const start = document.getElementById('start');
start.addEventListener ('click', () => requestAnimationFrame(move))
</script>
</body>
</html>
|
voraa,
не подскажите почему у меня анимация работала не так как надо? ведь логически то все верно. мне нужно понять может там нюансы какие-то есть? |
MallSerg,
не подскажите почему у меня анимация работала не так как надо? ведь логически то все верно. мне нужно понять может там нюансы какие-то есть? |
рони,
не подскажите почему у меня анимация работала не так как надо? ведь логически то все верно. мне нужно понять может там нюансы какие-то есть? |
Im_Ilya,
не используйте ==при сравнении, точные числа в вычислении координат редкость! лучше >= , >, <, <=. и не плодите однотипные сообщения. |
рони,
т.е. поэтому он у меня перескакивает часть экрана? |
Цитата:
|
рони,
Я думал об этом, а потом подумал в чем разница?)) если не сложно можете объяснить почему предпочтительнее использовать left и top |
движение по периметру
Im_Ilya,
как-то так ... (два раза не жмакать, дождитесь окончания)
<!DOCTYPE html>
<html>
<head>
<style>
#red {
position: fixed;
width: 25px;
height: 25px;
background-color: red;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
body {
height: 100%;
}
</style>
</head>
<body>
<div id="red"></div>
<button id="start">Start</button>
<script>
let box = document.getElementById(`red`);
let delay = 10; //скорость
let coords = box.getBoundingClientRect();
let {
left: x,
top: y
} = coords;
let l = 0,
t = 0;
function edge() {
if (l == 0 && t > -2 * y && t <= 0) {
box.style.top = `${--t}px`;
setTimeout(edge, delay);
} else
if (l < 2 * x && t <= -2 * y) {
box.style.left = `${++l}px`;
setTimeout(edge, delay);
} else if (l >= 2 * x && t < 2 * y) {
box.style.top = `${++t}px`;
setTimeout(edge, delay);
} else if (l > 0 && t >= 2 * y) {
box.style.left = `${--l}px`;
setTimeout(edge, delay);
} else if (l <= 0 && t > 0) {
box.style.top = `${--t}px`;
t > 0 && setTimeout(edge, delay);
}
}
const start = document.getElementById('start')
start.addEventListener('click', edge)
</script>
</body>
</html>
|
Цитата:
У вас если coords2.y != 0, то всегда будет срабатывать первое условие if(coords2.y!=0) до условия if(coords2.y!=windowHeight-box.offsetHeight) дело не дойдет. А какой смысл, двигаясь вверх, менять bottom, а двигаясь вниз - менять top очень трудно представить. |
рони,
voraa, Спасибо большое, благодаря вам я разобрался. Сейчас отредактирую свою функцию. |
Цитата:
Вы ставите delay = 10. Но если у монитора частота обновления экрана 60гц, то не будет через 10мс экран обновляться. Все равно будет через 1000/60 = 16.7 мс. Из за этого движение будет дерганным и не равномерным. А requestAnimationFrame для этого и создана, что бы синхронизировать обновления страницы с частотой обновления экрана. |
voraa,
Хорошо. Спасибо за совет. Я почитал про эту функцию когда ваш пример разбирал, только единственное я не понял из вашего примера что за переменные NowT и LastT? |
В функцию, которая вызывается requestAnimationFrame передается параметр - время (Это некоторое время от окончания загрузки страницы). Зная время предыдущего вызова функции по requestAnimationFrame и текущего, мы можем определить какое время прошло между вызовами. Это же не всегда четко 16.7. Иногда и больше - браузер сам это решает.
LastT - время предыдущего вызова NowT - время текущего вызова Зная время между вызовами (const dt = nowT - lastT )и скорость (speed) с которой должен перемещаться элемент, можно высчитать на какое расстояние он должен сместиться между этими двумя вызовами. const d = speed * dt / 1000; |
voraa,
Круто! Сам бы я не догадался, не тот уровень пока что)) Но все приходит с опытом |
voraa,
Подскажите еще, откуда передается параметр nowT? Я не могу сообразить |
Цитата:
Цитата:
|
| Часовой пояс GMT +3, время: 11:47. |