Skip to content

TileEditor 类

图片平铺工具,支持双击元素或调用 editor.openInnerEditor() 进入平铺编辑模式。

继承

TileEditor  >  InnerEditor

📆 更新日志

当前为 v1.0.1,查看更新日志

📦 安装插件(本地安装)

本插件不发布于公开 NPM 仓库,通过本地 .tgz 文件安装使用,需 购买插件 授权后才能使用。

第一步:获取插件包

购买后,你将获得一个名为 pxgrow-tiler-1.0.1.tgz 的安装包。

将该文件放置在你的项目根目录下的 pxgrow 文件夹中统一管理,安装后请勿删除。

第二步:本地安装命令

根据你使用的包管理器,选择以下方式之一:

sh
npm install ./pxgrow/pxgrow-tiler-1.0.1.tgz
sh
pnpm add ./pxgrow/pxgrow-tiler-1.0.1.tgz
sh
yarn add ./pxgrow/pxgrow-tiler-1.0.1.tgz
sh
bun add ./pxgrow/pxgrow-tiler-1.0.1.tgz

将在 package.json 中自动增加本地依赖:

"@pxgrow/tiler": "file:pxgrow/pxgrow-tiler-1.0.1.tgz"


或通过 script 标签引入,使用全局变量 PxGrow.tiler 访问插件内部功能。

需解压 pxgrow-tiler-1.0.1.tgz 文件,复制 package/dist/tiler.js 使用。

html
<script src="/lib/pxgrow/tiler.js"></script>
<script>
  const { TileEditor } = PxGrow.tiler
</script>

关键属性

editTarget: UI

当前编辑的目标元素。

innerTransformTool: TransformTool

元素编辑框的变换操作工具,支持手动移动、旋转、调整大小。

imageTransformTool: TransformTool

图片编辑框的变换操作工具,支持手动移动、旋转、调整大小。

显示属性

innerEditBox: EditBox

元素编辑框实例,用于操作元素。

imageEditBox: EditBox

图片编辑框实例,用于控制平铺图片对象。

imageTarget: Image

完整显示的图片对象。

配置属性(只读)

userConfig: ITileEditorConfig

用户的配置。

mergeConfig: ITileEditorConfig

实际使用的编辑器配置,实时合并编辑器的默认 config 与 userConfig,频繁访问会有性能开销。

mergedConfig: ITileEditorConfig

mergeConfig 的缓存,频繁访问不会有性能问题。

关键方法

updateEditor ( )

更新平铺编辑器,会卸载、再加载一次。

update ( )

更新显示编辑框和图片的显示。

updateImage ( )

仅更新图片。

updateImagePaint ( )

仅更新图片填充对象。

Tiler 配置

基础     高级

示例

默认效果

ts
// #Tiler [自由平铺]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

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

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

快速修改平铺控制点大小

ts
// #Tiler [快速修改平铺控制点大小]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

