canvas3角涵数仿真模拟水波实际效果的示例编码

日期:2021-01-20 类型:科技新闻 

关键词:微信小程序页面设计,python小程序,小程序首页模板,如何建立微信小程序,怎么做微信小程序

近期新项目中,ui设计方案了个水波实际效果的情况动漫,但是并沒有gif或svg动漫,刚开始试着用css完成了1下,动漫实际效果其实不是很好,在网上查了下基础全是用贝赛尔曲线图完成,想起以看的各种各样前波形图,因而想着用3角涵数图象初略仿真模拟1下

1、绘图sin涵数图象

sin涵数表述式以下,

y=Asin(wx+φ)+h

在其中 A表明振幅,ω表明角频率(ω=2π/T,T为涵数的周期),φ表明初相,h表明图象向y轴正方位平移的长度 ;(这里必须留意1下:h在数学课学的原本是表明向上平移的,但在canvas中选用的是显示屏座标系,即左上角为原点,h则表明向下平移);

绘图编码以下:

(1)加上canvas标识

<canvas id="canvas"></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();                   //闭合相对路径
})()

这样大家能够获得下列图象:

2、为涵数图象加上动漫

上面获得的是是1个静态数据的涵数图象,而大家1般见到的的波形图或水波全是随時间持续转变的,这里就要用到上1步中的主要参数相位φ,(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();                   //闭合相对路径
})()

实际效果以下(渣渣截图手机软件):

3、绘图详细填充相对路径

以上相对路径虽有闭合,但却不考虑大家必须填充的一部分,立即填充实际效果以下:

详细填充相对路径应如图所示:

闭合相对路径后建立1个渐变色色调,做为填充色调,编码以下:

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();
})()

实际效果以下:

4、健全水起伏画

1、最先能够对上面波形叠加1个频率更高的波形,使波形无规定

var s = 0.1*Math.sin(x/150)+1;
var y = A*Math.sin(W*x+Q) +H;
y=y*s;

2、再加上1个相位转变不一样的波形,其渐变色填充与上1个渐变色方位相反使其产生互相重合的黑影实际效果;并设定相对路径重合实际效果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);
  //绘图第1个波形
  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"
  //绘图第2个波形
  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();

})()

以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。