当前位置: 首页 > news >正文

canvas的基本用法

canvas

canvas元素简介

1.是个container元素<canvas width='100' height='100'></canvas>,有开闭标签

2.有且只有widthheight两个attribute,不需要写单位

canvas的基本使用

const canvasEl = document.getElementById('canvas01')
const ctx = canvasEl.getContext('2d')   //ctx包含了各种属性和画图的函数
ctx.fillStyle='#d55'
ctx.fillRect(200,20,200,50)   //填充矩形
ctx.strokeStyle='#55d'
ctx.lineWidth=10
ctx.strokeRect(100,60,-20,-50)   //描边矩形
ctx.lineWidth=2
ctx.strokeStyle='#5dd'
ctx.strokeRect(150,100,-20,-50)

canvas路径绘制

画多线段

ctx.beginPath()
ctx.moveTo(100,100)//用moveTo将画笔移动到下一个开始绘制的点,和之前绘制的尾部不连接
ctx.lineCap='round'
ctx.lineJoin='bevel'
ctx.lineWidth=5
ctx.lineTo(150,100)
ctx.lineTo(200,120)
ctx.moveTo(220,100)
ctx.lineTo(220,150)
ctx.stroke()
ctx.closePath()

线条的属性:

1.ctx.lineCap:线条端点样式,可以设置'round'|'butt'|'square' 圆角|截断|方角

2.ctx.lineJoin: 线条连接处样式 'round'|'bevel'|'miter' 圆角|倒角|默认

画三角形描边(stroke):需要用到ctx.closePath()

ctx.beginPath()
ctx.moveTo(200,200)
ctx.lineTo(200,250)
ctx.lineTo(300,100)
ctx.stroke()
ctx.closePath()

画三角填充(fill):可以没有ctx.closePath()

ctx.beginPath()
ctx.moveTo(200,200)
ctx.lineTo(200,250)
ctx.lineTo(300,100)
ctx.fill()
ctx.closePath()

画弧

CanvasPath.arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean)

ctx.beginPath()
ctx.arc(300,300,20,0,Math.PI*2,false)
ctx.moveTo(370,350)
ctx.arc(350,350,20,0,Math.PI,false)
ctx.stroke()
ctx.closePath()

画矩形

ctx.beginPath()
ctx.fillStyle='#e00'
ctx.rect(20,300,20,50)
ctx.fill()
ctx.closePath()ctx.beginPath()
ctx.lineStyle='#e00'
ctx.lineWidth=3
ctx.rect(20,400,50,80)
ctx.stroke()
ctx.closePath()

canvas绘制文字

ctx.font = "50px 仿宋"
ctx.textAlign = 'center'
ctx.textBaseline = 'bottom'
ctx.fillStyle = '#d00'
ctx.fillText("哈哈哈", 250, 90,200);
ctx.font = "20px 黑体"
ctx.strokeStyle = '#d000dd'
ctx.strokeText("嘿嘿嘿", 250, 200,200);

canvas绘制图片

1.ctx.drawImage(image, dx, dy)

2.ctx.drawImage(image, dx, dy, dWidth, dHeight)

3.ctx.drawImage(image,sx,sy,swidth,sheight,dx,dy,dwidth,dheight)

s开头的是裁剪坐标,d开头的是绘制坐标

示例:

const dogImage = new Image(200,200)
dogImage.src = './dog.jpg'
dogImage.onload = function(){ctx.drawImage(dogImage,10,10,300,300,0,0,100,100)
}

补充:

canvas绘制的图都是栅格图

canvas绘制状态

保存绘图状态,在进行复杂的绘图以后,可以随时返回当前的状态,主要是保存某个绘图时期的字体,颜色,线条宽度,坐标变换等状态,这样不用重复设置绘图样式,被保存的绘图状态会被推入一个栈中,每次调用restore()就会弹出到栈最顶层的状态,也就是让canvas的各类属性设置回到上一次保存的设置

