• Stars
    star
    251
  • Rank 161,862 (Top 4 %)
  • Language
    JavaScript
  • Created over 2 years ago
  • Updated 12 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

一个在线小白板,类似excalidraw。

界面截图1

一个在线小白板

  • 支持绘制矩形、菱形、三角形、圆形、线段、箭头、自由画笔、文字、图片

  • 绘制的图形支持拖动、缩放、旋转、编组

  • 支持垂直方向无限滚动,一块无限高度的白板

  • 支持放大缩小

  • 支持样式设置

  • 橡皮擦功能

  • 支持导入、导出

  • 支持前进回退

  • 本地存储

  • 滚动超出后支持一键回到内容

  • 支持多选

  • 支持网格模式

  • 支持只读模式,只读模式支持随意拖拽

  • 支持快捷键

相关文章

我做了一个在线白板!

我做了一个在线白板(二)

目录简介

1./tiny-whiteboard

在线白板工具库,不依赖任何框架。

2./app

使用tiny-whiteboard工具库,基于vue3.xElementPlus搭建的在线demo

本地开发

开发

git clone https://github.com/wanglin2/tiny_whiteboard.git
cd tiny_whiteboard

cd tiny-whiteboard

package.json文件里的下列字段删除:

"main": "./dist/tiny-whiteboard.umd.js",
"module": "./dist/tiny-whiteboard.es.js",
"exports": {
    ".": {
        "import": "./dist/tiny-whiteboard.es.js",
        "require": "./dist/tiny-whiteboard.umd.js"
    }
}

替换为:

"main": "./src/index.js",

然后执行:

npm i
npm link

cd ..
cd app
npm i
npm link tiny-whiteboard
npm run dev

这样修改tiny-whiteboard的代码即可实时生效进行调试。

打包demo

cd app
npm run build

打包tiny-whiteboard

cd tiny-whiteboard
npm run build

即可生成dist目录,如果要将包的入口指向打包后的文件,请恢复前面对package.json文件做的操作。

安装

npm i tiny-whiteboard

使用

提供一个宽高不为0的且定位不为static的容器元素,然后实例化tiny-whiteboard

import TinyWhiteboard from "tiny-whiteboard";

// 创建实例
let app = new TinyWhiteboard({
    container: container
});
// 接下来可以调用实例`app`的各种方法或者监听各种事件。
// 具体可以参考/app项目的示例。

限制

1.因实现方式原因,元素多了可能会存在性能和卡顿问题,请三思而后用。

2.因元素点击检测实现方式原因,目前不支持贝塞尔曲线或椭圆之类的图形。

坐标转换相关

项目内涉及到坐标转换相关的比较复杂和凌乱,如果没有搞清楚很容易迷失。大体上有以下这些:

1.鼠标坐标是相对屏幕的,需要转换成相对容器的,也就是鼠标坐标的xy需要减去容器和屏幕左侧及上方的距离。

2.元素的坐标都是相对容器坐标系的,也就是屏幕坐标系,原点在左上角,向右及向下为正方向,而画布的坐标在中心位置,也就是容器的中心点,也是向右及向下为正方向,所以绘制元素时需要把元素坐标转换成画布坐标,具体来说就是元素的xy坐标需要容器宽高的1/2

3.画布滚动后,鼠标滚动时只支持垂直方向滚动,只读模式下可以鼠标按住画布进行任意拖动,滚动只是单纯记录一个滚动偏移量scrollXscrollY,元素的实际坐标是没有变化的,只是在绘制元素的时候加上了scrollXscrollY,向上和向右滚动时scroll值为正,向下和向左滚动为负,元素的xy坐标需要减去scrollXscrollY

4.画布缩放后,缩放是应用在画布整体上,元素的实际位置和大小是没有变化的,所以当检测位置时鼠标的位置需要反向缩放才能对应到元素的实际坐标,具体来说就是鼠标坐标先转成画布坐标,然后除以缩放值,最后再转换屏幕坐标。

5.当元素旋转后,元素的大小和位置的值是没有变化的,只是通过rotate值进行了旋转,所以当通过鼠标位置检测元素时,鼠标的位置需要以元素的中心为旋转中心,反向进行旋转,然后再进行计算。

6.当开启网格时,坐标会和网格对齐,也就是坐标需要对网格的大小取余,然后减去该余数。

文档

1.实例化

<div id="container"></div>
import TinyWhiteboard from "tiny-whiteboard";

