Skip to content

Pen Element

Like drawing by hand, quickly create different styled path combinations. Supports Canvas 2D-style path APIs.


Inheritance

Pen  >  Group  >  UI

Key Properties

pathElement: Path

Current sub-path element. Created automatically by setStyle().

Key Methods

setStyle ( data: IPathInputData)

Set pen style. Internally creates a sub-path for drawing.

You should set style first, then draw paths. Supports all properties from Path and UI.

add ( ui: UI)

Add a UI element.

clear ( )

Clear all drawn content (remove + destroy).

Path Drawing APIs

Similar to Canvas 2D path APIs. All angle values use degrees from -180 to 180.

clearPath ( )

Clear current path data (only clears the latest path after the most recent setStyle() call; previous paths are not affected). Alias of beginPath().

moveTo ( )

moveTo(x, y)

Move the starting point to (x, y).

lineTo ( )

lineTo(x, y)

Draw a line from the previous point to (x, y).

bezierCurveTo ( )

bezierCurveTo(x1, y1, x2, y2, x, y)

Draw a cubic Bézier curve from the previous point to (x, y), using (x1, y1) and (x2, y2) as control points.

quadraticCurveTo ( )

quadraticCurveTo(x1, y1, x, y)

Draw a quadratic Bézier curve from the previous point to (x, y), using (x1, y1) as the control point.

rect ( )

rect(x, y, width, height)

Draw a rectangle.

roundRect ( )

roundRect(x, y, width, height, cornerRadius: number | number[])

Draw a rounded rectangle.

ellipse ( )

ellipse(x, y, radiusX, radiusY, rotation?, startAngle?, endAngle?, anticlockwise?: boolean)

Draw an ellipse or elliptical arc. Center is at (x, y), radii are (radiusX, radiusY). Direction follows anticlockwise (default clockwise). If angles are omitted, a full ellipse is drawn.

arc ( )

arc(x, y, radius, startAngle?, endAngle?, anticlockwise?: boolean)

Draw a circle or circular arc. Center is at (x, y). If angles are omitted, a full circle is drawn.

arcTo ( )

arcTo(x1, y1, x2, y2, radius)

Draw a tangent arc between two lines defined by the previous point, (x1, y1), and (x2, y2).

closePath ( )

Close the current path.

New Methods

drawEllipse ( ) new

drawEllipse(x, y, radiusX, radiusY, rotation?, startAngle?, endAngle?, anticlockwise?)

Move to the start point first, then draw an ellipse. Ensures the ellipse is disconnected from previous paths, keeping it independent.

drawArc ( ) new

drawArc(x, y, radius, startAngle?, endAngle?, anticlockwise?)

Move to the start point first, then draw an arc. Ensures independence from previous paths.

drawPoints ( ) new

drawPoints(points, curve?, close?)

Draw polyline from points array:

  • [x, y, x, y, ...] or
  • [{x, y}, {x, y} ...]

curve enables smoothing (0–1 or true = 0.5). close indicates whether to close the path.

Inheritance

Pen  >  Group  >  UI

Examples

Draw Shapes with Different Colors

ts
// #创建 Pen [画出不同颜色的形状 (Leafer)]
import { Leafer, Pen } from 'leafer-ui'

const leafer = new Leafer({ view: window })

const pen = new Pen() 

pen.setStyle({ fill: '#FF4B4B', windingRule: 'evenodd' })
pen.roundRect(0, 0, 100, 100, 30).arc(50, 50, 25)

pen.setStyle({ x: 50, y: 50, fill: '#FEB027' })
pen.arc(0, 0, 20)

leafer.add(pen)
ts
// #创建 Pen [画出不同颜色的形状 (App)]
import { App, Pen } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

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

const pen = new Pen() 

pen.setStyle({ fill: '#FF4B4B', windingRule: 'evenodd', editable: true })
pen.roundRect(0, 0, 100, 100, 30).arc(50, 50, 25)

pen.setStyle({ x: 50, y: 50, fill: '#FEB027', editable: true })
pen.arc(0, 0, 20)

app.tree.add(pen)

Draw Curves

ts
// #创建 Pen [画曲线 (Leafer)]
import { Leafer, Pen } from 'leafer-ui'

const leafer = new Leafer({ view: window })

const pen = new Pen() 

pen.setStyle({ fill: { type: 'radial', stops: [{ offset: 0, color: '#FF4B4B' }, { offset: 1, color: '#FEB027' }] } })
pen.roundRect(0, 0, 100, 100, 30)

pen.setStyle({ y: -5, fill: 'white' })
pen.moveTo(40, 30).bezierCurveTo(70, 30, 90, 60, 63, 80).quadraticCurveTo(50, 88, 40, 80).bezierCurveTo(10, 60, 50, 40, 40, 30)