ctx.save()

ctx.restore()

ctx.fillRect(0,0,100,100)
ctx.save()
ctx.translate(10,150)
ctx.fillRect(0,0,100,100)
ctx.restore()

canvas变形

1.ctx.translate(dx,dy) 平移画布

2.ctx.rotate(deg) 旋转画布

3.ctx.scale(sx,sy)缩放画布,只能在原坐标系统缩放

ctx.save()
ctx.beginPath()
ctx.translate(100,150)
ctx.scale(2, 2)
ctx.rotate(45)
ctx.fillRect(-50,-100,100,100)
ctx.restore()

canvas动画

1.通过setInterval,setTimeoutrequestAnimationFrame三种方法来控制时间

2.画一帧的步骤

1.ctx.clearRect()
2.ctx.save()
3.绘制动画图形
4.ctx.resotre()

示例:绘制表盘

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.container{position: relative;width: 500px;height: 500px;border-radius: 5px;margin: 50px auto;box-shadow: 1px 1px 10px 5px #d5d5d5;}canvas{position: absolute;top: 0;left: 0;}</style>
</head>
<body><div class="container"><canvas id="canvas01" width="500" height="500"></canvas></div><script>const canvasEl = document.getElementById('canvas01')const ctx = canvasEl.getContext('2d')function drawClock(pHours,pMinutes,pSeconds){let oldHours = pHours <= 12?(pHours/12)*60-15:((pHours-12)/12)*60-15let minutes = pMinutes - 15let seconds = pSeconds -15let hours = oldHours+Math.round((pMinutes/12))ctx.clearRect(0,0,500,500)ctx.save()//表盘ctx.beginPath()ctx.arc(250,250,105,0,Math.PI*2,false)ctx.fillStyle='#fff'ctx.fill()ctx.closePath()//表外框线条ctx.beginPath()ctx.strokeStyle= '#000'ctx.lineWidth = 5ctx.moveTo(356,250)ctx.arc(250,250,106,0,Math.PI*2,false)ctx.stroke()ctx.closePath()//表内框线ctx.beginPath()ctx.strokeStyle= '#000'ctx.lineWidth = 1ctx.moveTo(351,250)ctx.arc(250,250,101,0,Math.PI*2,false)ctx.stroke()ctx.closePath()//刻度线ctx.beginPath()ctx.lineWidth=1for(let j = 0;j<60;j++ ){ctx.save()ctx.translate(250,250)ctx.rotate(Math.PI*2/60*j)if(j%5===0){ctx.moveTo(95,0)ctx.lineTo(100,0)}else if(j%15===0){ctx.moveTo(90,0)ctx.lineTo(100,0)}else{ctx.moveTo(98,0)ctx.lineTo(100,0)}ctx.restore()}ctx.stroke()ctx.closePath()//刻度数字const numbers = [3,4,5,6,7,8,9,10,11,0,1,2]ctx.save()ctx.translate(247,254)for(let i = 0; i<numbers.length;i++){let x = Math.cos(Math.PI*2/12*i)*83let y = Math.sin(Math.PI*2/12*i)*83ctx.fillStyle='#000'ctx.textAlign = 'left'ctx.fillText(numbers[i],x,y)}ctx.restore()//秒针ctx.beginPath()ctx.strokeStyle= '#d33'ctx.lineCap = 'round'ctx.lineWidth = 1ctx.moveTo(250,250)ctx.arc(250,250,96,Math.PI*2/60*seconds,Math.PI*2/60*seconds,true)ctx.stroke()ctx.closePath()//分针ctx.beginPath()ctx.strokeStyle= '#111'ctx.lineCap = 'round'ctx.lineWidth = 2ctx.moveTo(250,250)ctx.arc(250,250,80,Math.PI*2/60*minutes,Math.PI*2/60*minutes,true)ctx.stroke()ctx.closePath()//时针ctx.beginPath()ctx.strokeStyle= '#222'ctx.lineCap = 'round'ctx.lineWidth = 4ctx.moveTo(250,250)ctx.arc(250,250,50,Math.PI*2/60*hours,Math.PI*2/60*hours,true)ctx.stroke()ctx.closePath()//表心ctx.beginPath()ctx.moveTo(250,250)ctx.fillStyle= '#fff'ctx.arc(250,250,1,0,Math.PI*2)ctx.fill()ctx.closePath()}let lastSecond = -1;function playAnimation(){const date = new Date()const seconds = date.getSeconds()const minutes = date.getMinutes()const hours = date.getHours()if(lastSecond !== seconds){drawClock(hours,minutes,seconds)lastSecond = seconds}requestAnimationFrame(()=>{playAnimation()})}playAnimation()</script>
</body>
</html>

相关文章:

canvas的基本用法

canvas canvas元素简介 1.是个container元素<canvas width100 height100></canvas>&#xff0c;有开闭标签 2.有且只有width和height两个attribute&#xff0c;不需要写单位 canvas的基本使用 const canvasEl document.getElementById(canvas01) const ctx …...

Tailwind CSS - Tailwind CSS 引入(安装、初始化、配置、引入、构建、使用 Tailwind CSS)

一、Tailwind CSS 概述 Tailwind CSS 是一个功能优先的 CSS 框架&#xff0c;它提供了大量的实用类&#xff08;utility classes&#xff09;&#xff0c;允许开发者通过组合这些类来快速构建用户界面 Tailwind CSS 与传统的 CSS 框架不同&#xff08;例如&#xff0c;Bootstr…...

鸿蒙开发黑科技“stack叠层”替代customdialog

前一篇提到的问题,本篇博文提出了一个解决方案: arkui-x LongPressGesture触发customdialog踩坑记录-CSDN博客 前一段时间遇到的这个问题,通过排除法观察,锁定为customdialog组件有bug,极为容易挂死。不论如何调整使用方法,都还是会触发挂死。 反馈给arkui团队,说是在…...

FreeRTOS从入门到精通 第十五章(事件标志组)

参考教程&#xff1a;【正点原子】手把手教你学FreeRTOS实时系统_哔哩哔哩_bilibili 一、事件标志组简介 1、概述 &#xff08;1&#xff09;事件标志位是一个“位”&#xff0c;用来表示事件是否发生。 &#xff08;2&#xff09;事件标志组是一组事件标志位的集合&#x…...

智慧园区管理平台实现智能整合提升企业运营模式与管理效率

内容概要 在当今数字化的背景下&#xff0c;智慧园区管理平台正逐渐成为企业提升运营效率和管理模式的重要工具。这个平台汇聚了多种先进技术&#xff0c;旨在通过智能整合各类资源与信息&#xff0c;帮助企业实现全面的管理创新。 智慧园区管理平台不仅仅是一个数据处理工具…...

markdown公式特殊字符

个人学习笔记 根号 在 Markdown 中&#xff0c;要表示根号 3&#xff0c;可以使用 LaTeX 语法来实现。常见的有以下两种方式&#xff1a; 行内公式形式&#xff1a;使用一对美元符号 $ 将内容包裹起来&#xff0c;即 $\sqrt{3}$ &#xff0c;在支持 LaTeX 语法渲染的 Markdow…...

【深度分析】微软全球裁员计划不影响印度地区,将继续增加当地就业机会

当微软的裁员刀锋掠过全球办公室时&#xff0c;班加罗尔的键盘声却愈发密集——这场资本迁徙背后&#xff0c;藏着数字殖民时代最锋利的生存法则。 表面是跨国公司的区域战略调整&#xff0c;实则是全球人才市场的地壳运动。微软一边在硅谷裁撤年薪20万美金的高级工程师&#x…...

学习数据结构(5)单向链表的实现

&#xff08;1&#xff09;头部插入 &#xff08;2&#xff09;尾部删除 &#xff08;3&#xff09;头部删除 &#xff08;4&#xff09;查找 &#xff08;5&#xff09;在指定位置之前插入节点 &#xff08;6&#xff09;在指定位置之后插入节点 &#xff08;7&#xff09;删除…...

刷题记录 HOT100回溯算法-5:22. 括号生成

题目&#xff1a;22. 括号生成 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;["((()))","(()())","(())()",…...

Keepalived高可用集群企业应用实例二

一、实现ipvs的高可用性 ipvs相关配置 虚拟服务器配置结构&#xff1a; virtual_server ip port { …… real_server { …… } real_server { …… } } virtual server (虚拟服务器)的定义格式 virtual_server ip port 定义虚拟主机ip地址及其端口 virtual_server …...

C++计算特定随机操作后序列元素乘积的期望

有一个长度为 n n n的序列 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1​,a2​,...,an​。初始序列的所有元素均为 0 0 0。再给定正整数 m m m、 c c c和 ( n − m 1 ) (n-m1) (n−m1)个正整数 b 1 , b 2 , . . . , b n − m 1 b_1,b_2,...,b_{n-m1} b1​,b2​,...,bn−m1​…...

c++字母大小写转换

可以通过标准库中的 <algorithm> 和 <cctype> 头文件来实现大小写转换。以下是常用的方法&#xff1a; 1. 使用 std::transform 和 std::toupper/std::tolower 1.1 转换为大写 #include <iostream> #include <string> #include <algorithm> //…...

MySQL知识点总结(十六)

请说明在复制拓扑中&#xff0c;中继日志集和从属服务器状态日志的作用。 中继日志用来保存从主服务器接受的二进制日志&#xff0c;与二进制日志相同的格式存储&#xff0c;由服务器自动管理&#xff0c;在其全部内容重放后会自动删除。 从属服务器状态日志存储关于如何连接…...

Windows程序设计10:文件指针及目录的创建与删除

文章目录 前言一、文件指针是什么&#xff1f;二、设置文件指针的位置&#xff1a;随机读写&#xff0c;SetFilePointer函数1.函数说明2.函数实例 三、 目录的创建CreateDirectory四、目录的删除RemoveDirectory总结 前言 Windows程序设计10&#xff1a;文件指针及目录的创建与…...

geolocator包的功能和用法

文章目录 1 概念介绍2 使用方法3 示例代码4 体验分享 我们在上一章回中介绍了如何实现滑动菜单相关的内容&#xff0c;本章回中将介绍如何获取位置信息.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的获取位置信息本质上是获取当前手机所在位置的…...

Node.js——body-parser、防盗链、路由模块化、express-generator应用生成器

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…...

22.Word:小张-经费联审核结算单❗【16】

目录 NO1.2 NO3.4​ NO5.6.7 NO8邮件合并 MS搜狗输入法 NO1.2 用ms打开文件&#xff0c;而不是wps❗不然后面都没分布局→页面设置→页面大小→页面方向→上下左右&#xff1a;页边距→页码范围&#xff1a;多页&#xff1a;拼页光标处于→布局→分隔符&#xff1a;分节符…...

Agent 高频知识汇总:查漏补缺参考大全

Agent 高频问题汇总 一、基础概念类 &#xff08;一&#xff09;请解释 Agent 的概念及其主要特点 Agent 是一种能够感知所处环境&#xff0c;并基于感知信息做出决策、采取行动以实现特定目标的实体。它既可以是简单的规则基系统&#xff0c;也能是复杂的智能体&#xff0c…...

本地化部署DeepSeek-R1

本文环境搭建均基于免费工具&#xff0c;感谢开源。 一、下载工具并安装 1. Ollama&#xff1a;最新版本 0.5.7 官网在这里 https://ollama.com/download 但是下载太慢&#xff0c;得换个思路 https://sourceforge.net/projects/ollama.mirror/ 2.Chatbox https://cha…...

验证二叉搜索数(98)

98. 验证二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* …...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...