JavaScript如何使用插值实现图像渐变


Posted in Javascript onJune 28, 2020

描述由一个图形变化为另一个图形过程中的各个中间图形,称为渐变图形。可以利用插值算法求得各个渐变图形。

设在源图形和目标图形上各取M个对应坐标点,并分别保存到数组中,源图形用数组SX[M]和SY[M]保存M个坐标点(sx,sy),目标图形用数组DX[M]和DY[M]保存M个坐标点(dx,dy)。若需生成源图形变换到目标图形中的N-1个渐变图形,采用简单的线性插值可以编写如下的二重循环:

for (k=1;k<N;k++)
     for (i=0;i<M;i++)
     {
      x=(dx[i]-sx[i])/N*k+sx[i];
      y=(dy[i]-sy[i])/N*k+sy[i];
      // 按求得的插值坐标点绘制渐变图形
     }

1.六瓣花朵渐变为圆

六瓣花朵的笛卡尔坐标方程式设定为:

t=r1*(1+sin(18*θ)/5) *(0.5+Math.sin(6*θ)/2);

x=t*cos(θ);

y=t* sin(θ); (0≤θ≤2π)

圆的笛卡尔坐标方程式为:

x=r*cos(θ)

y=r*sin(θ) (0≤θ≤2π)

在六瓣花朵和圆上分别取128个点,然后利用简单的线性插值绘制中间24个渐变图形。编写如下的HTML代码。

<!DOCTYPE html>
<head>
	<title>六瓣花朵渐变为圆</title>
	<script type="text/javascript">
		function draw(id)
		{
			var canvas = document.getElementById(
				id);
			if (canvas == null)
				return false;
			var context = canvas.getContext('2d');
			context.fillStyle = "#EEEEFF";
			context.fillRect(0, 0, 200, 200);
			context.strokeStyle = "red";
			context.lineWidth = 1;
			var dig = Math.PI / 64;
			var x1 = new Array(129);
			var y1 = new Array(129);
			var x2 = new Array(129);
			var y2 = new Array(129);
			for (var i = 0; i <= 128; i++)
			{
				d = 50 * (1 + Math.sin(18 * i * dig) /
					5);
				t = d * (0.5 + Math.sin(6 * i * dig) /
					2);
				x1[i] = t * Math.cos(i * dig);
				y1[i] = t * Math.sin(i * dig);
				x2[i] = 80 * Math.cos(i * dig);
				y2[i] = 80 * Math.sin(i * dig);
			}
			context.beginPath();
			for (n = 0; n <= 25; n++)
				for (i = 0; i <= 128; i++)
			{
				x = (x2[i] - x1[i]) / 25 * n + x1[i] +
					100;
				y = (y2[i] - y1[i]) / 25 * n + y1[i] +
					100;
				if (i == 0)
				{
					context.moveTo(x, y);
					bx = x;
					by = y;
				} else
					context.lineTo(x, y);
			}
			context.lineTo(bx, by);
			context.closePath();
			context.stroke();
		}
	</script>
</head>
<body onload="draw('myCanvas');">
	<canvas id="myCanvas" width="200" height="200"></canvas>
</body>
</html>

将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中绘制出从六瓣花朵渐变为圆的图案,如图1所示。

JavaScript如何使用插值实现图像渐变

图1 六瓣花朵渐变为圆

2.圆渐变为花朵

我们将图1图形中的圆渐变为六瓣花朵的过程动态展示出来。编写的HTML文件内容如下。

<!DOCTYPE>
<html>
<head>
	<title>圆渐变为花朵</title>
</head>

