百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

canvas基础及图片缩放的实现 canvas缩放后拖动

liuian 2024-12-18 15:37 71 浏览

基础部分

坐标系

画布坐标、屏幕坐标的概念

    • 屏幕坐标,绝对坐标,类似于css中的绝对定位
    • 画布坐标,类似于css中的相对定位,还要考虑缩放

几何变换:平移、缩放、旋转

    • 平移,位置移动,形状、相对位置不变
    • 缩放,位置(相对屏幕坐标)和大小都发生变化
    • 旋转,位置旋转,形状、相对位置不变

Canvas 中的所有几何变换针对的不是绘制的图形,而是针对画布本身,也就是说,当移动、缩放、旋转画布之后,新的坐标系只对新的操作生效

参考:

  • Canvas 几何变换 - Canvas 基础教程 - 简单教程,简单编程
    • Canvas 平移 translate() - Canvas 基础教程 - 简单教程,简单编程
    • Canvas 缩放 scale() - Canvas 基础教程 - 简单教程,简单编程
    • Canvas 旋转 rotate() - Canvas 基础教程 - 简单教程,简单编程

绘图步骤

基础绘图三步法

  1. 获取canvas对象
  2. 获取上下文环境对象context
  3. 开始绘制图形。

示例代码

const canvas = document.getElementById("canvas");
const context = convas.getContext("2d");
context.fillRect(100, 100, 50, 50);

通用绘图步骤

  1. 保存画布(状态),context.save();
  2. 画布操作,context.transform(叠加) 或者 context.setTransform(不叠加)
  3. 设置样式,绘制图形
  4. 恢复画布(状态),context.restore();

图形变换基本操作

  1. 清空画布,context.clearRect
  2. 保存状态,context.save
  3. 画布操作,doTransform
  4. getShapeList and forEach
  5. 恢复状态,context.restore


Canvas性能

Canvas的绘制和html的绘制是不一样的,html的绘制是增量的,当变化时,只会重新绘制变化的部分,没有变化的部分是不会重新绘制的,但是canvas不一样,每次都是全量绘制的,如果一个canvas里有很多图形,当改变一个图形时,需要重新绘制所有图形才可以(当然,可以用clearRect擦除部分区域,但一般很少这么用)。

了解canvas的绘制规则之后,就很容易发现性能问题,如果canvas上绘制了大量的图形(成千上万个),每次重绘就需要很长的时间,如果重绘的频率很高,那么就会有性能问题



那么如何解决这个问题呢,目前有以下几种方案

  1. 使用图层
  2. 使用临时图层
  3. 使用webworker或wasm
  4. 使用webgl

使用图层

图层的概念来自于PS,每一个图层都是一个canvas,既然在一个canvas上绘制太多图形会有性能问题,那么就分几个图层,每次仅重新绘制其中一个图层,每个图层的图形都不会很多,那么即使重绘的频率很高,也不会有性能问题。图层的概念图如下:

代码实现

用一个父元素作为容器,把所有的元素设置成一样的宽高并放在里面重叠。

<div class="container">
    <canvas width="500" height="500"></canvas>
    <canvas width="500" height="500"></canvas>
    <canvas width="500" height="500"></canvas>
    <canvas width="500" height="500"></canvas>
    <canvas width="500" height="500"></canvas>
</div>


使用临时图层

绘制是很耗性能的,如果每次都清空画布然后重新画一次,那么性能会消耗很大(即使分了几个图层),我们应区分“变”与“不变”的部分,只对“变”的部分重新渲染,“不变”的部分不渲染,将经常变化的部分抽离到临时图层,这样仅需要渲染临时图层,临时图层有几种实现思路,一种是使用操作图层(俗称高性能图层),一种是使用隐藏图层(不绘制到界面上的)


高性能图层

一般高频(实时响应鼠标、键盘等事件)的操作会放在高性能图层,等操作完成之后,再将最终结果保存到其它图层,比如绘制、拖拽、缩放一个(或一批)shape

隐藏图层

有些图层是不用给用户看的,这些canvas仅存在于内存中,不会插入html的dom中,用完就销毁,比如常见的canvas to image。

还有一种实现方式是离屏渲染(OffscreenCanvas),先在一个offCanvas操作,然后再将结果渲染到界面上(有点像虚拟dom操作),一般会结合webworker或webassembly


const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
// 绘制图片,或其它操作
context.drawImage();
// 转成base64图片
convas.toDataUrl();

使用webworker或wasm

影响canvas性能的除了绘制频率,还有一个重要的是像素点操作,一般图像处理会涉及到大量的像素点操作,如果放在主线程计算,那么会卡住其它操作,造成页面卡顿,特别影响用户体验,这些涉及大量计算的一般会单独开个线程来操作,而在浏览器中有这个能力的就只有webworker了。


有了webworker可能还不够,因为始终是在js上执行,js执行效率天生就比其它语言慢,所以一般的会使用webassembly,执行效率比js快很多,而且还能用到更丰富的图像处理库

使用webgl

如果还有更高的性能要求,那么普通的2d canvas可能就无法满足了,这个时候可以使用webgl,性能更高(当然学习成本也更高),再结合wasm,就可以有无限想象力了,鼎鼎大名的figma就是用webgl + wasm(rust)实现的,另外google doc在线文档也使用了webgl,飞书文档将来也会替换成wegbl,基于浏览器的渲染始终有诸多限制,一般有能力的都会实现自己的渲染引擎。

业务中图片缩放的实现设计

假设canvas大小为(867,350)

图片的大小为(768,576)

