双端 Diff 算法原理解析及 snabbdom 简单实现

news2025/4/6 11:39:19

一、准备工作

  • 先找个放猪的容器canvas,这里宽设置了1200,高设置了600
 <canvas width="1200" height="600" id="canvas">当前浏览器不支持canvas元素</canvas> 
  • 然后获取它进行操作
const canvas = document.getElementById('canvas');
if(canvas.getContext) {
 // 获取绘图上下文
 var ctx = canvas.getContext('2d');
 //然后就可以咔咔咔咔进行操作了
} 
  • 这里我顺便还设置了一下样式
 ctx.fillStyle = 'pink'; //填充的颜色为粉红色
 ctx.strokeStyle = "#f95a75"; //描线的颜色
 ctx.lineWidth = 4; //描线的厚度 

前面会详细一点,后面就阿巴阿巴了

二、吹风机头

  • 这个我一直不知道要怎么处理比较好,最后调啊调啊,采用两个半圆加上一个椭圆完成
  • 下面先绘制一个半圆* 每一次绘画前都要用ctx.beginPath()开启绘画,防止跟前面的藕断丝连* 画圆的操作:ctx.arc(x,y,radius,startAngle,endAngle,anticlockwise)* x,y为圆的圆心坐标* radius为半径* startAngle,endAngle 分别为圆弧或圆的开始位置,结束位置* anticlockwise是绘画方向,默认false为顺时针方向
 ctx.beginPath();
 ctx.arc(300, 200, 80, 0, Math.PI, false);
 ctx.fill(); 
  • 右上角也是一个半圆,一样的操作
 ctx.beginPath();
 ctx.arc(310, 200, 70, 0 , Math.PI,true);
 ctx.fill(); 
  • 左上角为一个椭圆* 椭圆操作:ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)* x,y为椭圆圆心坐标* radiusx为椭圆的在x轴和y轴的半径* rotation:椭圆自身旋转的方向* startAngle,endAngle 分别为圆弧的开始位置,结束位置* anticlockwise是绘画方向,默认false为顺时针方向
 ctx.beginPath();
 ctx.ellipse(250, 160, 120, 60, Math.PI*0.1, 0, 2 * Math.PI);
 ctx.fill(); 

这样看好丑,我们快搞个猪鼻子来遮遮丑

三、五官

👉鼻子

  • 先召唤鼻子出来把那个椭圆的前面挡掉,它太圆啦
  • 鼻子也是采用了一个椭圆
  • 设置了 ctx.globalCompositeOperation = 'source-over',目的是为了它能够在最前面不被遮挡
  • 把描线的宽度改为3ctx.lineWidth = 3
 ctx.beginPath();
 ctx.ellipse(162, 127, 22, 32, Math.PI*0.12, 0,2*Math.PI, true);
 ctx.globalCompositeOperation = 'source-over'
 ctx.lineWidth = 3;
 ctx.fill();
 ctx.stroke(); 

👉耳朵

  • 耳朵大概让它看起来更像一个头吧
  • 耳朵采用了两个小椭圆
  • 注意这里采用了: ctx.globalCompositeOperation = 'destination-over',就是表示它要当缩头乌龟了,跟其他重叠的地方它要隐藏,不然我们这里椭圆下面描线外露就会很丑就是说
  • 这里的椭圆我也给他倾斜了,不是直挺挺立着的
 ctx.beginPath();
 ctx.ellipse(250, 100, 15, 40, Math.PI*0.05, 0, 2 * Math.PI, true);
 ctx.ellipse(300, 115, 15, 40, Math.PI*0.1, 0, 2 * Math.PI, true);
 ctx.globalCompositeOperation = 'destination-over'
 ctx.fill();
 ctx.stroke(); 

很好,现在已经很有猪感

👉眼睛

  • 眼睛是灵魂,我们来画猪点睛
  • 眼睛这里是采用外面用白色的填充,里面填充一个小黑点,左右眼的操作是一样的,下面是左眼的操作,右眼就不废话啦
 ctx.beginPath();
 ctx.arc(235,125,12,0,Math.PI*2); //这里是外面的白色的那个圆
 ctx.fillStyle = '#fff'
 ctx.globalCompositeOperation = 'source-over' //注意这里也是让它不要被遮挡
 ctx.fill();
 ctx.stroke();
 ctx.beginPath();
 ctx.arc(232,123,4,0, Math.PI*2); //这里画中间的小黑眼珠
 ctx.fillStyle = 'black';
 ctx.fill(); 