<body>

	<canvas id="myCanvas" width="200" height="200"
	style="border:3px double #996633;">

	</canvas>

	<script type="text/javascript">
		var canvas = document.getElementById(
			'myCanvas');
		var context = canvas.getContext('2d');
		context.fillStyle = "#EEEEFF";
		context.fillRect(0, 0, 200, 200);
		context.fillStyle = "red";
		var dig = Math.PI / 64;
		var x1 = new Array(129);
		var y1 = new Array(129);
		var x2 = new Array(129);
		var y2 = new Array(129);
		var n = 0;
		for (var i = 0; i <= 128; i++)
		{
			d = 50 * (1 + Math.sin(18 * i * dig) /
				5);
			t = d * (0.5 + Math.sin(6 * i * dig) /
				2);
			x1[i] = t * Math.cos(i * dig);
			y1[i] = t * Math.sin(i * dig);
			x2[i] = 80 * Math.cos(i * dig);
			y2[i] = 80 * Math.sin(i * dig);
		}

		function draw()
		{
			context.clearRect(0, 0, 200, 200);
			context.beginPath();
			for (i = 0; i <= 128; i++)
			{
				x = (x1[i] - x2[i]) / 25 * n + x2[i] +
					100;
				y = (y1[i] - y2[i]) / 25 * n + y2[i] +
					100;
				if (i == 0)
				{
					context.moveTo(x, y);
					bx = x;
					by = y;
				} else
					context.lineTo(x, y);
			}
			context.lineTo(bx, by);
			context.stroke();
			n = n + 1;
			if (n > 25) n = 0;
			context.fill();
		}
		window.setInterval('draw()', 300);
	</script>

</body>

</html>

将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以在画布中看到从圆渐变为六瓣花朵的动画过程,如图2所示。

JavaScript如何使用插值实现图像渐变

图2 从圆渐变为六瓣花朵

3.六瓣花朵渐变为正方形

仿照上面的思路,设计程序将六瓣花朵渐变为正方形,且渐变计算时采用对数函数。编写如下的HTML代码。

<!DOCTYPE html>

<head>

	<title>六瓣花朵渐变为正方形</title>

	<script type="text/javascript">
		function draw(id)
		{
			var canvas = document.getElementById(
				id);
			if (canvas == null)
				return false;
			var context = canvas.getContext('2d');
			context.fillStyle = "#EEEEDD";
			context.fillRect(0, 0, 300, 300);
			context.strokeStyle = "red";
			context.lineWidth = 1;
			var dig = Math.PI / 60;
			var x1 = new Array(120);
			var y1 = new Array(120);
			var x2 = new Array(120);
			var y2 = new Array(120);
			// 生成花瓣基本数据,坐标保存在(x1[i],y1[i])中
			var petalNum = 6; // 花瓣数
			for (var i = 0; i < 120; i++)
			{
				d = 50 * (1 + Math.sin(petalNum * (
					i * dig + Math.PI / 4)));
				x1[i] = d * Math.cos(i * dig + Math
					.PI / 4);
				y1[i] = -d * Math.sin(i * dig +
					Math.PI / 4);
			}
			// 生成多边形基本数据,坐标保存在(x2[i],y2[i])中
			var r = 150;
			var sideNum = 4; // 正多边形边数
			var k = 120 / sideNum;
			dig = Math.PI / sideNum;
			var dd = 2 * r * Math.sin(dig) / k;
			for (i = 0; i < sideNum; i++)
			{
				aa = 2 * i * dig + 3 * Math.PI / 4;
				x0 = r * Math.sin(aa);
				y0 = r * Math.cos(aa);
				for (j = 0; j < k; j++)
				{
					x2[i * k + j] = x0 + j * dd * Math
						.sin(aa + Math.PI / 2 + Math.PI /
							sideNum);
					y2[i * k + j] = y0 + j * dd * Math
						.cos(aa + Math.PI / 2 + Math.PI /
							sideNum);
				}
			}
			context.beginPath();
			// 按对数规律进行图案渐变
			for (n = 0; n <= 25; n++)
			{
				for (i = 0; i < 120; i++)
				{
					x = (x2[i] - x1[i]) / Math.log(25) *
						Math.log(n) + x1[i] + 150;
					y = (y2[i] - y1[i]) / Math.log(25) *
						Math.log(n) + y1[i] + 150;
					if (i == 0)
					{
						context.moveTo(x, y);
						bx = x;
						by = y;
					} else
						context.lineTo(x, y);
				}
				context.lineTo(bx, by);
			}
			context.closePath();
			context.stroke();
		}
	</script>

