import React, { useCallback, useEffect, useRef, useState } from 'react'; import classnames from 'classnames'; import { fabric } from 'fabric'; import useMarkDown from 'docs/hooks/use-mark-down'; import { loadFont } from 'docs/utils'; import styles from './style.less'; export interface NotePaperProps extends React.HTMLAttributes { paperLink: string; active: boolean; } const NotePaper: React.FC = ({ className, style, paperLink, active, ...rest }) => { const canvasRef = useRef(null); const [content] = useMarkDown(paperLink); const [translate, setTranslate] = useState({ x: 0, y: 0 }); const [loading, setLoading] = useState(true); const registerDragEvent = useCallback((canvas: fabric.Canvas, handler: fabric.Object) => { let dragging = false; canvas.on('mouse:down', (e) => { if (e.target === handler) dragging = true; }); canvas.on('mouse:move', (e) => { if (dragging) { setTranslate((pre) => ({ x: pre.x + e.e.movementX, y: pre.y + e.e.movementY, })); } }); canvas.on('mouse:up', (e) => { dragging = false; }); }, []); const initPaperCanvas = useCallback(async () => { if (!content) return; if (!canvasRef.current) return; await loadFont('handwriting'); const canvas = canvasRef.current; const fabricCanvas = new fabric.Canvas(canvas, { width: 400, height: 350, selection: false, hoverCursor: 'default', }); const topBar = new fabric.Rect({ width: fabricCanvas.getWidth(), height: 60, fill: 'transparent', selectable: false, originX: 'left', originY: 'top', }); const textbox = new fabric.Textbox(content, { width: 800, left: 20, top: topBar.getScaledHeight() + 10, lineHeight: 1.8, fontSize: 14, fontFamily: 'handwriting', fill: '#333', lockMovementX: true, lockMovementY: true, hasBorders: false, hasControls: false, selectionColor: 'rgba(132, 131, 124, 0.2)', }); const scale = Math.min( 1, (fabricCanvas.getHeight() - topBar.getScaledHeight() - 20) / textbox.getScaledHeight(), ); textbox.scale(scale); fabricCanvas.add(topBar, textbox); fabricCanvas.requestRenderAll(); registerDragEvent(fabricCanvas, topBar); setLoading(false); }, [content]); useEffect(() => { initPaperCanvas(); }, [initPaperCanvas]); return (
{loading && loading...}
); }; export default NotePaper;