// 创建实例
let app = new TinyWhiteboard({
    container: document.getElementById('container')
});

实例化选项

字段名称 类型 默认值 描述 是否必填
container Element 容器元素
drawType String selection 当前画布的绘制模式,比如选择模式、矩形绘制模式、自由画笔模式等等
state Object {} 画布状态,对象,具体的属性请参考表格1-1

表格1-1 画布状态对象state的属性

字段名称 类型 默认值 描述
scale Number 1 画布的缩放值,0-1
scrollX Number 0 画布水平方向的滚动偏移量
scrollY Number 0 画布垂直方向的滚动偏移量
scrollStep Number 50 画布滚动步长
backgroundColor String 画布背景颜色
strokeStyle(v0.1.11+) String #000000 默认线条颜色
fillStyle(v0.1.11+) String transparent 默认填充颜色
fontFamily(v0.1.11+) String 微软雅黑, Microsoft YaHei 默认文字字体
fontSize(v0.1.11+) Number 18 默认文字字号
dragStrokeStyle(v0.1.11+) String #666 选中元素的拖拽元素的默认线条颜色
showGrid Boolean false 画布是否显示网格
readonly Boolean false 画布是否是只读模式
gridConfig Object {size: 20,strokeStyle: "#dfe0e1",lineWidth: 1} 画布网格配置,size(网格大小)、strokeStyle(网格线条颜色)、lineWidth(网格线条宽度)

实例属性

属性名称 类型 描述
opts Object 实例化选项
container Element 容器元素
drawType String 画布当前绘制模式
canvas Element 主画布元素
ctx Object 主画布元素的绘图上下文
state Object 画布当前状态

实例方法

undo()

回退。

redo()

前进。

setActiveElementStyle(style)

为画布当前激活的元素设置样式。

  • style:样式对象,object类型,具体属性请参考表格1-2。

表格1-2 元素样式对象style属性

属性名 类型 默认值 描述
strokeStyle String #000000 线条颜色
fillStyle String transparent 填充颜色
lineWidth String small 线条宽度,small(2px)、middle(4px)、large(6px)
lineDash Number 0 线条虚线大小
globalAlpha Number 1 透明度
fontSize Number 18 字号,文本元素特有样式
lineHeightRatio Number 1.5 行高,文本元素特有样式
fontFamily String 微软雅黑, Microsoft YaHei 字体,文本元素特有样式

setSelectedElementStyle(style)

为当前多选元素设置样式。

  • style:样式对象,可参考表格1-2。

setCurrentElementsStyle(style)

为当前激活或选中的元素设置样式。

  • style:样式对象,可参考表格1-2。

cancelActiveElement()

移除当前激活元素,即取消当前激活元素的激活状态。

deleteActiveElement()

从画布中删除当前的激活元素。

deleteCurrentElements()

从画布中删除当前激活或选中的元素。

copyCurrentElement()

复制当前激活或选中的元素。只是复制操作,如果需要粘贴需要调用下面的pasteCurrentElement()方法。

cutCurrentElement()

剪切当前激活或选中的元素。只是剪切操作,如果需要粘贴需要调用下面的pasteCurrentElement()方法。

pasteCurrentElement(useCurrentEventPos = false)

粘贴被复制或剪切的元素。

  • useCurrentEventPos:是否使用鼠标当前的位置,默认为false,偏移原图形20px,传true则粘贴到鼠标当前所在的位置。

copyPasteCurrentElements()

复制粘贴当前元素。

exportImage(opt)

导出为图片

  • opt:导出选项,Object,具体属性如下:

    • opt.type:导出图片类型,String,默认为image/png

    • opt.renderBg:是否显示背景,Boolean,默认为true

    • opt.useBlob:是否以blob类型导出,Boolean,默认为DataURL类型,以blob类型导出时函数的返回值是一个promise

    • opt.paddingX:绘制的水平内边距,Number,默认为10像素;

    • opt.paddingY:绘制的垂直内边距,Number,默认为10像素;

    • opt.onlySelected:(v0.1.7+)。是否仅导出被选中的元素,Boolean,默认为false

exportJson()

导出为json数据。

showGrid()

显示网格。

hideGrid()

隐藏网格。

updateGrid(config)

更新网格配置。

  • config:配置对象,Object,具体配置可参考表格1-1 的gridConfig属性。

setEditMode()

设置为编辑模式。

