Laya 中缩放的实现
Laya 缩放功能的实现
在 laya 中实现滚轮对选中对象的缩放,涉及到以下两个模块:
- 事件
- 容器坐标
1. 事件
在 Laya 中, Event 是事件类型的集合。包含了常见的鼠标事件、键盘事件。
- 1.1 事件的触发
触发一个事件,需要设置一个事件接收区域.
如若未明确指定事件,事件触发默认是冒泡模式。从子节点开始依次向父节点查询,直到找到绑定了指定事件的容器后结束。
在对容器进行绑定时有下面两种方式:
方法一:根据事件对象获取(不推荐使用)
mySprit.on(Laya.Event.MouseDOwn, this, this.Scale);
public Scale(e: Event)
{
// 此种形式获取 sp, 并未明确指定绑定事件的 sp,触发事件时,需冒泡查找, 不推荐使用
let sp = e.target as Laya.Sprite;
}
方法二: 直接传入目标容器
mySprit.on(Laya.Event.MouseDOwn, this, this.Scale, [targetSp]);
public Scale(sp, e: Event)
{
// 直接用传入的 sp 进行绑定
}
- 1.2 事件的绑定与解绑
只有在需要时候事件时,才绑定事件方法。用完后,需要解除绑定。这样可以避免同一个对象多次绑定的问题,
在 laya 中,事件管理器是允许同一个对象的同一个方法事件进行多次绑定的,这样容易造成许多意向不到的 bug, 所以务必
只在使用时进行绑定,用完立马解除绑定。注意,如鼠标移动事件、MouseUp 事件一般使用 Stage 来触发。
如下例:
// 下面的代码为按下鼠标左键,允许拖动目标容器,松开鼠标左键后,无法拖动目标容器
this.firstSp = new Laya.Sprite();
this.firstSp.graphics.drawRect(0, 0, 100, 100, null, "#ffffff"); // 绘制图形
this.firstSp.on(Laya.Event.MOUSE_DOWN, this, this.MouseDown, [this.firstSp]); // 绑定 mouse_down 事件
this.firstSp.hitArea = this.firstSp.getGraphicBounds(); // 指定可触发事件区域
this._rootSp.addChild(this.firstSp);
Laya.stage.addChild(this._rootSp);
// 在 mouse_down 事件后才绑定事件
private MouseDown(sp:Laya.Sprite, e:Laya.Event)
{
Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.MouseMove, [sp])
Laya.stage.on(Laya.Event.MOUSE_UP, this, this.MouseUp, [sp])
}
private MouseMove(sp:Laya.Sprite, e:Laya.Event)
{
sp.x += 5;
}
// 在 mouseup 事件后解除除了触发事件外的其他一切事件
private MouseUp(sp:Laya.Sprite, e:Laya.Event)
{
Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.MouseMove)
Laya.stage.off(Laya.Event.MOUSE_UP, this, this.MouseUp)
}
- 1.3 可点击区域的设置
容器要触发交互事件,必须设置可点击区域
// 将绘图区域设置为 点击区域
this.firstSp.hitArea = this.firstSp.getGraphicBounds(); // 指定可触发事件区域
// 用数值设定点击区域
this.firstSp.hitArea = new Laya.Rectangle(0, 0, 10000, 10000)
容器坐标
laya 2d 坐标系坐标单位为像素, Stage 左上角为左边原点 (0,0)。向右为 x 轴正向,向下为 Y 轴正向。所有容器创建时坐标原点默认为 (0,0), 此处需要注意:
所有容器的原点坐标都是相对于其父容器原点的坐标,是局部坐标,而非全局坐标。
因此,对象在容器中的坐标为局部坐标,转换为全局需要逐层向父容器变换,知道跟容器 Stage 为止。 同时要注意:
在移动、缩放对象时不要改变对象坐标,改变容器坐标,实现对象的改变。
// 对容器对象进行缩放
///-------------- Scale Drawing Sprite --------------------------
public static MouseWheel(currentSp: Laya.Sprite, e: Laya.Event) {
let spriteX = 0, spriteY = 0;
if(currentSp.parent) // 考虑了父容器的偏差, TODO: 父容器与 stage 有偏差
{
spriteX = (currentSp.parent as Laya.Sprite).x
spriteY = (currentSp.parent as Laya.Sprite).y;
}
this.Zoom(currentSp, e.stageX - spriteX, e.stageY - spriteY, e.delta);
}
private static Zoom(sp: Laya.Sprite, x: number, y: number, delta: number) {
let oldScale = sp.scaleX;
let scale = delta > 0 ? WebCad.GlobalScaleRatio : 1 / WebCad.GlobalScaleRatio;
let newScale = sp.scaleX * scale;
// 设置最大最小缩放范围
newScale = newScale < 0.1 ? 0.1 : (newScale > 50 ? 50 : newScale);
// 获取在缩放比例下,光标相对偏移位置
sp.x = sp.x - (x - sp.x) * (newScale - oldScale) / oldScale;
sp.y = sp.y - (y - sp.y) * (newScale - oldScale) / oldScale;
sp.scale(newScale, newScale);
}
当有多个操作的时候,比如需要对象同时涉及到缩放,平移以及旋转时候,我们应当遵循下面这个原则:
先处理缩放,再旋转,然后平移。
这里涉及到一个矩阵组合运算的原则:
**矩阵的组合
矩阵的乘法运算不遵守交换律,这意味着它们的顺序很重要。当矩阵相乘时,在最右边的矩阵是第一个与向量相乘的,所以我们应当从右向左来读这个乘法。所以在组合时,先缩放操作,然后旋转,最后才是位移,否则它们会互相影响。比如,你先位移再缩放,位移的向量也会同样缩放。
Laya 中缩放的实现的更多相关文章
- 二、Laya学习笔记 ---- Laya中如何新建一个场景UI并使用
因为我之前是用Egret的,Egret是场景皮肤HomeSceneSkin.exml,然后在场景代码HomeScene代码中为该场景赋值皮肤this.skinName = "HomeScen ...
- Halcon中缩放Region或XLD的方法研究
在Halcon中,Region和XLD之间可以彼此转换.但这种转换并不是“无损”的,XLD可以是不闭合的,但是Region一定是闭合的.因此,如果将不闭合的XLD转为Region,然后再转回XLD,那 ...
- Laya中的Image、Texture、WebGLImage
Image Image是Laya的一个UI组件,继承自Component. Image.bitmap属性,是AutoBitmap类型:AutoBitmap继承自Graphics,负责处理图片九宫格逻辑 ...
- Laya中地图拼接的缝隙问题
拼图的空隙. Egret也有拼图的空隙.比如制作飞机游戏,背景拼接轮换着下移,有明显的缝隙.用TextureMerger可以解决. 看了下Laya.可以设置repeat. 编辑模式,图片上右键,设置默 ...
- Css中光标,DHTML,缩放的使用
Css中光标的使用: 属性名称 属性值 说明cursor ...
- BITED-Windows8应用开发学习札记之四:如何在Win8 应用中实现语义缩放
语意缩放的意义在于:创新的语意缩放外观,让你的应用随时展现信息可视化的力量.如图表般的Tile,随着数据的不同而变化,让你的页面更富节奏.而所谓的语意缩放就是通过上下文的跳转,帮助我们实现一种更快更便 ...
- Winform中设置ZedGraph鼠标滚轮缩放的灵敏度以及设置滚轮缩放的方式(鼠标焦点为中心还是图形中心点)
场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...
- CSS 中Font Awesome 图标(附码表)
HTML中缩放的矢量图标,您可以使用CSS所提供的所有特性对它们进行更改,包括:大小.颜色.阴影或者其它任何支持的效果. Font Awesome 传送门:http://fontawesome.das ...
- CSS实现背景图尺寸不随浏览器缩放而变化
方法一. 把图片作为background,方法二使用img标签.同时要有一张足够大尺寸的图片. 方法一. 把图片作为background 有几个CSS的属性要提一下:background-size:c ...
随机推荐
- restapi(1)- 文件上传下载服务
上次对restapi开了个头,设计了一个包括了身份验证和使用权限的restful服务开发框架.这是一个通用框架,开发人员只要直接往里面加新功能就行了.虽然这次的restapi是围绕着数据库表的CRUD ...
- 简单的量子算法(一):Hadamard 变换、Parity Problem
Hadamard Transform Hadamard 变换在量子逻辑门中提过,只不过那时是单量子的Hadamard门,负责把\(|1\rangle\)变成\(|-\rangle\),\(|0\ran ...
- 「PowerBI」Tabular Editor 一个对中文世界很严重的bug即将修复完成
之前介绍过Tabular Editor这款开源工具,对PowerBI建模来说,非常好用,可以极大的增强自动化水平. 详细可查看此文章: 「PowerBI相关」一款极其优秀的DAX建模工具Tabular ...
- classpath和classpath*区别
classpath和classpath*区别: classpath:只会到你的class路径中查找找文件. classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找. ...
- Chrome离线安装包+谷歌访问助手
Chrome离线安装包+谷歌访问助手 所有chrome版本离线安装包下载地址 谷歌访问助手v2.3.0.crx(需要修改主页) 谷歌上网助手v1.4.3.crx(不用修改主页,需要注册) 两个插件为2 ...
- vue教程(二)--过滤器和监视改动功能
过滤器filter: 1.将数据进行添油加醋的操作. 2.过滤器分两种: 组件内的过滤器(组件内有效). 全局过滤器 组件内:filters:{过滤器名:过滤器函数fn},fn内通过return 返回 ...
- BFS vs DFS
1 Clone Graph 1 copy ervery nodes by bfs 2 add neighbors public UndirectedGraphNode cloneGraph( ...
- Selenium+java - 弹出框处理
一.弹出框分类: 弹出框分为两种,一种基于原生JavaScript写出来的弹窗,另一种是自定义封装好的样式的弹出框,本文重点介绍原生JavaScript写出来的弹窗,另一种弹窗用click()基本就能 ...
- 面试必谈的哈希,.Net 程序员温故而知新
引言: 作为资深老鸟,有事没事,出去面试:找准差距.定位价值. 面试必谈哈希, Q1:什么是哈希? Q2:哈希为什么快? Q3:你是怎么理解哈希算法利用空间换取时间的? Q4:你是怎么解决哈希冲突的? ...
- ASP.NET Core MVC 之局部视图(Partial Views)
1.什么是局部视图 局部视图是在其他视图中呈现的视图.通过执行局部视图生成的HTML输出呈现在调用视图中.与视图一样,局部视图使用 .cshtml 文件扩展名.当希望在不同视图之间共享网页的可重用部分 ...