leafer.add(pen)
ts
// #创建 Pen [画曲线 (App)]
import { App, Pen } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

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

const pen = new Pen() 

pen.setStyle({ fill: { type: 'radial', stops: [{ offset: 0, color: '#FF4B4B' }, { offset: 1, color: '#FEB027' }] }, editable: true })
pen.roundRect(0, 0, 100, 100, 30)

pen.setStyle({ y: -5, fill: 'white', editable: true })
pen.moveTo(40, 30).bezierCurveTo(70, 30, 90, 60, 63, 80).quadraticCurveTo(50, 88, 40, 80).bezierCurveTo(10, 60, 50, 40, 40, 30)

app.tree.add(pen)

Combine with UI Components

ts
// #创建 Pen [结合图形组件 (Leafer)]
import { Leafer, Pen, Ellipse } from 'leafer-ui'
import '@leafer-in/corner' // 导入圆角插件

const leafer = new Leafer({ view: window })

const pen = new Pen() 

pen.setStyle({ fill: { type: 'radial', stops: [{ offset: 0, color: '#79CB4D' }, { offset: 1, color: '#FEB027' }] } })
pen.roundRect(0, 0, 100, 100, 30)

pen.add(new Ellipse({ x: 20, y: 20, width: 60, height: 60, innerRadius: 0.5, startAngle: -60, endAngle: 180, cornerRadius: 5, fill: 'white' }))

leafer.add(pen)
ts
// #创建 Pen [结合图形组件 (App)]
import { App, Pen, Ellipse } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)
import '@leafer-in/corner' // 导入圆角插件

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

const pen = new Pen() 

pen.setStyle({ fill: { type: 'radial', stops: [{ offset: 0, color: '#79CB4D' }, { offset: 1, color: '#FEB027' }] }, editable: true })
pen.roundRect(0, 0, 100, 100, 30)

pen.add(new Ellipse({ x: 20, y: 20, width: 60, height: 60, innerRadius: 0.5, startAngle: -60, endAngle: 180, cornerRadius: 5, fill: 'white', editable: true }))

app.tree.add(pen)

Combine with Images

ts
// #创建 Pen [结合图片 (Leafer)]
import { Leafer, Pen } from 'leafer-ui'

const leafer = new Leafer({ view: window })

const pen = new Pen() 

pen.setStyle({ fill: { type: 'radial', stops: [{ offset: 0, color: '#4DCB71' }, { offset: 1, color: '#79CB4D' }] }, windingRule: 'evenodd' })
pen.roundRect(0, 0, 100, 100, 30).arc(50, 50, 25)

pen.setStyle({ fill: { type: 'image', url: '/image/leafer.jpg' } })
pen.arc(50, 50, 20)

leafer.add(pen)
ts
// #创建 Pen [结合图片 (App)]
import { App, Pen } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

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

const pen = new Pen() 

pen.setStyle({ fill: { type: 'radial', stops: [{ offset: 0, color: '#4DCB71' }, { offset: 1, color: '#79CB4D' }] }, windingRule: 'evenodd', editable: true })
pen.roundRect(0, 0, 100, 100, 30).arc(50, 50, 25)

pen.setStyle({ fill: { type: 'image', url: '/image/leafer.jpg' }, editable: true })
pen.arc(50, 50, 20)

app.tree.add(pen)

Combine with Text

ts
// #创建 Pen [结合文字 (Leafer)]
import { Leafer, Pen, Text } from 'leafer-ui'

const leafer = new Leafer({ view: window })

const pen = new Pen() 

pen.setStyle({ stroke: '#4DCB71', strokeWidth: 4, strokeAlign: 'inside' })
pen.roundRect(0, 20, 100, 60, 30)

pen.add(new Text({ x: 60, y: 42, fill: '#4DCB71', fontSize: 16, text: 'ON' }))

pen.setStyle({ fill: '#4DCB71' })
pen.arc(30, 50, 23)

leafer.add(pen)
ts
// #创建 Pen [结合文字 (App)]
import { App, Pen, Text } from 'leafer-ui'
import '@leafer-in/editor' // 导入图形编辑器插件
import '@leafer-in/viewport' // 导入视口插件 (可选)

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

const pen = new Pen() 

pen.setStyle({ stroke: '#4DCB71', strokeWidth: 4, strokeAlign: 'inside', editable: true })
pen.roundRect(0, 20, 100, 60, 30)

pen.add(new Text({ x: 60, y: 42, fill: '#4DCB71', fontSize: 16, text: 'ON', editable: true }))

pen.setStyle({ fill: '#4DCB71', editable: true })
pen.arc(30, 50, 23)

app.tree.add(pen)

Released under the MIT License.