Страницы

Поиск по вопросам

среда, 18 декабря 2019 г.

Как анимировать криволинейную границу объекта?

#javascript #вёрстка #svg #canvas


Имеется вот такой объект на сайте:



Данная "клякса" имеет криволинейную границу по правой и нижней стороне. 

Картинка статична, но я приведу ссылку с тем, как это уже реализовано на одном из
популярных сервисов. 

Хотелось бы узнать, как реализовать данный эффект? Интересует только анимация этих
"скруглений".

В каком направлении можно найти хотя бы приближённую информацию?
На данном сайте используется canvas для отрисовки объекта, но я знаю точно, что такое
можно провернуть и на SVG.
    


Ответы

Ответ 1



То что в макете больше всего напоминает синусоиду в полярных координатах. Начнем с окружности, в полярной системе координат (d - расстояние, t - угол) ее формула крайне проста: d = r; // d - расстояние до точки равно радиусу оркужности. Как это понимать: представьте что вы взяли в руки циркуль и чертите окружность. Вроде все. Расстояние до каждой точки окружности от центра неизменно и равно радиусу. Значение радиуса от угла неизменно. Если во время поворота циркуля менять его радиус в зависимости от угла и сделать эту завистмость в виде синусоиды - получится форма подобная той, что в макете d = r + sin(t*freq)*amp; // freq - частота, amp - амплитуда. А если добавить в эту зависимость время - получится анимация. let lerp = (a, b, val) => a + val * (b - a); // линейная интерполяция let rand = n => (Math.sin(n)*43758.5453123)%1; // псевдо случайное число https://joshondesign.com/2013/03/01/improvedEasingEquations function easeOutElastic(t) { var p = 0.5; return Math.pow(2,-10*t) * Math.sin((t-p/4)*(2*Math.PI)/p) + 1; } // одномерный шум let noise = p => { let fl = Math.floor(p); return lerp(rand(fl), rand(fl + 1.0), p%1); } requestAnimationFrame(draw); function draw(t) { requestAnimationFrame(draw); t = Math.max(0, t - 200); // небольшая задержка на старте let pts = "0,0"; // для каждого угла в первой четверти окружности с шагом 0.01 радиан считаем точку for (var a = 0; a <= Math.PI/2; a += 0.01) { a %= Math.PI*2; // нормализуем угол // анимация увеличения радиуса кляксы на старте до значения 90 let grow = Math.min(1, t/1000); grow = easeOutElastic(grow) let r = grow*70 // добавляем к базовому радиусу синус и косинус от времени и угла. + Math.cos(a*11 - t/379) * 2*grow + Math.sin(a*17 + noise(t/1e4)*15) * 3*grow; pts += "," + Math.cos(a)*r + "," + Math.sin(a)*r; } shape.setAttribute('points', pts); } body { margin:0;overflow:hidden; } Добавил элемент псевдо случайности, так веселее

Ответ 2



Подобная анимация реализуется с помощью изменения атрибута "d" path. Сначала нужно получить форму кривой в начальном положении: Затем с помощью перемещения узловых точек кривой в векторном редакторе получаем финальную форму кривой : Далее пишем команду анимации кривой: svg { width:40%; height:40%; } path { fill:#2F3136; stroke:black; stroke-width:4; } Вариант с фоновой картинкой и тенью .container { width:75%; height:75%; } path { fill:#2F3136; stroke:black; stroke-width:0; fill-opacity:0.5; -webkit-filter: drop-shadow(4px 4px 1px black); filter: drop-shadow(4px 4px 1px black); }
Анимация границы плюс анимация размера всего блока .container { width:75%; height:75%; } path { fill:#2F3136; stroke:black; stroke-width:0; fill-opacity:0.5; }


Комментариев нет:

Отправить комментарий