JavaScript全解析——canvas 绘制图片

news2025/1/16 3:58:24

●在 canvas 内也是可以直接插入一个图片的
●如果在 canvas 内想插入一个图片
○首先要用 js 加载一个图片
○当图片加载完毕以后, 我们在用 canvas 的 API 把它插入到画布上即可
●先用 js 加载一张图片出来

const myImg = new Image()
myImg.sec = './01小锋.png'
// 准备一个加载完毕的事件
myImg.onload = function () {
    console.log(this) // 这里的 this 就是这个图片的内容
}


复制代码

○这样我们就得到了一个图片内容
○这个可是 JS 的语法哦, 和 canvas 没有关系

●接下来就可以使用 canvas 的 API 把这个加载好的图片插入到画布上了
●语法 : 工具箱.drawImage( 图片内容, 起点 x 坐标, 起点 y 坐标, 宽度, 高度 )

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取当前这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 加载图片
myImg.sec = './01小锋.png'
// 准备一个加载完毕的事件
myImg.onload = function () {
    console.log(this) // 这里的 this 就是这个图片的内容
    
    // 3. 插入到画布内
    ctx.drawImage( this, 100, 100, 236, 368 )
}


复制代码

●这是, 图片就插入到页面上了
●注意 : 如果你设置的 宽度 和 高度 于图片尺寸不符, 会按照你预设尺寸缩放图片

绘制贝塞尔曲线
●canvas 中绘制贝塞尔曲线是一个既复杂又简单的工作
●首先, 我们要知道什么是贝塞尔曲线

了解贝塞尔曲线
●概念 :
贝塞尔曲线(Bezier curve)是计算机图形学中相当重要的参数曲线,它通过一个方程来描述一条曲线,根据方程的最高阶数,又分为线性贝赛尔曲线,二次贝塞尔曲线、三次贝塞尔曲线和更高阶的贝塞尔曲线。
贝塞尔曲线需要提供几个点的参数,首先是 曲线的起点和终点
如果控制点数量为 0,我们称之为线性贝塞尔;
控制点数量为 1,则为二阶贝塞尔曲线;
控制点数量为 2,则为三阶贝塞尔曲线,依此类推。
●我们比较常用到的就是 二阶 和 三阶, 其他的比较少
●更复杂一些的贝塞尔曲线, 我们就需要借助工具来进行测算了
●先来看二阶贝塞尔曲线
○其实就是由 三个点 绘制成两个直线
○然后我们会同时从每条直线的起点开始,向终点移动按比例拿到一个点。然后将这些点再连接,产生 n - 1 条直线。
○就这样,我们继续同样的操作的,直到变成一条直线,然后我们按比例取到一个点,这个点就是曲线经过的点。
○当我们比例一点点变大(从 0 到 1),就拿到了曲线中间的所有点,最终绘制出完整的曲线。

●再来看看三阶贝塞尔曲线
○和二阶贝塞尔曲线是一个道理, 只不过控制点数量变成了两个

●这个东西看起来好难
●但是其实绘制的时候不需要我们来逐个点的计算, canvas 给我们提供了对应的 API

绘制二阶贝塞尔曲线
●我们先用 canvas 的内的线段来描述一个二阶贝塞尔曲线的形状

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取当前这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 描绘测定贝塞尔曲线的线段形状
ctx.moveTo(20, 170)
ctx.lineTo(130, 40)
ctx.lineTo(180, 150)
ctx.stroke()


复制代码


●这就是我们预设的三个点位描绘出来的一个夹角
●接下来我们在这个基础上绘制贝塞尔曲线

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取当前这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 描绘测定贝塞尔曲线的线段形状
ctx.moveTo(20, 170)
ctx.lineTo(130, 40)
ctx.lineTo(180, 150)
ctx.stroke()

// 3. 绘制二阶贝塞尔期限
ctx.beginPath()
ctx.moveTo(20, 170) // 起点, 描绘 p0 点位
// 语法 : ctx.quadraticCurveTo(p1 x坐标, p1 y坐标, p2 x坐标, p2 y坐标)
ctx.quadraticCurveTo(130, 40, 180, 150)
ctx.strokeStyle = 'red'
ctx.stroke()


复制代码

●这条红色的曲线, 就是一个二阶贝塞尔曲线
●这个时候把我们预设的用来观察的线段取消掉就好了

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取当前这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 绘制二阶贝塞尔期限
ctx.beginPath()
ctx.moveTo(20, 170) // 起点, 描绘 p0 点位
// 语法 : ctx.quadraticCurveTo(p1 x坐标, p1 y坐标, p2 x坐标, p2 y坐标)
ctx.quadraticCurveTo(130, 40, 180, 150)
ctx.strokeStyle = 'red'
ctx.stroke()


