matlab 水波模拟 代码,canvas三角函数模拟水波效果的示例代码

最近项目中,ui设计了个水波效果的背景动画,然而并没有gif或svg动画,开始试着用css实现了一下,动画效果并不是很好,网上查了下基本都是用贝赛尔曲线实现,想起以看的各种前波形图,于是想着用三角函数图像初略模拟一下

一、绘制sin函数图像

sin函数表达式如下,

y=Asin(wx+φ)+h

其中 A表示振幅,ω表示角频率(ω=2π/T,T为函数的周期),φ表示初相,h表示图像向y轴正方向平移的长度 ;(这里需要注意一下:h在数学学的本来是表示向上平移的,但在canvas中采用的是屏幕坐标系,即左上角为原点,h则表示向下平移);

绘制代码如下:

(1)添加canvas标签

(2)添加css样式,设置canvas宽高

html,

body {

padding: 0;

margin: 0;

width: 100%;

height: 100%;

}

canvas {

width: 100%;

height: 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= height / 2;

//绘图方法

(function draw(){

ctx.clearRect(0, 0, width, height);//清空画布

ctx.beginPath(); //开始路径

ctx.strokeStyle="#000"; //设置线条颜色

ctx.lineWidth = 1; //设置线条宽度

ctx.moveTo(0, height /2); //起始点位置

for (let x = 0; x <= width; x++) {// 绘制x对应y的

var y = A*Math.sin(W*x+Q) +H

ctx.lineTo(x, y)

}

ctx.stroke(); //绘制路径

ctx.closePath(); //闭合路径

})()

这样我们可以得到以下图像:

260174f135b10d9ef49ff5deb9e203dc.png

二、为函数图像添加动画

上面得到的是是一个静态的函数图像,而我们一般见到的的波形图或水波都是随时间连续变化的,这里就要用到上一步中的参数相位φ,(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= height / 2;

//绘图方法

(function draw(){

ctx.clearRect(0, 0, width, height);//清空画布

ctx.beginPath(); //开始路径

ctx.strokeStyle="#000"; //设置线条颜色

ctx.lineWidth = 1; //设置线条宽度

ctx.moveTo(0, height /2); //起始点位置

for (let x = 0; x <= width; x++) {// 绘制x对应y的

var y = A*Math.sin(W*x+Q) +H

ctx.lineTo(x, y)

}

ctx.stroke(); //绘制路径

ctx.closePath(); //闭合路径

})()

效果如下(渣渣截图软件):

b80cb372a38b4f0d0fc489b86e58206a.gif

三、绘制完整填充路径

以上路径虽有闭合,但却不满足我们需要填充的部分,直接填充效果如下:

6600f52134eb48cbe1c5f4432899ca10.png

完整填充路径应如图所示:

cee84354c02db9080b645fd198039317.png

闭合路径后创建一个渐变颜色,作为填充颜色,代码如下:

var lingrad = ctx.createLinearGradient(0,0,width,0);

lingrad.addColorStop(0, 'rgba(0,186,128,0.8)');

lingrad.addColorStop(1, 'rgba(111,224,195,1)');

(function draw(){

window.requestAnimationFrame(draw);

ctx.clearRect(0, 0, width, height);

ctx.beginPath();

ctx.strokeStyle="#000";

ctx.fillStyle = lingrad;

ctx.lineWidth = 1;

ctx.moveTo(0, height /2);

Q+=speed;

for (let x = 0; x <= width; x++) {

var y = A*Math.sin(W*x+Q) +H;

ctx.lineTo(x, y);

}

ctx.lineTo(width, height);

ctx.lineTo(0, height);

ctx.fill();

ctx.closePath();

})()

效果如下:

5d4e1a1db0369c611f9f490b149d05d9.png

四、完善水波动画

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'),

width = canvas.width = canvas.offsetWidth,

height = canvas.height = canvas.offsetHeight;

var A=30,

W=1 /200,

Q=0,

H= height / 2;

var A2=30,

W2=1/300,

Q2=0,

H2= height / 2;

var speed=-0.01;

var speed2=-0.02;

var lingrad = ctx.createLinearGradient(0,0,width,0);

lingrad.addColorStop(0, 'rgba(0,186,128,0.8)');

lingrad.addColorStop(1, 'rgba(111,224,195,1)');

var lingrad2 = ctx.createLinearGradient(0,0,width,0);

lingrad2.addColorStop(0,'rgba(111,224,195,1)');

lingrad2.addColorStop(1, 'rgba(0,186,128,0.8)');

(function draw(){

window.requestAnimationFrame(draw);

ctx.clearRect(0, 0, width, height);

ctx.beginPath();

ctx.fillStyle = lingrad;

ctx.moveTo(0, height /2);

//绘制第一个波形

Q+=speed;

for (let x = 0; x <= width; x++) {

var s = 0.1*Math.sin(x/150)+1;

var y = A*Math.sin(W*x+Q) +H;

y=y*s;

ctx.lineTo(x, y);

}

ctx.lineTo(width, height);

ctx.lineTo(0, height);

ctx.fill();

ctx.closePath()

//设置重叠效果

ctx.globalCompositeOperation = "destination-over"

//绘制第二个波形

ctx.beginPath();

ctx.fillStyle = lingrad2;

Q2+=speed2;

for (let x = 0; x < width; x++) {

var y = A2*Math.sin(x*W2+Q2) +H2;

ctx.lineTo(x, y);

}

ctx.lineTo(width,height);

ctx.lineTo(0,height);

ctx.fill()

ctx.closePath();

})()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的使用canvas画布实现手写签名效果示例代码: HTML代码: ```html <canvas id="signature-canvas" width="400" height="200"></canvas> <button id="clear-button">清除</button> ``` JavaScript代码: ```javascript const canvas = document.getElementById('signature-canvas'); const context = canvas.getContext('2d'); let isDrawing = false; let lastX = 0; let lastY = 0; // 监听鼠标按下事件 canvas.addEventListener('mousedown', (event) => { isDrawing = true; [lastX, lastY] = [event.offsetX, event.offsetY]; }); // 监听鼠标移动事件 canvas.addEventListener('mousemove', (event) => { if (isDrawing) { context.beginPath(); context.moveTo(lastX, lastY); context.lineTo(event.offsetX, event.offsetY); context.stroke(); [lastX, lastY] = [event.offsetX, event.offsetY]; } }); // 监听鼠标松开事件 canvas.addEventListener('mouseup', () => { isDrawing = false; }); // 监听鼠标离开事件 canvas.addEventListener('mouseleave', () => { isDrawing = false; }); // 监听清除按钮点击事件 const clearButton = document.getElementById('clear-button'); clearButton.addEventListener('click', () => { context.clearRect(0, 0, canvas.width, canvas.height); }); ``` 这个示例代码中,我们使用了canvas的2D绘图上下文对象(context),监听了鼠标的按下、移动、松开和离开事件,通过绘制连续的线条来实现手写签名效果。此外,我们还添加了一个清除按钮,用于清除画布上的内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值