关于Canvas-editor在vue3上的使用,可解决需求(部分可禁止编辑)

先说结论:经细致调研Canvas-editor完全可以在vue3中使用(虽然不是开箱即用版本),其内部为typeScript的写法,校之市面上其他editor有较为灵活的选择,如果你苦于寻找一款适合你项目的某个特殊功能的editor又不知道是否合适时,可以使用一下这个,绝对会是一个好的选择

  • 关于canvas-editor 

canvas-editor | rich text editor by canvas/svgrich text editor by canvas/svghttps://hufe.club/canvas-editor-docs/

  • 关于canvas-editor的文档

如您所见,文档中的demo还是不错的,而这个文档的存在价值好比鸡肋,主打体现一个“有”。

文档中所有的函数几乎都没有注释,参数基本全靠阅读源码,在开发过程中我们只需要-------------打开官网    ----》   找到github地址   ----》  然后关闭官网就可以了。

  • 关于canvas-editor的使用

不需要npm   不需要npm   不需要npm下载canvas-editor    我们只要下载源码包就可以了

该editor编辑器主要使用canvas进行渲染,运行起来还是不错的

  1. 下载源码后,最后将源码跑起来就能得到官网中所示的demo
  2. 源码中我们只需要取用关键的部分即可然后对关键部分中不合适的再删除掉
  3. 在自己的项目中新建组件Canvas-editor  将整个editor内的文件都复制进去,而后新建index.vue将以下部分html放到template中
    <div class="menu" editor-component="menu">
            <div class="menu-item">
              <div class="menu-item__undo">
                <i></i>
              </div>
              <div class="menu-item__redo">
                <i></i>
              </div>
              <div class="menu-item__painter" title="格式刷(双击可连续使用)">
                <i></i>
              </div>
              <div class="menu-item__format" title="清除格式">
                <i></i>
              </div>
            </div>
            <div class="menu-divider"></div>
            <div class="menu-item">
              <div class="menu-item__font">
                <span class="select" title="字体">微软雅黑</span>
                <div class="options">
                  <ul>
                    <li data-family="Microsoft YaHei" style="font-family: &quot;Microsoft YaHei&quot;">微软雅黑</li>
                    <li data-family="华文宋体" style="font-family: &quot;华文宋体&quot;">华文宋体</li>
                    <li data-family="华文黑体" style="font-family: &quot;华文黑体&quot;">华文黑体</li>
                    <li data-family="华文仿宋" style="font-family: &quot;华文仿宋&quot;">华文仿宋</li>
                    <li data-family="华文楷体" style="font-family: &quot;华文楷体&quot;">华文楷体</li>
                    <li data-family="华文琥珀" style="font-family: &quot;华文琥珀&quot;">华文琥珀</li>
                    <li data-family="华文楷体" style="font-family: &quot;华文楷体&quot;">华文楷体</li>
                    <li data-family="华文隶书" style="font-family: &quot;华文隶书&quot;">华文隶书</li>
                    <li data-family="华文新魏" style="font-family: &quot;华文新魏&quot;">华文新魏</li>
                    <li data-family="华文行楷" style="font-family: &quot;华文行楷&quot;">华文行楷</li>
                    <li data-family="华文中宋" style="font-family: &quot;华文中宋&quot;">华文中宋</li>
                    <li data-family="华文彩云" style="font-family: &quot;华文彩云&quot;">华文彩云</li>
                    <li data-family="Arial" style="font-family: &quot;Arial&quot;">Arial</li>
                    <li data-family="Segoe UI" style="font-family: &quot;Segoe UI&quot;">Segoe UI</li>
                    <li data-family="Ink Free" style="font-family: &quot;Ink Free&quot;">Ink Free</li>
                    <li data-family="Fantasy" style="font-family: &quot;Fantasy&quot;">Fantasy</li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__size">
                <span class="select" title="字体">小四</span>
                <div class="options">
                  <ul>
                    <li data-size="56">初号</li>
                    <li data-size="48">小初</li>
                    <li data-size="34">一号</li>
                    <li data-size="32">小一</li>
                    <li data-size="29">二号</li>
                    <li data-size="24">小二</li>
                    <li data-size="21">三号</li>
                    <li data-size="20">小三</li>
                    <li data-size="18">四号</li>
                    <li data-size="16">小四</li>
                    <li data-size="14">五号</li>
                    <li data-size="12">小五</li>
                    <li data-size="10">六号</li>
                    <li data-size="8">小六</li>
                    <li data-size="7">七号</li>
                    <li data-size="6">八号</li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__size-add">
                <i></i>
              </div>
              <div class="menu-item__size-minus">
                <i></i>
              </div>
              <div class="menu-item__bold">
                <i></i>
              </div>
              <div class="menu-item__italic">
                <i></i>
              </div>
              <div class="menu-item__underline">
                <i></i>
                <span class="select"></span>
                <div class="options">
                  <ul>
                    <li data-decoration-style="solid">
                      <i></i>
                    </li>
                    <li data-decoration-style="double">
                      <i></i>
                    </li>
                    <li data-decoration-style="dashed">
                      <i></i>
                    </li>
                    <li data-decoration-style="dotted">
                      <i></i>
                    </li>
                    <li data-decoration-style="wavy">
                      <i></i>
                    </li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__strikeout" title="删除线(Ctrl+Shift+X)">
                <i></i>
              </div>
              <div class="menu-item__superscript">
                <i></i>
              </div>
              <div class="menu-item__subscript">
                <i></i>
              </div>
              <div class="menu-item__color" title="字体颜色">
                <i></i>
                <span></span>
                <input type="color" id="color" />
              </div>
              <div class="menu-item__highlight" title="高亮">
                <i></i>
                <span></span>
                <input type="color" id="highlight" />
              </div>
            </div>
            <div class="menu-divider"></div>
            <div class="menu-item">
              <div class="menu-item__title">
                <i></i>
                <span class="select" title="切换标题">正文</span>
                <div class="options" style="width: 120px">
                  <ul>
                    <li style="font-size: 16px">正文</li>
                    <li data-level="first" style="font-size: 26px">标题1</li>
                    <li data-level="second" style="font-size: 24px">标题2</li>
                    <li data-level="third" style="font-size: 22px">标题3</li>
                    <li data-level="fourth" style="font-size: 20px">标题4</li>
                    <li data-level="fifth" style="font-size: 18px">标题5</li>
                    <li data-level="sixth" style="font-size: 16px">标题6</li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__left">
                <i></i>
              </div>
              <div class="menu-item__center">
                <i></i>
              </div>
              <div class="menu-item__right">
                <i></i>
              </div>
              <div class="menu-item__alignment">
                <i></i>
              </div>
              <div class="menu-item__justify">
                <i></i>
              </div>
              <div class="menu-item__row-margin">
                <i title="行间距"></i>
                <div class="options">
                  <ul>
                    <li data-rowmargin="0.5">0.5</li>
                    <li data-rowmargin="1">1</li>
                    <li data-rowmargin="1.25">1.25</li>
                    <li data-rowmargin="1.5">1.5</li>
                    <li data-rowmargin="1.75">1.75</li>
                    <li data-rowmargin="2">2</li>
                    <li data-rowmargin="2.5">2.5</li>
                    <li data-rowmargin="3">3</li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__list">
                <i></i>
                <div class="options" style="width: 160px">
                  <ul>
                    <li>
                      <label>取消列表</label>
                    </li>
                    <li data-list-type="ol" data-list-style="decimal">
                      <label>有序列表:</label>
                      <ol>
                        <li>________</li>
                      </ol>
                    </li>
                    <li data-list-type="ul" data-list-style="checkbox">
                      <label>复选框列表:</label>
                      <ul style="list-style-type: &quot;☑️ &quot;">
                        <li>________</li>
                      </ul>
                    </li>
                    <li data-list-type="ul" data-list-style="disc">
                      <label>实心圆点列表:</label>
                      <ul style="list-style-type: disc">
                        <li>________</li>
                      </ul>
                    </li>
                    <li data-list-type="ul" data-list-style="circle">
                      <label>空心圆点列表:</label>
                      <ul style="list-style-type: circle">
                        <li>________</li>
                      </ul>
                    </li>
                    <li data-list-type="ul" data-list-style="square">
                      <label>空心方块列表:</label>
                      <ul style="list-style-type: &quot;☐ &quot;">
                        <li>________</li>
                      </ul>
                    </li>
                  </ul>
                </div>
              </div>
            </div>
            <div class="menu-divider"></div>
            <div class="menu-item">
              <div class="menu-item__table">
                <i title="表格"></i>
              </div>
              <div class="menu-item__table__collapse">
                <div class="table-close">×</div>
                <div class="table-title">
                  <span class="table-select">插入</span>
                  <span>表格</span>
                </div>
                <div class="table-panel"></div>
              </div>
              <div class="menu-item__image">
                <i title="图片"></i>
                <input type="file" id="image" accept=".png, .jpg, .jpeg, .svg, .gif" />
              </div>
              <div class="menu-item__hyperlink">
                <i title="超链接"></i>
              </div>
              <div class="menu-item__separator">
                <i title="分割线"></i>
                <div class="options">
                  <ul>
                    <li data-separator="0,0">
                      <i></i>
                    </li>
                    <li data-separator="1,1">
                      <i></i>
                    </li>
                    <li data-separator="3,1">
                      <i></i>
                    </li>
                    <li data-separator="4,4">
                      <i></i>
                    </li>
                    <li data-separator="7,3,3,3">
                      <i></i>
                    </li>
                    <li data-separator="6,2,2,2,2,2">
                      <i></i>
                    </li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__watermark">
                <i title="水印(添加、删除)"></i>
                <div class="options">
                  <ul>
                    <li data-menu="add">添加水印</li>
                    <li data-menu="delete">删除水印</li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__codeblock" title="代码块">
                <i></i>
              </div>
              <div class="menu-item__page-break" title="分页符">
                <i></i>
              </div>
              <div class="menu-item__control">
                <i title="控件"></i>
                <div class="options">
                  <ul>
                    <li data-control="text">文本</li>
                    <li data-control="number">数值</li>
                    <li data-control="select">列举</li>
                    <li data-control="date">日期</li>
                    <li data-control="checkbox">复选框</li>
                    <li data-control="radio">单选框</li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__checkbox" title="复选框">
                <i></i>
              </div>
              <div class="menu-item__radio" title="单选框">
                <i></i>
              </div>
              <div class="menu-item__latex" title="LateX">
                <i></i>
              </div>
              <div class="menu-item__date">
                <i title="日期"></i>
                <div class="options">
                  <ul>
                    <li data-format="yyyy-MM-dd"></li>
                    <li data-format="yyyy-MM-dd hh:mm:ss"></li>
                  </ul>
                </div>
              </div>
              <div class="menu-item__block" title="内容块">
                <i></i>
              </div>
            </div>
            <div class="menu-divider"></div>
            <div class="menu-item">
              <div class="menu-item__search" data-menu="search">
                <i></i>
              </div>
              <div class="menu-item__search__collapse" data-menu="search">
                <div class="menu-item__search__collapse__search">
                  <input type="text" />
                  <label class="search-result"></label>
                  <div class="arrow-left">
                    <i></i>
                  </div>
                  <div class="arrow-right">
                    <i></i>
                  </div>
                  <span>×</span>
                </div>
                <div class="menu-item__search__collapse__replace">
                  <input type="text" />
                  <button>替换</button>
                </div>
              </div>
              <div class="menu-item__print" data-menu="print">
                <i></i>
              </div>
            </div>
          </div>
          <div class="catalog" editor-component="catalog" v-show="props.options.isUseCatalog">
            <div class="catalog__header">
              <span>目录</span>
              <div class="catalog__header__close">
                <i></i>
              </div>
            </div>
            <div class="catalog__main"></div>
          </div>
          <div class="editor"></div>
          <div class="comment" editor-component="comment"></div>
          <div class="footer" editor-component="footer" v-show="props.options.isUseFooter">
            <div>
              <div class="catalog-mode" title="目录">
                <i></i>
              </div>
              <div class="page-mode">
                <i title="页面模式(分页、连页)"></i>
                <div class="options">
                  <ul>
                    <li data-page-mode="paging" class="active">分页</li>
                    <li data-page-mode="continuity">连页</li>
                  </ul>
                </div>
              </div>
              <span>
                可见页码:
                <span class="page-no-list">1</span>
              </span>
              <span>
                页面:
                <span class="page-no">1</span>
                /
                <span class="page-size">1</span>
              </span>
              <span>
                字数:
                <span class="word-count">0</span>
              </span>
              <span>
                行:
                <span class="row-no">0</span>
              </span>
              <span>
                列:
                <span class="col-no">0</span>
              </span>
            </div>
            <div class="editor-mode" title="编辑模式(编辑、清洁、只读、表单、设计)">编辑模式</div>
            <div>
              <div class="page-scale-minus" title="缩小(Ctrl+-)">
                <i></i>
              </div>
              <span class="page-scale-percentage" title="显示比例(点击可复原Ctrl+0)">100%</span>
              <div class="page-scale-add" title="放大(Ctrl+=)">
                <i></i>
              </div>
              <div class="paper-size">
                <i title="纸张类型"></i>
                <div class="options">
                  <ul>
                    <li data-paper-size="794*1123" class="active">A4</li>
                    <li data-paper-size="1593*2251">A2</li>
                    <li data-paper-size="1125*1593">A3</li>
                    <li data-paper-size="565*796">A5</li>
                    <li data-paper-size="412*488">5号信封</li>
                    <li data-paper-size="450*866">6号信封</li>
                    <li data-paper-size="609*862">7号信封</li>
                    <li data-paper-size="862*1221">9号信封</li>
                    <li data-paper-size="813*1266">法律用纸</li>
                    <li data-paper-size="813*1054">信纸</li>
                  </ul>
                </div>
              </div>
              <div class="paper-direction">
                <i title="纸张方向"></i>
                <div class="options">
                  <ul>
                    <li data-paper-direction="vertical" class="active">纵向</li>
                    <li data-paper-direction="horizontal">横向</li>
                  </ul>
                </div>
              </div>
              <div class="paper-margin" title="页边距">
                <i></i>
              </div>
              <div class="fullscreen" title="全屏显示">
                <i></i>
              </div>
              <div class="editor-option" title="编辑器设置">
                <i></i>
              </div>
            </div>
          </div>
  4. 然后将组件script搭建起来,调用init方法传入基本配置项。解决掉相关的引用报错就可以使用了

    const options = {
          // 获取 CSS 变量值
          background: {
            color: getComputedStyle(document.documentElement).getPropertyValue("--el-bg-color").trim(),
          },
          cursor: {
            color: "#fff",
          },
          defaultColor: "#fff",
          paperDirection: "vertical",
          pageMode: "continuity",
          margins: [0, 21, 0, 21],
          searchMatchColor: "#fff", //搜索高亮颜色
          table: { defaultBorderColor: "#374352" },
          isReadonly: false, // 是否是只读模式
          isUseCatalog: false, //是否使用目录
          isUseComment: false, //是否使用日志
          isUseFooter: false, // 是否使用底部工具栏
        }
    
    
    const initPage = () => {
      nextTick(() => {
        const { offsetWidth: width, offsetHeight: height } = document.querySelector(".canvas-editor");
        window.instance = Init(".canvas-editor", { ....options, width: width, height: height });
      });
    };

    以上,最后祝各位使用顺遂!!!

  • 关于自己项目中使用最后的问题解决及优化

1. 因该组件开始使用是有i诸多不适配的地方,故做了许多适配,如底板宽度,颜色,自适应等

2. 组件内将只读模式变为由父组件传入,在options提供isReadonly判断   底部栏和顶部栏都做了灵活使用isUseComment(签注),isUseFooter(底部栏),isUseCatalog(目录),其内部由原生事件做的事件绑定,已经针对做了错误处理

3. 新增pageMode: "continuity",时依旧能进行水印的功能

4. 新增设置disabled时enter按钮触发的bug问题

***   在自己项目中做了许多小的修改和优化,各位如果需要有使用的话可自取 ***

https://gitee.com/cheng-nannan/gantt-fly.git

注: 数据中有disabled属性是控制当前行段是否可编辑的属性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值