const app = new App({
    view: window, editor: {
        TileEditor: { // 配置平铺编辑器
            pointSize: 16, // 平铺控制点大小
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

快速修改平铺控制点颜色

ts
// #Tiler [快速修改平铺控制点颜色]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

const app = new App({
    view: window, editor: {
        TileEditor: { // 配置平铺编辑器
            pointColor: '#0d99ff', // 平铺控制点颜色
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

快速修改遮罩层颜色

ts
// #Tiler [设置遮罩层颜色]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

const app = new App({
    view: window, editor: {
        TileEditor: { // 配置平铺编辑器
            imageMask: 'rgba(255, 0, 0, 0.5)' // 遮罩层颜色,默认为 rgba(0,0,0,0.5)
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

图片只能在有效范围内拖动、平铺(暂不支持同时旋转、倾斜图片,限制效果会有误差,后续会支持)

ts
// #Tiler [图片只能在有效范围内拖动、平铺(暂不支持同时旋转、倾斜图片,限制效果会有误差,后续会支持)]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

const app = new App({
    view: window, editor: {
        dragLimitAnimate: true,
        rotateable: false, // 关闭图片旋转、倾斜功能
        skewable: false,
        TileEditor: { // 配置平铺编辑器
            dragLimit: true // 图片在平铺框的有限范围内拖动,默认为false
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

手势控制图片

ts
// #Tiler [手势控制图片]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

const app = new App({
    view: window,
    mobile: true, // 支持手机端体验优化
    editor: {
        moveable: 'gesture', // 手势控制图片
        resizeable: 'gesture',
        rotateable: 'gesture',
        TileEditor: { // 配置平铺编辑器
            innerEditBox: {
                moveable: true, // 元素编辑框不进行手势控制,防止与手势操作图片冲突
                resizeable: true,
                rotateable: true,
            }
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

旋转原始图片时,围绕元素中心旋转

ts
// #Tiler [围绕元素编辑框中心旋转]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

const app = new App({
    view: window, editor: {
        TileEditor: { // 配置平铺编辑器
            aroundInnerEditBox: true // 图片是否围绕元素编辑框中心旋转,默认为false
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

// setTimeout(() => app.editor.config.TileEditor.aroundInnerEditBox = false, 10000)

显示九宫格水平线

ts
// #Tiler [显示水平线]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)
import '@leafer-in/animate' // 导入动画插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

const app = new App({
    view: window, editor: {
        TileEditor: { // 配置平铺编辑器
            horizontalLine: true  // 显示水平线
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

仅在操作时显示水平线

ts
// #Tiler [仅在操作时显示水平线]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)
import '@leafer-in/animate' // 导入动画插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

const app = new App({
    view: window, editor: {
        TileEditor: { // 配置平铺编辑器
            horizontalLine: { hideOnActionEnd: true } // 仅在resize操作时显示水平线
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

在多个 fill、stroke 中指定需要平铺的图片填充对象

ts
// #Tiler [在多个 fill、stroke 中指定需要平铺的图片填充对象]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)
import '@leafer-in/animate' // 导入动画插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

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

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    strokeWidth: 10,
    fill: {
        type: 'image',
        url: '/image/arrows.png',
        mode: 'repeat',
    },
    stroke: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6,
        editing: true // 指定stroke为需要平铺的图片填充对象
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

移动元素编辑框

ts
// #Tiler [可移动的元素框]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

const app = new App({
    view: window, editor: {
        TileEditor: {
            innerEditBox: {
                moveable: true, // 元素框可移动
                //  moveCursor: 'grab', // 可自定义移动光标(参考编辑器的moveCursor配置)
            }
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

突出显示并置顶渲染平铺元素,淡化其他元素

ts
// #Tiler [突出显示并置顶渲染平铺元素,淡化其他元素]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@leafer-in/bright' // 导入突出显示元素插件
import '@pxgrow/tiler' // 导入图片平铺插件 

const app = new App({
    view: window, ground: {}, editor: {
        TileEditor: {
            editBox: {
                bright: true, // 突出显示并置顶渲染平铺元素
                dimOthers: true, // 淡化其他元素
            }
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 300,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

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

// // 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

自定义复杂样式

ts
// #Tiler [自定义复杂样式]
import { App, Rect } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

const app = new App({
    view: window, editor: {
        TileEditor: { // 图片平铺配置
            imageEditBox: { strokeWidth: 1, rect: { stroke: 'black', dashPattern: [4, 2] } }, // 模拟图片的编辑框,支持配置编辑器样式
            innerEditBox: { // 平铺编辑框,支持配置编辑器样式
                stroke: 'white',
                point: {
                    strokeWidth: 0,
                    shadow: {
                        x: 1,
                        y: 1,
                        blur: 6,
                        color: '#00000030'
                    }
                },
                middlePoint: {
                    width: 16, height: 6, cornerRadius: 3,
                    strokeWidth: 0,
                    shadow: {
                        x: 1,
                        y: 1,
                        blur: 6,
                        color: '#00000030'
                    }
                },
                rect: {
                    stroke: 'black',
                    strokeWidth: 2, // 平铺框默认没有描边宽度,需加上
                },
                spread: 0 // 平铺框默认扩展了一定的大小,设置0可还原
            }
        }
    }
})

const rect = new Rect({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

// 访问平铺编辑器实例(仅平铺编辑器打开的情况下有效)
// const clipEditor = app.editor.innerEditor

平铺 Image 元素

ts
// #Tiler [平铺 Image 元素]
import { App, Image } from 'leafer-ui'
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

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

const rect = new Image({
    x: 100,
    y: 100,
    width: 500,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

平铺 Line 元素

ts
// #Tiler [平铺 Line 元素]
import { App, Line } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

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

const rect = new Line({
    x: 300,
    y: 300,
    points: [0, 0, -46, -23, -127, -4, -201, 69, -221, 218, 69, 79, 56],
    closed: true,
    stroke: '#32cd79',
    strokeWidth: 5,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10,
        scale: 0.6
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

平铺 Path 元素

ts
// #Tiler [平铺 Path 元素]
import { App, Path } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

import '@pxgrow/tiler' // 导入图片平铺插件

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

const rect = new Path({
    x: 100,
    y: 100,
    scale: 0.5,
    path: 'M945.344 586.304c-13.056-93.44-132.48-98.048-132.48-98.048 0-29.888-39.808-47.424-39.808-47.424L201.664 440.832c-36.736 0-42.112 51.264-42.112 51.264 7.68 288 181.44 382.976 181.44 382.976l299.456 0c42.88-31.36 101.888-122.56 101.888-122.56 9.216 3.072 72.768-0.832 97.984-6.144C865.6 740.992 958.336 679.68 945.344 586.304zM365.568 825.28c-145.472-105.664-130.944-328.576-130.944-328.576l80.448 0c-44.416 126.4 43.648 285.696 55.872 307.904C383.232 826.816 365.568 825.28 365.568 825.28zM833.472 694.272c-37.568 22.272-65.152 7.68-65.152 7.68 39.04-54.4 42.112-159.296 42.112-159.296 6.848 2.304 12.288-26.048 61.312 23.744C920.768 616.128 871.04 672.064 833.472 694.272z M351.68 129.856c0 0-119.424 72.832-44.416 140.928 75.008 68.16 68.16 93.44 24.512 153.216 0 0 81.92-41.344 71.168-104.192s-89.6-94.208-72.768-137.792C347.136 138.304 351.68 129.856 351.68 129.856z M615.232 91.648c0 0-119.488 72.832-44.352 140.928 74.944 68.16 68.032 93.44 24.448 153.216 0 0 81.984-41.344 71.232-104.192-10.688-62.784-89.6-94.208-72.832-137.792C610.624 100.032 615.232 91.648 615.232 91.648z M491.136 64c0 0-74.304 6.144-88.128 78.144C389.248 214.144 435.968 240.96 471.936 276.992 507.904 312.96 492.608 380.352 452.032 427.904c0 0 72.768-25.344 89.6-94.976 16.832-69.76-17.344-94.272-52.8-134.784C453.312 157.504 456.64 83.968 491.136 64z',
    stroke: '#32cd79',
    strokeWidth: 5,
    editable: true,
    editInner: 'TileEditor', // 指定内部编辑器
    fill: {
        type: 'image',
        url: '/image/leafer.jpg',
        mode: 'repeat',
        gap: 10
    }
})

app.tree.add(rect)

// 模拟双击元素打开平铺编辑器
rect.on('image.loaded', () => {
    setTimeout(() => {
        app.editor.openInnerEditor(rect, true)
    }, 600)
})

Released under the Commercial License Agreement.