Синусоидальная анимация
Это эффект, которого я пытаюсь достичь: ссылка
Я получил четыре волны, и они действительно анимированные, но я застрял, давая каждой из них немного различную анимацию. В текущей точке все кривые движутся с одинаковой скоростью, в одном направлении и тоже переключаются в одном и том же месте. они должны слегка отличаться во всех этих аспектах. Конечный результат, который я ищу, очень похож на ссылку, которую я разместил, с той разницей, что каждая волна может иметь максимум один цикл, который повышается один раз и снижается один раз. Спасибо за ваш вклад.
Ниже мой код:
function start() {
var canvas = $("canvas");
console.log(canvas);
canvas.each(function(index, canvas) {
var context = canvas.getContext("2d");
canvas.width = $(".box").eq(index).width();
canvas.height = $(".box").eq(index).height();
context.clearRect(0, 0, canvas.width, canvas.height);
drawCurves(context, step);
step += 1;
});
requestAnimationFrame(start);
}
var step = -1;
function drawCurves(ctx, step) {
var width = ctx.canvas.width;
var height = ctx.canvas.height;
ctx.lineWidth = 2;
for (i = 0; i < 4 ; i++) {
var x = 0;
var y = 0;
ctx.beginPath();
if (i === 0 ) {
ctx.strokeStyle = "red";
var amplitude = 20;
var frequency = height / (2 * Math.PI) ;
console.log(i, frequency);
} if ( i === 1) {
ctx.strokeStyle = "blue";
var amplitude = 30;
var frequency = (height / (2 * Math.PI));
console.log(i, frequency);
} if ( i === 2) {
ctx.strokeStyle = "green";
var amplitude = 40;
var frequency = height / (2 * Math.PI) ;
console.log(i, frequency);
} if (i === 3) {
ctx.strokeStyle = "yellow";
var amplitude = 50;
var frequency = height / (2 * Math.PI) ;
console.log(i, frequency);
}
ctx.save();
ctx.translate(-amplitude * Math.sin(step / frequency), 0);
while (y < height) {
x = (width / 2) + (amplitude * Math.sin((y + step) / frequency)) ;
ctx.lineTo(x, y);
y++;
}
ctx.closePath();
ctx.stroke();
ctx.restore();
}
}
$(document).ready(function() {
start();
})
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="box">
<canvas id="canvas"></canvas>
</div>
<div class="box">
<canvas id="canvas"></canvas>
</div>
</body>
</html>
А вот кодовая ручка
2 ответа
@enxaneta спасибо за ваш вклад! Получил, как я хотел, ниже мое решение:
var step = 0;
function start(timestamp) {
var canvas = $("canvas");
canvas.each(function(index, canvas) {
var context = canvas.getContext("2d");
canvas.width = $(".box").eq(index).width();
canvas.height = $(".box").eq(index).height();
context.clearRect(0, 0, canvas.width, canvas.height);
if (canvas.height > 1000 ) {
drawWave(context, 20,"sin");
drawWave(context, 60,"cos");
drawWave(context, 40,"sin");
drawWave(context, 80,"cos");
}
if (canvas.height < 1000 ) {
drawWave(context, 10,"sin");
drawWave(context, 30,"cos");
drawWave(context, 20,"sin");
drawWave(context, 40,"cos");
}
step = timestamp / 7;
});
window.requestAnimationFrame(start);
}
function drawWave(ctx,amplitude,trig){
var width = ctx.canvas.width;
var height = ctx.canvas.height;
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = "blue";
var x = 0;
var y = 0;
var frequency = height / (2 * Math.PI);
ctx.save();
ctx.translate(-amplitude * Math[trig](step / frequency), 0);
while (y < height) {
x = width / 2 + amplitude * Math[trig]((y + step) / frequency);
ctx.lineTo(x, y);
y++;
}
// ctx.closePath();
ctx.stroke();
ctx.restore();
}
$(document).ready(function() {
start();
});
canvas {
background-color: wheat;
position: absolute;
}
.box {
width: 500px;
height: 2000px;
border: solid;
}
.box.t {
width: 500px;
height: 200px;
border: solid;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="box t">
<canvas id="canvas"></canvas>
</div>
<div class="box">
<canvas id="canvas"></canvas>
</div>
</body>
</html>
Ваш код рисует только одну синусоидальную волну. Я советую вам эти моменты:
_Если вам нужна другая (одновременная) волна, вы должны использовать разные значения x/y в точке рисования.
Вы используете $(document).ready(function() в качестве цикла анимации, это не лучший способ сделать это. Для анимации вы должны установить setInterval или лучше использовать requestAnimationFrame, который предназначен для создания анимации. В каждом цикле анимации рисуйте 4 линии пазухи, я забуду о шаге для использования объектов вместо этого, который я считаю лучше, но это не важный момент. У меня нет времени, чтобы попробовать ваш код, но что он делает при использовании requestAnimationFrame(start()) вместо $document.ready? Очевидно, в каждой анимации, чтобы очистить место рисования, используя clearRect (ширина, высота), например.
_ 4 шага добавляют +1 к +4 к y в том же декартовом уравнении. В синусоидальной кривой, которая на самом деле не будет видна человеческим глазом, потому что это действительно небольшое изменение. Вы можете использовать разностные уравнения, используя разностные синусоидальные уравнения для каждого шага / объекта, то есть Math.sin(y)+10 или Math.sin(y)*10 и т. Д.... или даже различное значение инкрементации для каждого разностного объекта. Я буду избегать преобразования и использовать цикл for для увеличения значения x и получения значения y с помощью sin(x) и любого уравнения, которое вам нужно, это личный выбор, но он не будет писать строку.translate() и будет использовать нормальные координаты. вместо перемещенных координат вы легко увидите в console.log реальные координаты в области холста.
Как и в предыдущем случае, вы можете отбросить проверяющие IF в начале программы, если вы используете объекты в массиве (и зацикливаете их) и устанавливаете styleColor и вес каждого из 4 объектов.
Надеюсь, это поможет, нет времени, чтобы написать чистый код.