【Canvas】js用Canvas绘制漩涡螺旋图动画效果

news2025/1/10 5:58:19

学习JavaScript编程,会用Canvas画图吗,学会它,能画很多有趣的事物,可自由发挥想象,会发现图形学的美,收获很多,这里有一个例子,如何用canvas画漩涡螺旋图动图效果,接下来开始讲,边学边做。

文章目录

  • 1. 设计页面
  • 2. 加载脚本
  • 3. 实现模块
  • 4. 运行效果

1. 设计页面

首先,做好一个页面,开始写布局,页面源代码如下,看起来很简单吧

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>漩涡螺旋行图 Vortex Diagram</title>
		<style>
			img{
				width: 300px;
				height: 300px;
			}
		</style>
	</head>
	<body>
		<div style="padding:20px 0; text-align: center;">
			<div>
				<img id="img1"></canvas>
			</div>
			<div style="padding-top: 20px;">
				<input type="range" max="360" min="1" id="range1" value="1"/><label id="speed1"></label>
			</div>
		</div>
		<script type="module">
			//引入模块
			import VortexDiagram from './vortex_diagram.js'
						
			window.onload=()=>{
				//加载脚本...
			}
		</script>
	</body>
</html>

2. 加载脚本

接下来,页面的加载脚本像这样写的,代码如下,应该看得明白吧

const { img1, range1, speed1 } = ((...args)=>{
	let e = {};
	args.forEach(a=>e[a]=document.getElementById(a));
	return e;
})('img1','range1','speed1');
//新建模块对象
let vd = new VortexDiagram();
//更新滑块的显示数据
const showSpeed = (value)=>{
	speed1.innerText = `${value}周/3s`;
	vd.speed=value*360;//调整速度
};
//当滑块滑动改变时,更新显示
range1.onchange = (e) => {
	const { value } = e.target;
	showSpeed(value);
};
showSpeed(1);
//调用对象的开始动画
vd.start({
	img:img1,
	//...设置参数
},window);

3. 实现模块

发现了吗,有个引用的模块vortex_diagram.js文件是没有的,需要自己去写一个,这时候要复杂一点,代码不会太多

先实现初始化的逻辑方法init(),代码如下

export default class YinAndYangTaiChiDiagram{
	
	speed = 360;//自转初速度
	
	constructor(){
		
	}
	
	//这里实现初始化,先传入所需配置,会返回一个绘制好的螺旋图,图像数据是base64格式的
	#init = (config,window) => {
		const { document } = window;
		const size = config.size;//图像大小
		let canv1 = document.createElement('canvas');
		canv1.width = size;
		canv1.height = size;
		const ctx = canv1.getContext('2d');
		//中心点
		let center = {
			x: size*0.5,
			y: size*0.5,
			r: size*0.5,
		};
		//比如说,是一片叶子所占的角度
		let angle = config.angle;
		//小圆半径
		let r = size*0.25;
		//开始绘图 第一个圆
		ctx.beginPath();
		ctx.arc(Math.cos(0)*r + center.x,Math.sin(0)*r + center.y,r,0,Math.PI*2);
		ctx.fill();
		//余弦函数cosA:表示在一个直角三角形中,∠A(非直角)的邻边与三角形的斜边的比		
		let x = Math.cos(angle/180*Math.PI)*r + center.x;
		//正弦函数sinA:表示在一个直角三角形中,∠A(非直角)的对边与三角形的斜边的比
		let y = Math.sin(angle/180*Math.PI)*r + center.y;
		ctx.beginPath();
		ctx.arc(x,y,r,0,Math.PI*2);
		ctx.save();
		ctx.clip();
		ctx.clearRect(x-r,y-r,r*2,r*2);
		ctx.restore();
		//比如说,一片叶子 绘制好了  要导出图片
		let img = new Image();
		img.onload = () => {
			//将图片绕中心点旋转,转到360°为止,旋转一下就绘制一下
			for(let index=angle*2; index<360; index+=angle*2){
				ctx.save();
				ctx.translate(center.r,center.r);
				ctx.rotate(index/180*Math.PI);
				ctx.translate(-center.r,-center.r);
				ctx.drawImage(img,0,0,size,size);
				ctx.restore();
			}
			//螺旋图就这样绘制完了  可以导出图片
			let img2 = new Image();
			img2.onload = () => {
				//看着还不像吧,导出前,顺便裁剪一下,把不要的边沿部分去掉
				ctx.clearRect(0,0,size,size);
				ctx.beginPath();
				ctx.arc(center.x,center.y,center.r*0.94,0,Math.PI*2);
				ctx.clip();
				ctx.drawImage(img2,0,0,size,size);
				config.success(canv1.toDataURL())
			};
			//想反转,就翻转一下螺旋图
			if(config.isReverse){
				ctx.translate(size, 0);
				ctx.scale(-1, 1);
			}
			img2.src =  canv1.toDataURL();
		};
		img.src = canv1.toDataURL();
	}
	
	//开始动画
	start(config,window){
		const img = config.img;
		//在开始动画的时候调用一下初始化方法
		this.#init({
			//...
			size:img.width,
		},window);
		//省略更多...
	}
}

