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

关于canvas的缩放和位移实战的一点点总结

关于canvas的缩放和位移,这里做一些总结。

变量定义

defuaultScale:canvas画布的精度,也是缩放的初始值

offsetX:x方向的偏移量

offsetY:y方向的偏移量

scale:画布缩放比例,默认值:defaultScale

realScale:真实缩放比例,默认值为1,公式为realScale = scale / defaultScale

centerX:缩放中心点x坐标

centerY:缩放中心点y坐标

lastX:记录最后移动canvas的点的x坐标

lastY:记录最后移动canvas的点的y坐标

lastD:记录两指间最后的距离

使用

初始化:

如果canvas处于隐藏状态将获取不到宽高

设置画布的精度,将影响画布的清晰程度。

canvas.width = canvas.offsetWidth * defaultScale;
canvas.height = canvas.offsetHeight * defaultScale;
context = canvas.getContext('2d'); 

通过context.save - context.restore来重置每次的位移和缩放属性,从而达到不影响其他数据的目的。

当保留缩放中心点时,真实偏移量需要将中心点考虑进来。

function draw(){context.save();clear(); // 清除上次的绘制// 真实偏移量const offsetX0 = offsetX - centerX + centerX / realScale;const offsetY0 = offsetY - centerY + centerY / realScale;context.scale(scale, scale);context.translate(offsetX0, offsetY0);drawOther(); // 绘制其他物体context.restore();drawDebug(); // 绘制debug面板
} 

缩放和位移的步长计算

开始触屏:

开始缩放时,中心点位置可能发生变化,需要补齐其偏差。

public handleTouchStart(e: TouchEvent) {const { clientX, clientY } = e.touches[0];// 记录起始点lastX = clientX;lastY = clientY; // 双指视为缩放 if (e.touches.length === 2) {// 记录两指间的距离lastD = Math.sqrt((clientX - e.touches[1].clientX) * (clientX - e.touches[1].clientX) +(clientY - e.touches[1].clientY) * (clientY - e.touches[1].clientY),); const _centerX = (clientX + e.touches[1].clientX) / 2;const _centerY = (clientY + e.touches[1].clientY) / 2;offsetX +=((1 - realScale) * (centerX - _centerX)) / realScale;offsetY +=((1 - realScale) * (centerY - _centerY)) / realScale;centerX = _centerX;centerY = _centerY; }
} 

触屏移动:

偏移步长 = 位移量 / 真实缩放

缩放步长 = 两指间距位移量 * 精度,(精度用于调节缩放幅度)

public handleTouchMove(e: TouchEvent) {const { clientX, clientY } = e.touches[0];if (e.touches.length === 1) {offsetX += (clientX - lastX) / realScale;offsetY += (clientY - lastY) / realScale;}else{const distance = Math.sqrt((clientX - e.touches[1].clientX) * (clientX - e.touches[1].clientX) +(clientY - e.touches[1].clientY) * (clientY - e.touches[1].clientY),);// 0.01为每次缩放的幅度,可以视情况进行调节const tmpScale = scale + (distance - lastD) * 0.01;if (tmpScale <= 0) { // 防止缩放造成物体反向return;}if (lastD) {scale = tmpScale;}// 保留最后两指间的距离lastD = distance;}// 保留最后移动的点lastX = clientX;lastY = clientY;
} 

坐标点映射

有时候点击canvas,需要将点击坐标映射到绘制的物体上,这里给出坐标的映射关系:

映射坐标 = 真实坐标 / 真实缩放值 - 真实偏移量

 public transorm(x: number,y: number,reverse = false,) {const offsetX0 = offsetX - centerX + centerX / realScale;const offsetY0 = offsetY - centerY + centerY / realScale;if (reverse) {// 逆映射return {x: (x + offsetX0) * realScale,y: (y + offsetY0) * realScale,};}return {x: x / realScale - offsetX0,y: y / realScale - offsetY0,};
} 

相关文章:

  • ros下配置机器人系统V1
  • 【云原生】设备入云之前端可视化编程
  • 【消息队列】RabbitMQ
  • Linux 【进程】
  • 1、读写分离、分库分表
  • 【正点原子STM32连载】 第三十二章 内部温度传感器实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
  • 05-接口和异常处理
  • 18-Linux系统服务
  • TiDB 集群故障诊断
  • 谷粒学苑_第五天
  • python实现SMB服务账号密码爆破功能 Metasploit 中的 smb_login
  • 【C基础篇】选择结构与循环控制
  • 一位程序员感慨:互联网行业太过共享,才导致了门槛越来越低
  • 【图像隐写】基于matlab遗传算法的奇异值分解数字水印嵌入提取【含Matlab源码 2115期】
  • 计算机视觉中的细节问题(二)
  • Android系统模拟器绘制实现概述
  • httpie使用详解
  • laravel 用artisan创建自己的模板
  • maven工程打包jar以及java jar命令的classpath使用
  • Objective-C 中关联引用的概念
  • React Native移动开发实战-3-实现页面间的数据传递
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • Redis学习笔记 - pipline(流水线、管道)
  • vue 个人积累(使用工具,组件)
  • vue.js框架原理浅析
  • vue中实现单选
  • 关于字符编码你应该知道的事情
  • 如何解决微信端直接跳WAP端
  • 设计模式 开闭原则
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • ​queue --- 一个同步的队列类​
  • # 安徽锐锋科技IDMS系统简介
  • #stm32整理(一)flash读写
  • #考研#计算机文化知识1(局域网及网络互联)
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (ros//EnvironmentVariables)ros环境变量
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (分类)KNN算法- 参数调优
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (接口封装)
  • (四)汇编语言——简单程序
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .Net+SQL Server企业应用性能优化笔记4——精确查找瓶颈
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • [100天算法】-实现 strStr()(day 52)
  • [20150904]exp slow.txt
  • [20170705]diff比较执行结果的内容.txt
  • [Android] 240204批量生成联系人,短信,通话记录的APK
  • [C# 网络编程系列]专题六:UDP编程
  • [dart学习]第四篇:函数
  • [I2C]I2C通信协议详解(二) --- I2C时序及规格指引