很好,不愧是灵魂的存在,我已经要爱上这只猪了

👉嘴巴

  • 嘴巴我们要求的是《微笑唇》
  • 不过它相当简单,给他加个圆弧就好了,不过这里是歪嘴巴哦,所以我调了一下数据
 ctx.beginPath();
 ctx.arc(280,215, 35, Math.PI*0.2, Math.PI);
 ctx.stroke(); 

因为我对它逐渐喜爱,所以它害羞了,来给它加点腮红

👉腮红

  • 加个填充圆就好了
 ctx.beginPath();
 ctx.arc(325, 200, 30, 0, Math.PI*2);
 ctx.fillStyle = '#ff9cc1'
 ctx.fill(); 

头到这里就搞定了,堂堂佩奇大丈夫当然要有身子

四、身体

👉衣服

  • 先上衣服遮遮羞,大家都知道,咱们小猪当然是穿裙子最好啦(Bushi,是因为最方便画)
  • 这里采用了画线(梯形)填充 + 二次贝塞尔线填充,让裙子更有感觉
  • 这里依旧使用了 ctx.globalCompositeOperation = 'destination-over' ,不清楚为啥用的回看耳朵那里
  • 二次贝塞尔线:quadraticCurveTo(cp1x, cp1y, x, y)* cp1xcp1y为控制点* xy为结束点* 可以借助它来调试Canvas Quadratic Curve Example (sitepointstatic.com)
 ctx.beginPath();
 ctx.globalCompositeOperation = 'destination-over'//不会有人到这里都不知道它是干嘛的吧
 ctx.fillStyle = '#ff6464';
 ctx.moveTo(240,245);
 ctx.lineTo(200,400);
 ctx.lineTo(400,400);
 ctx.lineTo(350,245); //到这里目的是给它传上了一件程梯形形状的裙子
 ctx.moveTo(240, 245);//给裙子左边加点弧度
 ctx.quadraticCurveTo(177, 350, 200, 400);
 ctx.moveTo(350, 245);//给裙子右边加点弧度
 ctx.quadraticCurveTo(448, 350, 400, 400);
 ctx.fill(); 

这裙子不能买,显胖

👉手

  • 手这里我们就简简单单过了,使用的东西我们之前基本都用过
  • 下面的代码为左手,右手的我忽略了
 ctx.beginPath();
 ctx.moveTo(230, 290);
 ctx.lineTo(150, 320);
 ctx.stroke();
 ctx.beginPath();
 ctx.moveTo(175, 312);
 ctx.lineTo(145, 310);
 ctx.moveTo(175, 312);
 ctx.lineTo(170, 330);
 ctx.stroke(); 

👉脚

  • 脚就更简单了哈哈,把线调粗一点,画两条线即可
  • 依旧是左脚代码
 ctx.beginPath();
 ctx.strokeStyle = '#f08181';
 ctx.lineWidth = 10;
 ctx.moveTo(260,400);
 ctx.lineTo(260,450);
 ctx.stroke(); 

俗话说,赤脚不怕穿鞋的,但是我们猪猪哪里需要那么凶,就要鞋就要鞋

👉皮鞋

  • 先来双破鞋
  • 又一看,感觉这个鞋子,四四方方,那里像双鞋子的样子
 ctx.beginPath();
 ctx.strokeStyle = 'black';
 ctx.globalCompositeOperation = 'source-over'
 ctx.lineWidth = 15;
 ctx.moveTo(260,450);
 ctx.lineTo(240,450);
 ctx.stroke(); 
  • 来加点料
  • 我们可以通过 lineCap设置线条的样式* butt:默认的就是它,方方正正,端点是垂直于线段边缘的平直边缘* round:这个就是我们皮鞋的正宗用料了,端点是在线段边缘处以线宽为直径的半圆* square:端点是在线段边缘处以线宽为长,以一半线宽为宽的矩形
  • 所以我们给他设置 ctx.lineCap='round',就相当于给它穿上高级鞋子了

