pixi.js容器的toLocal与toGlobal的理解

发布于:2023-01-17 ⋅ 阅读:(696) ⋅ 点赞:(0)

pixi.js中的显示对象(Sprite,Graphics,Container)的其他属性都比较常见和常用,如position,anchor,rotation,alpha等等。
但是toLocal和toGlobal不常用,却很有用。我把我的理解与应用记录一下。
pixi.js版本5.3.10

const app = new PIXI.Application({
  width:window.innerWidth,
  height:window.innerHeight,
  backgroundColor:0x1099bb,
  transparent:false
})
document.body.appendChild(app.view);

一、DisplayOjbect.toGlobal(position, point, skipupdate)

作用:计算显示对象以一个位置坐标为参照的全局坐标;返回值是一个PIXI.Point对象

参数说明:

position: 一个自定义坐标,计算时这个坐标点作为临时坐标的原点。
point:一个PIXI.Point对象,等同于返回值。
skipupdate:默认为false。
在这里插入图片描述

计算过程:

把disobj所在顶层容器对象的position移动到position参数位置,然后计算出disobj的position相对于画布坐标原点的坐标点,放入point参数内。

let t1 = PIXI.Texture.from("../resource/bunny.png")
// tolocal演示
let sp1 = new PIXI.Sprite(t1)
sp1.position.set(100,100)
let pt1 = new PIXI.Point(40,40)
// 这里多搞几层容器
let c1 = new PIXI.Container()
let c2 = new PIXI.Container()
let c3 = new PIXI.Container()
// 把精灵添加到容器中,每个容器都偏移一些
c3.addChild(sp1)
c3.position.set(100,100)
c2.addChild(containerl3)
c2.position.set(100,100)
c1.addChild(containerl2)
c1.position.set(100,100)
app.stage.addChild(c1)

let r1 = sp1.toGlobal(pt1) // 第二个第三个参数可以省略
console.log(r1)  // Point2 {x: 440, y: 440}
  1. sp1以及它的一系列上层容器都是偏移(100,100),那么sp1相对于顶层容器的位置就是(400,400);
  2. 把sp1所在顶层容器position移动到pt1(40,40),那么sp1的以pt1为参照的全局坐标就是(440,440);
  3. 如果position参数是{x:0,y:0},那么就可以得出sp1的以(0,0)为参照的全局坐标。

使用场景:

可以动态设置sp1的父级容器。
比如sp1在某个容器内,这时候去访问sp1的position,得到的是相对于容器的位置。想把sp1父容器设置为app.stage,那么就可以用toGlobal方法得到全局坐标,把这个坐标赋值给sp1就行了。
返过来,把一个全局的sp1放到一个容器c1内(可能有层级)。获取到容器的全局位置和sp1的全局位置,两者相减得到相对的位置偏移,把这个偏移赋值给sp1的position属性,再把sp1父级容器设置为c1,就行了。

二、DisplayOjbect.toLocal(position, from, point, skipupdate)

作用:计算显示对象相对于另一个点的局部位置;返回值是一个PIXI.Point对象

参数说明:

position: 一个自定义坐标,计算时这个坐标点作为临时坐标的原点。
from:另一个显示对象。
point:一个PIXI.Point对象,等同于返回值,可以省略。
skipupdate:默认为false。
pixi.js源码实现

计算过程:

先把from与position参数一起求出from的全局坐标,再求出显示对象位置与这个全局坐标的偏移坐标。
如果from为空,那么就是计算显示对象与position的相对偏移量

let t1 = PIXI.Texture.from("../resource/bunny.png")
let t2 = PIXI.Texture.from("../resource/eggHead.png")
// 第一个容器和子对象
let c1 = new PIXI.Container()
c1.x = 10
c1.y = 10
let sp1 = new PIXI.Sprite(t1)
sp1.x = 50
sp1.y = 50
c1.addChild(sp1)
// 第二个容器和子对象
let c2 = new PIXI.Container()
c2.x = 50
c2.y = 50
let sp2 = new PIXI.Sprite(t2)
sp2.x = 200
sp2.y = 200
c2.addChild(sp2)
let pt2 = new PIXI.Point(100,100)
let r2 = sp2.toLocal(pt2,sp1)
console.log(r2) // Point2 {x: -90, y: -90}
  1. 把sp1的移动到为以pt2为虚拟原点的后,求出全局坐标1, 再求以sp2的全局坐标参照,求出与全局坐标1的差
  2. sp1以pt2为参照的全局坐标为(160,160),sp2的全局坐标是(250,250)
  3. 以(250,250)为参照,(160,160)的相对偏移为(-90,-90)

使用场景:

可以用得到的偏移量来控制别的显示对象的移动。例如有一个区域,鼠标在这个区域内移动,那么就可以得到这个区域和鼠标位置之间的相对偏移量。然后用这个偏移量去改变其他的显示对象的position。
我想到的一个比较类似的场景就是王者荣耀控制英雄的移动。圆形区域的position固定,手指在区域内移动,可以算出手指位置相对于区域position的相对偏移。然后把这个叠加偏移量加到英雄的poition上。

如果参帮到你,非常荣幸。

本文含有隐藏内容,请 开通VIP 后查看