💡 上面提到了初中数学中的知识“勾股定理”,忘记了的同学建议先复习一下呢,再回来看就能看懂了,

  • 余弦函数cosA:表示在一个直角三角形中,∠A(非直角)的邻边与三角形的斜边的比
  • 正弦函数sinA:表示在一个直角三角形中,∠A(非直角)的对边与三角形的斜边的比

接着实现动画的逻辑方法start(),代码如下,能看懂最好

export default class YinAndYangTaiChiDiagram{
	
	speed = 360;
	
	constructor(){
		
	}
	
	#init = (size,window) => {
		//初始化,返回图像数据
	}
	
	//这里实现开始动画逻辑
	start(config,window){
		const img = config.img;
		this.#init(Object.assign({
			isReverse:config.isReverse || true,
			angle:config.angle || 30,
			size:img.width,
			success:(res)=>img.setAttribute('src',res),
		},config),window);
		
		let angle = 0;
		//设置图片元素的样式
		const style = img.style;
		style.transition=`all 3s linear`;//3秒完成一次动画效果
		//更新动画的方法
		const updateAnimation = () => {
			angle+=this.speed;
			if(angle>=Number.MAX_SAFE_INTEGER){
				alert("超过最大数值了!");
				window.location.reload();
				return;
			}
			style.transform=`rotate(${angle}deg)`;
		};
		//监听动画完成时的方法
		const listener = (event)=>{
			event.preventDefault();
			requestAnimationFrame(()=>updateAnimation());
		};
		img1.addEventListener('transitionend',listener,false);
		//当页面退出(或被关闭)时,移除监听动画方法
		window.onunload=()=>img1.removeEventListener('transitionend', listener);
		//最后,开始动画更新方法
		updateAnimation();
	}
}

4. 运行效果

最后,打开浏览器运行该网页,没问题的话,就能看到期待的漩涡螺旋动画效果了,效果图如下
请添加图片描述

💡 建议亲自上机测试,看到的真实效果是与上面动图不一样的,试试滑动滑块,调节旋转速度,速度变化了,会看到不一样的图案哦

🔈漩涡螺旋图动起来是不是很神奇呢,据说观察它具有神奇的催眠功效!看漩涡中心,就不怕眼花,催眠功效比较显著,嘿嘿, 还是看过之后,是否会产生困意呢

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

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

相关文章

c语言tips-结构体

1. 结构体定义和使用 #include <stdio.h>struct stu {int age;int height;int weight; };int main(int argc, char *argv[]) {struct stu stu1;stu1.age 18;stu1.height 172;stu1.weight 62;printf("年龄为&#xff1a;%d, 身高为&#xff1a;%d, 体重为&#x…

Self-attention自注意力机制——李宏毅机器学习笔记

self-attention想要解决的问题 复杂的输入 每次输入的length不同时&#xff0c;即Vector Set大小不同&#xff0c;该如何处理&#xff1f; one-hot encoding&#xff0c;缺点&#xff1a;所有的词汇之间没有语义资讯。 word embedding&#xff0c;会给每一个词汇一个向量&…

02-Docker-常用命令

目录 一、帮助启动类命令 启动docker 停止docker 重启docker 查看docker状态 开机启动 查看docker概要信息 查看docker总体帮助文档 查看docker命令帮助文档 二、镜像命令 1. 列出本地主机上的镜像 2. 查找镜像 3. 下载镜像 4. 查看镜像/容器/数据卷所占的空间 5.…

[附源码]SSM计算机毕业设计小说网站的设计与实现1JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Java#数据结构----2

目录 一.数据结构(树) 二.二叉树(任意节点的度<2) 二叉查找树又称为二叉排序树/二叉搜索树 平衡二叉树 平衡二叉树的旋转机制 三.红黑树 一.数据结构(树) 基本概念: 度: 每一个节点的子节点数量 树高: 树的总层数 根节点: 最顶层的节点 左子节点: 左下方的节点 右子节…

【Java八股文总结】之面试题(二)

文章目录面试题一、几种锁的区别1、synchronized 和ReentrantLock的区别二、Java高级1、反射1、反射的应用场合2、Java反射API3、反射使用步骤&#xff08;获取Class 对象、调用对象方法&#xff09;4、获取Class对象的3种方法5、创建对象的两种方法 newInstance(&#xff09;2…

数据结构和算法——基于Java——3.1链表(单链表)

理论补充 概念:链表是以节点的方式存储&#xff0c;是链式存储 特性 每个节点包含一个data数据域&#xff08;存放数据&#xff09;&#xff0c;一个next域&#xff08;指向下一个节点&#xff09;链表分带头结点和不带头节点&#xff08;单链表带头&#xff09;链表的内存分…