复制代码

绘制三阶贝塞尔曲线
●其实和二阶贝塞尔曲线一样, 只不过是我们描述的点位变多了一个而已
●和刚才一样, 我们还是先来描述一个预设线段, 用于观察

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取当前这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 描绘测定贝塞尔曲线的线段形状
ctx.moveTo(25, 175)
ctx.lineTo(60, 80)
ctx.lineTo(150, 30)
ctx.lineTo(170, 150)
ctx.stroke()


复制代码

●接下来按照我们预设好的点位开始绘制三阶贝塞尔曲线

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取当前这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 描绘测定贝塞尔曲线的线段形状
ctx.moveTo(25, 175)
ctx.lineTo(60, 80)
ctx.lineTo(150, 30)
ctx.lineTo(170, 150)
ctx.stroke()

// 3. 根据上述描述路径绘制三阶贝塞尔曲线
ctx.beginPath()
ctx.moveTo(25, 175) // 起点, 描述 p0 点位
// 语法 : ctx.bezierCurveTo(p1 x, p1 y, p2 x, p2 y, p3 x, p3 y)
ctx.bezierCurveTo(60, 80, 150, 30, 170, 150)
ctx.strokeStyle = 'red'
ctx.stroke()


复制代码

●这时一个三阶贝塞尔曲线就出现了
●是不是还挺简单的

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

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

相关文章

数据结构与算法基础(王卓)(33):折半插入排序、希尔排序

目录 折半插入排序 Project 1: 问题:缺少在插入元素之前的移动元素的操作 Project 2:(最终成品、结果) 希尔排序 Project 1:(个人思路) 标准答案:(PPT答案) 解释说明&#xff…

OpenGL(六)——坐标系统

目录 一、前言 二、空间系 2.1 局部空间 2.2 世界空间 2.3 观察空间 2.4裁剪空间 2.5 正射投影 2.6 透视投影 2.7 屏幕空间 三、透视箱子 3.1 创建模型矩阵 3.2 创建观察矩阵 3.3 创建透视投影矩阵 3.4 修改顶点着色器 3.5 传递变换矩阵 四、旋转的箱子 五、好…

面了一圈,还没拿到offer.....

最近收到很多小伙伴的留言,金三银四过完了一个offer都没收到。还有遇到那种特别喜欢怼人的面试官,直接面到怀疑人生,真是让人费解。。。 其实面试受打击是正常的,关键是要在面试中总结自己的不足!提前做好面试准备和技…

java基于知识库的中医药问询系统

本系统主要包含了等系统用户管理、中医药常识管理、科室信息管理、知识库管理多个功能模块。下面分别简单阐述一下这几个功能模块需求。 管理员的登录模块:管理员登录系统对本系统其他管理模块进行管理。 用户的登录模块:用户登录本系统,对个…

简历投了2个月没有面试,看这趋势,不发力是不行了

最近有朋友吐槽,感觉最近好难,简历投了2个月了,面试机会很少,自己每天也费心费力的投,一有新职位就赶紧投,自己也积极的跟人家打招呼,不是看完那边没有回复,要么就是不合适。于是我就…

基于ARM树莓派实现智能家居:语音识别控制,Socket网络控制,火灾报警检测,实时监控

目录 一 项目说明 ① 设计框架 ② 功能说明 ③ 硬件说明 ④ 软件说明 二 项目代码 <1> mainPro.c 主函数 <2> InputCommand.h 控制设备头文件 <3> contrlDevices.h 外接设备头文件 <4> bathroomLight.c 泳池灯 <5> livin…

【GUI】基于Python的文本数据处理(串口解析 0D 0A结尾)

【GUI】基于Python的文本数据处理&#xff08;串口解析 0D 0A结尾&#xff09; 如有串口数据&#xff1a; [37;22mD/NO_TAG [2023-04-24 23:01:06 ] ------------------------------------------------->>>>>> M_DADAT_GET_DAMAGE_INFO [0m 2023/04/24 2…

200左右什么蓝牙耳机比较好?国产200左右蓝牙耳机推荐

随着不少手机厂商取消3.5mm耳机孔&#xff0c;蓝牙耳机便成为了人们外出的最佳选择。最近看到很多人问&#xff0c;200左右什么蓝牙耳机比较好&#xff1f;针对这个问题&#xff0c;我来给大家推荐几款国产的蓝牙耳机&#xff0c;一起来看看吧。 一、南卡小音舱Lite2蓝牙耳机 …

如何防止订单重复支付

