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(开放最短路径优…...
保姆级万物识别教程:阿里开源镜像快速部署,识别图片超简单
保姆级万物识别教程:阿里开源镜像快速部署,识别图片超简单 1. 开篇:为什么选择这个镜像? 今天给大家介绍一个特别实用的AI工具——阿里开源的"万物识别-中文-通用领域"镜像。这个镜像最大的特点就是简单易用ÿ…...
别再手写表单了!用Vue3+AI做个自己的低代码设计器,5分钟搞定一个页面
用Vue3AI打造个人专属低代码表单设计器:5分钟解放重复劳动 如果你是一名中后台开发者,每天被各种CRUD表单折磨得焦头烂额,这篇文章就是为你准备的。想象一下:当你接到第100个类似的用户管理表单需求时,不再需要从零开始…...
Nuxt3 + PM2 + Nginx:打造高可用前端部署方案(附常见问题排查指南)
Nuxt3 PM2 Nginx:打造高可用前端部署方案(附常见问题排查指南) 在当今快速迭代的Web开发领域,Nuxt3凭借其出色的服务端渲染能力和现代化的开发体验,正成为越来越多技术团队的首选框架。然而,将Nuxt3应用部…...
**发散创新:基于微应用架构的轻量级权限控制实战设计**在现代前端开
发散创新:基于微应用架构的轻量级权限控制实战设计 在现代前端开发中,**微应用(Micro Frontend)*8 已成为构建复杂单页应用(SPA)的标准方案之一。它允许团队独立开发、部署和维护各自的功能模块,…...
WAN2.2文生视频开源镜像快速上手:ComfyUI界面操作+SDXL Prompt Styler详解
WAN2.2文生视频开源镜像快速上手:ComfyUI界面操作SDXL Prompt Styler详解 想试试用几句话就让AI帮你生成一段视频吗?WAN2.2文生视频开源镜像,结合了强大的ComfyUI界面和SDXL Prompt Styler风格化工具,让这个过程变得直观又简单。…...
TCC性能瓶颈到底卡在哪?:用Arthas+Metrics精准定位4大隐性耗时源并实测压降67%
第一章:TCC性能瓶颈到底卡在哪? TCC(Try-Confirm-Cancel)模式虽能保障分布式事务的强一致性,但其性能损耗远高于本地事务——根本原因并非网络延迟本身,而是其固有的三阶段协同机制与资源生命周期管理带来的…...
华为交换机等保2.0实战:手把手配置身份鉴别,从密码策略到登录超时
华为交换机等保2.0身份鉴别全流程配置指南 当企业网络面临等保2.0合规检查时,身份鉴别环节往往是整改重点。作为网络安全工程师,我曾协助多家企业通过等保测评,发现华为交换机的身份鉴别配置存在不少易忽略的细节。本文将分享一套经过实战验证…...
【Java 21记录模式性能优化终极指南】:3个被90%开发者忽略的模式匹配陷阱及提速300%的实战方案
第一章:Java 21记录模式性能优化全景概览Java 21 引入的记录模式(Record Patterns)不仅提升了模式匹配的表达力,更在JVM层面实现了多项关键性能优化。通过与模式匹配(Pattern Matching for instanceof)和解…...
如何将微信聊天记忆转化为数字珍藏:WeChatMsg的数据主权革命
如何将微信聊天记忆转化为数字珍藏:WeChatMsg的数据主权革命 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we…...
别再手动敲命令了!用PyCharm自带功能一键创建Linux桌面快捷方式(附手动配置备份方案)
告别终端:PyCharm内置工具3秒生成Linux桌面快捷方式(附应急手动方案) 每次打开PyCharm都要在终端输入一长串路径?作为开发者,我们的时间应该花在创造价值上,而不是重复输入命令。JetBrains早就为Linux用户准…...