setReadonlyMode()

设置为只读模式。

setData(data, noEmitChange)

设置画布数据,包括状态数据及元素数据。

  • data:数据,一般是通过调用getData()方法获取到的数据进行回填,Object,包括以下两个字段:

    • data.state:画布状态数据,Object,详情请参考表格1-1。

    • data.elements:画布上的元素数据,Array

    • noEmitChange:禁止触发历史记录收集及change事件触发,Boolean,默认为false,某些场景下需要设置为true避免无限循环。

resize()

当容器的大小变化后需要调用该方法。

updateState(data)

更新画布状态数据,只是更新状态数据,不会触发重新渲染,如有需要重新渲染或其他操作需要自行调用相关方法。

  • data: 画布状态,Object,详情可参考表格1-1。

updateCurrentType(drawType)

更新画布当前绘制模式。

  • drawType:绘制模式,String,可选值如下表格所示:
描述
selection 选择模式,该模式下可以单击某个元素进行激活元素,或进行多选元素操作
rectangle 矩形绘制模式
diamond 菱形绘制模式
triangle 三角形绘制模式
circle 圆形绘制模式
line 线段绘制模式
arrow 箭头绘制模式
freedraw 自由画笔绘制模式
text 文字绘制模式
image 图片绘制模式
eraser 橡皮擦模式

deleteElement(element)

从画布删除某个元素。

copyElement(element, notActive = false, pos)

复制指定的元素。

  • notActive:只复制而不激活,Boolean,默认为false

  • pos:是否指定坐标,否则会偏移原位置20像素,Object,格式为{x, y}

empty()

清空元素。

zoomIn(num)

放大。

  • num:放大值,Number,默认为0.1

zoomOut(num)

缩小。

  • num:缩小值,Number,默认为0.1

setZoom(zoom)

设置指定缩放值。

  • zoomNumber0-1

fit()

缩放移动合适的值以适应所有元素。

setBackgroundColor(color)

设置背景颜色。

getData()

获取数据,包括状态数据及元素数据,可进行持久化。

scrollTo(scrollX, scrollY)

滚动至指定位置。

  • scrollX, scrollY:滚动距离,Number

scrollToCenter()

滚动至中心,即定位到所有元素的中心位置。

resetCurrentType()

复位当前画布绘制模式到选择模式。

selectAll()

选中所有元素。

on(eventName, callback, context)

监听事件。事件请见下方表格:

事件名称 描述 回调参数
zoomChange 缩放时触发 scale(当前缩放值)
scrollChange 滚动时触发 scrollX(当前水平滚动值)、scrollY(当前垂直滚动值)
currentTypeChange 绘制模式变化时触发 drawType(当前绘制模式)
change 画布状态数据变化或元素变化时触发 data(状态和元素数据)
shuttle 前进后退时触发 index(当前指针)、length(当前历史记录数量)
activeElementChange 激活元素变化事件 activeElement(当前激活的元素)
multiSelectChange 多选元素选择完成时触发 selectedElementList(当前被多选选中的元素)
contextmenu(v0.1.5+) 右键菜单事件 e(事件对象)、elements(当前激活或选中的元素)

emit(eventName, ...args)

触发事件。

off(eventName, callback?)

解绑事件。

selectAll()

选中所有元素。

fit()

缩放以适应所有元素。

updateActiveElementPosition(x, y)

v0.1.4+。更新当前激活元素的位置。

updateActiveElementSize(width, height)

v0.1.4+。更新当前激活元素的尺寸。

updateActiveElementRotate(rotate)

v0.1.4+。更新当前激活元素的旋转角度。

moveUpCurrentElement()

v0.1.5+。将当前元素上移一层。

moveDownCurrentElement()

v0.1.5+。将当前元素下移一层。

moveTopCurrentElement()

v0.1.5+。将当前元素置于顶层。

moveBottomCurrentElement()

v0.1.5+。将当前元素置于底层。

2.elements元素管理实例

可通过app.elements获取到该实例。

实例属性

属性名称 类型 描述
elementList Array 当前画布中的所有元素列表
activeElement Object 当前激活的元素
isCreatingElement Boolean 当前是否正在创建新元素
isResizing Boolean 当前是否正在调整元素
resizingElement Object 当前正在调整的元素

实例方法

hasElements()

当前画布上是否有元素。

getElementsNum()

v0.1.5+。获取当前画布上的元素数量。

