【Canvas】JavaScript用Canvas制作美丽的对称图案

news2025/8/1 19:39:29

生活中有看到一个对称图案,看着很美,于是想到,试试用Canvas试着画对称图形来,想到就做,自己还真捣鼓出来了,自己弄了好多的对称图这里就不晒出来了,接下来讲讲怎么做,有兴趣的同学可以自己边学边动手做,瞧瞧谁做得对称图形最好看呢。

1. 页面设计

要做出一个好作品,是需要熟悉对“Canvas”的操作经验的,理清好思路和制作步骤,然后设计出页面,一个页面文件代码如下

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
		<title>对称图 Symmetric graph</title>
	</head>
	<body>
		<canvas id="canv1" style="border: 1px solid #ccc;"></canvas>
		<img id="output_img"/>
		<script type="module">
			import SymmetricGraph from './symmetric_graph.js';//引入模块
			
			window.onload=()=>{
				//...加载脚本
			}
		</script>
	</body>
</html>

2. 编写脚本

接着,写好加载脚本,代码如下,别看代码少,建议学一学,原本很多行代码就变成这样一行代码了

const doms = {};
['canv1','output_img'].map(id=>[id,document.getElementById(id)]).forEach(args=>doms[args[0]]=args[1]);
const { canv1,output_img } = doms;

//创建模块对象
let sg = new SymmetricGraph(canv1,output_img);
//设置对象的配置
sg.setConfig({
	lineWidth:5,//线条宽
	strokeStyle:'#f00',//线条颜色
	count:7,//复制图形的数量
});

3. 编写模块

上面发现了吗,加载的脚本中,有个对象类SymmetricGraph是哪里来的,发现缺少引用的模块文件symmetric_graph.js,接下来,我们就新建这一个模块

1. 初始化

模块文件的代码如下,先写好初始化逻辑,还有鼠标键的监听处理

export default class SymmetricGraph{
				
	#size;
	#ctx;
	#ctxV;
	#count=4;
	