五、文字

  • 既然本意是来熟练操作的,那么自然不能放过文字啦
  • 文本也是两种方式,分别为填充和描边,我们这里使用的是填充
  • 填充文字:ctx.fillText(text, x, y, maxWidth)* text:绘制的文案* xy:文本的起始位置* maxWidth:可选参数,最大宽度
 ctx.beginPath();
 ctx.fillStyle = 'pink'
 ctx.ellipse(550, 150, 150, 100, 0, 0, 2 * Math.PI);
 ctx.fill();
 ctx.beginPath();
 ctx.font = "50px serif"; // 设置文案大小和字体
 ctx.fillStyle = "#ee7934"; //设置填充颜色
 ctx.fillText('不准再说我丑了', 450, 160, 200); //这里去填充文字 

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

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

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

相关文章

让人头皮发麻的Android 性能优化版块,这样简单就学会了?

对现如今的Android 开发们来讲&#xff0c;不管是在面试还是日常工作当中&#xff0c;性能优化 都是一个绕不开的难题。 以下这些场景&#xff0c;大家或多或少都有遇到过&#xff1a; 1. 当你很努力地优化了应用的性能后&#xff0c;用户依然不断抱怨应用卡顿、启动速度慢等…

005. 组合总和 II

1.题目链接&#xff1a; 40. 组合总和 II 2.解题思路&#xff1a; 树层&#xff1a;同层遍历 树枝&#xff1a;递归遍历 2.1.题目要求&#xff1a; 给定一个数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candi…

6.终于了解volatile的原理和使用方法了

1.volatile能保证可见性 先说个案例&#xff1a; 有两个线程A和B&#xff0c;有一个公共的 boolean flag 标记位&#xff0c;最开始赋值为 true&#xff1b;B线程循环&#xff0c;根据这个flag来进行执行或者退出&#xff1b;这时线程A把flag改成false这个时候希望线程B看到变…

python安全工具开发笔记(三)——python 多线程

一、Python线程和进程 进程 进程是程序的一次执行。每个进程都有自己的地址空间、内存、数据栈及其它记录其运行轨迹的辅助数据。 线程 所有的线程运行在同一个进程当中&#xff0c;共享相同的运行环境。线程有开始顺序执行和结束三个部分。 帮助理解&#xff1a; 1、计算…

vs2019+Qt 使用 Qlabel 在界面上显示图像及显示失真问题

在使用 Qt 设计界面时&#xff0c;通常会涉及到在界面上显示图片的问题&#xff0c;而要在界面上显示图片需要使用控件 Qlabel 和 函数 QImage &#xff0c;下面对控件和函数逐一做出介绍&#xff01;&#xff01;&#xff01; 一、Qlabel 常见成员方法 1、setText(const QSt…

全国批发市场情况萧条,进销存系统或是业务转机

如今批发市场情况大不如前&#xff0c;越发惨淡&#xff0c;令人不禁扼腕叹息。让我们深入批发行业&#xff0c;撇开大环境因素&#xff0c;来究竟发现什么是导致批发市场的萧条现状的原因。 1、物流快速发展&#xff0c;失去地域优势 在90年代初&#xff0c;各地交通不便&…

idea相关配置-----java

导入项目 打开项目src的上一层目录即可 导入之后如果可以正常运行就不用看下面操作了&#xff0c; 如果不能运行可以参考下面内容 配置 1.jdk配置 2.添加项目jar包&#xff0c;然后应用 配置完成了 常用快捷键 快捷代码 sout 输出 forr 创建倒序 for循环 fori 创建 for循环…

国外Windows主机的特点

虚拟主机是一项为用户提供在线系统的服务&#xff0c;用于存储信息、图像、视频或其他可以通过互联网轻松访问的文件。而Windows虚拟主机是其中的一个类别&#xff0c;使用这款主机的用户需要和其他共享一个服务器——包括物理服务器和软件应用程序。目前&#xff0c;大多数应用…

Cesium For Unity3d 最新实践流程-2022-12-01