移动端开发:WebView介绍和使用、JSBridge等

Android应用层的开发有几大模块&#xff0c;其中WebView是最重要的模块之一。Android系统的WebView发展历史可谓一波三折&#xff0c;系统WebView开发者肯定费劲心思才换取了今天的局面——应用里的WebView和Chrome表现一致。 webview是什么&#xff1f; WebView是一种控件&a…

计算机的存储器(详解)

文章目录一&#xff0c;存储器&#xff08;一&#xff09;存储器的分类1) 根据功能和特性分类2) 根据存储容量和所在位置分类二&#xff0c;寄存器&#xff08;一&#xff09;寄存器的类别三&#xff0c;高速缓冲存储器&#xff08;一&#xff09;高速缓存的类别1) 一级高速缓存…

QT-MySQL QSqlDatabase: QMYSQL driver not loaded

使用Qt连接mysql数据库&#xff0c;遇到了一个问题&#xff0c;就是QT5.14.1版本在连接MySQL数据库时候&#xff0c;提示驱动加载失败&#xff0c;“QMYSQL driver not loaded” 编程环境&#xff1a;   Qt5.14.1,编译器是MSVC2017_64,是64位的。   mysql-8.0.30-winx64&am…

场馆系统的数据分析功能怎么样?

在大数据时代&#xff0c;对人们的消费数据进行分析&#xff0c;对企业发展至关重要。对于正在向智能化靠近的运动球馆来说&#xff0c;收集数据、分析数据来了解和改善场馆的运营已经成了一个新的趋势。 场馆系统组建了数据管理分析模块&#xff0c;让球馆通过信息化管理&…

【IoT】如何快速了解一个行业?如何做市场洞察?

如果要做一个新的事情&#xff0c;往往我们也不知道未来会怎么样。 我们准备去做一个事情之前一般都是会有个假设&#xff0c;比方说我们学习一项新技术&#xff0c;我们假设学习了以后能够给未来的生活带来提升&#xff0c;能给自己创造更多的机会&#xff0c;这就是个假设。 …

C++求解汉明距离

目录汉明距离介绍汉明距离应用解法1&#xff1a;Brian Kernighan算法解法2解法3汉明距离介绍 leetcode 461 汉明距离&#xff0c;难度&#xff1a;简单 两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。 给你两个整数 x 和 y&#xff0c;计算并返回…

[附源码]计算机毕业设计Springboot电影推荐网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

APS软件的技术指标与特色

企业可能经常会因为无法掌握生产制造现场的实际产能状况及物料进货状况&#xff0c;导致物料及产能规划与现场详细作业排程难度增大&#xff0c;从而采取有单就接的接单政策与粗估产能的生产排程方式。这种方式就可能导致企业的生产状况频发&#xff1a;在提高对顾客的服务水平…

【Android App】实战项目之实现你问我答的智能语音机器人(超详细 附源码和演示视频)

需要全部代码请点赞关注收藏后评论区留言私信~~~ 一、需求描述 想必大家都见过商场里的智能语音机器人&#xff0c;你对它提问时它可以自动回答你的问题&#xff0c;接下来我们也实现这样一个机器人&#xff0c;它依靠语音技术完成问询服务 基本功能如下 1&#xff1a;接收人们…

锦江酒店(中国区):在变革中拥抱未来 实现高质量发展

过去十年&#xff0c;中国酒店业经历了规模急剧扩张的黄金时期。后疫情时代&#xff0c;酒店行业正在发生深刻变革。 2022年&#xff0c;面对诸多外部不确定性&#xff0c;国内企业均感受到挑战。如何做到在国内大循环为主体、国内国际双循环相互促进的全新格局下高质量发展&a…

Java+JSP基于ssm共享充电宝管理系统-计算机毕业设计

项目介绍 本共享充电宝管理系统主要包括系统用户管理模块、维护人员模块、投放信息管理、区域信息管理、使用记录管理、登录模块、和退出模块等多个模块,系统采用SSM(springMvcspringMybatis)框架进行开发,本系统使用mysql,开发工具支持eclipse idea myeclipse等主流开发工具i…

点云库PCL学习——点云的格式、PCD文件的打开和显示

1、主要参考 (1)格式说明&#xff1a; 点云库PCL学习——点云的格式、PCD文件的打开和显示 ROS知识&#xff1a;点云文件.pcd格式_无水先生的博客-CSDN博客_pcd文件 &#xff08;2&#xff09;点云滤波&#xff0c;对nan的滤波 Python点云数据处理(三)滤波与RANSAC分割 - …

Bootstrap学习从一个模板开始

开源代码&#xff1a; BootstrapDash/celestialAdmin-free-admin-template: Celestial Free Bootstrap Admin Dashboard Template (github.com)https://github.com/BootstrapDash/celestialAdmin-free-admin-template 作为一个新手&#xff0c;知识还停留在简单的HTMLJSCSS的h…