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. springboot 整合mybatis,pagehelper。测试类。

    报名立减200元.暑假直降6888. 遇到的异常. 1.这是在使用mybatis成功连接数据库后,通过service层调用dao层出现的异常. 异常原因:在启动类上面的注解@MapperScan没有指 ...

  2. js的事件冒泡机制

    js的事件冒泡机制呢,就是一个DOM树,一级一级向上冒的过程,最终是到document这个根节点这里.js的事件冒泡机制,就像是一个水泡在水底下,冒泡到水面的过程. 摘自醉清玄

  3. 个人永久性免费-Excel催化剂功能第60波-数据有效性验证增强版,补足Excel天生不足

    Excel在数据处理.数据分析上已经是公认的最好用的软件之一,其易用性和强大性也吸引无数的初中高级用户每天都在使用Excel.但这些优点的同时,也带出了一些问题,正因为其不同于一般的专业软件,需要专业 ...

  4. android实现倒计时,最简单实现RecyclerView倒计时+SwipeRefreshLayout下拉刷新

    先上效果图: RecyclerView + SwipeRefreshLayout 实现倒计时效果 MainActivity.java package top.wintp.counttimedemo1; ...

  5. LiteDB源码解析系列(1)LiteDB介绍

    最近利用端午假期,我把LiteDB的源码仔细的阅读了一遍,酣畅淋漓,确实收获了不少.后面将编写一系列关于LteDB的文章分享给大家,希望这么好的源码不要被埋没. 1.LiteDB是什么 这是一个小型的 ...

  6. sqlserver2014创建数据库时,错误提示如下:尝试打开或创建物理‘c:\数据库\db.mdf’时,Create File遇到操作系统错误5(拒绝访问)

    CREATE DATABASE test1   ON  PRIMARY ( NAME =test1, FILENAME='C:\Program Files\test1.mdf',SIZE=10240K ...

  7. java - try catch finally 用法

    try { //执行的代码,其中可能有异常.一旦发现异常,则立即跳到catch执行.否则不会执行catch里面的内容 } catch { //除非try里面执行代码发生了异常,否则这里的代码不会执行 ...

  8. 用maven工具管理web项目的错误记录:org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException

    运行异常报告日志: 严重: Context initialization failedorg.springframework.beans.factory.xml.XmlBeanDefinitionSt ...

  9. Git学习(二):Git的初步使用

    一.Git的最小配置 1.使用如下命令创建Git的用户名和邮箱,如下所示: $git config --global user.name 'your_name' $git config --globa ...

  10. 2048 控制台版(C#)

    开篇 2048游戏现在很火啊,很多人应该已经玩过了.在博客园上也看见有人模仿做的GDI+版 2048游戏,鄙人暂且不做那么多动画的东西,毕竟是个小东东,在此奉上一个<控制台版2048>. ...