@zouchengxin/pixi-editor
v1.0.5
Published
An infinite canvas component built with PixiJS
Maintainers
Readme
pixi-editor
An infinite canvas component built with PixiJS, featuring viewport panning, element transformation (translate/rotate/scale), and a customizable element toolbar. Ideal for flowchart editors, whiteboard applications, map editors, and other large-scale interactive spaces.
✨ Features
- Infinite Canvas: Boundary-free drawing area via viewport transformations
- Smooth Viewport Control: Mouse/touch drag to pan the canvas
- Element Transformation: Translate, rotate, and scale selected elements (with configurable control handles)
- Element Toolbar: Context-aware toolbar for selected elements (delete, duplicate, layer adjustment, etc.)
- High Performance: WebGL rendering via PixiJS, supports a large number of graphic elements
- TypeScript Friendly: Includes complete type definitions
📦 Installation
npm install pixi.js @zouchengxin/pixi-editor🌐 Live Demo
Try it online: pixi-editor
🚀 Quick Start
Initialization
// tsconfig.json
// If you need to use a decorator
{
"compilerOptions": {
"experimentalDecorators": true
}
}<div id="editor-container">
<!-- The editor will be mounted here -->
</div>import { Editor } from "@zouchengxin/pixi-editor";
import "@zouchengxin/pixi-editor/style.css";
import { Element } from "@zouchengxin/pixi-editor/elements";
const editor = new Editor();
// API_KEY not provided, validity period until 2027-01-01,.
// You can adjust the system time for testing.
// Or contact the developer to obtain the API key.
await editor.init(API_KEY);
editor.mount("#editor-container");Elements
// Add Shape element.
editor.addElement("shape", { type: "rect", x: 100, y: 10, w: 60, h: 80 });
editor.addElement("shape", { type: "circle", x: 10, y: 10, fillColor: "red" });
// Add Image element.
async function selectImage() {
const pickerOpts = {
types: [
{
description: "Images",
accept: {
"image/*": [".png", ".jpeg", ".jpg"],
},
},
],
excludeAcceptAllOption: true,
multiple: false,
};
const [fileHandle] = await window.showOpenFilePicker(pickerOpts);
const fileData = await fileHandle.getFile();
return fileData;
}
const blob = await selectImage();
const srcId = "test-" + Date.now();
await editor.source.set(srcId, blob);
editor.addElement("image", { x: 10, y: 200, sourceId: srcId });
// Other elements are under developmentToolbar
// Add the internally provided toolbar.
const toolEl = document.createElement("pe-toolbar");
// @ts-ignore
toolEl.$editor = editor;
editor.container.appendChild(toolEl);Custom Element
import { Text } from 'pixi.js';
import { Element } from '@zouchengxin/pixi-editor/elements';
import { Model } from '@zouchengxin/pixi-editor/models';
import { BaseTool } from '@zouchengxin/pixi-editor/tools';
import { Reactive, Ref, Watch } from '@zouchengxin/pixi-editor/decorators';
import type { IModelOpt } from "@zouchengxin/pixi-editor/models";
interface ITestModelOpt extends IModelOpt {
text: string;
}
@Reactive
class TestModel extends Model{
@Ref text='test';
}
// inherits from Container class of pixijs
class TestElement extends Element<TestModel> {
static ident = 'test';
createModel(opt: ITestModelOpt) {
this.model = new TestModel(opt);
}
// Execute during initialization
init() {
super.init();
}
// Execute when reactive property changes (properties decorated with Ref)
render() {
super.render();
// You can add any scene objects to the Container.
// such as Text, Graphics, Sprite, etc
const text = new Text({
text: this.model.text,
style: {
fill: '#ffffff',
fontSize: 16,
},
});
this.addChild(text);
}
}
// inherits from Container class of pixijs
class TestTool extends BaseTool{
static ident = 'test';
// Execute during initialization
init(){
const text = new Text({
text: 'This is test tool',
});
this.addChild(text);
}
}
// Register tool
editor.registerTool(TestTool);
// Set current tool
editor.setTool('test');
// Register element
editor.registerElement(TestElement);
// Add test element
editor.addElement('test', { text: 'hello world', x: 200, y: 200 });Element Toolbar
import { html, LitElement } from 'lit';
import { customElement } from 'lit/decorators.js';
// Tag name: pe-el-${ident}
@customElement('pe-el-test')
class ElTest extends LitElement {
$editor: Editor;
$el: TestElement;
render() {
return html`
<div>Test</div>
`
}
}🖌️ API Reference
Editor
| Field | Type | Description |
| ----------- | ------------------ | ------------------------------------------- |
| app | PIXI.Application | Application instance in the pixi library |
| plugins | Plugin[] | Registered plugins |
| elements | Element[] | Registered elements |
| container | HTMLElement | The Dom element where the Editor is mounted |
| Method | Description |
| ----------------- | -------------------------------------------- |
| getPlugin | Get the corresponding plugin by name |
| init | Initialization function, API_KEY is optional |
| mount | Mount function |
| registerElement | Register element |
| registerTool | Register tool |
| addPlugin | Add plugin |
| addElement | Add element |
| removeElement | Remove element |
| exportPng | Export PNG image |
💬 Contact
- 交流群: 877673376
- API_KEY: https://ifdian.net/a/zouchengxin
