requestAnimationFrame - замедление обьекта
Здравствуйте.
Код ниже демонстрирует ускоренеи элемента. https://jsfiddle.net/sLy4dz7p/1/ <body style="background-color:#000;"> <div id="test" style="position:absolute;top:50%;left:50%;transform:translate(50%,50%);width:20px;height:20px;background-color:#fff;"></div> </body> <script> window.onload = function(){ var element = document.getElementById('test'); var start; var minSpeed=1; var maxSpeed=5; var minPosY=0; var maxPosY=250; var thisPosY=50; //Движение function moveMe(speed,pxY){ //Шаг function step(timestamp){ if (!start) { start = timestamp; }; time=timestamp-start; var px = time * speed / 10; element.style.transform = "translate("+0+"px,"+px+"px)"; if (px < pxY){ requestAnimationFrame(step); speed=speed+0.5; return; } console.log("Приехали"); return; } requestAnimationFrame(step); } moveMe(5,500); } </script> Никак не могу решить задачу. Необходимо плавно менять скорость перемещения относительно текущей позиции. То-есть если элемент находится на minPosY=0 то необходимо задать minSpeed=1, по мере увеличения Y в +, необходимо плавно наращивать скорость, пока она не станет равной 5 или не будет превышен maxPosY. По существу, представим поле, сверху обьект движется с минимальной скоростью, внизу с максимальной. Между минимумом и максимумом скорость меняется плавно. Help! |
|
|
А средствами чистого javascript этот вопрос никак не решить?
|
А для тебя JS по всем приведенным ссылкам не достаточно чистый?
там даже каких либо подключенных библиотек нету =(. |
Не крутил я animate. Он вроде как совсем новехенький.
Короч спутал я WEB Animate API и временную функцию. В общем на сколько я сейчас разобрался, надо сделать следующее. Найти начальную позицию. Расчитать оставшееся время. Задать параметры времеени и запустить элемент в путь. Надо найти ease функцию. Вот эта вроде как не то что надо function inOutQuad(n){ n *= 2; if (n < 1) return 0.5 * n * n; return - 0.5 * (--n * (n - 2) - 1); }; Только не понятно, как каждый раз актуализировать оставшееся растояние, текущую позицию, и скоростью преодаления пути. |
анимация блоков на js
potatosboxon,
<!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> body{ background-color: hsla(0, 0%, 66%, 1); margin: 0; } div{ display: inline-block; } </style> <script> document.addEventListener( "DOMContentLoaded" , function() { function animate({timing, draw, duration}) { let start = performance.now(); requestAnimationFrame(function animate(time) { let timeFraction = (time - start) / duration; if (timeFraction > 1) timeFraction = 1; let progress = timing(timeFraction); draw(progress); if (timeFraction < 1) { requestAnimationFrame(animate); } }); } function inOutQuad(n){ n *= 2; if (n < 1) return 0.5 * n * n; return - 0.5 * (--n * (n - 2) - 1); }; function easeOutExpo( t ) { if( t === 1 ) { return 1; } return ( -Math.pow( 2, -10 * t ) + 1 ); } class Boulder extends HTMLDivElement{ constructor(color, left = 100, size = 15) { super(); this.color = color; this.left = left; this.size = size; this.style.background = this.color; this.style.width = `${this.size}px`; this.style.height = `${this.size}px`; this.style.transform = `translate(${this.left}px, 0px)`; this.option = {timing : easeOutExpo, draw : this.draw.bind(this), duration : 5000}; animate(this.option); } draw(progress){ this.style.transform = `translate(${this.left}px, ${(window.innerHeight - this.size) * progress|0}px)`; } } customElements.define("custom-box", Boulder, { extends: "div" }); for (let i = 0; i < 7; i++) { const color = '#' + ('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6); const left = (window.innerWidth - 15) * Math.random()|0; const box = new Boulder(color, left); document.querySelector("body").append(box); } }); </script> </head> <body> </body> </html> |
Че то не получается у меня точно сформулировать мысль. Надо подумать прежде чем вопрос задавать.
Надо начать с простого. Пример демонстрирует ускорение. function ease(n){ return Math.pow(n, 2) }; function startAnimation(){ var element = document.getElementById('test'); var stop = false; // animating x (margin-left) from 20 to 300, for example var startx = 0; var destx = 250; var duration = 1500; var start = null; var end = null; function startAnim(timeStamp) { start = timeStamp; end = start + duration; draw(timeStamp); } function draw(now) { if (stop) return; if (now - start >= duration) stop = true; var p = (now - start) / duration; val = ease(p); var px = startx + (destx - startx) * val; element.style.transform = "translate("+0+"px,"+px+"px)"; requestAnimationFrame(draw); } requestAnimationFrame(startAnim); } startAnimation(); Как в данном случае замедлять элемент? |
Цитата:
|
Не решить мою задачу банальной t функцией.
Это хорошо эффектики всякие запускать, снежок там замедлять, ракету, но у меня совсем иная задача. У меня сетка 5x5. На 0:Y обьект должен перемещаться со скоростью 1. На 5:Y обьект должен перемещаться со скоростью 5. При движении от 0 к 5, от 5 к 0 - должна меняться скорость. При перемещении по X скорость должна сохраняться заданная при перемещении по Y. Спасибо за ответы, буду копать. |
Цитата:
|
Цитата:
Давайте разбираться. Получается, что начальная скорость v₀ = 1, конечная скорость v₁ = 5. Объект начинает двигаться от точки s₀ = 0 и завершает своё движение в точке s₁ = 5. Движение начинается в момент времени t₀ = 0 и завершается в t₁, которое мы можем вычислить основываясь на том, что объект движется равноускоренно, т. е. ускорение a₀ постоянно. Время окончания движения можно вычислить по формуле равноускоренного движения. Вычислив время завершения t₁, можно узнать ускорение a₀. Теперь у нас есть все константы, чтобы вычислить пройденный путь s и скорость v (для проверки) объекта в любой момент времени t. Поскольку вас интересует только движение на отрезке времени [t₀; t₁], то можно через каждые t₁ - t₀ секунд оборачивать время вспять. Например при помощи обратных тригонометрических функции. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> #grid { position: relative; width: 500px; height: 500px; background: repeating-linear-gradient( 0deg, var(--r)), repeating-linear-gradient(-90deg, var(--r)); --c: 5; --w: 1px; --r: transparent 0 var(--w), rgba(0, 0, 0, 0.05) 0 calc(100% / var(--c)); } #grid > .circle { width: 20px; height: 20px; background: yellowgreen; border-radius: 50%; margin: -10px 0 0 -10px; position: absolute; left: 50%; } #grid > .info::after { position: absolute; content: "v = " var(--v); white-space: nowrap; background: black; color: white; font: 1em monospace; border-radius: 0.25em; margin: 0.5em; padding: 0.2em 0.5em; right: 0; top: 0; } </style> </head> <body> <div id="grid"> <div class="info"></div> <div class="circle"></div> </div> <script> const v0 = 1; const v1 = 5; const s0 = 0; const s1 = 5; const t0 = 0; const t1 = 2 * s1 / (v0 + v1); const a0 = (v1 - v0) / (t1 - t0); function s(t) { return 0.5 * a0 * t ** 2 + v0 * t + s0; } function v(t) { return a0 * t + v0; } function F(x) { return t1 * (Math.acos(Math.cos(Math.PI * x / t1))) / Math.PI; } const circle = document.querySelector("#grid > .circle"); const info = document.querySelector("#grid > .info"); (function loop(time) { circle.style.transform = `translateY(${100 * s(F(time / 1000))}px)`; info.style.setProperty("--v", `"${v(F(time / 1000)).toFixed(2)}"`); requestAnimationFrame(loop); })(performance.now()); </script> </body> </html> ЕЩЁ Упомянутые графики — https://www.desmos.com/calculator/dejdiypcao |
Часовой пояс GMT +3, время: 00:31. |