Модернизирую найденный код. В оригинале клочья тумана проходят снизу вверх по canvas, и исчезают. Я пытаюсь добиться, чтобы ставшая max высота установилась в 0 (точнее наоборот, идем снизу вверх), и анимация зациклилась. Я пока не до конца поняла природу переменной var td = new Date().getTime() - p.start;
Математически это вообще (-delay), но переменная постоянно растет (повязанна на реальном времени?)
if (p.newTop < 0)
{
newTop = 100;
}
Переместить в координату 100 (100 чисто для наглядности) получилось. А вот "обнулить" td, чтобы присвоить ее newTop для нового витка, не получается.
const TIMEOUT = 40;
var stTime = 0;
canvasWidth = 1600;
canvasHeight = 200;
pCount = 0;
pCollection = new Array();
var puffs = 1;
var particlesPerPuff = 50; //2000
var img = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/85280/smoke2.png';
var smokeImage = new Image();
smokeImage.src = img;
for (var i1 = 0; i1 < puffs; i1++) {
var puffDelay = i1 * 1500;
for (var i2 = 0; i2 < particlesPerPuff; i2++) {
addNewParticle((i2 * 50) + puffDelay);
}
}
draw(new Date().getTime(), 3000);
function addNewParticle(delay) {
var p = {};
p.top = canvasHeight;
p.left = randBetween(-200, 800);
p.start = new Date().getTime() + delay;
p.life = 8000;
p.speedUp = 30;
p.speedRight = randBetween(0, 20);
p.startOpacity = .3
p.newTop = p.top;
p.newLeft = p.left;
p.size = 200;
p.growth = 10;
pCollection[pCount] = p;
pCount++;
}
function draw(time) {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
for (let i = 0; i < pCount; i++) {
var p = pCollection[i];
var td = new Date().getTime() - p.start;
console.log(td);
var frac = td / p.life
var newTop = p.top - (p.speedUp * (td / 1000));
var newLeft = p.left + (p.speedRight * (td / 1000));
var newOpacity = Math.max(p.startOpacity * (1), 0);
//var newOpacity = Math.max(p.startOpacity * (1-frac),0);
var newSize = p.size + (p.growth * (td / 1000));
p.newTop = newTop;
p.newLeft = newLeft;
if (p.newTop < 0) {
//td = new Date().getTime() - p.start;
newTop = 100;
}
ctx.fillStyle = 'rgba(150,150,150,' + newOpacity + ')';
ctx.globalAlpha = newOpacity;
ctx.drawImage(smokeImage, newLeft, newTop, newSize, newSize);
}
requestAnimationFrame(draw);
}
function randBetween(n1, n2) {
var r = (Math.random() * (n2 - n1)) + n1;
return r;
}
body {
background: black url(https://s.cdpn.io/16327/texture_bg.jpg) no-repeat 50% 0px;
}
#myCanvas {
height: 300px;
width: 2400px;
max-width: 99%;
min-width: 800px;
position: absolute;
bottom: 0;
z-index: 2;
}
#house {
position: absolute;
top: 20%;
left: 40%;
}
<canvas id="myCanvas" height="200" width="800"></canvas>
https://jsfiddle.net/Nata_Hamster/ut42nb5e/2/
Логика работы анимации в вашем примере такая:
Создается элемент Particle
. Ему, помимо прочих свойств, устанавливается время создания p.start = new Date().getTime() + delay
,
new Date().getTime()
- текущее время в миллисекундах
delay
- задержка появления
Затем, во время отрисовки элемента высчитывается его положение var newTop = p.top - (p.speedUp * (td / 1000));
p.top
- начальное положение p.speedUp
- скорость всплытияtd
- разница во времени в миллисекундах между текущим временем и временем начала var td = new Date().getTime() - p.start
.В итоге мы видим, что положение элемента в формуле var newTop = p.top - (p.speedUp * (td / 1000));
зависит от начального положения(p.top
), скорости(p.speedUp
) и разницы времени(td
).
Переменные начального положения(p.top
) и скорости(p.speedUp
) не меняются - они константа для элемента.
Следовательно, положение элемента зависит от времени(td
). Значит, вам надо поменять начальное значение времени, что бы задать положение элементу. Значит вам надо написать код p.start = new Date().getTime()
.
Пример внизу.
const TIMEOUT = 40;
var stTime = 0;
canvasWidth = 1600;
canvasHeight = 200;
pCount = 0;
pCollection = new Array();
var puffs = 1;
var particlesPerPuff = 50; //2000
var img = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/85280/smoke2.png';
var smokeImage = new Image();
smokeImage.src = img;
for (var i1 = 0; i1 < puffs; i1++) {
var puffDelay = i1 * 1500;
for (var i2 = 0; i2 < particlesPerPuff; i2++) {
addNewParticle((i2 * 50) + puffDelay);
}
}
draw(new Date().getTime(), 3000);
function addNewParticle(delay) {
var p = {};
p.top = canvasHeight;
p.left = randBetween(-200, 800);
p.start = new Date().getTime() + delay;
p.life = 8000;
p.speedUp = randBetween(10, 40); // делаем разную скорость, чтобы смотрелось красивее
p.speedRight = randBetween(0, 20);
p.startOpacity = .3
p.newTop = p.top;
p.newLeft = p.left;
p.size = 200;
p.growth = 10;
pCollection[pCount] = p;
pCount++;
}
function draw(time) {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
for (let i = 0; i < pCount; i++) {
var p = pCollection[i];
var td = new Date().getTime() - p.start;
var frac = td / p.life
var newTop = p.top - (p.speedUp * (td / 1000));
var newLeft = p.left + (p.speedRight * (td / 1000));
var newOpacity = Math.max(p.startOpacity * (1), 0);
//var newOpacity = Math.max(p.startOpacity * (1-frac),0);
var newSize = p.size + (p.growth * (td / 1000));
if (newTop <= 0) {
p.start = new Date().getTime(); // обнуляем начальное время анимации start
}
ctx.fillStyle = 'rgba(150,150,150,' + newOpacity + ')';
ctx.globalAlpha = newOpacity;
ctx.drawImage(smokeImage, newLeft, newTop, newSize, newSize);
}
requestAnimationFrame(draw);
}
function randBetween(n1, n2) {
var r = (Math.random() * (n2 - n1)) + n1;
return r;
}
body {
background: black url(https://s.cdpn.io/16327/texture_bg.jpg) no-repeat 50% 0px;
}
#myCanvas {
height: 300px;
width: 2400px;
max-width: 99%;
min-width: 800px;
position: absolute;
bottom: 0;
z-index: 2;
}
#house {
position: absolute;
top: 20%;
left: 40%;
}
<canvas id="myCanvas" height="200" width="800"></canvas>
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Пишу отправку сообщений на Django сервере и столкнулся с такой проблемой: при нажатии на input типа submit в форме типа post происходит передача методом...