addElement(element)

添加元素。不会触发渲染,需要手动调用app.render.render()方法重新渲染。

unshiftElement(element)

v0.1.5+。向前添加元素。

insertElement(element, index)

v0.1.5+。添加元素到指定位置。

getElementIndex(element)

v0.1.5+。获取元素在元素列表里的索引。

deleteElement(element)

删除元素。不会触发渲染,需要手动调用app.render.render()方法重新渲染。

deleteAllElements()

删除全部元素。不会触发渲染,需要手动调用app.render.render()方法重新渲染。

hasActiveElement()

是否存在激活元素。

setActiveElement(element)

替换激活的元素。不会触发渲染,需要手动调用app.render.render()方法重新渲染。

cancelActiveElement()

取消当前激活元素。不会触发渲染,需要手动调用app.render.render()方法重新渲染。

createElement(opts = {}, callback = () => {}, ctx = null, notActive)

创建元素。不会触发渲染,需要手动调用app.render.render()方法重新渲染。

  • opts:创建元素的选项;

  • callback:回调函数,回调参数:element(创建的元素);

  • ctx:回调函数的上下文对象;

  • notActive:是否不要激活该新创建的元素,默认为false

serialize(stringify)

序列化当前画布上的所有元素,可用来持久化数据。

  • stringify:默认为false,返回json对象类型,传true则返回字符串类型。

createElementsFromData(elements = [])

根据元素数据创建元素,即根据持久化的数据反向创建元素到画布上。不会触发渲染,需要手动调用app.render.render()方法重新渲染。

3.render渲染类

可通过app.render获取到该实例。

该实例的所有方法都已代理到app实例上,可以直接通过app.xxx调用。

4.coordinate坐标转换实例

可通过app.coordinate获取到该实例。

实例方法

addScrollY(y)

加上画布当前垂直的滚动距离。

addScrollX(x)

加上画布当前水平的滚动距离。

subScrollY(y)

减去画布当前垂直的滚动距离。

subScrollX(x)

减去画布当前水平的滚动距离。

transformToCanvasCoordinate(x, y)

屏幕坐标转换成画布坐标。

transformToScreenCoordinate(x, y)

画布转换转屏幕坐标。

transform(x, y)

综合转换,屏幕坐标转画布坐标,再减去滚动值。

windowToContainer(x, y)

相对窗口的坐标转换成相对容器的,用于当容器非全屏的时候。

containerToWindow(x, y)

相对容器的坐标转换成相对窗口的,用于当容器非全屏的时候。

scale(x, y)

屏幕坐标在应用画布缩放后的位置。

reverseScale(x, y)

屏幕坐标在反向应用画布缩放后的位置。

gridAdsorbent(x, y)

网格吸附。

5.event事件实例

可通过app.event获取该实例。

实例方法

on(eventName, callback, context)

监听事件。事件请见下方表格:

事件名称 描述 回调参数
mousedown 鼠标按下事件 e、事件实例对象event
mousemove 鼠标移动事件 e、事件实例对象event
mouseup 鼠标松开事件 e、事件实例对象event
dblclick 双击事件 e、事件实例对象event
mousewheel 鼠标滚动事件 dir(滚动方向,down代表向下,up代表向上)
keydown 按键按下事件 e(原始事件对象)、事件实例对象event
keyup 按键松开事件 e(原始事件对象)、事件实例对象event
  • e:事件对象,非原始事件对象,为处理后的事件对象,格式如下:

    {
          originEvent: e,// 原始事件对象
          unGridClientX,
          unGridClientY,
          clientX,
          clientY
    }

    clientXclientY是经过了一系列转换的:

    1.将相当于浏览器窗口左上角的坐标转换成相对容器左上角

    2.如果画布进行了缩放,那么鼠标坐标要反向进行缩放

    3.xy坐标加上了画布水平和垂直的滚动距离scrollXscrollY

    4.如果开启了网格,那么坐标要吸附到网格上

    unGridClientXunGridClientYclientXclientY的区别是没有经过第四步的处理。用于位置检测等不需要吸附的场景。

    对于第三步来说,向下滚动scroll值为正,而canvas坐标系向下为正,所以要造成元素向上滚动的效果显示的时候元素的y坐标需要减去scroll值,但是元素真实的y值并未改变,所以对于鼠标坐标来说需要加上scroll值,这样才能匹配元素真实的y坐标,水平方向也是一样的。

  • event:事件类的实例对象,存在以下属性:

    属性名称 类型 描述
    isMousedown Boolean 鼠标是否按下
    mousedownPos Object 按下时的鼠标位置,格式见下方。
    mouseOffset Object 鼠标当前位置和按下时位置的差值,格式见下方。
    lastMousePos Object 记录上一时刻的鼠标位置,格式为{x, y},经过处理的坐标。
    mouseDistance Number 前一瞬间的鼠标移动距离。
    lastMouseTime Number 记录上一时刻的时间,时间戳格式。
    mouseDuration Number 前一瞬间经过的时间,单位为毫秒。
    mouseSpeed Number 前一瞬间的鼠标移动速度,单位为px/ms。
    • mousedownPos属性格式:

      {
            x: 0,// 经过了以上4步转换后的坐标
            y: 0,
            unGridClientX: 0,// 经过了除第4步的坐标
            unGridClientY: 0,
            originClientX: 0,// 原始没有经过任何处理的坐标
            originClientY: 0
      }
    • mouseOffset属性格式:

      {
            x: 0,// 经过了以上4步转换后的坐标差数据
            y: 0,
            originX: 0,// 原始没有经过任何处理的坐标差数据
            originY: 0
      }