将上面这张图片放到canvas中,图片贴边处理,也即图片太大就缩小,图片太小就放大。那么我们如何实现这种效果呢?


总结一下,总共分为几步:

  1. 计算画布大小和图片大小
  2. 计算如果将图片以原图大小放入画布中心,左上角的坐标
  3. 将画布坐标移动到图片中心点
  4. 将画布放大或缩小(scale=Math.min(画布宽度/图片宽度,画布高度/图片高度))
  5. 重新移动画布坐标到左上角
  6. 绘制图片(或图形)

canvas的执行细节如下:

相关推荐

如何修改文件(如何修改文件创建时间)

工具/原料电脑windows系统方法/步骤1、新建一个文档文件。2、在文件名后面输入“.exe”按下enter键。3、文件的名字改变了,但格式没变。4、点击“菜单”点击“工具”,点击“文件夹选项...

win7剪贴板怎么调出来(windows7的剪贴板在哪里)

要开启Win7剪贴板,首先需要打开“运行”窗口,方法是按下“Win+R”快捷键。在弹出的窗口中输入“clipbrd”并点击“确定”按钮。这样就会打开剪贴板窗口。在窗口中可以看到最近复制或剪切的内容。如...

cmd一键清除垃圾命令chkdsk(cmd一键清理)

这个就是自检命令,在一些轻微的文件损坏可以用这个命令回复楼主你打的/F是修复磁盘上的错误意思/R是查找不正确的扇区并恢复可读信息。chkdsk的全称是checkdisk,就是磁盘检查的意思。这个东...

无备份彻底删除照片找回(苹果手机无备份彻底删除照片找回)

如果您的手机照片没有备份,但是误删了照片,可以尝试以下几个方法恢复:1.使用Android手机自带的垃圾桶功能:如果您使用的是安卓手机,最新版的Android系统中提供了“回收站”功能。您可以在相册...

qq怎么改实名认证(qq怎么改实名认证吗)

要先将原来的实名认证注销掉,才可修改QQ的实名认证,具体方法如下,打开手机【QQ】,点击左上角的【头像】,然后选择【我的QQ钱包】,点击右上角的【设置】,在设置界面选择【实名认证】,进入到实名认证界面...

win10启用网络发现自动关闭(win10启用网络发现自动关闭了)

因为在Win10系统中,网络发现是一个网络共享和连接的设置选项,如果关闭了网络发现,那么其他计算机就无法找到你的计算机并进行资源共享,这样能够提高安全性。同时关闭网络发现能够减少广播包,降低网络负载,...

看图软件cad手机版下载(看图软件cad手机版下载安装)

你可以在应用商店或者CAD官方网站上搜索"CAD快速识图"并下载安装。在下载前,建议先确认你的手机是否兼容这个应用程序,以及查看是否有最新版本可供下载。下载完成后,打开应用并按照提示完...

台式电脑连接无线网卡(台式电脑连接无线网卡吗)
  • 台式电脑连接无线网卡(台式电脑连接无线网卡吗)
  • 台式电脑连接无线网卡(台式电脑连接无线网卡吗)
  • 台式电脑连接无线网卡(台式电脑连接无线网卡吗)
  • 台式电脑连接无线网卡(台式电脑连接无线网卡吗)
怎么进入tp link无线路由器设置
怎么进入tp link无线路由器设置

tp-link路由器的设置登录入口进入方法如下1.打开tplogin.cn页面,点击右上角的“登录”菜单。2.输入用户名和密码,点击登录按钮,进入登录页面。3.如果你忘记了用户名或密码,可点击忘记密码,并输入注册邮箱或者手机号,点击确认,系...

2025-12-31 08:05 liuian

电脑莫名重启怎么回事(电脑莫名奇妙的重启)

电源的大电容漏电,供电不足造成的,这个就要更换电源2、主板上的内存插槽和内存之间接触不良出现问题,或者内存的显存集成块出现虚焊也会出现老是重启3、CPU风扇出问题,或者散热器的卡子松了。当CPU的风扇...

如何一键还原电脑系统win7(一键还原win7系统按那个键)

方法如下:  1、下载“一键GHOST硬盘版”用压缩工具软件解压,解压后选“setup.exe”文件,即自动把一键还原安装到硬盘中。安装完成后,在桌面和开始菜单将建立程序的快捷方式:  Win7系统...

笔记本键盘无法使用(dell笔记本电脑键盘失灵一键修复)

个别键因为脏了接触不好或者是弹簧失去了弹性,可以自行打开键盘,用无水酒精清洗一下键盘内部。修改笔记本键盘的驱动:通过“我的电脑”打开系统属性,选择硬件标签,打开设备管理器,我们发现中文Windows...

u启宝装机工具(u启宝装系统)

1、将下载好的ghostwin7系统镜像文件拷贝到u盘内,重启电脑,在看到开机画面时按下相应的启动快捷键(大家可以到u启动官网查找相应的快捷键)即可进入u启动的主菜单界面,随后选择usb选项并按回车...

找回wifi密码的方法(找回wifi密码怎么找)

1、在已经连接WiFi的手机上操作:在手机桌面找到设定,进入到手机设置页面。2、在设置中,找到WLAN也就是无线局域网,点击进入无线网络的查看或配置页面。3、进入到WLAN页面后,我们会看见周围的Wi...

电脑软件下载网址(电脑软件下载网址排行)
  • 电脑软件下载网址(电脑软件下载网址排行)
  • 电脑软件下载网址(电脑软件下载网址排行)
  • 电脑软件下载网址(电脑软件下载网址排行)
  • 电脑软件下载网址(电脑软件下载网址排行)