用HTML5 Canvas创造视觉盛宴——动态彩色线条效果

目录

一、程序代码

二、代码原理

三、运行效果


一、程序代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<!-- 声明文档类型为XHTML 1.0 Transitional -->

<html xmlns="http://www.w3.org/1999/xhtml"> <!-- 定义文档命名空间为XHTML -->

<head>
 <title>视觉盛宴</title> <!-- 设置页面标题为“视觉盛宴” -->

 <script type="text/javascript">
 
window.onload = function () { // 当窗口加载完成时执行以下代码

	C = Math.cos; // 缓存Math对象的cos函数
	S = Math.sin; // 缓存Math对象的sin函数
	U = 0; // 设置变量U的初始值为0(用于记录鼠标位置)
	w = window; // 将window对象缓存在变量w中
	j = document; // 将document对象缓存在变量j中
	d = j.getElementById("c"); // 获取id为"c"的Canvas元素,并将其缓存在变量d中
	c = d.getContext("2d"); // 获取Canvas绘图上下文,并将其缓存在变量c中
	W = d.width = w.innerWidth; // 设置Canvas的宽度为窗口的宽度,并将其缓存在变量W中
	H = d.height = w.innerHeight; // 设置Canvas的高度为窗口的高度,并将其缓存在变量H中
	c.fillRect(0, 0, W, H); // 在Canvas上绘制一个黑色的矩形,覆盖整个画布(默认)

	c.globalCompositeOperation = "lighter"; // 设置全局合成操作为"lighter",即颜色叠加模式
	c.lineWidth = 0.2; // 设置线条宽度为0.2
	c.lineCap = "round"; // 设置线条的端点样式为圆形

	var bool = 0, t = 0; // 定义两个变量bool和t,初始值分别为0

	d.onmousemove = function (e) { // 当鼠标在Canvas上移动时执行以下代码

		if(window.T) { // 如果变量T存在,则执行以下代码

			if(D==9) { D=Math.random()*15; f(1); } // 如果变量D等于9,则将变量D设置为一个0到15之间的随机数,并调用函数f(1)

			clearTimeout(T); // 清除计时器T

		}

		X = e.pageX; // 获取鼠标的X坐标,并将其缓存在变量X中
		Y = e.pageY; // 获取鼠标的Y坐标,并将其缓存在变量Y中
		a=0; // 将变量a的值设置为0
		b=0; // 将变量b的值设置为0 
		A = X, // 将变量A的值设置为鼠标的X坐标
		B = Y; // 将变量B的值设置为鼠标的Y坐标
		R=(e.pageX/W * 999>>0)/999; // 计算半径R,根据鼠标的X坐标和窗口宽度的比例计算得出
		r=(e.pageY/H * 999>>0)/999; // 计算半径r,根据鼠标的Y坐标和窗口高度的比例计算得出
		U=e.pageX/H * 360 >>0; // 计算角度U,根据鼠标的X坐标和窗口高度的比例计算得出,并取整数部分
		D=9; // 将变量D的值设置为9
		g = 360 * Math.PI / 180; // 将变量g的值设置为360度对应的弧度值
		T = setInterval(f = function (e) { // 创建一个定时器T,每16毫秒执行一次函数f

			c.save(); // 保存当前的绘图状态

			c.globalCompositeOperation = "source-over"; // 设置合成操作为"source-over",即覆盖模式

			if(e!=1) { // 如果传入的参数不等于1,则执行以下代码

				c.fillStyle = "rgba(0,0,0,0.02)"; // 设置填充颜色为半透明黑色

				c.fillRect(0, 0, W, H); // 在Canvas上绘制一个黑色的矩形,覆盖整个画布(默认)

			}

			c.restore(); // 恢复之前保存的绘图状态

			i = 25; while(i --) { // 循环25次执行以下代码

				c.beginPath(); // 开始一个新的路径

				if(D > 450 || bool) { // 如果变量D大于450或bool为真,则执行以下代码

					if(!bool) { // 如果bool为假,则执行以下代码

						bool = 1; // 将bool设置为真

					}

					if(D < 0.1) { // 如果变量D小于0.1,则执行以下代码

						bool = 0; // 将bool设置为假

					}

					t -= g; // 减小角度t的值

					D -= 0.1; // 减小半径D的值

				}

				if(!bool) { // 如果bool为假,则执行以下代码

					t += g; // 增加角度t的值

					D += 0.1; // 增加半径D的值

				}

				q = (R / r - 1) * t; // 计算变量q的值,用于创建hypotrochoid(参考:http://en.wikipedia.org/wiki/Hypotrochoid)

				x = (R - r) * C(t) + D * C(q) + (A + (X - A) * (i / 25)) + (r - R); // 计算x坐标的值,根据hypotrochoid公式计算得出

				y = (R - r) * S(t) - D * S(q) + (B + (Y - B) * (i / 25)); // 计算y坐标的值,根据hypotrochoid公式计算得出

				if (a) { // 如果变量a的值存在,则执行以下代码

					c.moveTo(a, b); // 将当前绘图点移动到变量a和b所表示的位置

					c.lineTo(x, y) // 绘制一条直线到坐标(x, y)

				}

				c.strokeStyle = "hsla(" + (U % 360) + ",100%,50%,0.75)"; // 设置线条颜色为根据角度U计算得出的彩虹色

				c.stroke(); // 绘制线条

				a = x; // 将变量a的值设置为x坐标的值

				b = y; // 将变量b的值设置为y坐标的值

			}

			U -= 0.5; // 减小角度U的值

			A = X; // 将变量A的值设置为鼠标的X坐标

			B = Y; // 将变量B的值设置为鼠标的Y坐标

		}, 16); // 定时器每16毫秒执行一次函数f

	}

	j.onkeydown = function(e) { a=b=0; R += 0.05 } // 当按下键盘时执行以下代码,将变量a和b的值都设为0,并将半径R增加0.05

	d.onmousemove({pageX:300, pageY:290}) // 模拟鼠标移动事件,设置pageX为300,pageY为290

}

