Как сделать перемещения объектов используя функцию ослабления?
Делаю перемещение объектов с эффектом волн. Четыре объекта перемещается вниз и вверх. Чтобы получился эффект волны я установила интервал по "y" каждого объекта на +10 пикселей. Мне нужно чтобы они перемещались используя функцию ослабление (замедление), однако когда они достигаю нижней планки, то сразу перемещаются вверх. Для теста решила над одним объектом сделать функцию ослабление, в итоге объект прыгает по канвасу и улетает за границу. Как сделать перемещение с эффектом ослабления, разумеется, чтобы они перемещались волнами?
Код: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>HTML 5 Canvas</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"> </script> <style type="text/css"> html, body { margin: 0px; } canvas { display: block; position: absolute; top: 0px; left: 0px; } </style> </head> <body> <canvas id="canvas"> Your browser does not support HTML5 canvas. If you would like to view, please update your browser. </canvas> <script> Rectangle = function(x, y, w, h) { this.x = x; this.y = y; this.width = w; this.height = h; this.draw = function(ctx) { ctx.fillStyle = "#000"; ctx.fillRect(this.x, this.y, this.width, this.height); } } var canvas = document.getElementById("canvas"); canvas.width = window.innerWidth; canvas.height = window.innerHeight; var context = canvas.getContext("2d"); var rect1 = new Rectangle(15,15,50,40); var rect2 = new Rectangle(75, 25, 50, 40); var rect3 = new Rectangle(135, 35, 50, 40); var rect4 = new Rectangle(195, 45, 50, 40); var movement1 =-2; var movement2 =-2; var movement3 =-2; var movement4 =-2; var startTime = new Date(); var time = new Date() - startTime; var changeY = 100 - rect1.y; setInterval(function() { var time = new Date() - startTime; context.clearRect(0, 0, canvas.width, canvas.height); rect1.y += movement1; rect2.y += movement2; rect3.y += movement3; rect4.y += movement4; if(rect1.y >= 70 || rect1.y < 15) { rect1.y = easeInOutQuad(time, rect1.y, changeY, 1000); } if(rect2.y >= 70 || rect2.y < 15) movement2 *= -1; if(rect3.y >= 70 || rect3.y < 15) movement3 *= -1; if(rect4.y >= 70 || rect4.y < 15) movement4 *= -1; rect1.draw(context); rect2.draw(context); rect3.draw(context); rect4.draw(context); },33); function linearTween(t, b, c, d) { return c * t / d + b; } function easeInQuad(t, b, c, d) { return c*(t/=d)*t + b; }; function easeOutQuad(t, b, c, d) { return -c *(t/=d)*(t-2) + b; }; function easeInOutQuad(t, b, c, d) { if ((t/=d/2) < 1) return c/2*t*t + b; return -c/2 * ((--t)*(t-2) - 1) + b; }; </script> </body> </html> |
Katy93,
делайте макет целиком, а не кусками. Пожалуйста, отформатируйте свой код! Для этого его можно заключить в специальные теги: js/css/html и т.п., например: [html run] ... минимальный код страницы с вашей проблемой [/html] О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting. |
Все отформатировала текст, теперь можно запустить кнопкой "Посмотреть". Как сделать функцию ослабления, при этом чтобы остался эффект волны?
|
canvas wave волна
Katy93,
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>HTML 5 Canvas</title> <style type="text/css"> html, body { margin: 0px; } canvas { display: block; position: absolute; top: 0px; left: 0px; } </style> </head> <body> <canvas id="canvas"> Your browser does not support HTML5 canvas. If you would like to view, please update your browser. </canvas> <script> Rectangle = function(x, y, w, h) { this.x = x; this.y = y; this.yy = y; this.width = w; this.height = h; this.to = [205, 15]; this.draw = function(ctx) { ctx.fillStyle = "#000"; ctx.fillRect(this.x, this.y, this.width, this.height); } } var canvas = document.getElementById("canvas"); canvas.width = window.innerWidth; canvas.height = window.innerHeight; var context = canvas.getContext("2d"); function anim(a) { function e(b) { context.clearRect(a.x, a.y, a.width, a.height) var k = .03; a.yy += (a.to[0] - a.yy) * k; a.y = Math.trunc(a.yy) a.draw(context); if (Math.abs(a.yy - a.to[0]) < .5) { a.to.reverse(); anim(a) } else requestAnimationFrame(e) } requestAnimationFrame(e) } for (var i = 0; i < 10; i++) { var rect = new Rectangle(15 + i * 52, 45 + (Math.cos(i) * 70 | 0), 50, 40) anim(rect) } </script> </body> </html> |
Мне не нужно выбирать из середины, перемещение должно происходить с первой квадрата по последний по очереди делая эффект волны.
Примерно вот так, выполнено с помощью TweenLite, только проблема в коде заключается в том что происходит выстраивание в линию, а потом продолжается движение. В моем случае движение должно происходить постоянно как только достиг нижней или верхней границы, тут же отправляется дальше движение без выстраивания в линию. Как это можно сделать? <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Tween</title> <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenLite.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/plugins/CSSPlugin.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/easing/EasePack.min.js'></script> </head> <body> <canvas id="canvas" width="670" height="500" style="background-color:#eee; border:1px solid #ccc;"></canvas> <script> var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var canvas = document.getElementById('canvas'); var x = 50; var y = 50; Rectangle = function(x,y,width,height) { this.x = x; this.y = y; this.width = width; this.height = height; this.draw = function(ctx) { ctx.beginPath(); ctx.fillRect(this.x, this.y, this.width, this.height); } } var rect1; var rect2; var rect3; var rect4; var obj; function animate() { ctx.clearRect(0,0,canvas.width,canvas.height); rect1.draw(ctx); rect2.draw(ctx); rect3.draw(ctx); rect4.draw(ctx); requestAnimationFrame(animate); } function init() { rect1 = new Rectangle(50,50,20,40); rect2 = new Rectangle(80,70,20,40); rect3 = new Rectangle(110,90,20,40); rect4 = new Rectangle(140,110,20,40); } init(); animate(); tweenSquare(rect1); tweenSquare2(rect2); tweenSquare3(rect3); tweenSquare4(rect4); function tweenSquare(s) { TweenLite.to(s, 2, {y:250, ease: Cubic.easeInOut,delay:0.4, onComplete: function() { TweenLite.to(s, 2, {y:50, ease: Cubic.easeInOut, onComplete: function() { tweenSquare(s); }}) }}); } function tweenSquare2(s) { TweenLite.to(s, 2, {y:250, ease: Cubic.easeInOut,delay:0.3,onComplete: function() { TweenLite.to(s, 2, {y:50, ease: Cubic.easeInOut,onComplete: function() { tweenSquare(s); }}) }}); } function tweenSquare3(s) { TweenLite.to(s, 2, {y:250, ease: Cubic.easeInOut,delay:0.2,onComplete: function() { TweenLite.to(s, 2, {y:50, ease: Cubic.easeInOut, onComplete: function() { tweenSquare(s); }}) }}); } function tweenSquare4(s) { TweenLite.to(s, 2, {y:250, ease: Cubic.easeInOut,delay:0.1, onComplete: function() { TweenLite.to(s, 2, {y:50, ease: Cubic.easeInOut, onComplete: function() { tweenSquare(s); }}) }}); } function start(){ console.log('start'); } function update(){ console.log('animating'); } function complete(){ console.log('end'); } </script> </body> </html> |
Katy93,
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>HTML 5 Canvas</title> <style type="text/css"> html, body { margin: 0px; } canvas { display: block; position: absolute; top: 0px; left: 0px; } </style> </head> <body> <canvas id="canvas"> Your browser does not support HTML5 canvas. If you would like to view, please update your browser. </canvas> <script> Rectangle = function(x, y, w, h) { this.x = x; this.y = y; this.yy = y; this.width = w; this.height = h; this.to = [205, 15]; this.draw = function(ctx) { ctx.fillStyle = "#000"; ctx.fillRect(this.x, this.y, this.width, this.height); } } var canvas = document.getElementById("canvas"); canvas.width = window.innerWidth; canvas.height = window.innerHeight; var context = canvas.getContext("2d"); function anim(a) { function e(b) { context.clearRect(a.x, a.y, a.width, a.height) var k = .03; a.yy += (a.to[0] - a.yy) * k; a.y = Math.trunc(a.yy) a.draw(context); if (Math.abs(a.yy - a.to[0]) < .05) { a.to.reverse(); anim(a) } else requestAnimationFrame(e) } requestAnimationFrame(e) } for (var i = 0; i < 10; i++) { let rect = new Rectangle(50 + i * 30, 50, 20, 40); window.setTimeout(_ => anim(rect), i * 100) } </script> </body> </html> |
Хорошо получилось, только вот объекты выстраиваются в линию. Нельзя ли сделать, так чтобы они сразу стартовали когда они достигнут конечной оси координат по y. Мне удалось, это сделать с помощью TweenLite, но хотелось бы увидеть анимацию, без этой библиотеке. Мой вариант TweenLite.
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Tween</title> <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenLite.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/plugins/CSSPlugin.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/easing/EasePack.min.js'></script> </head> <body> <canvas id="canvas" width="670" height="500" style="background-color:#eee; border:1px solid #ccc;"></canvas> <script> var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var canvas = document.getElementById('canvas'); var x = 50; var y = 50; Rectangle = function(x,y,width,height) { this.x = x; this.y = y; this.width = width; this.height = height; this.draw = function(ctx) { ctx.beginPath(); ctx.fillRect(this.x, this.y, this.width, this.height); } } var rects; var obj; function animate() { ctx.clearRect(0,0,canvas.width,canvas.height); draw(); requestAnimationFrame(animate); } var rects = []; function init() { for(var i=0; i < 20; i++) { rect = new Rectangle(50+i*30,70,20,40); rects.push(rect); } } function draw() { for(var i=0; i < rects.length; i++) { rects[i].draw(ctx); } } init(); animate(); for(var i = rects.length-1; i >=0; i--) { console.log(rects[i]); tweenSquare(rects[i],i); } function tweenSquare(s,i) { TweenLite.to(s, 1+i*0.1, {y:100, ease: Cubic.easeInOutCubic,delay:0.1+i*0.1, onComplete: function() { TweenLite.to(s, 1+i*0.1, {y:50, ease: Cubic.easeInOutCubic, onComplete: function() { tweenSquare(s,0.1+i*0.1); }}) }}); } </script> </body> </html> |
Katy93,
пока без вариантов, может гугла расспросить? |
Мне удалось добиться своего, только вот проблема не могу исправить скролинг текста, он почему-то все время уезжает за пределами экрана и появляется с другой стороны, а должен оставаться на месте, нужно сохранить
эффект волн, но чтобы текст оставался на месте. Я понимаю что дело в стиле left, но не знаю как исправить может кто подскажет? Вот рабочий код. <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>Text Wave</title> <style type="text/css"> .letter { font-family: sans-serif; font-size: 40px; font-weight: bold; position: absolute; top: -100px; left: 0px; } </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $(document).ready(function() { const width = $(window).width(); const letterSpacing = 35; var startTime = new Date().getTime(); const waveText = 'Мой текст'; var elements = $('#elements'); for (i = 0; i < waveText.length; i++) { $('<div>', { html: waveText[i] }) .addClass('letter') .appendTo(elements); } function runWave() { var elapsed = new Date().getTime() - startTime; var pos = elapsed * 0.05; $('div.letter').each(function(index, letter) { var posx = ((pos + letterSpacing * index) % width); var posy = 100 + Math.sin(posx / 50) * 20; $(letter).css('left', posx + 'px'); $(letter).css('top', posy + 'px'); }); } setInterval(runWave, 30); }); </script> </head> <body> <div id="elements"></div> </body> </html> |
Цитата:
|
Часовой пояс GMT +3, время: 10:25. |