cocos creator 实现双指缩放的两种方式
01
效果演示
Cocos Creator 版本:3.4.1
该 demo 演示了双指缩放时通过更改节点的 scale 属性或者更改摄像机的 position 属性实现场景的缩放效果
02
实现方法
两种方式都各有利弊,可以根据使用场景选择合适的方案
1开启多点触控
在项目设置中开启多点触控
2缩放节点
节点的缩放属性随着双指间距的放大缩小进行等比的变化
基本概念:
双指初始间距:双指刚触碰屏幕时的间距
双指当前间距:双指移动时的间距
节点初始缩放:双指刚触碰屏幕时节点的缩放
节点当前缩放:双指移动时节点的缩放
等比关系:
双指当前间距 / 双指初始间距 = 节点当前缩放 / 节点初始缩放
公式变换:
节点当前缩放 = 节点初始缩放 * (双指当前间距 / 双指初始间距)
完整代码:
onTouchMove(event: EventTouch) {
let touches = event.getTouches();
if (touches.length >= 2) {
let temp = v2();
Vec2.subtract(temp, touches[0].getLocation(), touches[1].getLocation());
// 双指当前间距
let distance = temp.length();
if (this.originalTouchDistance == -1) {
// 双指初始间距
this.originalTouchDistance = distance;
// 节点初始缩放
this.originalNodeScale = this.nodeTarget.scale.clone();
}
let targetScale = v3();
// 双指当前间距 / 双指初始间距
let scale = distance / this.originalTouchDistance;
// 节点初始缩放 * (双指当前间距 / 双指初始间距)
Vec3.multiplyScalar(targetScale, this.originalNodeScale, scale);
scale = targetScale.x;
// 属于节点缩放比
scale = clamp(scale, this.minScale, this.maxScale);
this.nodeTarget.setScale(scale, scale, scale);
}
}
3移动摄像机
当双指进行缩放操作时,通过移动摄像机的位置,同样可以实现场景缩放的视觉效果
摄像机到原点的距离随着双指间距的放大缩小进行等比的变化
方法和节点缩放一样,只不过是将节点的缩放变为摄像机到原点的距离的缩放
基本概念:
双指初始间距:双指刚触碰屏幕时的间距
双指当前间距:双指移动时的间距
摄像机初始距离:双指刚触碰屏幕时摄像机到原点的距离
摄像机当前距离:双指移动时摄像机到原点的距离
等比关系:
双指当前间距 / 双指初始间距 = 摄像机当前距离 / 摄像机初始距离
公式变换:
摄像机当前距离 = 摄像机初始距离 * (双指当前间距 / 双指初始间距)
求出摄像机当前的距离后,还需要根据距离计算出摄像机的坐标
将场景放大缩小,实际只是将摄像机拉近拉远,并不会改变摄像机的角度
所以可以根据 ∠A,利用三角函数求出摄像机的坐标
利用反正切函数计算 ∠A,即摄像机与水平轴的夹角:
getAngle(a: Vec2, b: Vec2) {
let delta = v2();
Vec2.subtract(delta, a, b);
// http://c.biancheng.net/ref/atan2.html
// 反正切函数 atan2() 和正切函数 tan() 的功能恰好相反:
// tan() 是已知一个角的弧度值,求该角的正切值;而 atan2() 是已知一个角的正切值(也就是 y/x),求该角的弧度值
let degree = misc.radiansToDegrees(Math.atan2(delta.y, delta.x));
return degree;
}
利用正弦函数计算对边 a,即摄像机的 y 坐标:
let y = Math.sin(rad) * curCameraDistance;
利用余弦函数计算临边 b,即摄像机的 z 坐标:
let z = Math.cos(rad) * curCameraDistance;
完整代码:
onTouchMove(event: EventTouch) {
let touches = event.getTouches();
if (touches.length >= 2) {
let temp = v2();
Vec2.subtract(temp, touches[0].getLocation(), touches[1].getLocation());
// 双指当前间距
let distance = temp.length();
if (this.originalTouchDistance == -1) {
// 双指初始间距
this.originalTouchDistance = distance;
// 摄像机初始位置
this.originalCameraPosition = this.nodeCamera.position.clone();
// 摄像机初始距离
this.originalCameraDistance = this.originalCameraPosition.length();
}
let scale = this.originalTouchDistance / distance;
// 摄像机机当前距离
let curCameraDistance = this.originalCameraDistance * scale;
// 约束摄像机距离
curCameraDistance = clamp(curCameraDistance, this.minLength, this.maxLength);
// 降维 可以将 z 视作二维平面中的 x
temp = v2(this.originalCameraPosition.z, this.originalCameraPosition.y);
// 计算两点间的角度
let angle = this.getAngle(temp, Vec2.ZERO);
// 根据角度计算弧度
let rad = misc.degreesToRadians(angle);
// http://c.biancheng.net/ref/sin.html
// sinA = 对边 / 斜边 可得 对边 = sinA * 斜边
let y = Math.sin(rad) * curCameraDistance;
// http://c.biancheng.net/ref/cos.html
// cosA = 临边 / 斜边 可得 临边 = cosA * 对边
let z = Math.cos(rad) * curCameraDistance;
this.nodeCamera.position = v3(this.nodeCamera.position.x, y, z);
}
}
爱意随风起,风止意难平。
落日归山海,山海藏深意。
更多教程
请扫码关注
cocos creator 实现双指缩放的两种方式相关推荐
- 关于图片缩放的两种方式
2019独角兽企业重金招聘Python工程师标准>>> 缩放图片有两种手段 缩放ImageView Bitmap originalBitmap = Bitmap.decodeReso ...
- Unity3D两种方式播放视频
Unity3D中播放游戏视频的方式有两种,第一种是在游戏对象中播放,就好比在游戏世界中创建一个Plane面对象,摄像机直直的照射在这个面上.第二种是在GUI层面上播放视频.播放视频其实和贴图非常相 ...
- QtCreator与catkin命令两种方式开发ROS程序(图示加代码)
QtCreator与catkin命令两种方式开发ROS程序(图示加代码) 一.Qt Creator安装及开发ROS 1.安装Qt Creator 2.使用Qt Creator开发ROS 1.创建工作空 ...
- Unity3D教程:播放视频的两种方式
Unity3D中播放游戏视频的方式有两种,第一种是在游戏对象中播放,就好比在游戏世界中创建一个Plane面对象,摄像机直直的照射在这个面上.第二种是在GUI层面上播放视频.播放视频其实和贴图非常相像, ...
- 0324的学习笔记----里面最重要的就是一个tom猫的动画,和涉及到的内存问题(创建imageview的两种方式,imagenamed就会形成缓存,占用很多内
还是可以自己对着视频,或者自己有空的时候在做一遍,把按钮做全面的,比较有意思. 看视频的时间是:2015.11.2日上午. 0324: 01-作业-QQ登陆界面 (1) 键盘的退出:[self.vie ...
- Unity3D研究院之两种方式播放游戏视频
今天突然想起之前做过的一个AR项目,更换识别图播放不同的视频.就想了解一下unity3d支持哪些音视频格式,就看到了雨凇大大这篇文章,总结得很详细,我就不上我的代码献丑了,把雨松大大的博客分享给大家吧 ...
- putextra 传递对象_intent.putextra用法 使用Intent传递对象的两种方式 - 电脑常识 - 服务器之家...
intent.putextra用法 使用Intent传递对象的两种方式 发布时间:2017-05-22 来源:服务器之家 Intent 的用法相信你已经比较熟悉了,我们可以借助它来启动活动.发送广播. ...
- MySQL 清空表数据的两种方式和区别
在MySQL中删除数据有两种方式:truncate table 表名.delete from 表名. 它们在以下方面存在区别: 执行效率 truncate不扫描表,相当于重新创建了表,只保留了表的结构 ...
- 继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错? springboot 两种方式稳定解决跨域问题
继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错???springboot 两种方式稳定解决跨域问题! 之前我写了一篇文章,来解决CORS报错 ...
最新文章
- Coolite 中GridView点击行中的按钮时跳转至不同的页面
- R语言ggplot2可视化在可视化图像中添加上限线条、下限线条、添加上下限图例实战
- php中this,self,parent三个关键字之间的区别(转载)
- ITK:线性强度变换
- 阿里云峰会 | 统一召回引擎在搜索场景的应用实践
- 【译】将IDataRecord自动填充到实体的扩展方法
- C - Mr. Panda and Strips Gym - 101194C(思维//尺取//2016 icpc china final)
- DIY Ruby CPU 分析 Part II
- 亚信安全发布2021年挖矿病毒专题报告,聚焦挖矿病毒进化与治理
- Bug提交规范及注意事项
- SAP License:SAP行业近期走向
- .NET 2.0中的企业库异常处理块
- Chrome 大版本更新来了,这是一次「史诗级」增强
- Python 查询 MAC 地址相关信息
- python 流水作业调度,流水作业调度完整代码
- 每天可以一看的哲理句子
- Tether操纵市场了吗?
- jenkins升级报错An attempt to save the global configuration was made before it was loaded
- 百度系统服务器地址,百度公共DNS地址是多少?百度DNS设置方法(windows、lunix、mac)...
- web前端课程设计——动漫网页2个网页HTML+CSS web前端开发技术 web课程设计 网页规划与设计
热门文章
- Apollo源码剖析学习笔记2
- 【SG函数板子】hdu1848
- linux查看目录磁盘限额,CentOS Linux磁盘限额设置
- c++常用函数对应的头文件
- E影安全智能浏览器之界面
- IC_EDA_ALL虚拟机(丰富版):questasim、vivado、vcs、verdi、dc、pt、spyglass、icc2、synplify、INCISIVE、IC617、MMSIM、工艺库
- 【华为OD机试真题2023B卷 JAVAJS】评论转换输出
- Android request asp.net web API by Cooki
- Sequential Minimal Optimization: A Fast Algorithm for Training Support Vector Machines 论文研读
- 深度网络模型压缩 - CNN Compression