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 中缩放的实现的更多相关文章

  1. 二、Laya学习笔记 ---- Laya中如何新建一个场景UI并使用

    因为我之前是用Egret的,Egret是场景皮肤HomeSceneSkin.exml,然后在场景代码HomeScene代码中为该场景赋值皮肤this.skinName = "HomeScen ...

  2. Halcon中缩放Region或XLD的方法研究

    在Halcon中,Region和XLD之间可以彼此转换.但这种转换并不是“无损”的,XLD可以是不闭合的,但是Region一定是闭合的.因此,如果将不闭合的XLD转为Region,然后再转回XLD,那 ...

  3. Laya中的Image、Texture、WebGLImage

    Image Image是Laya的一个UI组件,继承自Component. Image.bitmap属性,是AutoBitmap类型:AutoBitmap继承自Graphics,负责处理图片九宫格逻辑 ...

  4. Laya中地图拼接的缝隙问题

    拼图的空隙. Egret也有拼图的空隙.比如制作飞机游戏,背景拼接轮换着下移,有明显的缝隙.用TextureMerger可以解决. 看了下Laya.可以设置repeat. 编辑模式,图片上右键,设置默 ...

  5. Css中光标,DHTML,缩放的使用

    Css中光标的使用: 属性名称                属性值                                         说明cursor                 ...

  6. BITED-Windows8应用开发学习札记之四:如何在Win8 应用中实现语义缩放

    语意缩放的意义在于:创新的语意缩放外观,让你的应用随时展现信息可视化的力量.如图表般的Tile,随着数据的不同而变化,让你的页面更富节奏.而所谓的语意缩放就是通过上下文的跳转,帮助我们实现一种更快更便 ...

  7. Winform中设置ZedGraph鼠标滚轮缩放的灵敏度以及设置滚轮缩放的方式(鼠标焦点为中心还是图形中心点)

    场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  8. CSS 中Font Awesome 图标(附码表)

    HTML中缩放的矢量图标,您可以使用CSS所提供的所有特性对它们进行更改,包括:大小.颜色.阴影或者其它任何支持的效果. Font Awesome 传送门:http://fontawesome.das ...

  9. CSS实现背景图尺寸不随浏览器缩放而变化

    方法一. 把图片作为background,方法二使用img标签.同时要有一张足够大尺寸的图片. 方法一. 把图片作为background 有几个CSS的属性要提一下:background-size:c ...

随机推荐

  1. restapi(1)- 文件上传下载服务

    上次对restapi开了个头,设计了一个包括了身份验证和使用权限的restful服务开发框架.这是一个通用框架,开发人员只要直接往里面加新功能就行了.虽然这次的restapi是围绕着数据库表的CRUD ...

  2. 简单的量子算法(一):Hadamard 变换、Parity Problem

    Hadamard Transform Hadamard 变换在量子逻辑门中提过,只不过那时是单量子的Hadamard门,负责把\(|1\rangle\)变成\(|-\rangle\),\(|0\ran ...

  3. 「PowerBI」Tabular Editor 一个对中文世界很严重的bug即将修复完成

    之前介绍过Tabular Editor这款开源工具,对PowerBI建模来说,非常好用,可以极大的增强自动化水平. 详细可查看此文章: 「PowerBI相关」一款极其优秀的DAX建模工具Tabular ...

  4. classpath和classpath*区别

    classpath和classpath*区别: classpath:只会到你的class路径中查找找文件. classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找. ...

  5. Chrome离线安装包+谷歌访问助手

    Chrome离线安装包+谷歌访问助手 所有chrome版本离线安装包下载地址 谷歌访问助手v2.3.0.crx(需要修改主页) 谷歌上网助手v1.4.3.crx(不用修改主页,需要注册) 两个插件为2 ...

  6. vue教程(二)--过滤器和监视改动功能

    过滤器filter: 1.将数据进行添油加醋的操作. 2.过滤器分两种: 组件内的过滤器(组件内有效). 全局过滤器 组件内:filters:{过滤器名:过滤器函数fn},fn内通过return 返回 ...

  7. BFS vs DFS

    1 Clone Graph   1  copy ervery nodes by bfs  2  add neighbors public UndirectedGraphNode cloneGraph( ...

  8. Selenium+java - 弹出框处理

    一.弹出框分类: 弹出框分为两种,一种基于原生JavaScript写出来的弹窗,另一种是自定义封装好的样式的弹出框,本文重点介绍原生JavaScript写出来的弹窗,另一种弹窗用click()基本就能 ...

  9. 面试必谈的哈希,.Net 程序员温故而知新

    引言: 作为资深老鸟,有事没事,出去面试:找准差距.定位价值. 面试必谈哈希, Q1:什么是哈希? Q2:哈希为什么快? Q3:你是怎么理解哈希算法利用空间换取时间的? Q4:你是怎么解决哈希冲突的? ...

  10. ASP.NET Core MVC 之局部视图(Partial Views)

    1.什么是局部视图 局部视图是在其他视图中呈现的视图.通过执行局部视图生成的HTML输出呈现在调用视图中.与视图一样,局部视图使用 .cshtml 文件扩展名.当希望在不同视图之间共享网页的可重用部分 ...