</script>

</head>

<body>
<canvas id="c"></canvas> <!-- 创建一个id为"c"的Canvas元素 -->
</body>

</html>

二、代码原理

该代码利用Canvas的绘图功能和数学函数,创建了一个动态的彩色线条效果,能够根据鼠标的移动和键盘的操作呈现不同的视觉效果。它使用了数学函数来计算线条的坐标和角度,并根据鼠标位置和窗口大小进行动态调整。代码首先获取Canvas元素,并设置其宽度和高度为窗口的宽度和高度。然后设置绘图上下文的属性,如颜色叠加模式、线条宽度和端点样式。在鼠标移动事件中,根据鼠标的位置计算出各种参数,包括半径、角度和颜色。然后使用循环和数学函数绘制彩色线条,线条的位置和颜色会随着时间和鼠标移动而变化。

  1. 声明文档类型为XHTML 1.0 Transitional。
  2. 定义文档命名空间为XHTML。
  3. 设置页面标题为“视觉盛宴”。
  4. <head>标签内包含了一个JavaScript脚本。
  5. JavaScript脚本中,使用了一些全局变量和函数。
  6. window.onload事件处理函数会在窗口加载完成后执行。
  7. 在函数中,缓存了一些常用的对象和元素,如Math对象、window对象、document对象和Canvas元素。
  8. 设置了Canvas的宽高为窗口的宽高。
  9. 使用Canvas的上下文进行绘制操作。
  10. 创建了一个鼠标移动事件处理函数,当鼠标在Canvas上移动时执行一些操作。
  11. 创建了一个定时器,每16毫秒执行一次函数f
  12. 函数f中,保存了当前的绘图状态,并设置了合成操作和样式。
  13. 使用while循环绘制一些形状,并根据鼠标位置和其他参数计算出坐标值。
  14. 更新一些变量的值。
  15. 在按键事件处理函数中,更新了一些变量的值。
  16. 模拟了一次鼠标移动事件。