	constructor(canv1,output_img){
		const ctx = canv1.getContext('2d');
		const { width, height } = ctx.canvas;
		const size = Math.max(width,height);
		const canvasV = document.createElement('canvas');
		canvasV.width=size;
		canvasV.height=size;
		const ctxV = canvasV.getContext('2d');
		ctx.canvas.width=size;
		ctx.canvas.height=size;
		//保存需要读取的设置
		this.#size=size;
		this.#ctx=ctx;
		this.#ctxV=ctxV;
		//默认设置
		this.setConfig();
		
		let pointes = [];
		//鼠标键按下时的处理
		canv1.addEventListener('mousedown',(e)=>{
			const { x, y } = e;
			pointes.push({x,y});
			ctx.beginPath();
			ctx.moveTo(x,y);
		});
		//鼠标键按下并移动时的处理
		canv1.addEventListener('mousemove',(e)=>{
			if(pointes.length<=0) return;
			const { x, y } = e;
			ctx.lineTo(x,y);
			ctx.stroke();
			this.drawImage(ctx.canvas.toDataURL(),this.#count);
		});
		//鼠标键松开时的处理
		canv1.addEventListener('mouseup',(e)=>{
			const { x, y } = e;
			pointes.length=0;
		});
	}
	
	//设置配置
	setConfig(e={}){
		const config={
			lineWidth:2,
			strokeStyle:'#250',
			backgroundColor:'#fff',
			count:4,
		};
		Object.assign(config,e);
		const ctx = this.#ctx;
		ctx.lineWidth=config.lineWidth;
		ctx.strokeStyle=config.strokeStyle;
		this.#ctxV.fillStyle=config.backgroundColor;
		this.#count=config.count;
	}
	
	//主要方法,绘制多个复制的图形
	drawImage(src,count=4){
		//...这里省略,下一步接着讲
	}
	
}

2. 主要方法

将到重点,这是绘制图像的方法drawImage(),传入两个参数,分别时要复制的图像src,和复制数量count,仔细看下代码,会发现很简单

let img = new Image();
img.onload=()=>{
	const size = this.#size;
	const s = size*0.5;
	const ctx = this.#ctxV;
	const max = 360;
	let offset = max/count;
	//填充画布背景
	ctx.rect(0,0,size,size);
	ctx.fill();
	//旋转不同角度,再绘制图形
	for(let i=0; i<max; i+=offset){
		ctx.save();
		ctx.translate(size/2,size/2);
		ctx.rotate(i/180*Math.PI);
		ctx.translate(-size/2,-size/2);
		ctx.drawImage(img,(size-s)/2,0,s,s);
		ctx.restore();
	}
	//将绘制好的图案设置到图像标签中,显示出来
	output_img.setAttribute('src',ctx.canvas.toDataURL());
	//清空画布
	ctx.clearRect(0,0,size,size);
};
img.src=src;

4. 运行测试

很快收工了,写得代码不多,没有问题的话,就用浏览器打开网页,试着在画布上用鼠标按下,随意画,就会看到生成漂亮的图案了,鼠标右键可保存下来,这个用途有很多的,能想到的是,可以用在刻印上,或者当作纹理图案素材,最后,附上录制的效果图
在这里插入图片描述

💡试试修改页面脚本中的如下配置,可以绘制很多不一样的图案哦

sg.setConfig({
	lineWidth:5,//线条宽
	strokeStyle:'#f00',//线条颜色
	count:7,//复制图形的数量
});

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

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

相关文章

java 自定义生成验证码

目录说明效果展示Base64编码的文件类型枚举类验证码默认常量值验证码生成工具类使用说明 项目登录或者其他重要的操作中都要生成验证码&#xff0c;其重要性在此不多说。 主要是介绍自己封装的验证码生成工具类的使用。 建议安装lombok插件,不使用此插件则需要手动生成get、s…

cron表达式,结构、字段说明、特殊字符说明、常用表达式

1.cron表达式的结构 Cron表达式是一个字符串&#xff0c;结构非常简单。Cron表达式从左到右分为6或7个字段&#xff0c;每个字段代表一个含义&#xff0c;用空格隔开。如下图所示&#xff1a; 2.cron表达式中各个字段的说明和规则 Cron一共有7位&#xff0c;最后一位是年份&…

浅析资源调度框架YARN

第一章 资源调度框架YARN理论 1.1 YARN概述 分布式操作系统 hadoop 1.xMapReduce主从架构 主节点JobTracker 从节点TaskTrackerslot hadoop 2.xMapReduce编程API YARN主从架构 主节点ResourceManager 从节点NodeManagerContainer hadoop 3.xCommonHDFS 纠删码 …

关于升级高德地图导航9.5.0的问题 ‘com.amap.api:navi-3dmap:9.5.0_3dmap9.5.0‘

最近打开项目&#xff0c;发现高德有新版本更新&#xff0c;果断更新。哈哈哈哈。然而结果好像并没有这么简单。要是世界上什么事情这么简单就好了。年轻人。还是太年轻了啊。 然后更新完最新的依赖 /*高德地图远程依赖*/implementation com.amap.api:navi-3dmap:9.5.0_3dmap9…

I/O 设备(输入/输出设备)

文章目录I/O 设备输入设备输出设备1&#xff0c;显示器2&#xff0c;打印机3&#xff0c;投影仪I/O 设备 输入设备 借助计算机的输入设备&#xff0c;用户能够轻松地将数据或者指令传递给计算机。同时&#xff0c;计算机中的 CPU 会接收用户输入的指令或数据&#xff0c;并对…

Tesla M40 下Ubuntu anaconda pycharm pytorch安装

显卡&#xff1a;Tesla M40 24GB (2张&#xff09; 显卡驱动版本(推荐)&#xff1a;470.57.02 cuda版本&#xff1a;11.4 安装前需要&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;禁用nouveau驱动&#xff01;&#xff01;&#xff01;&#xff01;&#x…

矢量网络分析仪的S11和S12参数是什么呢?

矢量网络分析仪的基础功能是S参数测试。所谓S参数&#xff0c;就是散射参数&#xff0c;是描述电磁波在被测设备的入射波量、反射波量以及波量传输特性的参数。简单理解&#xff1a;S11代表端口1的反射&#xff0c;S22代表端口2的反射&#xff0c;S21是端口1至端口2的传输&…

阿里云安装软件:jdk11

命令下载 1. 安装准备 检查系统jdk版本 java -version检查jdk自带安装包 rpm -qa | grep java卸载jdk yum -y remove tzdata-java.noarch如果有就卸载&#xff0c;卸载的包名通过&#xff08;rpm -qa | grep java&#xff09;获取&#xff0c;包名要全部输入 rpm -e --nodeps …

Kotlin基础认知 - 为何Kotlin文件有的带.kt后缀,有的不带?

有一天看到项目中的Kotlin类&#xff0c;有的有.kt后缀&#xff0c;有的没有&#xff0c;针对这个情况我就简单看了下&#xff0c;然后记录一波 创建 Kotlin Class 或 Kotlin File创建Kotlin class创建Kotlin File俩者区别展现形式外部展现内部展现延伸扩展、对向转换Class无后…

【Silvaco example】Temperature Ramping - Effect on Leakage

1、例子讲解 本示例演示了Atlas中任何device的全局温度梯度&#xff08;global temperature ramping&#xff09;的正确方法。 &#xff08;1&#xff09;结构定义 为了简单起见&#xff0c;这里选择了二极管结构。 go atlasmeshx.mesh loc0.00 spac0.05 x.mesh loc0.10 sp…

简单手段发IF=7+文章:磷酸三苯酯对鲤鱼的毒性作用及肠道微生物群落影响

研究背景 磷酸三苯基酯&#xff08;TPHP&#xff09;是一种有机磷阻燃剂&#xff0c;它通过挥发以及溶解分散到环境中&#xff0c;并通过食物链富集生物体&#xff0c;对生态系统产生不可避免的负面影响。已发现TPHP可以引起组织病变&#xff0c;干扰脂质代谢&#xff0c;并降…

全新营销时代,金融企业如何有“种”有“收”?

贯穿2022年的主题&#xff0c;就是“不确定性”。 复杂的大环境下&#xff0c;金融行业的发展饱受“震荡”。疫情、通胀&#xff0c;乃至二级市场的风云变幻&#xff0c;都在考验金融企业经营的确定性。那么&#xff0c;金融企业踏平波动、坚定前行的力量从何而来&#xff1f;…

Spring Boot 简介及快速搭建

Spring Boot 简介及快速搭建 springboot的优点&#xff1a; –快速构建一个独立的 Spring 应用程序 &#xff1b; –嵌入的 Tomcat 、 Jetty 或者 Undertow&#xff0c;无须部署 WAR 文件&#xff1b; –提供starter POMs来简化Maven配置和减少版本冲突所带来的问题&#xff1…

Vue3 setup函数的使用

全新的 setup 函数 在开始编写 Vue 组件之前&#xff0c;需要了解两个全新的前置知识点&#xff1a; 全新的 setup 函数&#xff0c;关系到组件的生命周期和渲染等问题 写 TypeScript 组件离不开的 defineComponent API setup 的含义 Vue 3 的 Composition API 系列里&#x…

计算机网络---应用层概述

&#xff08;一&#xff09;应用层概述 基本定义&#xff1a; 应用层&#xff08;Application layer&#xff09;是OSI模型的第七层。应用层直接和应用程序接口并提供常见的网络应用服务。应用层也向表示层发出请求。应用层是开放系统的最高层,是直接为应用进程提供服务的。其…

数据可视化设计经验分享:10分钟做出炫酷数据大屏

又快到年终了&#xff0c;数据大屏作为一个数据管理的分析工具&#xff0c;在年底数据大屏的制作需求日益增加。在一些公司比如银行、证券、医院、外贸等“数据大户”&#xff0c;在数据大屏的应用上更是有大量需求。 在接下来的两个月&#xff0c;许多人会感到痛苦吧&#xf…

.net---继承和多态

继承和多态继承和多态的基本概念继承继承的类型实现继承接口继承继承派生类base关键字构造函数的调用类成员的继承类成员的隐藏继承&#xff1a;虚方法和隐藏方法抽象类和抽象方法抽象类抽象方法密封类和密封方法密封类接口接口成员接口实现多态重载重写继承和多态的基本概念 …

NIO中ByteBuffer

// Invariants: mark < position < limit < capacityprivate int mark -1;private int position 0;private int limit;private int capacity; 从源码中可以看出&#xff0c;ByteBuffer的几个实例变量。我们稍后会详细解析这几个变量的意义。 在我们刚创建ByteBuff…

绿色积分消费时代来临,共享购跟随国家的号召

近年来&#xff0c;中国共享经济商业模式不断发展成熟。自2016年国家“十三五”规划纲要首次提出“共享经济”概念以来&#xff0c;中国政府不断助推共享经济发展。最新发布的《共享经济指导原则与基本框架》为共享经济作出定义&#xff1a;共享经济即“资源供给者通过平台与资…

IDEA配置Maven

1. IDEA配置Maven环境 先在IDEA中配置Maven环境&#xff1a; 选择 IDEA中 File --> Settings 搜索 maven 设置 IDEA 使用本地安装的 Maven&#xff0c;并修改配置文件路径 2. IDEA 创建 Maven项目 创建模块 创建模块&#xff0c;选择Maven&#xff0c;点击Next 填写模块名称…