目录 Cesium-Unity3d 最新实践流程 一、前言 二、实践 1、Unity 安装 2、Cesium for Unity 下载 3、打开项目 4、编辑、运行项目 4、效果 Cesium For Unity3d 最新实践流程 一、前言 2022年11月30日晚11点30分&#xff0c;Cesium for Unity 开源插件预览版发布&#…

7.axios的基本使用

Axios是专注于网络数据请求的库&#xff0c;比jQuery更轻量&#xff0c;项目地址 下载解压后在dist中可以找到axios.js&#xff0c;在html文件中引用它就好了 目录 1 GET请求 2 POST请求 3 axios() 1 GET请求 服务是两个数相加 返回的res对象有六个属性&#xff0c;你…

【Python】基础语法1(常量与表达式、变量和类型、注释、输入输出、运算符)

文章目录1、常量与表达式2. 变量和类型2.1 变量是什么2.2 变量的语法2.3 变量的类型2.3.1整数2.3.2 浮点数2.3.3 字符串2.3.4 布尔2.3.5 其他2.4 变量类型的意义2.5 动态类型特性3. 注释3.1 注释的语法3.2 注释的规范4. 输入输出4.1 通过控制台输出4.2 通过控制台输入5. 运算符…

java - 数据结构,时间复杂度和空间复杂度

一、算法效率 算法效率分析分为两种&#xff1a;第一种是时间效率&#xff0c;第二种是空间效率。 时间效率被称为时间复杂度&#xff0c;而空间效率被称作空间复杂度。 时间复杂度主要衡量的是一个算法的运行速度&#xff0c;而空间复杂度主要衡量一个算法所需要的额外空间&am…

子不语发生工商变更:注册资本增至3000万元,预计全年净利润下滑

近日&#xff0c;浙江子不语电子商务有限公司&#xff08;下称“子不语”&#xff09;发生工商变更&#xff0c;其中注册资本由2600万元增至3000万元。据天眼查信息显示&#xff0c;子不语的全资股东为ZIBUYU INTERNATIONAL LIMITED&#xff0c;法定代表人为华丙如。 据了解&am…

【前端验证】验证自动化脚本的最后一块拼图补全——gen_tb

我们的目标是┏ (゜ω゜)=☞芯片前端全栈工程师~喵! 前言 在完成了 【芯片前端】可能是定向验证的巅峰之作——auto_testbench_尼德兰的喵的博客-CSDN博客 【python脚本】用于生成简单握手接口与自测环境的gen_uvm_agent脚本_尼德兰的喵的博客-CSDN博客 两个工具之后,对于…

[附源码]计算机毕业设计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…

Unity数字孪生UI设计——导入视频

Unity导入mp4或URL链接 1、准备视频 Uinty3D常用视频格式: mov、.mpg、.mpeg、.mp4、.avi .asf 如果都不识别,试试转换成ogv格式 转换完成之后,将视频素材文件拖入Uinty Assets文件夹内 2、创建UI及添加组件 1、右键Assets文件夹或任意文件夹→Create→Render Texture纹理渲…

七、Sleuth分布式链路请求跟踪

SpringCloud Sleuth分布式链路请求跟踪 概述 为什么会出现这个技术&#xff1f;需要解决哪些问题&#xff1f; 问题 在微服务框架中&#xff0c;一个由客户端发起的请求在后端系统中会经过多个不同的服务节点调用来协同产生最后的请求结果&#xff0c;每一个前端请求都会形…

[附源码]计算机毕业设计springboot面向高校活动聚App

项目运行 环境配置&#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…

半正定Toeplitz矩阵的范德蒙德分解

半正定Toeplitz矩阵的范德蒙德分解 Toeplitz矩阵的定义&#xff1a;Matrices whose entries are constant along each diagonal are called Toeplitz matrices. 形如 T[r0r1r2r3r−1r0r1r2r−2r−1r0r1r−3r−2r−1r0](1)\boldsymbol{T}\left[ \begin{matrix} r_0& r_1&…

前端开发调试技巧

1、alert弹框调试 正对js代码的调试&#xff0c;我们往往需要获取某些变量的值&#xff0c;于是在早期我们往往通过alert方法将变量的值通过弹窗的形式进行打印。 <script>alert(测试弹框) </script>2、console控制台打印 alert方法对于我们来说或许仍然比较繁琐…