三、运行效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/389384.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

windows@命令行映射磁盘驱动器若干方法@开机自动映射网络磁盘

文章目录 windows映射网络磁盘驱动器资源管理器中GUI方式创建命令行方式创建命令行列出驱动器列表删除取消映射持久化配置映射&#x1f47a;记住凭证 FAQ开机自启登录系统后自动挂载&#x1f47a;[以alist webdav 挂载为例]分析对策延迟挂载&#x1f47a;Note 访问已经挂载网络…

【C语言】简单贪吃蛇实现保姆级教学!!!

关注小庄 顿顿解馋૮(˶ᵔ ᵕ ᵔ˶)ა 新年快乐呀小伙伴 引言&#xff1a; 小伙伴们应该都有一个做游戏的梦吧&#xff1f;今天让小庄来用C语言简单实现一下我们的童年邪典贪吃蛇&#xff0c;顺便巩固我们的C语言知识&#xff0c;请安心食用~ 文章目录 贪吃蛇效果一.游戏前工作…

uniapp 开发一个密码管理app

密码管理app 介绍 最近发现自己的账号密码真的是太多了&#xff0c;各种网站&#xff0c;系统&#xff0c;公司内网的&#xff0c;很多站点在登陆的时候都要重新设置密码或者通过短信或者邮箱重新设置密码&#xff0c;真的很麻烦 所以准备开发一个app用来记录这些站好和密码…

使用TinyXML-2解析XML文件

一、XML介绍 当我们想要在不同的程序、系统或平台之间共享信息时&#xff0c;就需要一种统一的方式来组织和表示数据。XML&#xff08;EXtensible Markup Language&#xff0c;即可扩展标记语言&#xff09;是一种用于描述数据的标记语言&#xff0c;它让数据以一种结构化的方…

《区块链公链数据分析简易速速上手小册》第1章:区块链基础(2024 最新版)

文章目录 1.1 区块链技术概览&#xff1a;深入探究与实用案例1.1.1 区块链的核心概念1.1.2 重点案例&#xff1a;供应链管理1.1.3 拓展案例 1&#xff1a;数字身份验证1.1.4 拓展案例 2&#xff1a;智能合约在房地产交易中的应用 1.2 主流公链介绍1.2.1 公链的核心概念1.2.2 重…

深入理解lambda表达式

