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 相关文章推荐
获取DOM对象的几种扩展及简写
Oct 09 Javascript
传递参数的标准方法(jQuery.ajax)
Nov 19 Javascript
基于jQuery的可以控制左右滚动及自动滚动效果的代码
Jul 25 Javascript
兼容IE、FireFox、Chrome等浏览器的xml处理函数js代码
Nov 30 Javascript
js 获取页面高度和宽度兼容 ie firefox chrome等
May 14 Javascript
一个css与js结合的下拉菜单支持主流浏览器
Oct 08 Javascript
详解Javascript动态操作CSS
Dec 08 Javascript
Bootstrap3学习笔记(三)之表格
May 20 Javascript
AngularJS入门之动画
Jul 27 Javascript
js/jq仿window文件夹移动/剪切/复制等操作代码
Mar 08 Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
Mar 23 Javascript
JS中一些高效的魔法运算符总结
May 06 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
如何将一个表单同时提交到两个地方处理
2006/10/09 PHP
php树型类实例
2014/12/05 PHP
PHP符合PSR编程规范的实例分享
2016/12/21 PHP
PHP Post获取不到非表单数据的问题解决办法
2018/02/27 PHP
php设计模式之模板模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
js 调整select 位置的函数
2008/02/21 Javascript
jQuery 表单验证扩展代码(二)
2010/10/20 Javascript
JQuery实现绚丽的横向下拉菜单
2013/12/19 Javascript
js文本框走动跑马灯效果代码分享
2015/08/25 Javascript
JS处理json日期格式化问题
2015/10/01 Javascript
jQuery添加和删除输入文本框标签代码
2016/05/20 Javascript
AngularJS 单元测试(二)详解
2016/09/21 Javascript
如何利用JQuery实现从底部回到顶部的功能
2016/12/27 Javascript
JSON中key动态设置及JSON.parse和JSON.stringify()的区别
2016/12/29 Javascript
jquery uploadify隐藏上传进度的实现方法
2017/02/06 Javascript
在js代码拼接dom对象到页面上的模板总结
2018/10/21 Javascript
配置eslint规范项目代码风格
2019/03/11 Javascript
Vue快速实现通用表单验证的方法
2020/02/24 Javascript
vue 内联样式style中的background用法说明
2020/08/05 Javascript
[14:36]2014 DOTA2国际邀请赛中国区预选赛5.21 Orenda VS NE
2014/05/22 DOTA
[38:39]完美世界DOTA2联赛循环赛 IO vs GXR BO2第二场 11.04
2020/11/05 DOTA
Python中装饰器的一个妙用
2015/02/08 Python
Python与Java间Socket通信实例代码
2017/03/06 Python
python实现文本界面网络聊天室
2018/12/12 Python
分析经典Python开发工程师面试题
2019/04/08 Python
Python计算不规则图形面积算法实现解析
2019/11/22 Python
Django ORM判断查询结果是否为空,判断django中的orm为空实例
2020/07/09 Python
英文自荐信格式
2013/11/28 职场文书
党校培训自我鉴定
2014/02/01 职场文书
销售主管岗位职责范本
2014/02/14 职场文书
班班通校本培训方案
2014/03/12 职场文书
员工考核评语大全
2014/04/26 职场文书
大学学风建设方案
2014/05/04 职场文书
工程部主管岗位职责
2015/02/12 职场文书
商场收银员岗位职责
2015/04/07 职场文书
博士论文答辩开场白
2015/06/01 职场文书