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 相关文章推荐
JavaScript 三种不同位置代码的写法
Oct 25 Javascript
Textbox控件注册回车事件及触发按钮提交事件具体实现
Mar 04 Javascript
JS中批量给元素绑定事件过程中的相关问题使用闭包解决
Apr 15 Javascript
禁止iframe页面的所有js脚本如alert及弹出窗口等
Sep 03 Javascript
深入理解JavaScript系列(28):设计模式之工厂模式详解
Mar 03 Javascript
javascript实现tab响应式切换特效
Jan 29 Javascript
javascript每日必学之封装
Feb 23 Javascript
基于jQuery实现表格的查看修改删除
Aug 01 Javascript
JS尾递归的实现方法及代码优化技巧
Jan 19 Javascript
如何给element添加一个抽屉组件的方法步骤
Jul 14 Javascript
解决layui的table插件无法多层级获取json数据的问题
Sep 19 Javascript
vue项目实现多语言切换的思路
Sep 17 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
Mysql数据库操作类( 1127版,提供源码下载 )
2010/12/02 PHP
php 删除一个数组中的某个值.兼容多维数组!
2012/02/18 PHP
Thinkphp3.2.3整合phpqrcode生成带logo的二维码
2016/07/21 PHP
深入理解Javascript闭包 新手版
2010/12/28 Javascript
JavaScript的漂亮的代码片段
2013/06/05 Javascript
javascript 事件处理示例分享
2014/12/31 Javascript
javascript制作照片墙及制作过程中出现的问题
2016/04/04 Javascript
JavaScript中的prototype原型学习指南
2016/05/09 Javascript
BootStrap按钮标签及基本样式
2016/11/23 Javascript
基于NodeJS+MongoDB+AngularJS+Bootstrap开发书店案例分析
2017/01/12 NodeJs
Spring Boot+AngularJS+BootStrap实现进度条示例代码
2017/03/02 Javascript
bootstrap表单示例代码分享
2017/05/18 Javascript
详解vue 模拟后台数据(加载本地json文件)调试
2017/08/25 Javascript
详解layui弹窗父子窗口之间传参数的方法
2018/01/16 Javascript
JavaScript生成指定范围的时间列表
2018/03/19 Javascript
Node.js 使用axios读写influxDB的方法示例
2018/10/26 Javascript
vue2.0中set添加属性后视图不能更新的解决办法
2019/02/22 Javascript
JS函数基本定义与用法示例
2020/01/15 Javascript
js实现简单进度条效果
2020/03/25 Javascript
对python中的高效迭代器函数详解
2018/10/18 Python
Python根据欧拉角求旋转矩阵的实例
2019/01/28 Python
使用Python生成200个激活码的实现方法
2019/11/22 Python
Python逐行读取文件内容的方法总结
2020/02/14 Python
python如何实现word批量转HTML
2020/09/30 Python
Python实现列表索引批量删除的5种方法
2020/11/16 Python
基于Python-Pycharm实现的猴子摘桃小游戏(源代码)
2021/02/20 Python
CSS3中颜色线性渐变实战
2015/07/18 HTML / CSS
简单整理HTML5的基本特性和语法
2016/02/18 HTML / CSS
手工制作的男士奢华英国鞋和服装之家:Goodwin Smith
2019/06/21 全球购物
GOLFINO英国官网:高尔夫服装
2020/04/11 全球购物
mysql_pconnect()和mysql_connect()有什么区别
2012/05/25 面试题
优秀团队获奖感言
2014/02/19 职场文书
测量工程专业求职信
2014/02/24 职场文书
语文高效课堂实施方案
2014/05/03 职场文书
科级干部群众路线教育实践活动对照检查材料思想汇报
2014/09/20 职场文书
第一节英语课开场白
2015/06/01 职场文书