React使用wangEditor编辑器添加数学公式的编辑功能

本文介绍如何在React教育App的后台管理中,替换截图上传数学公式,引入轻量级WangEditor和KityFormula插件,实现实时公式编辑和手写功能,提升用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目框架是React是教育类app的后台管理 属于接前同事的项目 现在客户要求编辑器可以编辑数学公式之前是直接截图上传公式图片 其实都不理想

这样在这里插入图片描述
在这里插入图片描述

就开始查资料

启发于这篇文章 直接编辑和手写因为里面的资源都是打不开了,只能自己找

一.基于javascript和css开发的 Web富文本编辑器, 轻量、简洁、易用、开源免费
使用原因 wangeditor的文档 (地址:http://www.wangeditor.com/

1.轻量:相对于百度富文本,体积真心小,

2.简洁:我的理解,功能刚刚够用。使用wangeditor的项目,要对富文本的功能要求简单。

安装 npm 命令安装 npm install wangeditor or yarn add wangeditor(注意 wangeditor 全部是小写字母

公式编辑器kityformula

在这里插入图片描述创建一个kityformula.ts或kityformula.js

texport default function (editor) {
  // panel 中需要用到的id
  const inputIFrameId = 'kityformula_' + Math.ceil(Math.random() * 10)
  const btnOkId = 'kityformula-btn' + Math.ceil(Math.random() * 10)
  const conf = {
    width: 900,
    height: 560,
    // panel 中可包含多个 tab
    tabs: [{
      // tab 的标题
      title: editor.i18next.t('menus.panelMenus.formula.插入公式'),
      // 模板
      //src的地址是kityformula的文件 我会上传文件
      tpl: `<div>
                  <iframe id="${inputIFrameId}" class="iframe" height="500px" width="100%" frameborder="0" scrolling="no" src="/kityformula/index.html"></iframe>
                  <div class="w-e-button-container">
                      <button id="${btnOkId}" class="right">
                          ${editor.i18next.t('确认插入')}
                      </button>
                  </div>
              </div>`,
      // 事件绑定 
      events: [{
        selector: '#' + btnOkId,
        type: 'click',
        fn: () => {
          // 执行插入公式
          const node = document.getElementById(inputIFrameId)
          const kfe = node.contentWindow.kfe
          let latex = kfe.execCommand('get.source')
          latex = latex.replace(/\s/g, '') // 去掉空格
          editor.txt.append(  //svg.image的比gif.latex清楚太多
            '<p>  <img class="formula" style="vertical-align: middle;"  src="https://latex.codecogs.com/svg.image?' +
            latex +
            '" data-latex="' +
            latex +
            '" /></p>'
          )
          // 返回 true,表示该事件执行完之后,panel 要关闭。否则 panel 不会关闭
          return true
        }
      }
      ]
    } // tab end
    ] // tabs end
  }


  return conf
}

在这里插入图片描述

在使用的页面引入

import React, { Component } from 'react';
import E from 'wangeditor'
import Axios from 'axios'
import createKityformula from "./kityformula";//这个就是

看看这里快速扩展一个菜单
在这里插入图片描述
我在 componentDidMount 直接初始化了

  componentDidMount () {
  //这里是菜单和内容分开了
    const editor = new E(this.refs.editorElemMenu, this.refs.editorElemBody)
    let config = editor.customConfig ? editor.customConfig : editor.config;
    config.onchange = html => {
      const regex = new RegExp('<img', 'gi')
      html = html.replace(regex, `<img style="vertical-align: middle;"`);
      this.props.onChange(html)
    }
    config.uploadFileName = 'file';
    config.uploadImgServer = '/web/dailySentence/upload'
    config.uploadImgHooks = {

      customInsert: function (insertImgFn, result) {
        // result 即服务端返回的接口
        if (result.success) {
          insertImgFn(result.data.url)
        } else {
          alert(result.errMessage)
        }
        // insertImgFn 可把图片插入到编辑器,传入图片 src ,执行函数即可
      }

    }
    config.menus = [
      'head',  // 标题
      'bold',  // 粗体
      'fontSize',  // 字号
      'fontName',  // 字体
      'kityformulaKey',  // 数学公式******
      'italic',  // 斜体
      'underline',  // 下划线
      'strikeThrough',  // 删除线
      'foreColor',  // 文字颜色
      'backColor',  // 背景颜色
      'link',  // 插入链接
      'lineHeight', // 行高
      'list',  // 列表
      'justify',  // 对齐方式
      'quote',  // 引用
      'emoticon',  // 表情
      'image',  // 插入图片
      'table',  // 表格
      'video',  // 插入视频
      'code',  // 插入代码
      'undo',  // 撤销
      'redo',  // 重复
    ]

    config.fontSizes = {
      'xx-small': { name: '10px', value: '0' },
      'x-small': { name: '12px', value: '1' },
      'small': { name: '14px', value: '2' },
      'normal': { name: '16px', value: '3' },
      'large': { name: '18px', value: '4' },
      'x-large': { name: '24px', value: '5' },
      'xx-large': { name: '32px', value: '6' },
      'xxx-large': { name: '48px', value: '7' },
    }
    config.fontNames = [
      '黑体',
      '宋体',
      '微软雅黑',
      'Arial',
      'Tahoma',
      'Verdana',
      'Times New Roman',
      'Courier New',
    ]
    config.uploadImgShowBase64 = true
    config.zIndex = parseInt(this.props.zIndex) || 500
    //添加自定义功能开始
    const { PanelMenu, Panel } = E;
    class Kityformula extends PanelMenu {
      // 公式输入插件
      constructor(editors) {
      //data-title='提示'
        const $elem = E.$(
          `<div class="w-e-menu" data-title='公式输入'>
          //图标这个直接找一个  我就上了也可以直接汉字
                  <i class="iconfont icongongshi" style="font-size:18px;"></i>
              </div>`
        );
        super($elem, editors);
      }
      // 菜单点击事件
      clickHandler () {
        const conf = createKityformula(editor);
        const panel = new Panel(this, conf);
        panel.create();
      }
      tryChangeActive () { }
    }
     //自定义手写版
    class Myscript extends PanelMenu {
      // 公式手写插件
      constructor(editors) {
        const $elem = E.$(
          `<div class="w-e-menu" data-title="手写公式">
                  <i class="iconfont iconshouxieban" style="font-size:18px;"></i>
              </div>`
        );
        super($elem, editors);
      }

      // 菜单点击事件
      clickHandler () {
        // 做任何你想做的事情
        // 可参考【常用 API】文档,来操作编辑器
        const conf = myscriptMath(editor);
        const panel = new Panel(this, conf);
        panel.create();
      }
      tryChangeActive () { }
    }
    editor.config.menuTooltipPosition = 'down'

    // 注册菜单
    const kityformulaKey = "kityformulaKey"; // 菜单 key ,各个菜单不能重复
    const myscriptKey = "myscriptKey"; // 菜单 key ,各个菜单不能重复
    editor.menus.extend("kityformulaKey", Kityformula);
    editor.menus.extend("myscriptKey", Myscript);
    

    
    // config.menus = [  "kityformulaKey","myscriptKey"],记得加上菜单
    //添加自定义功能结束
    editor.create()
    this.setState({
      editor: editor
    })

  };

公式手写板myscript-math-web
和上面一样
在这里插入图片描述
需要注意这个插件需要自己申请applicationkeyhmackey,申请的地址是
点击这个
在这里插入图片描述

在这里插入图片描述

直接全局搜索 applicationkeyhmackey这两个替换成自己的
在这里插入图片描述还有一个问题就是页面多个编辑器时 下菜单会遮住插件 也就是z-index大因为是组件复用 我就直接传z-index 动态设置
在这里插入图片描述

如何想获取图片上传 上面的那个文章有

现在的题目在这里插入图片描述

也可以回去latex输出伪代码 比如像这个编辑器一样

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过 Euler integral

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.
最后kityformula和myscriptMath会上传到资源里欢迎大牛指错不足

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值