emit(eventName, ...args)

触发事件。

off(eventName, callback?)

解绑事件。

6.cursor鼠标样式实例

可通过app.cursor获取该实例。

实例方法

set(type = "default")

设置鼠标指针样式。

hide()

隐藏鼠标指针。

reset()

复位鼠标指针。

setCrosshair()

设置为 ✚ 字型。

setMove()

设置为 可移动 状态。

setEraser()

设置为橡皮擦样式。

7.history历史记录管理实例

可通过app.history获取该实例。

实例方法

undo()

后退。

redo()

前进。

add(data)

添加一个历史记录数据,data一般是通过app.getData()获取到的数据。

clear()

清空历史记录数据。

8.export导入导出实例

可通过app.export获取该实例。

实例方法

exportImage(opt)

导出为图片,参数详见前面的文档。

exportJson()

导出为json数据。

9.background背景设置实例

可通过app.background获取该实例。

实例方法

addBackgroundColor()

添加背景颜色,背景色值为app.state.backgroundColor

remove()

移除背景。

canvasAddBackgroundColor(ctx, width, height, backgroundColor)

给一个canvas设置背景颜色,非css样式。

  • ctxcanvas绘图上下文。

10.selection多选实例

可通过app.selection获取该实例。

实例方法

selectElements(elements = [])

选中指定元素。

copySelectionElements(pos)

复制粘贴当前选中的元素。

  • pos:是否指定粘贴的坐标,否则会偏移原位置20像素,Object,格式为{x, y}

getSelectionElements()

获取当前被选中的元素。

hasSelectionElements()

当前是否存在被选中元素。

deleteSelectedElements()

从画布删除当前选中的元素。

setSelectedElementStyle(style)

为当前选中的元素设置样式。

11.mode模式实例

可通过app.mode获取该实例。

实例方法

setEditMode()

设置为编辑模式。

setReadonlyMode()

设置为只读模式。

12.imageEdit图片选择实例

可通过app.imageEdit获取该实例。

13.textEdit文字编辑实例

可通过app.textEdit获取该实例。

14.keyCommand快捷键实例

可通过app.keyCommand获取该实例。

实例属性

属性名称 类型 描述
keyMap Object 按键的名称到keyCode映射。

实例方法

bindEvent()

绑定keydown事件。

unBindEvent()

解绑keydown事件。如果你的事件会和快捷键冲突,那么可以暂时调用该方法解绑快捷键的keydown事件。

addShortcut(key, fn, ctx)

添加快捷键命令。

  • key:快捷键,允许三种组合方式:单个按键(如Enter)、或(Tab | Insert)、与(Shift + a),具体的按键名称可以app.keyCommand.keyMap查看。

  • fn:快捷键对应的执行函数。

  • ctx:函数的上下文。

removeShortcut(key, fn)

移除快捷键命令。

15.工具方法

可以通过如下方式获取到内置的工具方法:

import TinyWhiteboard from "tiny-whiteboard";

TinyWhiteboard.utils.xxx

createCanvas(width,height,opt = { noStyle: false, noTranslate: false, className: '' })

