Bootstrap

在Vue中使用Excalidraw实现在线画板

概述

Excalidraw是一个非常好用的画图板工具,但是是用React写的,本文分享一种在Vue项目中使用的方法。

效果

image.png

image.png

实现

Excalidraw简介

这篇文章(Excalidraw 完美的绘图工具:https://zhuanlan.zhihu.com/p/684940131)介绍的很全面,大家移步可以过去看看。

使用

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': {}
  },
})

3.页面使用

在Vue文件中的使用方式如下:

<template>
  <div class="container">
    <div class="header">
      LZUGIS
      <button style="float: right" @click="save">Save</button>
    </div>
    <div class="excalidraw" id="excalidraw"></div>
    <div class="footer">@lzugis 2024</div>
  </div>
</template>

<script>
import { createRoot } from "react-dom/client";
import React from "react";
import { Excalidraw } from "@excalidraw/excalidraw";

let root = null,
  app = null;

export default {
  data() {
    return {};
  },
  mounted() {
    root = createRoot(document.getElementById("excalidraw"));
    const elements = JSON.parse(localStorage.getItem("excalidraw-elements"));
    const libs = JSON.parse(localStorage.getItem("excalidraw-libs"));
    const state = JSON.parse(localStorage.getItem("excalidraw-state"));
    const {
      theme,
      activeTool,
      name,
      scrollX,
      scrollY,
      zoom,
      offsetLeftm,
      offsetTop,
    } = state;
    root.render(
      React.createElement(Excalidraw, {
        name: "我的画板",
        initialData: {
          elements: elements,
          libraryItems: libs,
          appState: {
            theme,
            activeTool,
            name,
            scrollX,
            scrollY,
            zoom,
            offsetLeftm,
            offsetTop,
          },
        },
        langCode: "zh-CN",
        onChange: this.onChange,
        onLibraryChange: this.onLibraryChange,
        excalidrawAPI: this.excalidrawAPI,
        // props
      })
    );
  },
  unmounted() {
    root.unmount();
  },
  methods: {
    save() {
      if (app) {
        localStorage.setItem(
          "excalidraw-state",
          JSON.stringify(app.getAppState())
        );
        localStorage.setItem(
          "excalidraw-elements",
          JSON.stringify(app.getSceneElements())
        );
      }
    },
    onChange(e) {
      localStorage.setItem("excalidraw-elements", JSON.stringify(e));
    },
    onLibraryChange(e) {
      localStorage.setItem("excalidraw-libs", JSON.stringify(e));
    },
    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;
  }
}
</style>
;