Недавно я сделал проект, в котором необходимо реализовать анимационные эффекты дождя и легкого снега, поэтому я сделал здесь компонент капли, чтобы показать общие падающие объекты этого холста. Прежде чем представить вам основной текст, позвольте мне показать вам визуализации:
Отображение визуализации:
Идет дождь и снег
Это выглядит хорошо. По сравнению с использованием создания элементов DOM для создания изображений движения с несколькими объектами, использование Canvas будет проще и быстрее, а производительность будет лучше.
Позвонить код
<! Doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title> документ </title> <style> #canvas {ширина: 100%; рост: 100%;} </style> </head> <body> <canvas id = "canvas"> </canvas> src = "canvasdrop.js"> </script> <script> canvasdrop.init ({type: "Rain", // Drop Type, Rain или SnowSpeed: [0,4,2,5], // диапазон скорости размер_Ранга: [0,5,1,5], // размер и диапазон радиуса. hasgravity: true // Есть ли какое -либо гравитационное рассмотрение}); </script> </body> </html>Хорошо, давайте объясним простой принцип реализации. Во -первых, определите некоторые глобальные переменные, которые мы будем использовать, такие как угол направления ветра, вероятность, данные объекта и т. Д.
Определить глобальные переменные
// Определите два данных объекта // объект объекта Drops Drops Object // и отскок объекта отскакивает объект var drops = [], bounces = []; // Гравитационное ускорение установлено на 0,2/один кадр варит = 0,2; var speed_x_x, // горизонтальное ускорение скорости_x_y, // Longiline Acceleress Wild_anger; // направление ветра // ширина пикселя и высота канвас -вар -канвасгидны, canvasheight; // вероятность создания drop var drop_chance; // Настройка объекта Varts; // По умолчанию, будет ли это requestAnimationFrame Frame, если есть, используйте, если нет, это будет около 30 фреймов. || window.webkitrequestanimationframe || window.mozrequestanimationframe || window.orequestanimationframe || window.msrequestanimationframe || function (обратный вызов) {window.settimeout (обратный вызов, 1000/30);};Определите основной объект
Затем нам нужно определить несколько важных объектов. Существует меньше объектов, которые организация должна определить. В общей сложности только три основных объекта определяются во всем компоненте Drop, которые следующие:
Объект векторной скорости, с горизонтальными x и вертикальными единицами скорости y: V = смещение пиксели/рамки
Понимание векторного объекта также очень простое и грубое, то есть записать скорость падения объекта/V
var vector = function (x, y) {// частное атрибут горизонтальная скорость x, вертикальная скорость ythis.x = x || 0; this.y = y || 0;}; // public Method- Добавить: Функция изменения скорости, увеличьте скорость в соответствии с параметрами // Из-за потребностей бизнеса рассматривается все падение ускорения, поэтому не наблюдается замедления, и его можно расширить на более позднем этапе/** @param v объект || string */ector.prototype.add = function (v) {if (vx! = null && vy! = null) {this.x += vx; this.y += vy;} els {// Возврат векторный экземпляр с тем же атрибутом, возвращающим новый вектор (this.x, this.y);}; выбросить объект Drop объекта, то есть капли дождя и снег в вышеупомянутом эффекте, позже вы можете расширить его на метеорит или оболочку. Основное определение объекта DROP заключается в следующем // Constructor var drop = function () {/ * .... */}; // public Method-Update drop.prototype.update = function () {/ * .... */}; // public метод drawdrop.prototype.draw = function () {/ * ...... */};Прочитав три вышеупомянутых метода, вы догадались их роль? Давайте поймем, что делают эти три метода.
Конструктор
Конструктор в основном отвечает за определение начальной информации объекта DROP, такой как скорость, начальные координаты, размер, ускорение и т. Д.
// Конструктор DropVar Drop = function () {// Случайный установите начальные координаты Drop // Сначала выберите падающий элемент, из которого есть сторона из var randomedge = math.random () * 2; if (randingedge> 1) {this.pos = new Vector (50 + math.random () * canvas.width, wydth -width. Math.random () * canvas.height);} // Установить размер падающего элемента // случайное значение принимается в диапазоне радиуса вызываемой функции Opts this.radius = (opts.size_range [0] + math.random () * opts.size_range [1]) * dpr; // Получите начальную скорость падения // случайное значение по скорости. (Opts.speed [0] + math.random () * opts.speed [1]) * dpr; this.prev = this.pos; // умножьте угол на 0,017453293 (2PI/360), чтобы преобразовать его в радиан. var wangage = 0,017453293; // Получить угол направления ветра wind_anger = opts.wind_direction * wangyager; // Получить боковое ускорение speed_x = this.speed * math.cos (wind_anger); // Получить продольное ускорение speed_y = - this.speed * math.sin (wind_anger); // привязать экземпляр скорости.Обновление метода Drop объекта
Метод обновления отвечает за изменение атрибутов каждого экземпляра Drop Frame, таких как изменение смещения.
Drop.prototype.update = function () {this.prev = this.pos.copy (); // Если есть гравитация, продольная скорость будет увеличена, если (opts.hasgravity) {this.vel.y += Gravity;} // this.pos.add (this.vel);};Метод рисования объекта Drop
Метод рисования отвечает за рисование каждого экземпляра кадра.
Drop.prototype.draw = function () {ctx.beginpath (); ctx.moveto (this.pos.x, this.pos.y); // В настоящее время существует только две ситуации, одна - дождь, то есть curve bezier if (opts.type == "rain") {ctx.moveto (это. Math.abs (this.radius * math.cos (wind_anger)); var ay = math.abs (this.radius * math.sin (wind_anger)); ctx.beziercurveto (this.pos.x + ax, this.pos.y + ay, this.prev.x + ax, this.prev.y. this.pos.y); ctx.stroke (); // Другое snow---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Опк объект отскока от падения и падения, то есть капель воды, которые отскакивают от дождевой воды выше, вы также можете расширить в отскок гравия или дым на более поздней стадии
Определение очень простое, поэтому я не буду подробно объяснить это здесь
var Bounce = function (x, y) {var dist = math.random () * 7; var angle = math.pi + math.random () * math.pi; this.pos = новый вектор (x, y); this.radius = 0,2+ math.random () * 0,8; this.vel = new Vector (math.cos. Dist);}; Bounce.prototype.update = function () {this.vel.y += Gravity; this.vel.x *= 0,95; this.vel.y *= 0,95; this.pos.add (this.vel);}; bounce.prototype.draw = function () {ctx.beganpath (); this.radius * dpr, 0, math.pi * 2); ctx.fill ();};Внешний интерфейс
обновлять
То есть начальная функция, эквивалентная всей анимации холста
function update () {var d = новая дата; // Очистить чертеж ctx.clearrect (0, 0, canvas.width, canvas.height); var i = drops.length; while (i--) {var drop = Drops [i]; Drop.update (); // Если экземпляр Drop отходит в дно, вам нужно быть ясным в array (); //. canvas.height) {// Если вам нужно отскочить, добавьте экземпляр Bounce в массив Bounce if (opts.hasbounce) {var n = math.round (4 + math.random () * 4); while (n-) bounces.push (новый отскок (drop.pos.x, canvas.height));} // Если экземпляр Drop опускается в дно, вы должны быть ясны в массиве Drops объекта экземпляра Drops.splice (i, 1);} drop.draw ();} // Если вам нужно восстановить, если (opts.hasbound) {var-les; (i--) {var bounce = bounces [i]; bounce.update (); bounce.draw (); if (bounce.pos.y> canvas.height) bounces.splice (i, 1);}} // Если число генерируемого каждый раз-это если (varge varge.maxnum) (if. 0, len = opts.numlevel; for (; i <len; i ++) {drops.push (new drop ());}}} // непрерывно зацикливатьсяинициатор
Интерфейс init, инициализируйте все основные свойства всего холста, таких как получение соотношения пикселя экрана и установка размера пикселя холста и настройка стиля холста
function init(opts) {OPTS = opts;canvas = document.getElementById(opts.id);ctx = canvas.getContext("2d");//// Compatible with high-definition screens, the canvas canvas pixels must also change DPR = window.devicePixelRatio;// Canvas artboard pixel size, and must be compatible with high-definition экраны, поэтому длина и ширина холста артборда должны быть умножены на dpr canvaswidth = canvas.clientwidth * dpr; canvasheight = canvas.clientHeight * dpr; // установить ширину и высоту canvash.4shant width = width = widtth = width width width width width width width widshame = canvaswidth. setStyle ();} функция setStyle () {if (opts.type == "rain") {ctx.linewidth = 1 * dpr; ctx.strokestyle = 'rgba (223,223,223,0,6)'; ctx.fillstyle = Rgba (223,223,223,0,6) ';} else {ctx.linewidth = 2 * dpr; ctx.strokestyle =' rgba (254,254,254,0,8)Заключение
ОК, простой компонент Drop был завершен, конечно, есть много вещей, которые не идеальны. После написания этого компонента Drop, для реализации анимации Canvas, я считаю, что в сцене H5 есть много мест.
Наконец, давайте поговорим о недостатках и позже работе:
0. Не хватает внешних интерфейсов для этого компонента, регулируемый диапазон не очень большой, а абстракция не очень тщательная.
1. SetStyle Set Basic Style
2. Настройка обновления и нарисовать методы снижения и отскока объектов позволяет пользователям устанавливать больше форм и стиля эффектов падения скорости и изменения размера.
3. Необходимо добавить интерфейс для паузы анимации, ускорения и замедления.
Вышесказанное - это соответствующие знания о JS и холсте, которые я представил вам о достижении дождливых и снежных последствий. Я надеюсь, что это будет полезно для вас. Если у вас есть какие -либо вопросы, пожалуйста, оставьте мне сообщение, и редактор ответит вам вовремя. Большое спасибо за вашу поддержку сайту wulin.com!
Эта статья воспроизведена: http://blog.csdn.net/xllily_11/article/details/514444311