创建canvas元素。

  • width:宽度

  • height:高度

  • opt:选项

    • opt.noStyle:是否不需要设置样式,如果需要的话,那么会给canvas元素加上left=0top=0的绝对定位样式;
    • noTranslate:是否不需要将画布原点移动到画布中心;
    • className:添加到画布元素上的类名;

getTowPointDistance(x1, y1, x2, y2)

计算两点之间的距离。

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

计算点到直线的距离。

checkIsAtSegment(x, y, x1, y1, x2, y2, dis = 10)

检查是否点击到了一条线段。

  • dis:点距离线段多少距离内都认为是点击到了;

radToDeg(rad)

弧度转角度。

degToRad(deg)

角度转弧度。

getTowPointRotate(cx, cy, tx, ty, fx, fy)

计算中心点相同的两个坐标相差的角度数。

getRotatedPoint(x, y, cx, cy, rotate)

获取坐标经指定中心点旋转指定角度的坐标,顺时针还是逆时针rotate传正负即可。

getElementCenterPoint(element)

获取元素的中心点坐标。

  • element:元素,Object,必要的字段如为{ x, y, width, height }

getElementCornerPoint(element, dir)

获取元素的四个角坐标。

  • element:元素,Object,必要的字段如为{ x, y, width, height }

  • dir:要获取的哪个角,可选项为:topLefttopRightbottomRightbottomLeft

getElementRotatedCornerPoint(element, dir)

获取元素旋转后的四个角坐标。参数同上。

checkPointIsInRectangle(x, y, rx, ry, rw, rh)

判断一个坐标是否在一个矩形内。第三个参数可以直接传一个带有xywidthheight属性的元素对象。

getBoundingRect(pointArr = [], returnCorners = false)

获取多个点的外包围框。

返回数据:

{
  x,
  y,
  width,
  height,
}
  • pointArr:点数组,数组的每一项的格式为:[x, y]

  • returnCorners:v0.1.4+。以四个角坐标的形式返回:

[
  [x0, y0],
  [x1, y1],
  [x2, y2],
  [x3, y3],
]

deepCopy(obj)

简单深拷贝,只能用于拷贝纯粹的对象。

getFontString(fontSize, fontFamily)

拼接canvas文字字体字号字符串。

splitTextLines(text)

将文本切割成行,返回一个数组。

getTextActWidth(text, style)

计算文本的实际渲染宽度。

  • style:对象类型,包含fontSizefontFamily两个属性;

getWrapTextMaxRowTextNumber(text)

计算换行文本的最长一行的文字数量。

throttle(fn, ctx, time = 100)

节流函数。

downloadFile(file, fileName)

下载文件。

getElementCorners(element)

获取元素的四个角的坐标,应用了旋转之后的,返回一个数组。

getMultiElementRectInfo(elementList = [])

获取多个元素的最外层包围框信息。返回{minx,maxx,miny,maxy};

createImageObj(url)

创建图片对象,即new Image()的图片对象,返回promise

16.图形绘制工具方法

可以通过如下方式获取到内置的图形绘制工具方法:

import TinyWhiteboard from "tiny-whiteboard";

TinyWhiteboard.draw.xxx

drawRect(ctx, x, y, width, height, fill = false)

绘制矩形。

  • ctxcanvas绘图上下文。

  • fill:是否进行填充。

drawDiamond(ctx, x, y, width, height, fill = false)

绘制菱形。

drawTriangle(ctx, x, y, width, height, fill = false)

绘制三角形。

drawCircle(ctx, x, y, r, fill = false)

绘制圆形。

drawLine(ctx, points)

绘制折线。

  • points:折线的端点列表。Array,数组的每一项为[x, y]

drawArrow(ctx, pointArr)

绘制箭头。

pointArr:箭头的首尾两个顶点坐标,Array,数组的每一项为[x, y]

drawLineSegment(ctx, mx, my, tx, ty, lineWidth = 0)

绘制线段。

  • lineWidth:线宽

drawText(ctx, textObj, x, y)

绘制文字。

  • textObj:文本数据,Object,字段如下:
    • textObj.text:文本字符串;
    • textObj.style:文本属性,Object,需包含三个字段:fontSizefontFamilylineHeightRatio(行高,需为数字类型,比如1.5,代表行高1.5倍)

drawImage(ctx, element, x, y, width, height)

绘制图片。

element:图片数据,Object,字段如下:

element.ratio:图片的长宽比;

element.imageObj:要绘制到canvas上的图片对象或其他能被canvas绘制的对象;

