[Из песочницы] Анимационная пасхалка, или дань уважения студии при увольнении из нее
На Хабре много статей. Но не каждая показывает, как размышлял автор, его грабли и действия.
Здесь я хочу вам рассказать, как я делал пасхалку для логотипа веб-студии в которой я работал.
Как то раз увидев завораживающую анимацию от создателя библиотеки mo-js для svg-эфектов, я загорелся и решенил сделать что-то подобное. Как раз мне на глаза попалась обновленная главная страничка нашей студии, недолго думая я собрался сделать анимацию для логотипа.
И раз эта статья рассказывает, как все это происходило, то к моему сожалению я не стану пересказывать весь мануал по данной библиотеки. Его вам придется прочитать самим, если конечно захотите сделать что-то подобное.
Ну, а чтобы сразу вникнуть в статью:
→ Ссылка на демо просмотр только от 1204×400, кликнуть на колокольчик
→ Ссылка на GitHub
Первые начинания
Мы все ошибаемся, но не всегда понимаем, что идем по каменистой дорожке.
Изначально я хотел разбивать логотип на мелкие кусочки, сжимать их в 1 точку, и только потом как пазл собирать в единое целое со всевозможными эффектами (думаю это было бы красиво). Но быстро понял, что делаю очень быструю анимацию и естественно она будет без звука. Когда логотип создателя библиотеки, как я написал, был «Завораживающим».
Свое второе вдохновение я нашел в одной навязчивой мелодии (Clannad песенка булочек), думаю многие щас вздохнули в меланхоличном припадке. Да она просто умиляющая. И раз это колыбельная, то и тематика ей должна быть подстать!
Сюжет выдумывать особо и не пришлось. Колыбельная — «ночь, звезды, луна», замечательные ассоциации, большие варианты развития сюжета моей пасхалки.
Первым делом я нашел минус этой песенки и нарезал ее до 30 секунд, это максимум времени, сколько может выдержать любой гость, не закрыв страницы (думаю на большее меня бы и самого не хватило). Далее сделал метки эффектов, наиболее подходящим инструментом я выбрал Adobe Audition CC 2017 (честно говоря другого инструмента я и не искал, просто он мне попался на глаза первым).
Выглядело это так:
Библиотека предоставляет вложенные временные шкалы объекта TimeLine (), я бы мог разделить все на отдельные блоки, и начинать их анимацию по отдельности. Но т.к. у меня была привязка к мелодии, я счел необходимым сделать все на 1 единой временной шкале, дабы не запутать себя самого с таймингом. Просто сделал большие блоки массивов с временем начала в виде предоставляемого библиотекой параметра задержки (delay).
Радужный дождь и взращивание букв
С точки зрения обычного пользователя, сюжет анимации всегда довольно простой. Падают радужные лучи, вырастают буквы, появляется рельеф, звезды и выходит луна, финиш, еще можно что-то там повозить. Но редко кто описывает, как он это делал, сколько вложил сил, терпения и слез своей музы.
Структуризация кода всегда помогает мыслить в рамках отдельных модулей и у меня получилось 5 объектов для манипуляций над элементами анимации.
FirstRainbow
Анимация падения радуги мне далась довольно легко, я банально скопировал ее с примера в тутореал. Сделал массив с координатами и описал это в 1 методеrainbow(200, 500, 'A', 'str1')
где параметры — это продолжительность, время задержки (в моем случае начала) анимации и последние 2 описывают координату.Эффект падения получился невзрачный:
Скрытый текст
Изменили на улучшенный:Скрытый текстLetters
Описывает анимацию букв. Он стал первым по сложности для меня объектом. Концепция анимации заключалась в росте, будто растения. С буквами пришлось изрядно повозиться, думаю не каждый умеет работать в Illustrator (я в том числе). И как человек получивший в этом опыт, советую:- Всегда вычищайте код svg после редактора.
- Переименовывайте классы в уникальные
- Не забывайте удалять лишнии слои.
Потратил 60% общего времени только на синхронизацию, сверку координат, отрисовку отдельных линий (которые нельзя сымитировать стандартными фигурами). Мне приходилось по 20 раз менять 1 параметр, ради достижения хорошего эффекта. Но мой внутренний перфекционист пошел на компромисс со временем и сдался.Код же прост для обзора:
...that.plant_D(800, 10111), ...that.plant_A(800, 10200), ...that.plant_R(800, 10300), ...that.plant_N(800, 10400), ...that.plant_E(800, 10500), ...that.plant_O(800, 10600), ...that.plant_S(800, 12500), ...that.plant_T(800, 13100), ...that.plant_U(800, 13400), ...that.plant_D2(800, 13700), ...that.plant_I(800, 14000), ...that.plant_O2(800, 14300)
Вторым с чем я столкнулся — это с собственной невежественностью в чтении мануалов, мы все в той или иной степени этим страдаем. Банально упустил пункт о том, что собственные заготовки svg должны быть в разрешении 100×100 и первая буква «D» пошла наперекосяк. Ну и конечно, в таких случаях мы всегда делаем костыль, что и случилось. Просто поменял ей размер, после инициализации (а раз я использовал объект Burst, то и менять мне надо сразу всех потомков).for (let el of equal.el.children) { el.style['height'] = '180px'; }
В дальнейшем я задал вопрос на GitHub, на что меня ткнули в пунктик мануала)Добавление собственной svg происход след. образом:
class elipceR2 extends mojs.CustomShape { getShape () { return '
'; } getLength () { return 200; } // optional }
добавить и использовать (простота во всем):mojs.addShape( 'elipceR2', elipceR2'); new mojs.Shape({ shape: 'elipceR2'});
Либо использовать дефолтные svg-фигуры.MoonRise
Описывает горизонт, горы, выход луны. С луной возился долго, надо было соблюдать стилистику и луна с детальным рельефом тут не подходила:Скрытый текст
Но, я удачно нагуглил более лучший вариант:Скрытый текст
немного поправить напильником и получаем замечательную луну, хорошо подходящую к нашей стилистике.Для приличия код:
that.moon(5000, 20000), that.mountains(1500, 18500), that.horizonLine(1600, 18500),
Stars
Второй по сложности объект. Стал основными источником синхронизации эффектов с музыкальной нарезкой «Семейства булочек».Я сделал несколько массивов звезд и вывел их в заданный момент, попутно закинув их в контекст объекта для дальнейших манипуляций c цветом, размером и их координатами.
Где, параметры это время анимации, начало, и кол-во звезд.
that.curentStars = [ ...that.star(200, 17050, 5), ...that.star(200, 17300, 15), ...that.star(200, 17600, 25), ...that.star(200, 17900, 30), ...that.star(200, 18200, 35), ];
Как-то размыть svg средствами библиотеки мне не удалось, пришлось их просто увеличивать. Как всегда, длительность анимации, ее начало, массив и кол-во звезд, которые мы берем рандомно,that.shineStars(10, 21200, that.curentStars, 3); that.shineStars(10, 21600, that.curentStars, 3); that.shineStars(10, 21900, that.curentStars, 3); that.shineStars(10, 22100, that.curentStars, 4); that.shineStars(10, 22400, that.curentStars, 4); that.shineStars(10, 22700, that.curentStars, 4); that.shineStars(10, 23300, that.curentStars, 10); that.shineStars(10, 23900, that.curentStars, 15); that.shineStars(10, 24500, that.curentStars, 12); that.shineStars(10, 25150, that.curentStars, 9); that.shineStars(10, 25700, that.curentStars, 6); that.shineStars(10, 26300, that.curentStars, 7); that.shineStars(10, 26600, that.curentStars, 4); that.shineStars(10, 27200, that.curentStars, 8); that.shineStars(10, 28170, that.curentStars, 3);
попутно закидывая в свойство для падения this.curRimShineStar.Оказалось, что если выбирать звезды рандомно, то бывают моменты, когда звезда имеет очень маленькое расстояние к координате к которой она должна была начать движение. И как следствие я просто видел падающую точку. Отфильтровав массив по координатам на правую зону, я добился более продолжительной анимации и показу хвоста за звездой.
that.shootingStar(500, 29600, {y: 52, x: PARAMS.COORDINATES_X.str1.D}); that.shootingStar(500, 29800, {y: 52, x: PARAMS.COORDINATES_X.str1.A}); that.shootingStar(500, 30100, {y: 52, x: PARAMS.COORDINATES_X.str1.R[0]}); that.shootingStar(500, 30400, {y: 52, x: PARAMS.COORDINATES_X.str1.N[0]}); that.shootingStar(500, 30700, {y: 52, x: PARAMS.COORDINATES_X.str1.N[1]}); that.shootingStar(500, 31070, {y: 52, x: PARAMS.COORDINATES_X.str1.E}); that.shootingStar(500, 31370, {y: 52, x: PARAMS.COORDINATES_X.str1.O});
Очень огорчило отсутствие некоторых подробностей по местоположению параметров в объектах, но все решилось банальным выводом его в консоль и чтением исходников (долго, но всегда гарантированный результат). Мне потребовалось узнать, когда объект завершит свою анимацию после всех манипуляций с ним и я не сразу понял что свойство Object.timeline._props.time его показывает, изначально я искал его в Object._oГде то я конечно схалтурил в коде, за что трудно себя простить. Но в целом анимация удалась замечательной.
PointsTimer
Чтобы гость мог покрутить ползунок и самому посмотреть, как это происходило, пришлось добавить и таймер, который завершал анимацию через пару секунд простоя. Тут моя фантазия уже закончилась и я просто добавил 3 уменьшающихся круга. По истечению которых, при помощи той же JQuery.animate () мы растворяем буквы в логотипе и удаляем все теги, что добавила библиотека.
К сожалению библиотека не может делать очень долгих анимаций, это можно заметить, есть дернуть ползунок очень быстро в сторону, вы увидите как все пойдет кусками, где то будут элементы, где то нет. Решить это можно думаю лишь принудительным манипулированием скорости ползунка.
Комментарии (2)
27 февраля 2017 в 11:55
0↑
↓
Очень завораживает! Мне понравилось27 февраля 2017 в 13:02
0↑
↓
Смутила луна, которая просвечивает, когда появляется из-за горы. А в целом симпатично