先看结果:
会弹出
会以base64图片形式插入ckeditor编辑器
1.先把Kityformula库解压放到public文件夹下
2.写一个CKeditor的插件,逻辑就是在编辑器的toolbar里加一个按钮,点击后弹一个弹窗,然后将公式编辑器Kityformula用iframe的形式嵌入这个弹窗里
iframe的代码:
<script setup lang="ts">
const props = defineProps(["latex"]);
const param = props.latex?.split(",,zyx,,")[0];
const data = encodeURIComponent(param);
const url = props.latex ? `/kityFormula.html?c=${data}` : "/kityFormula.html";
</script>
<template>
<div>
<iframe
id="editor5-iframe"
:src="url"
frameborder="0"
width="800px"
height="390px"
/>
</div>
</template>
<style scoped></style>
下面写Ckeditor插件
KityformulaPlugin.js如下:
import ButtonView from "@ckeditor/ckeditor5-ui/src/button/buttonview";
import ContextualBalloon from "@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon";
import { addDialog } from "@/components/ReDialog";
import EditorDialog from "@/components/EditorDialog/index.vue";
export default class CustomDialogPlugin extends Plugin {
static get requires() {
return [ContextualBalloon];
}
static get pluginName() {
return "CustomDialogPlugin";
}
init() {
const editor = this.editor;
// 监听双击事件
// 这里其实是回显的逻辑,当公式已经被插入Ckeditor之后,双击,应该再次弹出公式编辑器,然后把公式放到公式编辑器里.下面的target.alt其实就是最下面---1处的latex
editor.ui.on("update", () => {
const editableElement = editor.ui.view.editable.element;
if (editableElement && !this._dblClickHandler) {
// 定义双击事件处理函数
this._dblClickHandler = event => {
const target = event.target;
const dataPath = target.alt;
if (dataPath && dataPath.split(",,zyx,,")[1]) {
this.openDialog(editor, dataPath);
}
};
// 添加双击事件监听器
editableElement.addEventListener("dblclick", this._dblClickHandler);
}
});
// 注册工具栏按钮
editor.ui.componentFactory.add("kityformulaDialog", locale => {
const view = new ButtonView(locale);
view.set({
label: "公式",
tooltip: true,
withText: true // 自定义图标
});
view.on("execute", () => {
this.openDialog(editor);
});
return view;
});
}
/**
* 打开自定义弹窗
* @param {ButtonView} buttonView - 触发弹窗的按钮视图
*/
openDialog(editor, latex) {
addDialog({ // 这是自己封装的弹窗组件,你也可以用template内的弹窗组件,这里其实只是要在点击弹窗确认按钮后,获取公式编辑器里的内容,写入Ckeditor内部
title: "数学公式(请在英文输入法下输入)",
fullscreenIcon: true,
closeOnClickModal: false,
width: "840px",
height: "400px",
props: {
open: open,
latex: latex
},
contentRenderer: () => EditorDialog,
beforeSure: done => {
const node = document.getElementById("editor5-iframe");
const kfe = node.contentWindow.kfe;
kfe.execCommand("get.image.data", function (data) {
const latex = kfe.execCommand("get.source");
// kityFormula为空,不执行插入
if (latex === "\\placeholder ") {
done();
return;
}
//1处-------------这里想给img添加其他属性,好传latex,但是都会被ckeditor强制删除,有没有人能提供添加属性的方式.这里加不了其他属性,所以就直接加在了alt上.
const formulaImgHtml = `
<img
src="${data.img}"
alt="${latex + ",,zyx,,kityFormula"}"
class="kityformula-style-css"
/>
`;
editor.model.change(() => {
const viewFragment = editor.data.processor.toView(formulaImgHtml);
const modelFragment = editor.data.toModel(viewFragment);
editor.model.insertContent(modelFragment);
});
done();
});
}
});
}
}
3.在CKeditor编辑器组件里添加这个插件就行了
4.总结(只要理解下面的原理,上面都不看,都能自己摸索出来) 原理就是给ckeditor(或者你的编辑器)添加一个按钮,点击能弹出弹窗,在弹窗里嵌入iframe,src的值就是public里面的那个formula.html,这样就能将公式编辑器显示在弹窗里. 然后,可以在公式编辑器里输入公式,然后在点击弹窗的确认按钮的时候,将公式编辑器里的latex格式的公式,转换成base64的图片(同时把latex保存在img的alt上).插入到你的编辑器里(我这是ckeditor).然后,双击ckeditor内你写好的公式,应该再弹出公式编辑器,然后拿到img的alt,其实就是latex,给公式编辑器,让公式编辑器展示,以供修改. 核心代码就是
kfe.execCommand("get.image.data", function (data) {
const latex = kfe.execCommand("get.source");
// kityFormula为空,不执行插入
if (latex === "\\placeholder ") {
done();
return;
}
const formulaImgHtml = `
<img
src="${data.img}"
alt="${latex + ",,zyx,,kityFormula"}"
class="kityformula-style-css"
/>
`;
editor.model.change(() => {
const viewFragment = editor.data.processor.toView(formulaImgHtml);
const modelFragment = editor.data.toModel(viewFragment);
editor.model.insertContent(modelFragment);
});
done();
});
11