17.图形点击检测工具方法

可以通过如下方式获取到内置的图形点击检测工具方法:

import TinyWhiteboard from "tiny-whiteboard";

TinyWhiteboard.checkHit.xxx

checkIsAtMultiSegment(segments, rp)

检测是否点击到折线上。

  • segments:折线的端点数组,Array,数组的每一项为[fx, fy, tx, ty],即线段的首尾两个坐标;

  • rp:要检测的点,格式为{x, y}

checkIsAtRectangleEdge(element, rp)

检测是否点击到矩形边缘。

  • elementObject,需包含字段{ x, y, width, height }

checkIsAtRectangleInner(element, rp)

检测是否点击到矩形内部。

checkIsAtCircleEdge(element, rp)

检测是否点击到圆的边缘,圆的半径为widthheight中的较小值的一半。

checkIsAtLineEdge(element, rp)

检测是否点击到线段边缘。

  • elementObject,格式如下:
{
    pointArr: [
        [x, y],
        ...
    ]
}

checkIsAtFreedrawLineEdge(element, rp)

检测是否点击到自由画笔图形边缘。element字段同上。

checkIsAtDiamondEdge(element, rp)

检测是否点击到菱形边缘。

  • elementObject,需包含字段{ x, y, width, height }

checkIsAtTriangleEdge(element, rp)

检测是否点击到三角形边缘。

  • elementObject,需包含字段{ x, y, width, height }

checkIsAtArrowEdge(element, rp)

检测是否点击到箭头边缘。

  • elementObject,格式如下:
{
    pointArr: [
        [x1, y1],
        [x2, y2]
    ]
}

18.内置元素类

可以通过以下方式获取到某个元素类:

import TinyWhiteboard from "tiny-whiteboard";

TinyWhiteboard.elements.xxx

目前存在以下元素类:

类名 简介
BaseElement 基础元素类,不用来实例化
Arrow 箭头元素类,继承自BaseElement
Circle 正圆元素类,继承自BaseElement
Diamond 菱形元素类,继承自BaseElement
Image 图片元素类,继承自BaseElement
Rectangle 矩形元素类,继承自BaseElement
Text 文本元素类,继承自BaseElement
Triangle 三角形元素类,继承自BaseElement
BaseMultiPointElement 由多个坐标组成的元素的基础类,继承自BaseElement,不用来实例化
Freedraw 自由画笔元素类,继承自BaseMultiPointElement
Line 线段/折线元素类,继承自BaseMultiPointElement
DragElement 拖拽元素类,继承自BaseElement,每个元素都会实例化一个该类,用来当元素激活时显示拖拽框及进行元素调整操作
MultiSelectElement 用于多选情况下的虚拟元素类,继承自BaseElement

基础元素实例属性

属性名称 类型 描述
type String 元素类型
isActive Boolean 是否被激活
isSelected Boolean 是否被多选选中
x、y Number 元素的位置
width、height Number 元素的宽高
rotate Number 元素的旋转角度
style Object 元素的样式对象
pointArr Array 由多个点组成的元素(Arrow、Line、Freedraw)的特有属性。组成元素的点坐标数组。

基础元素实例方法

on(eventName, callback, context)

v0.1.4+。监听元素事件。事件请见下方表格:

事件名称 描述 回调参数
elementPositionChange 元素x、y坐标发生变化时触发 x、y
elementSizeChange 元素width、height大小发生变化时触发 width、height
elementRotateChange 元素rotate旋转角度发生变化时触发 rotate

serialize()

序列化元素,返回的数据可用于进行持久化及回显。

render()

渲染元素。

setStyle(style = {})

设置元素的绘图样式。

move(ox, oy)

移动元素,在元素当前的位置上累加oxoy

updatePos(x, y)

更新元素的位置。

updateSize(width, height)

更新元素的宽高。

updateRect(x, y, width, height)

更新元素的位置及宽高。

offsetRotate(or)

旋转元素,在元素当前的旋转角度上累加or角度。

rotateByCenter(rotate, cx, cy)

根据指定中心点旋转元素的各个点。对于由多个点坐标组成的元素来说是修改其pointArr坐标,对于其他元素来说是修改其x、y坐标。

isHit(x, y)

检测该坐标是否能击中该元素。

getEndpointList()

v0.1.4+。获取图形应用了旋转之后的端点列表。可用于计算元素的外包围框数据。

