【Canvas与艺术】绘制铜质钢底24周年纪念章
【关键点】
底图的查找和多次尝试、文字描边。
【成图】
【代码】
<!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <head> <title>使用HTML5/Canvas绘制铜质钢底24周年纪念章</title> <style type="text/css"> .centerlize{ margin:0 auto; width:1200px; } </style> </head> <body onload="init();"> <div class="centerlize"> <canvas id="myCanvas" width="12px" height="12px" style="border:1px dotted black;"> 如果看到这段文字说您的浏览器尚不支持HTML5 Canvas,请更换浏览器再试. </canvas> <img id="myImg1" src="159-1.jpg" style="display:none;"/> <img id="myImg2" src="159-2.jpg" style="display:none;"/> </div> </body> </html> <script type="text/javascript"> <!-- /***************************************************************** * 将全体代码(从<!DOCTYPE到script>)拷贝下来,粘贴到文本编辑器中, * 另存为.html文件,再用chrome浏览器打开,就能看到实现效果。 ******************************************************************/ // canvas的绘图环境 var ctx; // 高宽 const WIDTH=512; const HEIGHT=512; // 舞台对象 var stage; //------------------------------- // 初始化 //------------------------------- function init(){ // 获得canvas对象 var canvas=document.getElementById('myCanvas'); canvas.width=WIDTH; canvas.height=HEIGHT; // 初始化canvas的绘图环境 ctx=canvas.getContext('2d'); ctx.translate(WIDTH/2,HEIGHT/2);// 原点平移 // 准备 stage=new Stage(); stage.init(); // 开幕 animate(); } // 播放动画 function animate(){ stage.update(); stage.paintBg(ctx); stage.paintFg(ctx); // 循环 if(true){ //sleep(100); window.requestAnimationFrame(animate); } } // 舞台类 function Stage(){ // 初始化 this.init=function(){ } // 更新 this.update=function(){ } // 画背景 this.paintBg=function(ctx){ ctx.clearRect(-WIDTH/2,-HEIGHT/2,WIDTH,HEIGHT);// 清屏 writeText(ctx,WIDTH/2-30,HEIGHT/2-10,"逆火原创","8px consolas","black");// 版权 } // 画前景 this.paintFg=function(ctx){ // 外凸圈 var r=244; ctx.save(); ctx.beginPath(); ctx.arc(0,0,r,0,Math.PI*2,false); ctx.closePath(); var lgrd=ctx.createLinearGradient(-r,-r,2*r,2*r); lgrd.addColorStop(0,"rgb(255,230,111)"); lgrd.addColorStop(1,"rgb(0,0,0)"); ctx.fillStyle=lgrd; ctx.fill(); // 分隔圈 ctx.save(); ctx.beginPath(); ctx.arc(0,0,241,0,Math.PI*2,false); ctx.closePath(); ctx.strokeStyle="rgb(174,143,0)"; ctx.stroke(); // 中圈 ctx.save(); ctx.rotate(Math.PI*5/4); var r=240; ctx.beginPath(); ctx.arc(0,0,r,0,Math.PI*2,false); ctx.closePath(); ctx.clip(); var img=document.getElementById("myImg1"); ctx.drawImage(img,0,0,300,300,-r,-r,2*r,2*r); ctx.restore(); // 内凹圈 var r=144; ctx.beginPath(); ctx.arc(0,0,r,0,Math.PI*2,false); ctx.closePath(); var lgrd=ctx.createLinearGradient(-r,-r,2*r,2*r); lgrd.addColorStop(0,"rgb(151,124,0)"); lgrd.addColorStop(1,"rgb(255,230,111)"); ctx.fillStyle=lgrd; ctx.fill(); // 分隔圈 ctx.beginPath(); ctx.arc(0,0,141,0,Math.PI*2,false); ctx.closePath(); ctx.strokeStyle="rgb(65,42,36)" ctx.stroke(); // 内圈 ctx.save(); ctx.rotate(1*Math.PI+Math.PI/4); var r=140; ctx.beginPath(); ctx.arc(0,0,r,0,Math.PI*2,false); ctx.closePath(); ctx.clip(); var img=document.getElementById("myImg2"); ctx.drawImage(img,50,200,2*r,2*r,-r,-r,2*r,2*r); ctx.restore(); // 加个蒙版 ctx.beginPath(); ctx.arc(0,0,r,0,Math.PI*2,false); ctx.closePath(); ctx.fillStyle="rgba(25,25,25,0.1)"; ctx.fill(); // 上半圈文字 var words="CELEBRATING"; var arr=words.split(""); for(var i=0;i<arr.length;i++){ var letter=arr[i]; var theta=i*Math.PI/180*12.5+Math.PI+Math.PI/180*30; var r=165; var x=r*Math.cos(theta); var y=r*Math.sin(theta); ctx.save(); ctx.translate(x,y); ctx.rotate(theta+Math.PI/2); ctx.scale(1,0.8); ctx.textBaseline="bottom"; ctx.textAlign="center"; ctx.font = "48px Stencil Std"; ctx.fillStyle="rgb(67,42,20)"; ctx.fillText(letter,0,0); ctx.strokeStyle="rgb(255,160,66)"; ctx.strokeText(letter,0,0); ctx.restore(); } // 下半圈文字 var words="aniversary"; var arr=words.split(""); for(var i=0;i<arr.length;i++){ var letter=arr[i]; var theta=-i*Math.PI/180*12.5+Math.PI-Math.PI/180*36; var r=214; var x=r*Math.cos(theta); var y=r*Math.sin(theta); ctx.save(); ctx.translate(x,y); ctx.rotate(theta-Math.PI/2); ctx.scale(1,0.8); ctx.textBaseline="bottom"; ctx.textAlign="center"; ctx.font = "48px Stencil Std"; ctx.fillStyle="rgb(67,42,20)"; ctx.fillText(letter,0,0); ctx.strokeStyle="rgb(255,160,66)"; ctx.strokeText(letter,0,0); ctx.restore(); } // 两侧五星 draw5Star(ctx,-189,0,21); ctx.fillStyle="rgb(67,42,20)"; ctx.fill(); ctx.strokeStyle="rgb(255,160,66)"; ctx.stroke(); draw5Star(ctx,189,0,21); ctx.fillStyle="rgb(67,42,20)"; ctx.fill(); ctx.strokeStyle="rgb(255,160,66)"; ctx.stroke(); // 24 var x=-10,y=55; var word="24"; ctx.textBaseline="bottom"; ctx.textAlign="center"; ctx.font = "96px Stencil Std"; ctx.fillStyle="rgb(67,42,20)"; ctx.fillText(word,x,y); ctx.strokeStyle="rgb(255,160,66)"; ctx.strokeText(word,x,y); // th var x=70,y=-15; var word="th"; ctx.textBaseline="bottom"; ctx.textAlign="center"; ctx.font = "36px consolas"; ctx.fillStyle="rgb(67,42,20)"; ctx.fillText(word,x,y); ctx.strokeStyle="rgb(255,160,66)"; ctx.strokeText(word,x,y); // 24颗星 var r=120; for(var i=0;i<24;i++){ var theta=i*Math.PI*2/24; var x=r*Math.cos(theta); var y=r*Math.sin(theta); draw5Star(ctx,x,y,8); ctx.fillStyle="rgb(255,215,0)"; ctx.fill(); } } } /*-------------------------------------------------- 函数:绘制正五角星的推荐画法 ctx:绘图上下文 x:五角星中心横坐标 y:五角星中心纵坐标 R:五角星中心到顶点的距离 ---------------------------------------------------*/ function draw5Star(ctx,x,y,R){ var r=R*Math.sin(Math.PI/10)/Math.sin(Math.PI/10*7); var arr=[0,0,0,0,0,0,0,0,0,0]; // 顶五点 for(var i=0;i<5;i++){ var theta=i*Math.PI/5*2-Math.PI/10; var x1=R*Math.cos(theta)+x; var y1=R*Math.sin(theta)+y; arr[i*2]=createPt(x1,y1); } // 内五点 for(var i=0;i<5;i++){ var theta=i*Math.PI/5*2+Math.PI/10; var x1=r*Math.cos(theta)+x; var y1=r*Math.sin(theta)+y; arr[i*2+1]=createPt(x1,y1); } ctx.beginPath(); for(var i=0;i<arr.length;i++){ ctx.lineTo(arr[i].x,arr[i].y); } ctx.closePath(); } /*---------------------------------------------------------- 函数:创建一个二维坐标点 x:横坐标 y:纵坐标 Pt即Point ----------------------------------------------------------*/ function createPt(x,y){ var retval={}; retval.x=x; retval.y=y; return retval; } /*---------------------------------------------------------- 函数:延时若干毫秒 milliseconds:毫秒数 ----------------------------------------------------------*/ function sleep(milliSeconds) { const date = Date.now(); let currDate = null; while (currDate - date < milliSeconds) { currDate = Date.now(); } } /*---------------------------------------------------------- 函数:书写文字 ctx:绘图上下文 x:横坐标 y:纵坐标 text:文字 font:字体 color:颜色 ----------------------------------------------------------*/ function writeText(ctx,x,y,text,font,color){ ctx.save(); ctx.textBaseline="bottom"; ctx.textAlign="center"; ctx.font = font; ctx.fillStyle=color; ctx.fillText(text,x,y); ctx.restore(); } /*------------------------------------------------------------- 《三百六十五里路》 作词 : 小轩 作曲 : 谭健常 歌曲:三百六十五里路 演唱:文章 睡意朦胧的星辰 阻挡不了我行程 多年飘泊日夜餐风露宿 为了理想我宁愿忍受寂寞 饮尽那份孤独 抖落一地的尘土 踏上遥远的路途 满怀痴情追求我的梦想 三百六十五日年年的度过 过一日 行一程 三百六十五里路呦 越过春夏秋冬 三百六十五里路呦 岂能让它虚度 那年万丈的雄心 从来没有消失过 只是时光渐去依然执着 自从理想被已经移过多少 三百六十五日 三百六十里路呦 从故乡到异乡 三百六十五里路呦 从少年到白头 有多少三百六十里路呦 越过春夏秋冬 三百六十五里路呦 岂能让它虚度 多少个三百六十五里路呦 从故乡到异乡 三百六十五里路呦 从少年到白头 三百六十五里长路 饮尽那份孤独 --------------------------------------------------------------*/ //--> </script>
【底图】
159-1.jpg
159-2.jpg
END
分类:
Canvas与徽章
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
2022-04-24 【Java】将字符串随机乱序的三函数
2018-04-24 学习研究技术就该只问耕耘不问收获