この記事では、この効果がどのように達成されるかを分析します。ソースコードについて混乱している場合は、分析を読むと突然理解できると思います。まず、レンダリング:
1. 原理分析
前の記事の単純な水の波のアニメーション効果と比較して、この記事のアニメーション効果はマウスと対話できるだけでなく、波の形成も行うことができます。より自然で、より一貫した物理法則です。全体の形成過程はアニメーションの通りで、液面の位置でマウスをクリックすると、ここの液面が比較的大きく変動し、その振動が両側に広がります。エネルギーが減衰すると、その後の振動の振幅はどんどん低くなり、最終的にエネルギーはゼロに減衰し、ページは穏やかになります。とても神秘的だと思いませんか?毛主席は物体の表面現象に騙されないようにと言いました(誰が言ったか分かりませんo(^▽^)o)。以下では、原則を段階的に分析していきます。
まず、静的な状態では、液体表面全体が長方形に等しいことがわかります。液体表面の位置をクリックすると、それに応じて長方形が変化します。しかし実際には、長方形全体が変化したのではなく、長方形の上端のみが変化しました。では、長方形の上端だけを変更するにはどうすればよいでしょうか?その秘密は、長方形の上端が単に左点から右点までの lineTo() ではないことです。代わりに、多くの点 lineTo() で構成されます。このように理解するのは簡単ではないかもしれませんが、画像を見て話しましょう:
上部に多くの点を設定します。これらの点の座標は同じですが、特定の距離で区切られています。水平方向の距離。このように、静止した状態では普通の長方形と変わらないことがわかります。これらの点の位置を変更すると、同時に長方形の形状も変更され、さまざまな効果を生み出すことができます。
2. 微分方程式
微分方程式に関しては頭が痛くなる人も多いかもしれませんが、方法はありません。この知識ポイントは高度な数学の微分方程式に関するセクションにあります。理解できない場合は忘れてください。以下のような使い方も覚えておくと良いですが、オシャレのために簡単に紹介します。
数学における漸化式は、差分方程式とも呼ばれ、シーケンスを再帰的に定義する方程式です。シーケンス内の各項目は、前の項目の関数として定義されます。単純に定義された漸化関係の中には、非常に複雑な (カオス的な) 特性を示すものもあります。それらは数学の非線形解析の分野に属します。
シーケンス内の各項目は前の項目の関数として定義されることを覚えておいてください。これが私たちが使用する原則です。彼の画像を matalab で描画すると、次のようになります:
元の関数に注目してください。赤い曲線で十分です。水の波のように見えますか?やるべきことは、このような波形に従って点の束を配置することです。
3. コードの実装
1. 準備
さあ、みんなが大好きなコーディングの時間です。まず、ポイント クラス Vertexes を作成します。その機能は、次のように vertex.js にあります:
function Vertex(x,y,baseY){ this.baseY = baseY; //基线 this.x = x; //点的坐标 this.y = y; this.vy = 0; //竖直方向的速度 this.targetY = 0; //目标位置 this.friction = 0.15; //摩擦力 this.deceleration = 0.95; //减速 } //y坐标更新 Vertex.prototype.updateY = function(diffVal){ this.targetY = diffVal + this.baseY; //改变目标位置 this.vy += (this.targetY - this.y); //速度 this.vy *= this.deceleration; this.y += this.vy * this.friction; //改变坐标竖直方向的位置 }
この関数を使用して、ポイントの束を作成します。メインファイルのindex.jsに戻ります。最初に使用する必要があるものをいくつか初期化しましょう:
var canvas = document.getElementById('canvas'), ctx = canvas.getContext('2d'), W = window.innerWidth; H = window.innerHeight; canvas.width = W; canvas.height = H; var color1 = "#6ca0f6", //矩形1的颜色 color2 = "#367aec"; //矩形2的颜色 var vertexes = [], //顶点坐标 verNum = 250, //顶点数 diffPt = [], //差分值
然后,创建点并把它push进vertexes中,同时也创建相应数量的差分值,同样把它放到diffPt数组中,这样每个点都有了对应的差分值。
for(var i=0; i<verNum; i++){ vertexes[i] = new Vertex(W/(verNum-1)*i, H/2, H/2); diffPt[i] = 0; //初始值都为0 }
结果是,每个顶点的y坐标都在(H/2)的高度,水平坐标每隔一定的间隔取一个点。在这里是每隔4.5个像素取一个点,这与你canvas的宽度和点的数目有关。这样我们就把点创建完成了,来绘制一下看看效果。
代码如下:
function draw(){ //矩形1 ctx.save() ctx.fillStyle = color1; ctx.beginPath(); ctx.moveTo(0, H); ctx.lineTo(vertexes[0].x, vertexes[0].y); for(var i=1; i<vertexes.length; i++){ ctx.lineTo(vertexes[i].x, vertexes[i].y); } ctx.lineTo(W,H); ctx.lineTo(0,H); ctx.fill(); ctx.restore(); //矩形2 ctx.save(); ctx.fillStyle = color2; ctx.beginPath(); ctx.moveTo(0, H); ctx.lineTo(vertexes[0].x, vertexes[0].y+5); for(var i=1; i<vertexes.length; i++){ ctx.lineTo(vertexes[i].x, vertexes[i].y+5); } ctx.lineTo(W, H); ctx.lineTo(0, H); ctx.fill(); ctx.restore(); }
就像你看到的那样此时我们的液面完全是静止的(因为没更新点嘛)。之所以要绘制两个矩形,你看看效果图就明白了,只是为了更好看,你完全可以绘制第三层,第四层。下面我们就来更新这些点的坐标。
2.核心代码
点的更新我们放在了update函数中。首先,我们设置一个初始的震荡点,缓冲变量和初始差分值。
var vPos = 125; //震荡点 var dd = 15; //缓冲 var autoDiff = 1000; //初始差分值
这里的震荡点就是我们的起震位置,意思是vertexes中的第125号点开始起震,它对应的差分值就是autoDiff。它的改变会引起其他点的变化,从而达到更新其他差分值的效果。
function update(){ autoDiff -= autoDiff*0.9; //1 diffPt[vPos] = autoDiff; //左侧 for(var i=vPos-1; i>0; i--){ //2 var d = vPos-i; if(d > dd){ d=dd; } diffPt[i]-=(diffPt[i] - diffPt[i+1])*(1-0.01*d); } //右侧 for(var i=vPos+1; i<verNum; i++){ //3 var d = i-vPos; if(d>dd){ d=dd; } diffPt[i] -= (diffPt[i] - diffPt[i-1])*(1-0.01*d); } //更新Y坐标 for(var i=0; i<vertexes.length; i++){ //4 vertexes[i].updateY(diffPt[i]); } }
现在我们对上面的部分做详细解释:
代码1: 我们设置了起震位置的差分偏移量为autoDiff=100,注意autoDiff -= autoDiff*0.9;, 也就是说它的值每一帧都会变化。
代码2:为起震位置的左边,主要关注diffPt[i]-=(diffPt[i] - diffPt[i+1])*(1-0.01*d);这一行。i的起始位置为124,默认差分值为0。稍作简单推算,你会发现,经过更新后第124号点的差分值为99,同理第123号为97.02。以此类推,我们就可以得到第一帧的所有点的差分值。右边同理。
代码4:在得到第一帧的差分值后就该调用每个点的更新函数了,并且传入计算好的差分值。形成的效果如下图所示
看一下updateY函数,我们把目标位置targetY设置为差分值diffVal和基线baseY的和。然后,通过距离计算需要运动的速度vy,最后将速度作用于点的纵坐标。这一段是不是与弹性动画缓动动画那一节很相似呢?
在缓冲系数dd的作用下,两侧的波会在扩散的过程中越来越小,最后趋近于0.我们也是通过这个变量去控制液体的粘度系数,达到粘稠度高的物体扩散的越缓慢并且起伏比较低,粘稠度低的物体扩散迅速但起伏大的效果。
随后,因为autoDiff的不断衰减,不同幅值波形的叠加形成波浪效果,最终衰减到0.液面也就趋于平静了。
现在,我们把update()和draw()放入动画循环中你就会看到水波起伏然后趋于平静的效果。
(function drawframe(){ ctx.clearRect(0, 0, W, H); window.requestAnimationFrame(drawframe, canvas); update() draw(); })()
3.鼠标交互
上面的代码已经实现了波浪动画的效果,但是震荡完成后就平静了,不会再发生震荡的效果。这一步我们就来实现点哪,哪震的效果。实现的思路很简单:水波之所以区域平静是因为起震位置的差分值不断衰减的结果,我们只需要在点击鼠标的位置重设autoDiff就可以了。此外,起震点的位置也要变成鼠标点击的位置。代码如下:
canvas.addEventListener('mousedown', function(e){ var mouse = {x:null, y:null}; if(e.pageX||e.pageY){ mouse.x = e.pageX; mouse.y = e.pageY; }else{ mouse.x = e.clientX + document.body.scrollLeft +document.documentElement.scrollLeft; mouse.y = e.clientY + document.body.scrollTop +document.documentElement.scrollTop; } //重设差分值 if(mouse.y>(H/2-50) && mouse.y<(H/2 +50)){ autoDiff = 1000; vPos = 1 + Math.floor((verNum - 2) * mouse.x / W); diffPt[vPos] = autoDiff; } console.log(mouse.x, mouse.y) }, false)
在获取鼠标位置这里应该注意一点,我们没有减去canvas的偏移量,这是因为在这里canvas做的是全屏设置。所以,如果你的画布并不是全屏大小,建议你使用我们的utils.js文件中的方法captureMouse来获取鼠标的坐标。
另外在判断鼠标是否点击在了液面上,我们设定了一个比较宽的范围,上下共100px。这样做的目的是让用户很容易就能触发这个事件,而不是只在页面那唯一的一个值上才能触发。这种做法相信你以前做过,对于比较小的物体我们会遮罩一个大一些的透明物体,然后在该物体上做事件的触发,便于用户操作。

Vue和Canvas:如何实现手写签名和手势识别功能引言:手写签名和手势识别功能在现代应用程序中越来越常见,它们可以为用户提供更加直观和自然的交互方式。Vue.js作为一款流行的前端框架,搭配Canvas元素可以实现这两个功能。本文将介绍如何使用Vue.js和Canvas元素来实现手写签名和手势识别功能,并给出相应的代码示例。一、手写签名功能实现要实现手写签

canvas的优势有强大的绘图功能、高性能、跨平台兼容性、支持多种图形格式、可以与其他Web技术集成、可以实现动态效果和可以实现复杂的图像处理。详细介绍:1、Canvas提供了丰富的绘图功能,可以绘制各种形状、线条、文本、图像等;2、Canvas在浏览器中直接操作像素,因此具有很高的性能;3、Canvas是基于HTML5标准的一部分,可以在各种现代浏览器上运行等等。

如何利用Vue和Canvas创建逼真的天气动态背景引言:在现代网页设计中,动态背景效果是吸引用户眼球的重要元素之一。本文将介绍如何利用Vue和Canvas技术来创建一个逼真的天气动态背景效果。通过代码示例,你将学习如何编写Vue组件和利用Canvas绘制不同天气场景,从而实现一个独特而吸引人的背景效果。步骤一:创建Vue项目首先,我们需要创建一个Vue项目。

canvas特效有粒子效果、线条动画、图片处理、文字动画、音频可视化、3D效果、游戏开发等。详细介绍:1、粒子效果,通过控制粒子的位置、速度和颜色等属性来实现各种效果,如烟花、雨滴、星空等;2、线条动画,通过在画布上绘制连续的线条,创建出各种动态的线条效果;3、图片处理,通过对图片进行处理,可以实现各种炫酷的效果,如图片切换、图片特效等;4、文字动画等等特性。

canvas引擎有Three.js、Pixi.js、EaselJS、Konva.js、Paper.js等。详细介绍:1、Pixi.js,提供了简单易用的API,支持精灵、纹理、滤镜等功能,同时还提供了丰富的工具和插件,方便开发者进行交互、动画和优化等操作;2、Pixi.js,提供了简单易用的API,支持精灵、纹理、滤镜等功能,还提供了丰富的工具和插件;3、EaselJS等等。

canvas插件有Fabric.js、EaselJS、Konva.js、Three.js、Paper.js、Chart.js和Phaser。详细介绍:1、Fabric.js 是一个基于Canvas的开源 JavaScript 库,它提供了一些强大的功能;2、EaselJS是CreateJS库中的一个模块,它提供了一套简化了Canvas编程的API;3、Konva.js等等。

Vue和Canvas:如何实现图片的马赛克效果引言:随着Web技术的不断发展,越来越多的人开始使用Vue框架来构建交互式的前端应用。而在前端开发中,常常需要为用户提供图片处理的功能。本文将介绍如何利用Vue和Canvas实现图片的马赛克效果,为用户带来更好的视觉体验。一、马赛克效果概述马赛克效果是一种将图像的细节部分进行像素化处理,使得整个图像变得模糊和抽象

canvas框架有Fabric.js框架、Konva.js框架、EaselJS框架、Paper.js框架、Three.js框架等。详细介绍:1、Fabric.js框架,支持图形的选择、缩放、旋转、拖拽等操作,并且可以导出为图片或SVG格式;2、Konva.js框架,支持图形的层级管理、变换操作、事件监听等功能,适用于创建交互式的图形应用程序;3、EaselJS框架等等。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

Dreamweaver Mac版
ビジュアル Web 開発ツール

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。