License

MIT

More Repositories

1

mind-map

一个还算强大的Web思维导图。A relatively powerful web mind map.
JavaScript
5,290
star
2

code-run

一个代码在线编辑预览工具,类似codepen、jsbin、jsfiddle等。
JavaScript
501
star
3

douban_api

豆瓣API服务
JavaScript
143
star
4

VideoTimeLine

一个简单的Vue2视频时间轴组件
Vue
97
star
5

markjs

一个插件化的多边形标注库
JavaScript
89
star
6

snow

看,下雪了~
JavaScript
83
star
7

web_map_demo

Web地图demo,一个简单的2D地图加载器,支持拖动、缩放、显示叠加物、搜索。
Vue
83
star
8

lx-doc

理想文档。定位于个人和小团队的在线云文档。支持思维导图、白板、流程图、PPT、电子表格等
JavaScript
67
star
9

canvas-editor-demo

一个基于canvas实现的富文本编辑器demo,仅仅是demo。
JavaScript
62
star
10

simple-flow-chart

一个简单的流程图设计器,基于Vue2。
Vue
48
star
11

markdown_editor_sync_scroll_demo

Markdown编辑器精确同步滚动demo
HTML
21
star
12

tree_layout

绘制一棵漂亮的树,可用于绘制思维导图。
JavaScript
18
star
13

front-article

小前端【街角小林】所有的前端原创文章。
15
star
14

simple-novice-guide

一个简单的新手引导库
TypeScript
14
star
15

AssociationLineDemo

图形之间的关联线连接demo。
HTML
13
star
16

json-tree-view

一个简洁的json格式化插件。
JavaScript
12
star
17

VNode_visualization

虚拟DOM的diff算法动画演示
JavaScript
11
star
18

visual-drag-platform-fit-demo

可视化拖拽平台的页面屏幕适应方案
Vue
10
star
19

web_articles

前端优质文章集锦
8
star
20

simple-word-cloud

一个简单的词云库
JavaScript
8
star
21

wanglin2

7
star
22

PolygonEditDemo

一个简单的多边形编辑器demo
Vue
6
star
23

handPaintedStyle

手绘风格图形的简单实现
Vue
5
star
24

download-image-demo

前端下载图片的N种方法
Vue
5
star
25

VNode-Demo

虚拟dom的diff demo
JavaScript
4
star
26

vite-demo

JavaScript
4
star
27

ES_Modules_CDN

支持ES模块的cdn服务demo。
JavaScript
3
star
28

simple-canvas-editor

一个使用canvas实现的简单富文本编辑器。
HTML
3
star
29

pieChart

一个简单的饼图
Vue
3
star
30

ComponentLibraryImport

组件库实现按需引入的几种方式
Vue
3
star
31

literature-articles

个人原创的文学文章。
CSS
3
star
32

vue_v0.11_analysis

vue0.11版本源码阅读系列文章
JavaScript
2
star
33

simulateCSSBackgroundInCanvas

在canvas中模拟css的background相关样式
JavaScript
2
star
34

nice-doc

个人文档平台
2
star
35

learn_vue_2.6.0

Vue2.6.1源码阅读系列
JavaScript
2
star
36

textUnderline

文本划线的极简实现
Vue
2
star
37

canvas-in-action

Canvas实战系列文章。
CSS
2
star
38

mind-map-themes

提供更多的mind-map主题。
1
star
39

es5-es5-inherit-example

ES6和ES5继承的示例
JavaScript
1
star
40

collect

个人收藏夹
1
star
41

vue_dynamic_import_component

vue动态引入组件demo
JavaScript
1
star
42

playground

Vue3代码在线运行工具
JavaScript
1
star
43

esm_cjs

JavaScript
1
star
44

hannuota

汉诺塔小游戏
Vue
1
star
45

tiny_whiteboard_demo

tiny_whiteboard在线demo,非可读仓库,请勿关注。
JavaScript
1
star
46

text_diff_demo

文本diff demo
JavaScript
1
star
47

code-run-online

CodeRun在线示例
JavaScript
1
star
48

vue_components

一个monorepo类型的组件库
JavaScript
1
star
49

lx-doc-site

JavaScript
1
star
50

canvas-demos

Vue
1
star
51

whbm-nav

新开源系列:五花八门导航。
Vue
1
star
52

mind_map_test

无意义仓库,仅用于测试。
HTML
1
star