海上生明月,天涯共此时.

----《望月怀远》(唐·张九龄)

不觉间又到了中秋时节,相信广大朋友们都收到了公司或其他朋友送来的月饼,我相信没有人不期待中秋(假期)的来临。

“小饼如嚼月,中有酥与饴”说的就是美味的月饼,既然月饼如此深得大家的喜爱,今天咱们就用canvas画一个月饼,送个显示器前的你。

这次使用的技术栈是vue + vite 进行开发编辑工作的,(就是简单的html+css)这么简单的功能当然应该使用静态html的啦,请各 位朋友怎么方便怎么来吧~

目录结构

开始绘制
(1)第一步绘制一个富有中国元素的背景(有点密集恐惧症)

#canvas {width: 100%;height: 100%;background-image: repeating-radial-gradient(circle at center center,transparent 0px,transparent 8px,rgba(255, 255, 255, 0.05) 8px,rgba(255, 255, 255, 0.05) 11px,transparent 11px,transparent 17px,rgba(255, 255, 255, 0.05) 17px,rgba(255, 255, 255, 0.05) 25px,transparent 25px,transparent 38px,rgba(255, 255, 255, 0.05) 38px,rgba(255, 255, 255, 0.05) 42px),repeating-radial-gradient(circle at center center,rgb(230, 0, 0) 0px,rgb(230, 0, 0) 11px,rgb(230, 0, 0) 11px,rgb(230, 0, 0) 19px,rgb(230, 0, 0) 19px,rgb(230, 0, 0) 24px,rgb(230, 0, 0) 24px,rgb(230, 0, 0) 33px,rgb(230, 0, 0) 33px,rgb(230, 0, 0) 44px,rgb(230, 0, 0) 44px,rgb(230, 0, 0) 46px);background-size: 30px 30px;cursor: pointer;}

绘制月饼线条
接下来进入到绘制月饼的正式环节,首先我们要获取到画布,然后再绘制线条,月饼大家都知道,大部分的花纹是轴对称的展示,所以我们将其抽出,分为单独的一个个类去进行实现,最后再在底部添加我们的中秋祝福或诗句。

