Skip to content

转换坐标

当你 缩放平移视图 后,想在画布中用鼠标创建图形,会发现将 事件坐标 x, y 给到图形,位置已经不对了,此时就需要用到 转换坐标 的功能。

先了解一下坐标系的原理

我们的应用是一个多层级的树状结构,层层嵌套,每个层级都有独立的 x、y、scaleX、scaleY、rotation、skewX、skewY 属性,这些属性因子构成了一个个独立起点的房间(坐标系)。


坐标体系


转换坐标 的原理就是转换不同层级间的这些属性因子关系,省去手动计算。


坐标体系透视图


world 世界坐标系

在画布上的坐标,类似 HTML 的 client 坐标系,以画布左上角为起点。

page 场景坐标系

在 leafer 或 app.tree 内的坐标, 类似 HTML 的 page 坐标系,以 缩放层 为起点。

local 本地坐标系

相对父元素的坐标,类似 HTML 的 offset 坐标系,以父元素为起点。

inner 内部坐标系

在元素、组元素内的坐标,以元素的 x,y 位置为起点。

box 坐标系

在元素、组元素 box 包围盒 内的坐标,以元素实际内容的左上角为起点。

示例

我们通过 画笔工具 的例子, 来了解 转换坐标 的作用

按下鼠标拖动开始画线,抬起结束,当缩放平移视图后,仍然可以准确绘制新的线条。

ts
import { Leafer, DragEvent, Pen } from 'leafer-ui'
import '@leafer-in/viewport'

const leafer = new Leafer({ view: window, type: 'design' })

const pen = new Pen()
leafer.add(pen)

leafer.on(DragEvent.START, (e: DragEvent) => {
    const point = e.getPagePoint() // 转换事件为 page 坐标 = pen.getPagePoint(e)
    pen.setStyle({ stroke: 'black', strokeWidth: 10, strokeCap: 'round', strokeJoin: 'round' })
    pen.moveTo(point.x, point.y)
})

leafer.on(DragEvent.DRAG, (e: DragEvent) => {
    const point = e.getPagePoint() // 转换事件为 page 坐标 = pen.getPagePoint(e)
    pen.lineTo(point.x, point.y)
})
js
import { Leafer, DragEvent, Pen } from 'leafer-ui'
import '@leafer-in/viewport'

const leafer = new Leafer({ view: window, type: 'design' })

const pen = new Pen()
leafer.add(pen)

leafer.on(DragEvent.START, (e) => {
    const inner = e.getPagePoint() // 转换事件为 page 坐标 = pen.getPagePoint(e)
    pen.setStyle({ stroke: 'black', strokeWidth: 10, strokeCap: 'round', strokeJoin: 'round' })
    pen.moveTo(inner.x, inner.y)
})

leafer.on(DragEvent.DRAG, (e) => {
    const inner = e.getPagePoint() // 转换事件为 page 坐标 = pen.getPagePoint(e)
    pen.lineTo(inner.x, inner.y)
})

转换方法

事件中的坐标转换方法

UIEvent     PointerEvent     DragEvent     MoveEvent

元素上的坐标转换方法

名称描述
worldTransform相对于世界坐标的变换矩阵, 包含 scaleX、scaleY 属性,转换坐标的因子
localTransform相对于父元素的变换矩阵,转换坐标的因子
getPagePoint()获取 page 坐标( 世界坐标page 坐标 ),支持转换移动距离
getLocalPoint()获取本地坐标( 世界坐标本地坐标 ),支持转换移动距离
getInnerPoint()获取内部坐标( 世界坐标内部坐标 ),支持转换移动距离
getBoxPoint()获取 box 坐标( 世界坐标box 坐标 ),支持转换移动距离
getWorldPointByPage()获取世界坐标( page 坐标世界坐标 ),支持转换移动距离
getWorldPointByLocal()获取世界坐标( 本地坐标世界坐标 ),支持转换移动距离
getInnerPointByLocal()获取内部坐标( 本地坐标内部坐标 ),支持转换移动距离
getWorldPoint()获取世界坐标( 内部坐标世界坐标 ),支持转换移动距离
getLocalPointByInner()获取本地坐标( 内部坐标本地坐标 ),支持转换移动距离
getBoxPointByInner()获取 box 坐标( 内部坐标box 坐标 ),支持转换移动距离
getWorldPointByBox()获取世界坐标( box 坐标世界坐标 ),支持转换移动距离
getInnerPointByBox()获取内部坐标( box 坐标内部坐标 ),支持转换移动距离

浏览器原生事件的坐标转换方法

名称描述
getWorldPointByClient()获取 世界坐标(浏览器原生事件的 client 坐标 转 世界坐标),只能在 App 或 Leafer 实例上调用此方法
getPagePointByClient()获取 page 坐标(浏览器原生事件的 client 坐标 转 page 坐标),只能在 App 或 Leafer 实例上调用此方法

数学计算

Matrix 类     Point 类

下一步

获取包围盒

Released under the MIT License.