</head>

<body onload="draw('myCanvas');">

	<canvas id="myCanvas" width="320" height="320"></canvas>

</body>

</html>

将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以看到在画布中绘制出从六瓣花朵渐变为正方形的图案,如图3所示。

JavaScript如何使用插值实现图像渐变

图3 从六瓣花朵渐变为正方形

将绘制图3的HTML程序中的花瓣数设置为5,正多边形边数也设置为5,即修改语句“var petalNum=6;”为“var petalNum=5;”,修改语句“var sideNum=4;”为“var sideNum=5;”,则在画布中绘制出如图4所示的从五瓣花朵渐变为正五边形的图案。

JavaScript如何使用插值实现图像渐变

图4 从五瓣花朵渐变为正五边形

4.正五边形渐变为五瓣花朵

我们将图4图形中的正五边形渐变为五瓣花朵的过程动态展示出来。编写的HTML文件内容如下。

<!DOCTYPE>
<html>
<head>
	<title>正五边形渐变为五瓣花朵</title>
</head>
<body>
	<canvas id="myCanvas" width="300" height="300"
	style="border:3px double #996633;"></canvas>

	<script type="text/javascript">
		var canvas = document.getElementById(
			'myCanvas');
		var context = canvas.getContext('2d');
		context.fillStyle = "#EEEEFF";
		context.fillRect(0, 0, 300, 300);
		context.fillStyle = "red";
		var dig = Math.PI / 60;
		var x1 = new Array(120);
		var y1 = new Array(120);
		var x2 = new Array(120);
		var y2 = new Array(120);
		// 生成花瓣基本数据,坐标保存在(x1[i],y1[i])中
		var petalNum = 5;
		for (var i = 0; i < 120; i++)
		{
			d = 50 * (1 + Math.sin(petalNum * (i *
				dig + Math.PI / 4)));
			x1[i] = d * Math.cos(i * dig + Math.PI /
				4);
			y1[i] = -d * Math.sin(i * dig + Math
				.PI / 4);
		}
		// 生成多边形基本数据,坐标保存在(x2[i],y2[i])中
		var r = 150;
		var sideNum = 5;
		var k = 120 / sideNum;
		dig = Math.PI / sideNum;
		var dd = 2 * r * Math.sin(dig) / k;
		for (i = 0; i < sideNum; i++)
		{
			aa = 2 * i * dig + 3 * Math.PI / 4;
			x0 = r * Math.sin(aa);
			y0 = r * Math.cos(aa);
			for (j = 0; j < k; j++)
			{
				x2[i * k + j] = x0 + j * dd * Math.sin(
					aa + Math.PI / 2 + Math.PI /
					sideNum);
				y2[i * k + j] = y0 + j * dd * Math.cos(
					aa + Math.PI / 2 + Math.PI /
					sideNum);
			}
		}
		var n = 0;

		function draw()
		{
			context.clearRect(0, 0, 300, 300);
			context.beginPath();
			for (i = 0; i < 120; i++)
			{
				x = (x1[i] - x2[i]) / Math.log(25) *
					Math.log(n) + x2[i] + 150;
				y = (y1[i] - y2[i]) / Math.log(25) *
					Math.log(n) + y2[i] + 150;
				if (i == 0)
				{
					context.moveTo(x, y);
					bx = x;
					by = y;
				} else
					context.lineTo(x, y);
			}
			context.lineTo(bx, by);
			context.closePath();
			context.stroke();
			n = n + 1;
			if (n > 25) n = 0;
			context.fill();
		}
		window.setInterval('draw()', 400);
	</script>

</body>

</html>

将上述HTML代码保存到一个html文本文件中,再在浏览器中打开包含这段HTML代码的html文件,可以在画布中看到从正五边形渐变为五瓣花朵的动画过程,如图5所示。

JavaScript如何使用插值实现图像渐变

图5 正五边形渐变为五瓣花朵

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

