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

news2024/11/29 12:48:33

目录

一、程序代码

二、代码原理

三、运行效果


一、程序代码

<!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. 模拟了一次鼠标移动事件。

三、运行效果

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux 04】编辑器 vim 详细介绍

文章目录 &#x1f308; Ⅰ 基本概念&#x1f308; Ⅱ 基本操作1. 进入 / 退出 vim2. vim 模式切换 &#x1f308; 命令模式1. 光标的移动2. 复制与粘贴3. 剪切与删除4. 撤销与恢复 &#x1f308; Ⅲ 底行模式&#x1f308; Ⅳ 异常退出 &#x1f308; Ⅰ 基本概念 vim 是一种…

ArduPilot开源飞控之硬件SBC分析

ArduPilot开源飞控之硬件SBC分析 1. 源由2. Companion Computer2.1 APSync【不推荐&#xff0c;无更新】2.2 DroneKit【不推荐&#xff0c;无更新/SDK】2.3 FlytOS【不推荐&#xff0c;闭源】2.4 Maverick【不推荐&#xff0c;闭源】2.5 ROS【专门讨论&#xff0c;开源/复杂】2…

【STM32 CubeMX】串口编程DMA

文章目录 前言一、DMA方式1.1 DMA是什么1.2 CubeMX配置DMA1.3 DMA方式函数使用DMA的发送接收函数 总结 前言 在嵌入式系统中&#xff0c;串口通信是一项至关重要的功能&#xff0c;它允许单片机与外部设备进行数据交换&#xff0c;如传感器、显示器或其他设备。然而&#xff0…

基于GPT-4一键完成数据分析全流程的AI Agent: Streamline Analyst

大型语言模型&#xff08;LLM&#xff09;的兴起不仅为获取知识和解决问题开辟了新的可能性&#xff0c;而且催生了一些新型智能系统&#xff0c;例如旨在辅助用户完成特定任务的AI Copilot以及旨在自动化和自主执行复杂任务的AI Agent&#xff0c;使得编程、创作等任务变得高效…

每日OJ题_递归②_力扣21. 合并两个有序链表

目录 力扣21. 合并两个有序链表 解析代码 力扣21. 合并两个有序链表 21. 合并两个有序链表 难度 简单 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4]…

Three.js学习9:Three.js 响应式设计

当浏览器窗口尺寸变化的时候&#xff0c;Three.js 渲染的场景&#xff0c;也就是 canvas 不会变化。 让 canvas 随着窗口的尺寸变化&#xff0c;可以利用 window 对象的 resize 事件实现响应式变化。 window.onresize function(){winH window.innerHeight;winW window.inn…

leetcode:343.整数拆分

解题思路&#xff1a; 拆分的越多越好&#xff08;暂且认为&#xff09;&#xff0c;尽可能拆成m个近似相等的数&#xff0c;会使得乘积最大 dp含义&#xff1a;将i进行拆分得到最大的积为dp[i] 递推公式&#xff1a;j x dp[i-j](固定j&#xff0c;只通过凑dp[i-j]进而实现所…

C++ 动态规划 计数类DP 整数划分

一个正整数 n 可以表示成若干个正整数之和&#xff0c;形如&#xff1a;nn1n2…nk &#xff0c;其中 n1≥n2≥…≥nk,k≥1 。 我们将这样的一种表示称为正整数 n 的一种划分。 现在给定一个正整数 n &#xff0c;请你求出 n 共有多少种不同的划分方法。 输入格式 共一行&…

SpringCloud第二天

1.Nacos配置管理 Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。 1.1.统一配置管理 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&#xff0c;逐个修改微服务配置就会让人抓狂&#xff0c;而且很容易出错。我们需要一种统一配置管理方案&#x…

【AIGC】Stable Diffusion之模型微调工具

推荐一款好用的模型微调工具&#xff0c;cybertron furnace 是一个lora训练整合包&#xff0c;提供训练 lora 模型的工具集或环境。集成环境包括必要的依赖项和配置文件、预训练脚本&#xff0c;支持人物、二次元、画风、自定义lora的训练&#xff0c;以简化用户训练 lora 模型…

Linux中sigaction函数和SIGCHLD信号的使用

sigaction函数&#xff1a; 函数说明&#xff1a;注册一个信号处理函数 函数原型&#xff1a;int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 函数参数&#xff1a; signum:捕捉的信号act:传入参数&#xff0c;…

【C++笔记】第一阶段:C++基础入门

C基础入门 1 C初识1.1 创建一个C程序1.1.1 创建项目1.1.2 创建文件1.1.3 编写代码1.1.4 运行程序 1.2 注释1.3 变量1.4 常量1.5 关键字1.6 标识符命名规则 2 数据类型2.1 整型2.2 sizeof关键字2.3 实型&#xff08;浮点型&#xff09;2.4 字符型2.5 转义字符2.6 字符串型2.7 布…

单源最短路建图方式例题整理

1129. 热浪&#xff08;活动 - AcWing&#xff09; 思路&#xff1a;题目只是加了一个背景&#xff0c;但实际上还是很裸的单源最短路问题。我们有四种写法&#xff0c;bellman_ford算法时间复杂度不如spfa&#xff0c;而且这里对边数没有限定&#xff0c;所以没必要使用bellma…

爱上JVM——常见问题:JVM组成(一)

1 JVM组成 1.1 JVM由那些部分组成&#xff0c;运行流程是什么&#xff1f; 难易程度&#xff1a;☆☆☆ 出现频率&#xff1a;☆☆☆☆ JVM是什么 Java Virtual Machine Java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 好处&#xff1a; 一次编写&…

【AIGC】Stable Diffusion的模型入门

下载好相关模型文件后&#xff0c;直接放入Stable Diffusion相关目录即可使用&#xff0c;Stable Diffusion 模型就是我们日常所说的大模型&#xff0c;下载后放入**\webui\models\Stable-diffusion**目录&#xff0c;界面上就会展示相应的模型选项&#xff0c;如下图所示。作者…

【JAVA-Day81】 线程休眠: Java 中暂停线程执行的方法 ⏸️

线程休眠&#xff1a; Java 中暂停线程执行的方法 ⏸️&#x1f4a4; 线程休眠&#xff1a; Java 中暂停线程执行的方法 ⏸️&#x1f4a4;摘要 &#x1f4dd;引言 &#x1f680;正文 &#x1f4da;一、什么是线程休眠 ⏸️二、线程什么情况下会休眠 ❓三、模拟线程休眠 &#…

jenkins-maven环境的安装

jenkins-maven环境的安装

leetcode 160 相交链表

题目 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结…

Gemini 1.5 Pro揭秘:Google DeepMind新一代AI模型如何突破千万级别词汇限制?

Gemini 1.5 Pro 发布&#xff01; 这款模型凭借其超长的上下文处理能力脱颖而出&#xff0c;支持10M tokens。 它的多模态特性意味着&#xff0c;无论面对多么庞大复杂的内容&#xff0c;Gemini 1.5 Pro都能游刃有余地应对。 在AI的世界里&#xff0c;上下文的理解如同记忆的…

【类与对象(1)】类的引入、访问及封装、定义、作用域、实例化、类大小的计算、this指针

1.类的引入 C兼容了C语言结构体的用法&#xff0c;但是同时又升级成了类。结构体中只能定义变量&#xff0c;类中不仅可以定义变量&#xff0c;还可以定义函数。 例如&#xff0c;数据结构中实现栈&#xff0c;结构体stack中只定义了变量&#xff0c;要实现的函数在结构体外定…