vue3-canvas-create-range
vue3-canvas-create-range
一个基于Vue3的画布范围选择插件,支持多边形、矩形、线段绘制、选择和编辑功能。
特性
- 🎯 支持顶点拖动和整体移动
- ⌨️ 支持键盘快捷操作
- 🎨 可自定义填充颜色和选中状态样式
- 📏 可配置最小顶点数和最大多边形数量
- 📏 支持画线模式(两点点击自动完成)
- 🔄 支持响应式布局
安装
npm install vue3-canvas-create-range
使用
全局注册
import { createApp } from 'vue'
import CanvasRange from 'vue3-canvas-create-range'
import 'vue3-canvas-create-range/style.css'
const app = createApp(App)
app.use(CanvasRange)
app.mount('#app')
组件中使用
<template>
<div style="width: 500px; height: 300px;">
<CanvasRange
v-model:polygons="polygons"
:initial-polygons="initialPolygons"
:fill-color="'#2196f380'"
:selected-color="'#ff980080'"
:min-points="3"
:max-polygons="5"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { Point } from 'vue3-canvas-create-range'
const polygons = ref<Point[][]>([])
const initialPolygons = [
[
{ x: 100, y: 100 },
{ x: 200, y: 100 },
{ x: 150, y: 200 },
],
]
const handleSelect = (index: number) => {
console.log('Selected polygon:', index)
}
</script>
API
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| v-model:polygons | Point[][] |
[] |
多边形数据,双向绑定 |
| initial-polygons | Point[][] |
[] |
初始多边形数据 |
| fill-color | string |
'#2196f380' |
多边形填充颜色(勿用rgba格式) |
| selected-color | string |
'#ff980080' |
选中状态填充颜色 |
| selected-line-color | string |
'#E6A23C' |
选中状态线条颜色 |
| handle-color | string |
'' |
控制点颜色(绘制中顶点 + 选中控制点);空则绘制中为黄、选中跟 selected-line-color |
| handle-radius | number |
4 |
选中时控制点半径 |
| min-points | number |
3 |
最小顶点数 |
| max-polygons | number |
Infinity |
最大多边形数量 |
| keydown-enable | boolean |
false |
是否启用键盘快捷键 |
| mouse-enable | boolean |
false |
是否启用鼠标交互 |
| rectangle | boolean |
false |
是否只能画矩形 |
| line | boolean |
false |
画线模式:两点点击自动完成,只描边不填充(与 rectangle 互斥,同时开启时优先 rectangle) |
| line-width | number |
2 |
描边宽度 |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| update:polygons | (polygons: Point[][]) |
多边形数据更新时触发(完整数据) |
| select | (index: number) |
点击/程序化选中时触发 |
| hover | (index: number | null) |
指针下将要点中的形状变化时触发;离开或无命中为 null。视觉/层级与选中一致,但不改变正式选中 |
| add | (polygons: Point[]) |
新增多边形时触发 |
| update | (index: number, polygons: Point[]) |
编辑时触发 |
| delete | (index: number) |
删除多边形时触发 |
Methods
| 方法名 | 参数 | 说明 |
|---|---|---|
| clear | - | 清除所有多边形 |
| deleteIndex | (index: number) |
按索引删除 |
| selectIndex | (index: number | null) |
程序化选中;null 取消选中。线/矩形/多边形的编辑控件由当前模式与点数自动决定 |
| redrawDisplayCanvas | - | 立即重绘显示层 |
| resize | - | 容器尺寸变化后调用,按 DPR 重建画布 |
类型定义
interface Point {
x: number
y: number
}
键盘快捷键
当keydown-enable设置为true时:
Esc: 取消当前绘制或清除选中Delete: 删除选中的多边形
鼠标操作
当mouse-enable设置为true时:
- 左键点击:开始/继续绘制多边形;画线模式下第二次点击自动完成线段
- 右键点击:完成当前多边形绘制;画线模式下取消未完成的绘制
- 拖动顶点:调整多边形/线段形状
- 拖动多边形:移动整个多边形;画线模式下可拖动整条线段
性能说明
组件用 三张叠在一起的透明画布,各管一类东西,这样改某一类时不必重画其它类:
| 层 | 画什么 | 什么时候重画 |
|---|---|---|
| 底层 | 所有「未选中」的已完成形状 | 增删形状、换选中项(要把旧选中补回 / 新选中拿掉) |
| 选中层 | 悬停预览(与选中同色同填、置顶、无控制点)+ 正式选中(控制点) | 换悬停、换选中、拖动/改点选中项 |
| 交互层 | 正在画、还没完成 的预览 | 多边形/线段落点跟手、矩形拖拽虚线框 |
悬停预览:
样式与层级和正式选中一致(selected-color / selected-line-color,并提到选中层置顶),区别只是:不出控制点、不改内部选中态、不发 select,只发 hover。
换悬停目标时会重画底层+选中层(形状要从底层挪上/挪回),开销与「点一下换选中」同级;同一目标上移动鼠标不会重复重画,拖拽仍只动选中那一个。
交互层现在的作用:
只负责「画到一半」的临时画面——例如多边形已点的顶点、连到鼠标的虚线、矩形拖出的虚线框。这些还不是正式数据里的形状,完成后会进底层/选中层,交互层清空。
它和「拖已有选中项」无关:拖已有形状走的是选中层,交互层保持空白。
为什么拖动能接近「每帧只画 1 个」:
未选中的形状印在底层且拖动时不碰;被拖的一定是选中项,只擦重选中层上的那一个。总数 10 个还是 1000 个,拖动时的绘制量差不多。
其它:
- 悬停/点击用空间网格做命中,形状多时不必每次从第一个扫到最后一个
update/update:polygons拖拽时实时跟手(每帧最多同步一次);松手再发update-finish- 支持
devicePixelRatio高分屏清晰绘制 - 父级 CSS
transform: scale不在组件内适配;若业务有缩放,请避免直接 scale 画布,或由使用方自行处理
许可证
MIT
Related Packages
@lazy-copilot/datetimepicker
2,602
1
@giliweb/datetimerangepicker
1,868
1
@ozjsey/v-select-text
Vue 3 directive for reactive text selection — select the rendered text of any el...
11
0
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.2.6 | ^3.3.0 | ||
| 1.2.5 | ^3.3.0 | ||
| 1.2.4 | ^3.3.0 | ||
| 1.2.3 | ^3.3.0 | ||
| 1.2.2 | ^3.3.0 | ||
| 1.2.1 | ^3.3.0 | ||
| 1.2.0 | ^3.3.0 | ||
| 1.1.9 | ^3.3.0 | ||
| 1.1.8 | ^3.3.0 | ||
| 1.1.7 | ^3.3.0 | ||
| 1.1.6 | ^3.3.0 | ||
| 1.1.5 | ^3.3.0 | ||
| 1.1.4 | ^3.3.0 | ||
| 1.1.3 | ^3.3.0 | ||
| 1.1.2 | ^3.3.0 | ||
| 1.1.0 | ^3.3.0 | ||
| 1.0.9 | ^3.3.0 | ||
| 1.0.8 | ^3.3.0 | ||
| 1.0.7 | ^3.3.0 | ||
| 1.0.6 | ^3.3.0 | ||
| 1.0.5 | ^3.3.0 | ||
| 1.0.4 | ^3.3.0 | ||
| 1.0.3 | ^3.3.0 | ||
| 1.0.2 | ^3.3.0 | ||
| 1.0.1 | ^3.3.0 | ||
| 1.0.0 | ^3.3.0 |