深入理解ASP.NET Core中的中间件和Lambda表达式 var builder WebApplication.CreateBuilder(args); var app builder.Build(); app.Use(async (context, next) > { // Add code before request. await next(context);// Add code after request.}); 这段C#代码是用于设…

杨中科 .netcore 依赖注入

1.概念 概念 生活中的“控制反转”:自己发电和用电网的电。 依赖注入(Dependency Injection&#xff0c;Dl)是控制反转:(Inversion of Control&#xff0c;l0c)思想的实现方式。 依赖注入简化模块的组装过程&#xff0c;降低模块之间的耦合度 自己发电的代码 var connSetti…

Peter算法小课堂—哈希与哈希表

额……字符串我们是第一次学&#xff0c;给大家铺一些基础的不能再基础的基础&#xff0c; 字符串比较大小 字符串大小的比较&#xff0c;不是以字符串的长度直接决定&#xff0c;而是从最左边第一个字符开始比较&#xff0c;大者为大&#xff0c;小者为小&#xff0c;若相等…

HTTP缓存技术

大家好我是苏麟 , 今天说说HTTP缓存技术 . 资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) HTTP缓存技术 HTTP 缓存有哪些实现方式? 对于一些具有重复性的 HTTP 请求&#xff0c;比如每次请求得到的数据都一样的&#xff0c;我们可以把这对「请求-响…

OpenHarmony—UIAbility组件生命周期

概述 当用户打开、切换和返回到对应应用时&#xff0c;应用中的UIAbility实例会在其生命周期的不同状态之间转换。UIAbility类提供了一系列回调&#xff0c;通过这些回调可以知道当前UIAbility实例的某个状态发生改变&#xff0c;会经过UIAbility实例的创建和销毁&#xff0c;…

OS设备管理

设备管理 操作系统作为系统资源的管理者&#xff0c;其提供的功能有&#xff1a;处理机管理、存储器管理、文件管理、设备管理。其中前三个管理都是在计算机的主机内部管理其相对应的硬件。 I/O设备 I/O即输入/输出。I/O设备即可以将数据输入到计算机&#xff0c;或者可以接收…

【华为数通HCIP | 网络工程师】H12-831刷题日记 题目+解析(2)

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

2007-2021年上市公司内控信息披露指数/上市公司内部控制信息披露指数数据

2007-2021年上市公司内控信息披露指数/上市公司内部控制信息披露指数数据 1、时间&#xff1a;2007-2021年 2、范围&#xff1a;上市公司 3、指标&#xff1a;证券代码、证券简称、辖区、证监会行业、申万行业、内部环境、风险评估、控制活动、信息与沟通、内部监督、内部控…

软考28-上午题-哈希表和堆

一、哈希表 将关键字作为自变量&#xff0c;使用哈希函数H(key)&#xff0c;得到该记录的存储地址。 这一映射过程&#xff0c;称为哈希造表、散列&#xff1b;所得的存储位置 哈希地址、散列地址。 1-1、冲突的定义 两个关键字K1和K2&#xff0c;K1 ! K2&#xff0c;&…

行测线上考试答案查找?推荐你使用这七个公众号和工具 #学习方法#经验分享

合理利用学习辅助工具和资料&#xff0c;可以帮助大学生更好地组织学习内容、掌握知识点和提升学术水平。 1.快解题 这是一个网站 是一款服务于职业考证的考试搜题软件,拥有几千万不同考试医学考试题库和执业医师试题库,通过章节练习,模拟试题,历年真题等练习来让不同的用户…

BLDC驱动刹车电路、能量泄放电路

不同STM32的性能; APM2.8飞控整合资料&#xff1a; APM2.8飞控说明书 GitBook BLDC的制动首先要考虑MOS的泄放电阻的选择&#xff0c;参考前面博客。 刹车电阻制动&#xff1a; 如图所示就是一种通过功率电阻耗散电机制动过程中产生电能的电路。因为功率电阻在这个电路中起…

开什么店最稳定轻松?适合一个人开的实体店推荐

在创业的道路上&#xff0c;很多人都希望找到一种稳定轻松的开店方式。 作为一名资深的鲜奶吧创业者&#xff0c;我将分享我的经验和见解&#xff0c;希望能给那些想开实体店的朋友们一些启示&#xff01;&#xff01; 我开鲜奶吧已经有 5 年时间了&#xff0c;目前经营的是鲜…

Leetcode-103. 二叉树的锯齿形层序遍历

这个年和树过不去啦啦啦&#xff01; 题目&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&…

C#入门及进阶|数组和集合(六):集合概述

1.集合概述 数组是一组具有相同名称和类型的变量集合&#xff0c;但是数组初始化后就不便于再改变其大小&#xff0c;不能实现在程序中动态添加和删除数组元素&#xff0c;使数组的使用具有很多局限性。集合能解决数组存在的这个问题&#xff0c;下面我们来学习介绍集合…

TCP_IP(6)

网络层 在复杂的网络环境中确定一个合适的路径. IP协议 与TCP协议并列,都是网络体系中最核心的协议. 基本概念 主机:配有IP地址,但是不进行路由控制的设备; 路由器:即配有IP地址,又能进行路由控制; 节点:主机和路由器的统称; 协议头格式 4位版本号(version):指定IP协议的版…