生活中有看到一个对称图案,看着很美,于是想到,试试用Canvas试着画对称图形来,想到就做,自己还真捣鼓出来了,自己弄了好多的对称图这里就不晒出来了,接下来讲讲怎么做,有兴趣的同学可以自己边学边动手做,瞧瞧谁做得对称图形最好看呢。
要做出一个好作品,是需要熟悉对“Canvas”的操作经验的,理清好思路和制作步骤,然后设计出页面,一个页面文件代码如下
对称图 Symmetric graph
接着,写好加载脚本,代码如下,别看代码少,建议学一学,原本很多行代码就变成这样一行代码了
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,//复制图形的数量
});
上面发现了吗,加载的脚本中,有个对象类SymmetricGraph是哪里来的,发现缺少引用的模块文件symmetric_graph.js,接下来,我们就新建这一个模块
模块文件的代码如下,先写好初始化逻辑,还有鼠标键的监听处理
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){//...这里省略,下一步接着讲}}
将到重点,这是绘制图像的方法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; ictx.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;
很快收工了,写得代码不多,没有问题的话,就用浏览器打开网页,试着在画布上用鼠标按下,随意画,就会看到生成漂亮的图案了,鼠标右键可保存下来,这个用途有很多的,能想到的是,可以用在刻印上,或者当作纹理图案素材,最后,附上录制的效果图

💡试试修改页面脚本中的如下配置,可以绘制很多不一样的图案哦
sg.setConfig({lineWidth:5,//线条宽strokeStyle:'#f00',//线条颜色count:7,//复制图形的数量
});