最近のプロジェクトでは、UI に水の波の効果を伴う背景アニメーションをデザインしましたが、CSS を使用して実装しようとしましたが、アニメーション効果はあまり良くありませんでした。それを実現するためにベジェ曲線を使用したのですが、以前見たさまざまな波形図を思い出したので、三角関数画像を使用して簡単にシミュレーションしてみようと思いました。
1. sin関数の画像を描画するsin 関数の式は次のようになります。
y=Asin(wx+φ)+h
このうち、A は振幅、ω は角周波数 (ω=2π/T、T は関数の周期)、φ は初期位相、h は画像の正方向への平行移動の長さを表します。 y 軸 (ここで注意してください。数学では h は本来上方への移動を意味しますが、キャンバスでは画面座標系が使用されます。つまり、左上隅が原点であり、h は下方への移動を意味します)。
描画コードは以下の通りです。
(1) Canvasタグの追加
<canvas id=canvas></canvas>
(2) CSSスタイルを追加し、キャンバスの幅と高さを設定します
html,body { パディング: 0; マージン: 0; 幅: 100%; 高さ: 100%;}
(3) 描画機能イメージ
var Canvas = document.getElementById(canvas), ctx = Canvas.getContext('2d'), width = Canvas.width = Canvas.offsetWidth, height = Canvas.height = Canvas.offsetHeight;//パラメータを宣言 var A=50, W=1 / 50, Q=0, H= 高さ / 2;//描画メソッド(functiondraw(){ ctx.clearRect(0, 0, width, height);//キャンバスをクリア ctx.beginPath(); //開始パス ctx.drawingStyle=#000; //線の色を設定 ctx.lineWidth = 1; //線の幅を設定 ctx.moveTo(0, height) /2) ; //(let x = 0; x <= width; x++) の開始点の位置 {// y = A*Math.sin(W*x+Q) +H に対応する x の変数を描画しますctx.lineTo(x, y) } ctx.ストローク() //パスを描画します ctx.closePath() //パスを閉じます })();
このようにして、次の画像が得られます。
2. 機能画像にアニメーションを追加する上で得られたものは静的な関数画像であり、私たちが一般に目にする波形や水の波は時間とともに連続的に変化します。ここでは、前のステップでパラメーター位相 φ を使用する必要があります (コード内の js は Q)。時間の経過とともに φ を増加または減少させて、異なる時点で異なる画像を取得します。 window.requestAnimationFrame を使用してフレーム アニメーションを実装します。
上記のコードを次のように変更します。
var Canvas = document.getElementById(canvas), ctx = Canvas.getContext('2d'), width = Canvas.width = Canvas.offsetWidth, height = Canvas.height = Canvas.offsetHeight;//パラメータを宣言 var A=50, W=1 / 50, Q=0, H= 高さ / 2;//描画メソッド(functiondraw(){ ctx.clearRect(0, 0, width, height);//キャンバスをクリア ctx.beginPath(); //開始パス ctx.drawingStyle=#000; //線の色を設定 ctx.lineWidth = 1; //線の幅を設定 ctx.moveTo(0, height) /2) ; //(let x = 0; x <= width; x++) の開始点の位置 {// y = A*Math.sin(W*x+Q) +H に対応する x の変数を描画しますctx.lineTo(x, y) } ctx.ストローク() //パスを描画します ctx.closePath() //パスを閉じます })();
効果は次のとおりです (Zhazha スクリーンショット ソフトウェア)。
3. 完全な塗りつぶしパスを描画します上記のパスは閉じていますが、埋める必要がある部分を満たしていません。直接塗りつぶしの効果は次のとおりです。
完全なパスは次のようになります。
パスを閉じた後、塗りつぶし色としてグラデーション色を作成します。コードは次のとおりです。
var lingrad = ctx.createLinearGradient(0,0,width,0); lingrad.addColorStop(0, 'rgba(0,186,128,0.8)'); (関数) draw(){ window.requestAnimationFrame(draw); ctx.clearRect(0, 幅, 高さ); ctx.drawingStyle = #000; ctx.moveTo(0, 高さ /2); =speed; for (let x = 0; x <= width; x++) { var y = A*Math.sin(W*x+Q) +H; ctx.lineTo(幅, 高さ); .closePath();})()
効果は次のとおりです。
4. 水の波のアニメーションを改善1. まず、上記の波形にさらに高い周波数の波形を重ねて、波形を不規則にすることができます。
var s = 0.1*Math.sin(x/150)+1;var y = A*Math.sin(W*x+Q) +H;y=y*s;
2. 異なる位相変化を持つ別の波形を追加し、そのグラデーションの塗りつぶしが前のグラデーションの方向と逆になるようにして、重なり合うシャドウ効果を形成し、パスの重なり効果を globalCompositeOperation に設定します。
var Canvas = document.getElementById(canvas)、ctx = Canvas.getContext('2d')、幅 = Canvas.width = Canvas.offsetWidth、高さ = Canvas.height = Canvas.offsetHeight;var A=30、W=1 / 200、Q=0、H= 高さ / 2;var A2=30、W2=1/300、Q2=0、H2= 高さ / 2;var 速度 = -0.01;var 速度 2 = -0.02;var lingrad = ctx.createLinearGradient(0,0,width,0);linggrad.addColorStop(0, 'rgba(0,186,128,0.8)');lingrad.addColorStop( 1, 'rgba(111,224,195,1)'); var lingrad2 = ctx.createLinearGradient(0,0,width,0);linggrad2.addColorStop(0,'rgba(111,224,195,1)');linggrad2.addColorStop(1, 'rgba(0,186,128,0.8)'); draw(){ window.requestAnimationFrame(draw); ctx.clearRect(0, width, height); ctx.fillStyle = lingrad; //最初の波形を描画します Q+=speed; = 0; x <= 幅; x++) { var s = 0.1*Math.sin(x/150)+1; A*Math.sin(W*x+Q) +H; ctx.lineTo(x, height); .fill(); ctx.closePath() //オーバーラップ効果を設定 ctx.globalCompositeOperation = destination-over //2 番目の波形を描画 ctx.beginPath(); ctx.fillStyle = lingrad2; for (let x = 0; x < width; x++) { var y = A2*Math.sin(x*W2+Q2) +H2; ctx.lineTo(幅,高さ); ctx.closePath();})()
以上がこの記事の全内容です。皆様の学習のお役に立てれば幸いです。また、VeVb Wulin Network をご支援いただければ幸いです。