Javascript 相关文章推荐
jquery 图片预加载 自动等比例缩放插件
Dec 25 Javascript
说明你的Javascript技术很烂的五个原因
Apr 26 Javascript
Javascript中的包装类型介绍
Apr 02 Javascript
利用jquery给指定的table动态添加一行、删除一行的方法
Oct 12 Javascript
详解Angular的内置过滤器和自定义过滤器【推荐】
Dec 26 Javascript
javascript防篡改对象实例详解
Apr 10 Javascript
vue axios用法教程详解
Jul 23 Javascript
微信小程序开发之改变data中数组或对象的某一属性值
Jul 05 Javascript
微信公众号获取用户地理位置并列出附近的门店的示例代码
Jul 25 Javascript
使用ThinkJs搭建微信中控服务的实现方法
Aug 08 Javascript
原生JS实现烟花效果
Mar 10 Javascript
javascript实现移动端轮播图
Dec 09 Javascript
vue实现登录拦截
Jun 29 #Javascript
Laravel 如何在blade文件中使用Vue组件的示例代码
Jun 28 #Javascript
JavaScript多种图形实现代码实例
Jun 28 #Javascript
从Node.js事件触发器到Vue自定义事件的深入讲解
Jun 26 #Javascript
Vue如何提升首屏加载速度实例解析
Jun 25 #Javascript
vuecli3.x中轻松4步带你使用tinymce的步骤
Jun 25 #Javascript
国内常用的js类库大全(CDN公共库)
Jun 24 #Javascript
You might like
无数据库的详细域名查询程序PHP版(5)
2006/10/09 PHP
PHP clearstatcache()函数详解
2010/03/02 PHP
php Smarty 字符比较代码
2011/02/27 PHP
PHP setTime 设置当前时间的代码
2012/08/27 PHP
PHP与Java进行通信的实现方法
2013/10/21 PHP
zend framework文件上传功能实例代码
2013/12/25 PHP
php中将一个对象保存到Session中的方法
2015/03/13 PHP
JQuery textlimit 显示用户输入的字符数 限制用户输入的字符数
2009/05/14 Javascript
ASP小贴士/ASP Tips javascript tips可以当桌面
2009/12/10 Javascript
Prototype的Class.create函数解析
2011/09/22 Javascript
Jquery实现搜索框提示功能示例代码
2013/08/13 Javascript
JavaScript访问字符串中单个字符的两种方法
2015/07/03 Javascript
JavaScript中获取Radio被选中的值
2015/11/11 Javascript
浅析JavaScript Array和string的转换(推荐)
2016/05/20 Javascript
AngularJS中的API(接口)简单实现
2016/07/28 Javascript
js HTML5 Canvas绘制转盘抽奖
2020/09/13 Javascript
AngularJS实现与Java Web服务器交互操作示例【附demo源码下载】
2016/11/02 Javascript
浅谈vue中数据双向绑定的实现原理
2017/09/14 Javascript
js中时间格式化的几种方法
2018/07/22 Javascript
layui的table中显示图片方法
2018/08/17 Javascript
js canvas画布实现高斯模糊效果
2018/11/27 Javascript
node后端服务保活的实现
2019/11/10 Javascript
[27:39]Ti4 循环赛第二日 LGD vs Fnatic
2014/07/11 DOTA
将Django框架和遗留的Web应用集成的方法
2015/07/24 Python
玩转python爬虫之cookie使用方法
2016/02/17 Python
判断python字典中key是否存在的两种方法
2018/08/10 Python
Python使用LDAP做用户认证的方法
2019/06/20 Python
Python 堆叠柱状图绘制方法
2019/07/29 Python
Python定义一个Actor任务
2020/07/29 Python
沙特阿拉伯网上购物:Sayidaty Mall
2018/05/06 全球购物
巴黎欧莱雅法国官网:L’Oreal Paris
2019/04/30 全球购物
卫校护理专业毕业生求职信
2013/11/26 职场文书
口头翻译求职人自荐信
2013/12/07 职场文书
《值日生》教学反思
2014/02/17 职场文书
社区班子对照检查材料
2014/08/27 职场文书
td 内容自动换行 table表格td设置宽度后文字太多自动换行
2022/12/24 HTML / CSS