20
Июл
2021

Как оптимизировать или исправить анимацию волны?

Делаю примитивную анимацию волны. Но столкнулся с проблемой. Первая кривая Безье не согласуется с последующими, из-за этого пришлось спрятать этот участок за холстом.

Как можно упростить анимацию, ведь сейчас каждый раз создается новый путь?

Подозреваю, что можно отрисовать одиночный элемент, полуволну, которую повторить с помощью pattern, например. Но высота, ширина волны, а в дальнейшем и наклон могут меняться. Поэтому не хочу делать этот tile "в камне". Как можно сделать этот повторяющийся элемент стыкуемым и одновременно программно изменяемым? Можно ли решить с помощью SVG и CSS-анимаций?

Пример со спрятанными волнами в начале:

const SPEED = 0.05;
const WAVE_WIDTH = 100;
const WAVE_HEIGHT = 50;
const CANVAS_WIDTH = 600;
const CANVAS_HEIGHT = 200;

let canvas = document.querySelector('canvas');
let ctx = canvas.getContext('2d');

let w = canvas.width = CANVAS_WIDTH;
let h = canvas.height = CANVAS_HEIGHT;

ctx.fillStyle = 'blue';

let wave_fase = 0;

draw();

function draw(){
    ctx.clearRect(0,0,w,h);
    
    let waves_path_string = `M ${WAVE_WIDTH*(wave_fase - 3)} ${h}
                            V ${h/2 - WAVE_HEIGHT/2}
                            q ${WAVE_WIDTH/2} ${-WAVE_HEIGHT/2} ${WAVE_WIDTH} ${WAVE_HEIGHT/2} `;
    
    waves_path_string += 't' + ` ${WAVE_WIDTH} 0`.repeat(w/WAVE_WIDTH + 3) + ` V ${h} z`;
    
    ctx.fill(new Path2D(waves_path_string));
    
    wave_fase = (wave_fase + SPEED)%2;
    
    requestAnimationFrame(draw);
}
<canvas></canvas>

А здесь видно первую волну, которая не хочет встраиваться в общий ряд.

const SPEED = 0.01;
const WAVE_WIDTH = 60;
const WAVE_HEIGHT = 40;
const CANVAS_WIDTH = 600;
const CANVAS_HEIGHT = 200;

let canvas = document.querySelector('canvas');
let ctx = canvas.getContext('2d');

let w = canvas.width = CANVAS_WIDTH;
let h = canvas.height = CANVAS_HEIGHT;

ctx.fillStyle = 'blue';

let wave_fase = 0;

draw();

function draw(){
    ctx.clearRect(0,0,w,h);
    
    let waves_path_string = `M ${WAVE_WIDTH*wave_fase} ${h}
                              V ${h/2 - WAVE_HEIGHT/2}
                              q ${WAVE_WIDTH/2} ${-WAVE_HEIGHT/2} ${WAVE_WIDTH} ${WAVE_HEIGHT/2} `;
    
    waves_path_string += 't' + ` ${WAVE_WIDTH} 0`.repeat(w/WAVE_WIDTH) + ` V ${h} z`;
    
    ctx.fill(new Path2D(waves_path_string));
    
    wave_fase = (wave_fase + SPEED)%2;
    
    requestAnimationFrame(draw);
}
<canvas></canvas>

Источник: https://ru.stackoverflow.com/questions/1307201/%D0%9A%D0%B0%D0%BA-%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D1%82%D1%8C-%D0%B8%D0%BB%D0%B8-%D0%B8%D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-%D0%B0%D0%BD%D0%B8%D0%BC%D0%B0%D1%86%D0%B8%D1%8E-%D0%B2%D0%BE%D0%BB%D0%BD%D1%8B

Тебе может это понравится...

Добавить комментарий