Canvas绘制图片和区域

如何使用Canvas在图片上绘制区域?
一. 首先,我们需要初始化三个canvas画布(初始化Canvas)
initCanvas() {// 初始化canvas画布let canvasWrap = document.getElementsByClassName("canvas-wrap");this.wrapWidth = canvasWrap[0].clientWidth;this.wrapHeight = canvasWrap[0].clientHeight;this.imgCanvas = document.getElementById("imgCanvas");this.imgCtx = this.imgCanvas.getContext("2d");// 绘制canvasthis.drawCanvas = document.getElementById("drawCanvas");this.drawCtx = this.drawCanvas.getContext("2d");// 保存绘制区域 saveCanvasthis.saveCanvas = document.getElementById("saveCanvas");this.saveCtx = this.saveCanvas.getContext("2d");
}
imgCanvas用于绘制原始图片drawCanvas用于临时绘制区域saveCanvas用于保存最终绘制的区域
二. 计算并设置canvas的宽高比例,以适应图片尺寸
initImgCanvas() {// 计算宽高比let ww = this.wrapWidth; // 画布宽度let wh = this.wrapHeight; // 画布高度 let iw = this.imgWidth; // 图片宽度let ih = this.imgHeight; // 图片高度if (iw / ih < ww / wh) {// 以高为主this.ratio = ih / wh;this.canvasHeight = wh;this.canvasWidth = (wh * iw) / ih;} else {// 以宽为主 this.ratio = iw / ww;this.canvasWidth = ww;this.canvasHeight = (ww * ih) / iw;}// 初始化画布大小this.imgCanvas.width = this.canvasWidth;this.imgCanvas.height = this.canvasHeight;this.drawCanvas.width = this.canvasWidth; this.drawCanvas.height = this.canvasHeight;this.saveCanvas.width = this.canvasWidth;this.saveCanvas.height = this.canvasHeight;// 图片加载绘制let img = document.createElement("img");img.src = this.imgUrl;img.onload = () => {console.log("图片已加载");this.imgCtx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight);this.renderDatas(); // 渲染原有数据};
}
这里先计算画布和图片的宽高比,根据比例关系决定以宽为主还是以高为主进行等比缩放。然后设置三个canvas的宽高,并在图片加载完成后将其绘制到imgCanvas上。renderDatas函数用于渲染已有的绘制数据。
三. 绘制的主要逻辑
startDraw() {// 绘制区域if (this.isDrawing) return;this.isDrawing = true;// 绘制逻辑this.drawCanvas.addEventListener("click", this.drawImageClickFn);this.drawCanvas.addEventListener("dblclick", this.drawImageDblClickFn);this.drawCanvas.addEventListener("mousemove", this.drawImageMoveFn);
}
相关文章:
Canvas绘制图片和区域
如何使用Canvas在图片上绘制区域? 一. 首先,我们需要初始化三个canvas画布(初始化Canvas) initCanvas() {// 初始化canvas画布let canvasWrap document.getElementsByClassName("canvas-wrap");this.wrapWidth canva…...
Day10—Spark SQL基础
Spark SQL介绍 Spark SQL是一个用于结构化数据处理的Spark组件。所谓结构化数据,是指具有Schema信息的数据,例如JSON、Parquet、Avro、CSV格式的数据。与基础的Spark RDD API不同,Spark SQL提供了对结构化数据的查询和计算接口。 Spark …...
开源技术:在线教育系统源码及教育培训APP开发指南
本篇文章,小编将探讨如何利用开源技术开发在线教育系统及教育培训APP,旨在为有志于此的开发者提供全面的指导和实践建议。 一、在线教育系统的基本构架 1.1架构设计 包括前端、后端和数据库三个主要部分。 1.2前端技术 在前端开发中,HTML…...
[C++][设计模式][观察者模式]详细讲解
目录 1.动机2.模式定义3.要点总结4.代码感受1.代码一1.FileSplitter.cpp2.MainForm.cpp 2.代码二1.FileSplitter.cpp2.MainForm.cpp 1.动机 在软件构建过程中,需要为某些对象建立一种“通知依赖关系” 一个对象(目标对象)的状态发生改变,所有的依赖对象…...
Adobe Acrobat 编辑器软件下载安装,Acrobat 轻松编辑和管理各种PDF文件
Adobe Acrobat,它凭借卓越的功能和丰富的工具,为用户提供了一个全面的解决方案,用于查看、创建、编辑和管理各种PDF文件。 作为一款专业的PDF阅读器,Adobe Acrobat能够轻松打开并展示各种格式的PDF文档,无论是文字、图…...
eVTOL飞机:技术挑战、应用机遇和运动的作用
最近,航空业的嗡嗡声围绕着电动空中出租车、空中拼车、无人驾驶航空货物运送等。这些概念都依赖于一类称为eVTOL的飞机,eVTOL是电动垂直起降的缩写。 与直升机类似,但没有噪音和排放,eVTOL可以在不需要简易机场的情况下飞行、悬停…...
【python】flask中如何向https服务器传输信息
【背景】 用flask做一个支持流媒体传输的网页,如何将信息post给流媒体服务器呢? 【方法】 简单例子,视图函数这么写: url = "https://yourip/mytext" headers = {Content-Type:application/octet-stream} @app.route(/,methods=["POST"...
计算机网络 —— 应用层(FTP)
计算机网络 —— 应用层(FTP) FTP核心特性:运作流程: FTP工作原理主动模式被动模式 我门今天来看应用层的FTP(文件传输协议) FTP FTP(File Transfer Protocol,文件传输协议&#x…...
zookeeper + kafka消息队列
zookeeper kafka 消息队列 一、消息队列简介 1、什么是消息队列 消息队列(Message Queue)是一种用于跨进程或分布式系统中传递消息的通信机制。消息队列在异步通信、系统解耦、负载均衡和容错方面具有重要作用。 (1)特性 异步…...
Python高级编程:深度学习基础
Python高级编程:深度学习基础 在前几篇文章中,我们探讨了Python的基础语法、面向对象编程、标准库、第三方库、并发编程、异步编程、网络编程与网络爬虫、数据库操作与ORM、数据分析与数据可视化以及机器学习基础。在这篇文章中,我们将深入探讨Python在深度学习领域的应用。…...
如何从magento1迁移到magento2
m2相较m1 变化可以说非常大,相当于从头到位都改写一遍,更现代化,更优雅。除了数据库表变化不是很大。 主要迁移的内容有: 1,主题 2,插件(自己开发的或者第三方插件) 3,数据库 主题 不能迁移到m…...
【Nginx】Nginx安装及简单使用
https://www.bilibili.com/video/BV1F5411J7vK https://www.kuangstudy.com/bbs/1353634800149213186 https://stonecoding.net/system/nginx/nginx.html https://blog.csdn.net/qq_40492693/article/details/124453090 Nginx 是一个高性能的 HTTP 和反向代理 Web 服务器。其特…...
【Linux系列】find命令使用与用法详解
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
Apple - DNS Service Discovery Programming Guide
本文翻译整理自:DNS Service Discovery Programming Guide(更新日期:2013-08-08 https://developer.apple.com/library/archive/documentation/Networking/Conceptual/dns_discovery_api/Introduction.html#//apple_ref/doc/uid/TP30000964 文…...
如何高效地为pip换源:详细操作指南
在Python开发中,pip是我们不可或缺的包管理工具。然而,默认的官方源下载速度较慢,尤其是在国内使用时可能会遇到网络问题。为了提高下载速度,我们可以通过更换国内的镜像源来解决这一问题。本文将详细介绍如何高效地为pip换源&…...
免费ddns工具,快解析DNS解析使用教程
DDNS(Dynamic Domain Name Server),中文叫动态域名解析,主要用于没有固定公网ip的网络环境下,使用一个固定的域名,解析动态变化的ip地址,达到远程访问的目的。 众所周知,目前公网ip资源非常紧缺…...
【Vite】控制打包结构
配置 vite.config.json 文件: import { defineConfig } from "vite";export default defineConfig({// ...build: {rollupOptions: {output: {entryFileNames: "js/[name]-[hash].js",chunkFileNames: "js/[name]-[hash].js",assetF…...
Debian Linux安装minikubekubectl
minikube&kubectl minkube用于在本地开发环境中快速搭建一个单节点的Kubernetes集群,还有k3s,k3d,kind都是轻量级的k8skubectl是使用K8s API 与K8s集群的控制面进行通信的命令行工具 这里使用Debian Linux演示,其他系统安装见官网,首先…...
Discuz动漫二次元风格网站模板
1、本模板为门户论坛个人空间形式,其中个人空间模板需要单独购买,点击购买,美化N多默认模板页面 2、全新设计的标签页,标签页帖子图文调用 3、论坛首页,分区下版块帖子论坛首页自动调用,自带分区图片模式与…...
RIP、OSPF、IS-IS学习
文章目录 前言RIP路由信息协议OSPF开放最短路径优先IS-IS 中间系统到中间系统总结 前言 路由协议的种类繁多,每种协议都有其独特的特性、工作原理和适用场景。本文将重点介绍:RIP(路由信息协议)、OSPF(开放最短路径优…...
Win11Debloat:让你的Windows系统重获新生的终极优化指南
Win11Debloat:让你的Windows系统重获新生的终极优化指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and …...
DeTikZify:AI驱动的科研图表代码自动化解决方案
DeTikZify:AI驱动的科研图表代码自动化解决方案 【免费下载链接】DeTikZify Synthesizing Graphics Programs for Scientific Figures and Sketches with TikZ 项目地址: https://gitcode.com/gh_mirrors/de/DeTikZify 一、科研绘图的隐形痛点:我…...
【读书笔记】《如何做到爱孩子也被孩子爱》
《如何做到爱孩子也被孩子爱》作者:法国著名心理学家(著有《你好,焦虑分子》)核心框架:爱、理性与逻辑 本书提出教养孩子的三大抓手,缺一不可: 爱 → 带来丰富情感与能量,让孩子将来…...
解码汽车ECU的“健康档案”:剖析吉利Basetech五大运行周期计数器(OCC)的协同诊断逻辑
1. 汽车ECU的“健康档案”是什么? 当你去医院体检时,医生会查看你的病历记录、化验报告和近期症状,综合判断你的健康状况。汽车ECU(电子控制单元)也有类似的"健康档案",它就是吉利Basetech技术中…...
避坑指南:nRF52840蓝牙DFU配置中那些官方文档没细说的‘坑’(基于SDK 17.1.0)
nRF52840蓝牙DFU实战避坑手册:从原理到解决方案的深度解析 在嵌入式开发领域,无线固件升级(DFU)功能已成为蓝牙产品的标配需求。nRF52840作为Nordic Semiconductor的旗舰级蓝牙SoC,配合其完善的SDK支持,理论上应该能够轻松实现这一…...
【软考高项】需求跟踪矩阵在项目全生命周期中的关键作用与实践指南
1. 需求跟踪矩阵:项目管理的"导航仪" 刚入行做项目经理那会儿,我最怕的就是需求变更。明明已经确认好的需求,开发到一半客户突然说要改,整个团队手忙脚乱地翻文档、改代码、调测试用例,最后交付时还是漏了几…...
新手福音:基于预置镜像,在快马平台零配置开启Python Web开发之旅
作为一个刚接触Python Web开发的新手,我最近在InsCode(快马)平台上体验了一把零配置搭建个人博客的过程。不得不说,这种基于预置镜像的开发方式,简直是为我们这些初学者量身定制的福音。下面我就来分享一下这次的学习心得。 为什么选择预置镜…...
大多数人用AI还是“一次性聊天” Claude Cowork却让你把重复工作彻底扔上自动驾驶
花大价钱开了Claude Pro,每天扔进去一句“帮我写文案”“帮我优化内容”,结果用完就关窗口,下次还是从零开始?重复任务永远在偷走你的注意力,脑子里永远挂着“待办事项”这个隐形标签,效率看起来提升了&…...
SAP BAPI实战指南:核心模块高频接口速查与应用解析
1. SAP BAPI入门:为什么开发者需要这份速查手册 第一次接触SAP BAPI时,我盯着满屏的接口文档差点崩溃——光是FICO模块就有二十多个常用BAPI,每个接口的参数列表长得像毕业论文。后来在项目上踩过几次坑才明白,BAPI的难点不在于技…...
Phi-4-mini-reasoning作品集:自动将推理过程转化为教学级讲解语言
Phi-4-mini-reasoning作品集:自动将推理过程转化为教学级讲解语言 1. 模型简介 Phi-4-mini-reasoning是一个轻量级的开源文本生成模型,专注于将复杂推理过程转化为清晰易懂的教学语言。作为Phi-4模型家族的一员,它特别擅长处理需要逐步解释…...