constructor(options) {this.x = 0; // x轴坐标this.y = 0; // y轴坐标this.name = "五仁" // 馅名this.strokeStyle = "rgb(180,110,48)"; // 线条色this.fillStyle = "rgb(251,216,96)"; // 填充色this.fontSize = 36; // 字体大小this.scale = 1; // 缩放大小Object.assign(this, options)this.ctx = null;this.progress = 0; // 绘制进度this.stepFn = [] // 绘制步骤this.isComplete = false; // 是否绘制结束this.nowDate = new Date(); // 当前时间this.lastDate = new Date(); // 结束时间return this;}render(ctx) {// 渲染if (!ctx)throw new Error("context is undefined.");this.ctx = ctx;this.stepFn.length = 0;this.stepFn.push(() => this.drawEdge(180, 20))this.stepFn.push(() => this.drawEdge(140, 12))this.stepFn.push(() => this.drawRoundRectPath(140, 220, 40))this.stepFn.push(() => this.drawRoundRectPath(220, 140, 40))this.stepFn.push(() => this.drawLine(30, -110, 30, 110))this.stepFn.push(() => this.drawLine(0, -110, 0, 110))this.stepFn.push(() => this.drawLine(-30, -110, -30, 110))this.stepFn.push(() => this.drawLine(-110, -30, 110, -30))this.stepFn.push(() => this.drawLine(-110, 0, 110, 0))this.stepFn.push(() => this.drawLine(-110, 30, 110, 30))this.stepFn.push(() => this.drawRect(140, 140))this.stepFn.push(() => this.drawBox(140))this.stepFn.push(() => this.drawText())return this;}draw() {// 绘制for (let i = 0; i < this.progress; i++) {this.stepFn[i] && this.stepFn[i]()}if (this.progress > this.stepFn.length) return this.isComplete = true;this.nowDate = new Date();if(this.nowDate-this.lastDate>200){this.progress++;this.lastDate = this.nowDate;}}drawBox(size) {// 绘制折线盒子const {ctx, x, y, strokeStyle, scale} = this;let v = 17,n = -size / 2;ctx.save()ctx.translate(x, y);ctx.scale(scale, scale)ctx.beginPath();ctx.lineCap = "round";ctx.lineWidth = 4;ctx.strokeStyle = strokeStyle;ctx.moveTo(v + n, n)ctx.lineTo(v + n, size - v + n)ctx.lineTo(size - v + n, size - v + n)ctx.lineTo(size - v + n, v + n)ctx.lineTo(v * 2 + n, v + n)ctx.lineTo(v * 2 + n, size - v * 2 + n)ctx.lineTo(size - v * 2 + n, size - v * 2 + n)ctx.lineTo(size - v * 2 + n, 45 + n)ctx.stroke()ctx.restore();}drawLine(x1, y1, x2, y2) {// 绘制线条const {ctx, x, y, strokeStyle, scale} = this;ctx.save()ctx.translate(x, y);ctx.scale(scale, scale)ctx.beginPath();ctx.lineCap = "round";ctx.lineWidth = 4;ctx.strokeStyle = strokeStyle;ctx.moveTo(x1, y1)ctx.lineTo(x2, y2)ctx.stroke()ctx.restore();}drawRect(width, height) {// 绘制矩形const {ctx, x, y, strokeStyle, fillStyle, scale} = this;ctx.save()ctx.translate(x, y);ctx.scale(scale, scale)ctx.beginPath();ctx.lineCap = "round";ctx.lineWidth = 4;ctx.strokeStyle = strokeStyle;ctx.fillStyle = fillStyle;ctx.rect(-width / 2, -height / 2, width, width)ctx.fill();ctx.stroke()ctx.restore();}drawRoundRectPath(width, height, radius) {// 绘制圆角矩形const {ctx, x, y, strokeStyle, fillStyle, scale} = this;let w = -width / 2,h = -height / 2ctx.save()ctx.translate(x, y);ctx.scale(scale, scale)ctx.lineCap = "round";ctx.strokeStyle = strokeStyle;ctx.fillStyle = fillStyle;ctx.lineWidth = 5;ctx.beginPath();ctx.arc(width - radius + w, height - radius + h, radius, 0, Math.PI / 2);ctx.lineTo(radius + w, height + h);ctx.arc(radius + w, height - radius + h, radius, Math.PI / 2, Math.PI);ctx.lineTo(w, radius + h);ctx.arc(radius + w, radius + h, radius, Math.PI, Math.PI * 3 / 2);ctx.lineTo(width - radius + w, h);ctx.arc(width - radius + w, radius + h, radius, Math.PI * 3 / 2, Math.PI * 2);ctx.lineTo(width + w, height - radius + h);ctx.closePath();ctx.stroke()ctx.restore();}drawEdge(radius, lineWidth) {// 绘制花边const {ctx, x, y, strokeStyle, fillStyle, scale} = this;let n = 12,v = 360 / n,m = 30;ctx.save()ctx.translate(x, y);ctx.scale(scale, scale)ctx.beginPath();ctx.lineCap = "round";for (let i = 0; i < n; i++) {let angle1 = i * v * Math.PI / 180;let angle2 = (i + 1) * v * Math.PI / 180;let angle3 = (i + 0.5) * v * Math.PI / 180;ctx.lineWidth = lineWidth;ctx.strokeStyle = strokeStyle;ctx.fillStyle = fillStyle;let _sx = radius * Math.cos(angle1),_sy = radius * Math.sin(angle1);ctx.lineTo(_sx, _sy);let _ex = radius * Math.cos(angle2),_ey = radius * Math.sin(angle2);let _mx = (radius + m) * Math.cos(angle3),_my = (radius + m) * Math.sin(angle3);ctx.bezierCurveTo(_mx, _my, _ex, _ey, _ex, _ey)}ctx.closePath();ctx.stroke()ctx.fill();ctx.restore();}

填充文字

drawText(n) {// 绘制文字const {ctx, x, y, name, fontSize, strokeStyle, scale} = this;let size = fontSize;ctx.save()ctx.translate(x, y);ctx.scale(scale, scale)ctx.fillStyle = strokeStyle;ctx.textAlign = "center";ctx.font = `bolder ${size}px fangsong,self`ctx.shadowColor = strokeStyle;ctx.shadowBlur = 1;if (name.length == 2) {ctx.fillText(name.charAt(0), 0, -size * 0.5 + 5);ctx.fillText(name.charAt(1), 0, size * 0.5 + 5);}if (name.length >= 3) {size *= 0.7;ctx.font = `bolder ${size}px fangsong,self`ctx.fillText(name.charAt(0), 0, -size * 1 + 2);ctx.fillText(name.charAt(1), 0, size * 0 + 2);ctx.fillText(name.charAt(2), 0, size * 1 + 2);}ctx.restore();}

添加诗句
使用canvas的filltext进行对应诗句的填充

drawText() {const { ctx, w, h, text } = this;ctx.save();ctx.fillStyle = "rgb(253,190,0)";ctx.textAlign = "center";ctx.font = `bolder 32px fangsong,self`;ctx.shadowColor = "rgb(253,190,0)";ctx.shadowBlur = 10;ctx.fillText(text[0].substr(0, this.textIndex), w / 2, h * 0.36 + 240);if (text[0].length < this.textIndex) {ctx.fillText(text[1].substr(0, this.textIndex - text[0].length),w / 2,h * 0.36 + 240 + 52);}ctx.restore();},

切换不同口味

<div class="taste"><spanv-for="(item, index) in types":key="index"class="wur"@click="constructor(item)">{{ item }}</span></div>

data中定义口味

types: [“黑芝麻”, “五仁”, “蛋黄”, “莲蓉”, “豆沙”],
结束
这次运用到的一些图形绘制希望各位小伙伴能够灵活运用,举一反三,在中秋即将到来之际,送给朋友、同事一个不一样的中秋月饼吧~

点赞支持、手留余香、与有荣焉,动动你发财的小手哟,感谢各位大佬能留下您的足迹。

如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star: http://github.crmeb.net/u/defu不胜感激 !

一个不能吃的中秋月饼相关推荐

  1. 让数据可视化告诉你,中秋吃这样的月饼绝对没错

    今年的中秋节已经结束,中秋除了团圆,最重要的事情就是吃月饼,一到中秋超市里铺天盖地的都是各式各样的月饼,什么广式.苏式,五仁.抹茶等等,相信很多人都是来者不拒. 但是对于我这种数据思维严密的人来说,吃 ...

  2. 亲测吃知乎月饼变身“喷射战士”,我给大家科普一下发生甚么事了

    晓查 发自 凹非寺 量子位 报道 | 公众号 QbitAI "泻药,人在厕所,刚下马桶." 没想到,知乎"谢邀"的谐音梗竟然成真了. 中秋将至,互联网大厂都推出 ...

  3. 盘点各大互联网公司2017中秋月饼设计,你最喜欢哪一个?

    日常, 普通人拼车拼房拼自己, 各大公司拼员工拼技术拼实力. 每逢佳节, 普通人拼奖金拼福利拼假期, 而各大公司拼的是独树一帜的创意. 在一年一度的中秋佳节来临之际, 月饼作为中秋节的福利的代表, 当 ...

  4. 2019年互联网公司月饼哪家强?阿里、百度、网易等14家中秋月饼盘点

    一年一度的中秋节日马上到来,"八月十五月儿圆,中秋月饼香又甜",没有月饼的中秋节是不完整的.而在互联网公司,月饼已然成为福利和文化的象征.特别是一些互联网大厂,在月饼设计上特别用心 ...

  5. 2022 互联网中秋月饼大赏,腾讯送火腿,字节寓意圆满,你最钟爱哪款呢?

    整理 | 梦依丹 出品 | CSDN(ID:CSDNnews) 配图来自视觉中国 又是一年花好处,人月中秋两团圆!今年的中秋,你是在家乡还是在他乡度过呢?无论在何处,只要心在一起,多远都不是距离. 每 ...

  6. 这家200多年历史的中华老字号,是如何赢得今年快手中秋月饼品牌冠军的?

    一年一度的中秋节过去了,说到中秋节就不能不提中秋节的代表食品--月饼. △中秋节月饼 作为时效性极强的商品,月饼商家往往提前一个多月就开始布局销售策略和上架商品.快手电商也不例外,今年8月底,各品牌之 ...

  7. 怎么样下载浓情中秋月饼宣传产品介绍PPT模板

    中秋节很多人最喜欢买的当然就是月饼了,这也是给中秋月饼做宣传的最好时机,那么怎么样下载浓情中秋月饼宣传产品介绍PPT模板,分享一个福利给大家吧,分享一套浓情中秋月饼宣传产品介绍PPT模板,该模板由办公 ...

  8. 使用 Python 创建您自己的NFT集合(一)自己动手制作中秋月饼上链送给亲朋好友

    文章目录 使用 Python 创建您自己的NFT集合(一) 一.批量制作NFT方案选择 二. 拼接图像实现思路 三.如何使用 Python 拼接创建中秋月饼NFT图像集 月饼设计 代码实现以及设计(生 ...

  9. 做了一个仿吃鸡游戏,可多人联网,算是学习总结。

    网上偶见UNITY,很有兴趣于是自学了一段时间,这是我做的一个仿吃鸡游戏DEMO,虽然只是抱着学习实践的很低要求,但从代码.模型.美工.场景都要自己做,繁杂超过了我的预估.对次时代游戏有兴趣可加我qq ...

最新文章

  1. DecimalFormat格式化输出带小数的数字类型
  2. 在大规模 Kubernetes 集群上实现高 SLO 的方法
  3. python使用sqlalchemy判断数据库是否包含某张表
  4. android.graphics.drawable.Drawable.Callback回调接口
  5. 线性表_双向循环链表(Caesar加密变换结点顺序 代码实现 )
  6. java泛型为类类型_Java泛型:仅定义为返回类型的通用类型
  7. SPSS安装以及如何解决can not create java virtual machine问题
  8. OSPF —— 重分发(配置命令)
  9. ESP8266串口WiFi模块基本使用方法和配置教程
  10. PostgreSQL创建、连接企业型地理数据库
  11. 什么可以有助睡眠,助睡眠的生活好品
  12. View inflate方法和LayoutInflater inflate方法的区别
  13. OSChina 周一乱弹 —— 花式遛狗法
  14. 解决word2019中求和符号上下标被强制挪到右边的问题
  15. 关于2进制与十六进制的转换;C语言
  16. 粗效过滤器安装技术参数
  17. 云服务器系统一键安装,一键安装服务器系统
  18. 投影机基本故障及解决方法
  19. Kotlin协程实现原理
  20. 【我的OpenGL学习进阶之旅】关于3D模型知识之:什么是obj文件和mtl文件

热门文章

  1. MAC使用SSH连接IPhone
  2. 洛谷P2058 海港(模拟,优先队列)
  3. 学历,工作经验,火焰纹章
  4. 以开发之名|线上家装新美学——梦想之家,由你来定
  5. 面试上海启明星辰+渗透测试工程师! 通过
  6. 怎样制作Lrc歌词文件
  7. c语言窗口插入图片,c语言添加图片Word版
  8. 霓虹灯潮流时尚视频制作AE模板素材
  9. SQL零基础入门学习(三)
  10. 软件设计师的证书有多少含金量?