@wbiokr/arrow
v1.3.0
Published
Arrow editor for drawing arrows on web pages
Downloads
1,597
Readme
@wbiokr/arrow
箭头绘制编辑器 - 在网页上绘制可编辑的箭头
环境要求
- Node.js >= 20.19.0 或 >= 22.12.0
安装
npm install @wbiokr/arrow快速开始
HTML
<div id="container"></div>CSS(可选)
#container {
position: relative;
width: 1000px;
height: 600px;
background: #fff;
margin: 50px auto;
}JavaScript
import { ArrowEditor } from '@wbiokr/arrow'
const editor = new ArrowEditor('#container')使用方法
绘制箭头
- 点击空白处开始绘制
- 移动鼠标添加拐点
- 双击或按
Enter完成绘制 - 按
Esc取消绘制
移动箭头
- 点击箭头选中
- 拖拽移动箭头
旋转箭头
- 点击箭头选中
- 拖拽顶部的橙色旋转手柄
缩放箭头
- 点击箭头选中
- 拖拽右下角的蓝色缩放手柄
删除箭头
- 点击箭头选中
- 按
Delete或Backspace键 - 或在工具条上点击"删除箭头"按钮
切换选中
点击其他箭头可快速切换选中状态。
取消选中
点击空白处或按 Esc 键
配置选项
const editor = new ArrowEditor('#container', {
// 是否只在按 Ctrl 键时绘制(默认 false)
isCtrl: false,
// 是否阻止事件冒泡(默认 false)
stopPropagation: false,
// 是否阻止默认行为(默认 false)
preventDefault: false,
// 默认颜色(默认 '#2b8cff')
defaultColor: '#2b8cff',
// 默认粗细(默认 8)
defaultStrokeWidth: 8,
// 默认曲线率(默认 0)
defaultCurveRate: 0,
// 绘制完成回调
onDrawEnd(data) {
// data = { arrow: 当前箭头,arrows: 所有箭头数据 }
console.log('绘制完成:', data)
},
// 删除回调
onRemove(data) {
// data = { arrow: 被删除的箭头,arrows: 剩余箭头数据 }
console.log('删除:', data)
},
// 变更回调(颜色、粗细、曲线率、旋转、缩放)
onChange(data) {
// data = { type, arrow, value?, arrows }
// type: 'color' | 'strokeWidth' | 'curveRate' | 'rotate' | 'scale'
console.log('变更:', data)
}
})配置说明
| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| isCtrl | Boolean | false | 是否只在按 Ctrl 键时绘制 |
| stopPropagation | Boolean | false | 是否阻止事件冒泡 |
| preventDefault | Boolean | false | 是否阻止默认行为 |
| defaultColor | String | '#2b8cff' | 默认箭头颜色 |
| defaultStrokeWidth | Number | 8 | 默认箭头粗细 |
| defaultCurveRate | Number | 0 | 默认曲线率(0=直线,1=最弯曲) |
| defaultArrowLength | Number | 22 | 默认箭头长度(5-50) |
| defaultArrowWidth | Number | 20 | 默认箭头宽度(5-50) |
| onDrawEnd | Function | null | 绘制完成回调,接收 { arrow, arrows } |
| onRemove | Function | null | 删除回调,接收 { arrow, arrows } |
| onChange | Function | null | 变更回调,接收 { type, arrow, value?, arrows } |
API
实例化
const editor = new ArrowEditor(container, options)container: CSS 选择器字符串或 DOM 元素options: 配置对象(可选)
方法
getData()
获取所有箭头数据
const data = editor.getData()
// 返回:[{ points: [{x, y}, ...], curveRate, strokeWidth, arrowLength, arrowWidth, color }, ...]setData(data)
设置箭头数据
editor.setData([
{
points: [{ x: 100, y: 100 }, { x: 200, y: 200 }],
curveRate: 0.5,
strokeWidth: 8,
color: '#2b8cff'
}
])clear()
清空所有箭头
editor.clear()destroy()
销毁编辑器,移除所有事件监听器和 DOM 元素
editor.destroy()工具条
选中箭头后会弹出工具条,可以调整:
- 颜色:点击颜色选择器
- 粗细:拖动滑块(1-60px)
- 曲线率:拖动滑块(0-1,0=直线,1=最弯曲)
- 箭头长度:拖动滑块(5-50px,默认 22px)
- 箭头宽度:拖动滑块(5-50px,默认 20px)
- 缩放:
- X 缩放:仅水平方向缩放
- Y 缩放:仅垂直方向缩放
- 3D 旋转:
- X 轴旋转:上下拖动,模拟绕 X 轴旋转的透视效果
- Y 轴旋转:左右拖动,模拟绕 Y 轴旋转的透视效果
- 2.5D 挤出:
- 上挤出:向上方挤出立体阴影
- 下挤出:向下方挤出立体阴影
- 左挤出:向左方挤出立体阴影
- 右挤出:向右方挤出立体阴影
- 重置:恢复原始形状
- 2.5D 透视:
- 上透视:上方缩小,下方放大(灭点在上方)
- 下透视:下方缩小,上方放大(灭点在下方)
- 左透视:左方缩小,右方放大(灭点在左方)
- 右透视:右方缩小,左方放大(灭点在右方)
- 倾斜:
- 左倾斜:向左倾斜
- 右倾斜:向右倾斜
- 上倾斜:向上倾斜
- 下倾斜:向下倾斜
- 重置:恢复原始形状
工具条可以拖拽到任意位置。
缩放手柄
选中箭头后,箭头周围会显示三个缩放手柄:
- 右下角手柄:同时 X 和 Y 方向缩放(等比缩放)
- 右边中间手柄:仅 X 方向缩放
- 底部中间手柄:仅 Y 方向缩放
3D 旋转说明
- X 轴旋转:绕 X 轴旋转,上下拖动鼠标控制角度,Y 坐标会根据旋转角度缩放(模拟透视效果)
- Y 轴旋转:绕 Y 轴旋转,左右拖动鼠标控制角度,X 坐标会根据旋转角度缩放(模拟透视效果)
- Z 轴旋转:现有的顶部橙色手柄,绕 Z 轴(垂直于屏幕)旋转
注:由于 SVG 是 2D 平面,X/Y 轴旋转使用余弦缩放模拟 3D 透视效果,旋转角度范围为 -90°到 90°。
2.5D 挤出效果
- 上/下/左/右挤出:通过绘制多层灰色阴影,模拟箭头立体挤出的 2.5D 效果
- 重置:清除挤出效果,恢复原始 2D 形状
2.5D 挤出效果是一种伪 3D 效果,通过沿指定方向绘制多层半透明阴影层来模拟立体深度感。
2.5D 透视效果
- 上透视:灭点在上方,上方缩小下方放大,产生仰视效果
- 下透视:灭点在下方,下方缩小上方放大,产生俯视效果
- 左透视:灭点在左方,左方缩小右方放大
- 右透视:灭点在右方,右方缩小左方放大
透视效果通过近大远小的原理,根据各点距离灭点的距离动态调整缩放比例,模拟真实的 3D 透视感。
倾斜效果
- 左倾斜:向左方向倾斜(平行四边形效果)
- 右倾斜:向右方向倾斜
- 上倾斜:向上方向倾斜
- 下倾斜:向下方向倾斜
倾斜效果通过错切变换(Skew Transform),根据点的位置偏移坐标,产生倾斜的视觉效果。
键盘快捷键
| 快捷键 | 功能 |
|--------|------|
| Enter | 完成绘制 |
| Esc | 取消绘制 / 取消选中 |
| Delete / Backspace | 删除选中的箭头 |
| Space | 绘制中添加拐点 |
| ↑ ↓ ← → | 选中箭头时微调位置(1 像素) |
数据存储示例
// 保存数据
const editor = new ArrowEditor('#container', {
onDrawEnd(data) {
localStorage.setItem('arrows', JSON.stringify(data.arrows))
},
onChange(data) {
localStorage.setItem('arrows', JSON.stringify(data.arrows))
},
onRemove(data) {
localStorage.setItem('arrows', JSON.stringify(data.arrows))
}
})
// 加载数据
editor.setData(JSON.parse(localStorage.getItem('arrows')) || [])开发
npm install
npm run dev打包
npm run buildLicense
MIT
