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 相关文章推荐
关闭浏览器时提示onbeforeunload事件
Dec 25 Javascript
js选择并转移导航菜单示例代码
Aug 19 Javascript
drag-and-drop实现图片浏览器预览
Aug 06 Javascript
浅谈angular.js中实现双向绑定的方法$watch $digest $apply
Oct 14 Javascript
Javascript类型系统之String字符串类型详解
Jun 21 Javascript
javascript中Number的方法小结
Nov 21 Javascript
从零学习node.js之文件操作(三)
Feb 21 Javascript
jquery实现弹窗功能(窗口居中显示)
Feb 27 Javascript
深入理解node.js之path模块
May 03 Javascript
vue项目前端埋点的实现
Mar 06 Javascript
详解如何探测小程序返回到webview页面
May 14 Javascript
微信小程序收货地址API兼容低版本解决方法
May 18 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
AM/FM收音机的安装与调试
2021/03/02 无线电
PHP中的MYSQL常用函数(php下操作数据库必备)
2010/09/12 PHP
thinkphp在低版本Nginx 下支持PATHINFO的方法分享
2016/05/27 PHP
PHP单例模式数据库连接类与页面静态化实现方法
2019/03/20 PHP
关于PHP5.6+版本“No input file specified”问题的解决
2019/12/11 PHP
一种JavaScript的设计模式
2006/11/22 Javascript
jQuery EasyUI API 中文文档 - EasyLoader 加载器
2011/09/29 Javascript
网页加载时页面显示进度条加载完成之后显示网页内容
2012/12/23 Javascript
js 获取后台的字段 改变 checkbox的被选中的状态 代码
2013/06/05 Javascript
Javascript 学习笔记之 对象篇(二) : 原型对象
2014/06/24 Javascript
javascript动态添加删除tabs标签的方法
2015/07/06 Javascript
超链接怎么正确调用javascript函数
2016/05/23 Javascript
Bootstrap中的Panel和Table全面解析
2016/06/13 Javascript
使用UrlConnection实现后台模拟http请求的简单实例
2017/01/04 Javascript
利用JS实现简单的瀑布流加载图片效果
2017/04/22 Javascript
基于百度地图api清除指定覆盖物(Overlay)的方法
2018/01/26 Javascript
微信小程序视图控件与bindtap之间的问题的解决
2019/04/08 Javascript
今天,小程序正式支持 SVG
2019/04/20 Javascript
详解小程序云开发攻略(解决最棘手的问题)
2019/09/30 Javascript
让IDE识别webpack的别名alias的实现方法
2020/05/06 Javascript
微信小程序实现选项卡滑动切换
2020/10/22 Javascript
jQuery实现简单弹幕制作
2020/12/10 jQuery
浅谈pyhton学习中出现的各种问题(新手必看)
2017/05/17 Python
python高效过滤出文件夹下指定文件名结尾的文件实例
2018/10/21 Python
详解django中url路由配置及渲染方式
2019/02/25 Python
美特斯邦威官方商城:邦购网
2016/10/13 全球购物
巴西备受欢迎的服装和生活方式品牌:FARM Rio
2020/02/04 全球购物
介绍一下Java中标识符的命名规则
2014/02/03 面试题
联谊活动策划书
2014/01/26 职场文书
球队口号
2014/06/18 职场文书
医院反腐倡廉演讲稿
2014/09/16 职场文书
关于观后感的作文
2015/06/18 职场文书
2015年音乐教研组工作总结
2015/07/22 职场文书
2015年中秋寄语
2015/07/31 职场文书
办公室卫生管理制度
2015/08/04 职场文书
Python爬虫网络请求之代理服务器和动态Cookies
2022/04/12 Python