Признание: На самом деле я не очень хорошо знаю физику. Сказать, что я обладаю базовыми знаниями – это сильно преувеличить. Последний раз я знала что-то достаточно сложное по физике 11 лет назад. Мне было 17, и я знала ровно столько, чтобы получить твердую четверку на выпускных экзаменах в школе, после которых я немедленно выкинула всю эту информацию из своей головы, чтобы освободить место для более важных вещей, таких как тексты песен из альбома «Nellyville» Nelly.
Но тут пришел 2013 год, и я поняла, что я могла бы использовать некоторые физические расчеты, чтобы создавать крутую анимацию с канвой. Черт побери! К счастью, я довольно быстро осознала, что мне не обязательно вспоминать программу старших классов. Достаточно просто схитрить.
Банальная физика
Мне нравится называть это банальной физикой, так как мы используем очень базовое понимание векторов и пишем JavaScript, который в какой-то мере воспроизводит эти векторы, но никоим образом не представляет собой реальную физическую среду. Преимущество банальной физики заключается в том, что вам на самом деле даже не нужно понимать теорию физики за ее пределами. Вам нужно понимать только то, как ее использовать для анимации.
Векторы
Вектор – это математический объект, характеризующийся величиной и направлением. Скорость и ускорение – это векторы. Если вы скажете, что собираетесь ехать в северо-восточном направлении со скоростью 35 миль в час, вы опишете вектор.
Создаем скорость с помощью JavaScript
Наверняка, вы уже знаете, что такое скорость, но я все равно вам расскажу. Вектор скорости – это вектор, который состоит из скорости и направления. Когда мы воспроизводим скорость в JavaScript, мы делим ее на два вектора – скорость в направлении x и скорость в направлении y. Здесь мы имеем дело с пикселями и анимацией JavaScript, поэтому мы можем описать нашу скорость с точки зрения количества пикселей в кадр. Квадрату в примере присвоена скорость в направлении х в размере 2 пикселей на каждый кадр, и скорость в направлении y в размере 2 пикселей на каждый кадр. В результате мы получаем линейное диагональное движение.
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var width = canvas.width = window.innerWidth; var height = canvas.height = window.innerHeight; // position var x = 0; var y = 0; // velocity var vx = 2; var vy = 2; // animation loop function animate() { // clear canvas ctx.clearRect(0, 0, width, height); // draw square ctx.fillRect(x,y,20,20); // update position with velocity x += vx; y += vy; requestAnimationFrame(animate); // if square is out of view reset position to the start if (y > height || x > width) { x = 0; y = 0; } } animate();
Создаем ускорение с JavaScript
Ускорение – это коэффициент изменения скорости объекта. И как же мы воспроизводим это в JavaScript? У нас есть скорость vx и vy, и мы можем добавить ускорение в направлении x или y в каждом кадре. То есть, если ускорение равно 0,5 пикселей, мы добавим 0,5 пикселя к скорости x и скорости y в каждом кадре. Это заставит наш квадратик ускориться.
Невероятно простой и забавный пример – давайте сделаем фонтан из частиц!
Фонтан из частиц – это первый эффект банальной физики, который я анимировала. В частности, я сделала его с помощью Flash и ActionScript, но сейчас мы можем сделать это с JavaScript и канвой. По сути, я планирую использовать объект «частица» для создания фонтана.
Чтобы сделать фонтан, нам нужно сгенерировать некоторое количество частиц. Каждая частица должна иметь свое положение и скорость (vx и vy). Начальной позицией мы сделаем центр канвы, после чего зададим произвольную скорость частиц, чтобы они «распылялись» из нашего фонтана.
function Particle(x, y, vx, vy, size, color, opacity) { this.update = function() { x += vx; y += vy; } this.draw = function() { ctx.globalAlpha = opacity; ctx.fillStyle = color; ctx.fillRect(x, y, size, size); } } function createParticle(i) { // initial position in middle of canvas var x = width*0.5; var y = height*0.5; // randomize the vx and vy a little - but we still want them flying 'up' and 'out' var vx = -2+Math.random()*4; var vy = Math.random()*-3; // randomize size and opacity a little & pick a color from our color palette var size = 5+Math.random()*5; var color = colors[i%colors.length]; var opacity = 0.5 + Math.random()*0.5; var p = new Particle(x, y, vx, vy, size, color, opacity); particles.push(p); }
В результате должно получиться что-то вроде этого (возможно, вам придется нажать «rerun», чтобы их увидеть).
Частицы просто распыляются вверх и никогда не падают вниз. Нам нужно добавить немного «силы притяжения», чтобы заставить частицы падать. Мы уже знаем, как это сделать, потому что силу притяжения, по сути, можно воспроизвести с помощью ускорения в направлении y (вниз). Давайте установим значение силы притяжения (ускорения) равное 0,04 пикселя. Также мы немного уменьшим прозрачность каждого кадра, чтобы каждая частица в результате растворялась. После этого мы сделаем нулевую прозрачность в точке, в которой мы будем «возвращать» нашу частицу в центр фонтана.
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var width = canvas.width = window.innerWidth; var height = canvas.height = window.innerHeight; var particles = []; var colors = ['#029DAF', '#E5D599', '#FFC219', '#F07C19', '#E32551']; var gravity = 0.04; function initParticles() { for (var i = 0; i < 200; i++) { setTimeout(createParticle, 20*i, i); } } function createParticle(i) { // initial position in middle of canvas var x = width*0.5; var y = height*0.5; // randomize the vx and vy a little - but we still want them flying 'up' and 'out' var vx = -2+Math.random()*4; var vy = Math.random()*-3; // randomize size and opacity a little & pick a color from our color palette var size = 5+Math.random()*5; var color = colors[i%colors.length]; var opacity = 0.5 + Math.random()*0.5; var p = new Particle(x, y, vx, vy, size, color, opacity); particles.push(p); } function Particle(x, y, vx, vy, size, color, opacity) { function reset() { x = width*0.5; y = height*0.5; opacity = 0.5 + Math.random()*0.5; vx = -2+Math.random()*4; vy = Math.random()*-3; } this.update = function() { // if a particle has faded to nothing we can reset it to the starting position if (opacity - 0.005 > 0) opacity -= 0.005 ; else reset(); // add gravity to vy vy += gravity; x += vx; y += vy; } this.draw = function() { ctx.globalAlpha = opacity; ctx.fillStyle = color; ctx.fillRect(x, y, size, size); } } function render() { ctx.clearRect(0, 0, width, height); for (var i = 0; i < particles.length; i++) { particles[i].update(); particles[i].draw(); } requestAnimationFrame(render); } // resize window.addEventListener('resize', resize); function resize() { width = canvas.width = window.innerWidth; height = canvas.height = window.innerHeight; } // init initParticles(); render();
Таким образом, у нас получится бесконечный фонтан частиц!
→ Принимайте оплату от компаний через Интернет. Без сайта, ИП и ООО.
→ Приём платежей от компаний для Вашего сайта. С документооборотом и обменом оригиналами.
→ Автоматизация продаж и обслуживание сделок с юр.лицами. Без посредника в расчетах.
ссылка на оригинал статьи http://habrahabr.ru/post/262099/
Добавить комментарий