Excalidraw概述
Excalidraw是一款开源的在线绘图工具,主要用于白板、思维导图、原型草图设计、流程图等场景。它基于Vite + React + TypeScript + Yarn + Husky的技术栈开发,目前开源star数量已经超过86k,深受开发者喜爱。
tips:体验地址 https://excalidraw.com
功能特点
- 手绘风格:Excalidraw支持手绘风格的草图设计,使得绘制过程更加自然和亲切。
- 多种图形元素:支持基本的几何形状如方框、圆、菱形等,并可以绘制连接线。
- 导出功能:支持将图形内容导出为图片或SVG格式,方便在其他设备上导入编辑。
- 多人协作:支持多人协同工作,可以通过分享链接让其他人加入同一个白板进行创作。
- 自定义主题:用户可以自定义主题风格,满足不同的业务场景需求。
使用场景
Excalidraw可以应用于多种场景,包括但不限于: - 草图设计:用于绘制手绘风格的草图。
- 思维导图和流程图:支持创建复杂的思维导图和流程图。
- 会议白板:适合在会议中使用,支持激光笔标注等功能。
- 知识管理:在Obsidian笔记应用中嵌入Excalidraw插件,用于组织和表达复杂信息
VUE集成
tips:官方文档 https://docs.excalidraw.com/docs
1. 引入依赖
npm install react react-dom @excalidraw/excalidraw
# 或
yarn add react react-dom @excalidraw/excalidraw
2. 添加配置
修改vite.config.js,添加如下配置:
export default defineConfig({
...,
define: {
'process.env': {}
},
})
2. 添加页面
tips:GitHub解决办法仅能初始化画板,不能获取浏览器缓存信息,需要在初始化进行处理
<template>
<div class="container">
<div class="excalidraw" id="excalidraw"></div>
</div>
</template>
<script>
import React from 'react'
import { createRoot } from 'react-dom/client'
import { Excalidraw } from '@excalidraw/excalidraw'
let root = null
let app = null
export default {
data() {
return {
appState: {
// 默认的 appState 配置
viewBackgroundColor: '#fff', // 画布背景颜色
currentItemStrokeColor: '#000000', // 当前绘画工具颜色
currentItemBackgroundColor: '#ffffff', // 当前工具填充颜色
activeTool: 'selection', // 默认工具为选择工具
zoom: 1 // 缩放比例
}
}
},
mounted() {
// 组件挂载时恢复绘画数据和 appState
this.initializeExcalidraw()
},
unmounted() {
// 组件卸载时销毁 Excalidraw 实例
if (root) {
root.unmount()
}
},
methods: {
initializeExcalidraw() {
const savedElements = localStorage.getItem('excalidrawElements')
const savedAppState = localStorage.getItem('appState')
const initialData = savedElements
? JSON.parse(savedElements)
: { elements: [], appState: this.appState }
const appState = savedAppState ? JSON.parse(savedAppState) : this.appState
const excalidrawElement = React.createElement(Excalidraw, {
initialData: initialData,
onChange: this.handleDrawingChange,
excalidrawAPI: this.excalidrawAPI,
langCode: 'zh-CN'
})
root = createRoot(document.getElementById('excalidraw'))
root.render(excalidrawElement)
},
handleDrawingChange(elements, newAppState) {
let state = app.getAppState()
console.log(state, 'state')
let { collaborators, ...appState } = state
console.log(appState, 'appState')
// delete state.collaborators;
localStorage.setItem(
'excalidrawElements',
JSON.stringify({ elements, appState: appState })
)
},
excalidrawAPI(e) {
app = e
window.app = e
}
}
}
</script>
<style scoped lang="scss">
.container {
width: 100%;
height: 100vh;
overflow: hidden;
display: flex;
flex-direction: column;
.header {
height: 3rem;
line-height: 3rem;
padding: 0 1rem;
font-size: 1.2rem;
background-color: #038fe5;
color: white;
}
.footer {
height: 2rem;
line-height: 2rem;
text-align: center;
background-color: #038fe5;
color: white;
}
.excalidraw {
flex-grow: 1; /* 占满剩余空间 */
height: 100%;
}
}
</style>