想必大家对在线支付都不陌生&#xff0c;今天和大家聊聊如何防止订单重复支付。 看看订单支付流程 我们来看看&#xff0c;电商订单支付的简要流程&#xff1a; 订单钱包支付流程 从下单/计算开始&#xff1a; 下单/结算&#xff1a;这一步虽然不是直接的支付起点&#xff0c;但…

opencv场景识别

opencv场景识别 文章目录 一、需求1、现状2、设想 二、模型使用1、opencv dnn支持的功能2、ANN_MLP相关知识3、MLP图像分类模型训练学习 三、更换方向1、目标检测模型2、darknet网络介绍 四、opencv调用darknet模型1、**darknet模型获取**2、python调用darknet模型3、遇到的一些…

NewBing最新更新使用体验(无需等待人人可用)

NewBing最新更新使用体验 微软Bing爆炸级更新&#xff01;无需等待人人可用&#xff01; 今天&#xff0c;微软突然官宣全面开放BingChat&#xff1a; 无需任何等待。只需注册一个账户&#xff0c;首页即可体验。 NewBing最新更新新特性官方文档 https://www.microsoft.com/en-…

ETL 组件Spark资源设置指导

一、概念介绍 1.RDD RDD&#xff08;Resilient Distributed Dataset&#xff09;:弹性分布式数据集&#xff0c;是Spark中最基础的数据抽象。它本质就是一个类&#xff0c;屏蔽了底层对数据的复杂抽象和处理&#xff0c;为用户提供了一组方便数据转换和求值的方法。 简单来说…

研报精选230505

目录 【行业230505国信证券】风电or电网产业链周评&#xff08;4月第5周&#xff09;&#xff1a;海风开发资源集中释放&#xff0c;黑色类原材料价格持续下行 【行业230505天风证券】通信AI系列之&#xff1a;人工智能之火点燃算力需求&#xff0c;AI服务器迎投资机遇 【行业2…

数字孪生遇上VR:未来的新生态

数字孪生和虚拟现实&#xff08;VR&#xff09;是当今技术领域备受关注的两个概念。 数字孪生作为物理世界的数字映像&#xff0c;已经在许多行业得到了广泛应用。而VR则是一种基于计算机生成的三维交互式虚拟环境&#xff0c;被广泛应用于娱乐、教育和游戏等领域。 数字孪生…

十一、MyBatis的逆向工程

文章目录 十一、MyBatis的逆向工程11.1 (清新简洁版)创建逆向工程的步骤11.2 (奢华尊享版)创建逆向工程的步骤11.3 说明尊享版和简洁版的区别 本人其他相关文章链接 十一、MyBatis的逆向工程 正向工程&#xff1a;先创建Java实体类&#xff0c;由框架负责根据实体类生成数据库…

Spring MVC程序开发

文章目录 一、什么是 Spring MVC&#xff08;一&#xff09;MVC的定义&#xff08;二&#xff09;MVC 和 Spring MVC 的关系&#xff08;三&#xff09;为什么要学习 Spring MVC 二、Spring MVC使用方法和技巧&#xff08;一&#xff09;Spring MVC 创建和连接&#xff08;二&a…

clonezilla(再生龙)克隆系统操作

一、前言 背景&#xff1a;由于存在对嵌入式设备系统备份的需求&#xff0c;主要使用在对一个嵌入式设备安装好ros以及其他插件&#xff08;安装时间十分冗长&#xff09;&#xff0c;然后对该系统进行备份&#xff0c;快速复制到下一台嵌入式设备中。因此引出了克隆linux系统…

MySQL知识学习08(MySQL自增主键一定是连续的吗)

众所周知&#xff0c;自增主键可以让聚集索引尽量地保持递增顺序插入&#xff0c;避免了随机查询&#xff0c;从而提高了查询效率。 但实际上&#xff0c;MySQL 的自增主键并不能保证一定是连续递增的。 下面举个例子来看下&#xff0c;如下所示创建一张表&#xff1a; 1、自…

C++类与对象(二)——拷贝构造函数

文章目录 拷贝构造函数1.拷贝构造函数的概念2.拷贝构造函数的特性 前言 本章继续学习类的6个默认成员函数——拷贝构造函数 拷贝构造函数 1.拷贝构造函数的概念 拷贝构造函数&#xff1a;使用已经存在的一个对象初始化创建另一个对象。 举例&#xff1a; class Date { publ…

Golang每日一练(leetDay0056) 单个编辑距离、寻找峰值

目录 161. 单个编辑距离 One Edit Distance &#x1f31f;&#x1f31f; 162. 寻找峰值 Find Peak Element &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 …