Skip to content

获取包围盒

当我们用鼠标绘制图形,或对元素进行对齐、矩形碰撞检测的时候,需要获取元素实际内容的位置和大小(包围盒),用来进行下一步操作。

包围盒模型

图中是一个元素由内到外形成的不同类型包围盒,每个包围盒都包含位置(x、y)和大小(width、height)信息,类似 CSS 的盒模型。

盒子模型

margin 包围盒

外部边界: 基准边界 + margin。

render 包围盒

渲染边界: 笔触边界 + 阴影等。

stroke 包围盒

笔触边界: 基准边界 + stroke,可响应交互事件的边界。

box 包围盒

基准边界: 包含 padding,以此为基准向内、向外延伸边界。

content 包围盒

内容边界: 填充内容的边界,不包含 padding,一般用于测量 Text 的实际文本大小。

OBB 和 AABB

当元素旋转后,在 不同的坐标系下 会形成不同的 OBB 和 AABB 包围盒。

包围盒

示例

我们通过 创建图形 的例子,来了解 包围盒与坐标系 的相互作用

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

ts
import { App, DragEvent, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件(可选)


const app = new App({ view: window, editor: {} })

app.tree.add(Rect.one({ editable: true, fill: '#FEB027', cornerRadius: [20, 0, 0, 20] }, 100, 100))
app.tree.add(Rect.one({ editable: true, fill: '#FFE04B', rotation: 10, cornerRadius: [0, 20, 20, 0] }, 300, 100))

app.editor.select(app.tree.children[0])

setTimeout(() => {

    // 2秒后进入创建图形模式
    app.editor.visible = false
    app.tree.hitChildren = false

    // 创建矩形(拖拽)
    let rect: Rect

    app.on(DragEvent.START, () => {
        rect = new Rect({ editable: true, fill: 'rgb(50,205,121)' })
        app.tree.add(rect)
    })

    app.on(DragEvent.DRAG, (e: DragEvent) => {
        if (rect) rect.set(e.getPageBounds()) // 获取事件在 page 坐标系中绘制形成的包围盒
    })

}, 2000)
js
import { App, DragEvent, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件(可选)


const app = new App({ view: window, editor: {} })

app.tree.add(Rect.one({ editable: true, fill: '#FEB027', cornerRadius: [20, 0, 0, 20] }, 100, 100))
app.tree.add(Rect.one({ editable: true, fill: '#FFE04B', rotation: 10, cornerRadius: [0, 20, 20, 0] }, 300, 100))

app.editor.select(app.tree.children[0])

setTimeout(() => {

    // 2秒后进入创建图形模式
    app.editor.visible = false
    app.tree.hitChildren = false

    // 创建矩形(拖拽)
    let rect

    app.on(DragEvent.START, () => {
        rect = new Rect({ editable: true, fill: 'rgb(50,205,121)' })
        app.tree.add(rect)
    })

    app.on(DragEvent.DRAG, (e) => {
        if (rect) rect.set(e.getPageBounds())  // 获取事件在 page 坐标系中绘制形成的包围盒
    })

}, 2000)

获取方法

事件中的获取方法

DragEvent

元素上的获取方法

名称描述
boxBounds元素在 内部坐标系 中的基础边界(OBB 包围盒)
renderBounds元素在 内部坐标系 中的渲染边界(AABB 包围盒)
worldBoxBounds元素在 世界坐标系 中的基础边界(AABB 包围盒)
worldRenderBounds元素在 世界坐标系 中的渲染边界(AABB 包围盒)
getBounds()获取 AABB 包围盒(边界)
getLayoutBounds()获取 OBB 包围盒(边界),含缩放、旋转等布局属性
getLayoutPoints()获取 OBB 包围盒(边界)的四个坐标点)

数学计算

Bounds 类

下一步

局部渲染

Released under the MIT License.