mirror of
				https://github.com/excalidraw/excalidraw.git
				synced 2025-10-26 08:24:20 +01:00 
			
		
		
		
	 e8def8da8d
			
		
	
	e8def8da8d
	
	
	
		
			
			* feat: integrate mermaidToExcalidraw * create mermaid to excal dialog * allow mermaid syntax and export in preview * fix * fix webpack config * fix markdown error by using named export * center preview * set elements as selected when inserted onto canvas * persist mermaid data to storage * store canvas data in refs * load mermaid lazily * tweak design * compute width, height correctly for arrows * fix undefined vertex issue * add mermaid icon in dropdown * add a note in dialog * reset preview when error * show error in preview when error * show mermaid error messgae react way * design tweaks * add example and docs link * fix * tweak design to remove scroll bar * show a spinner unless mermaid loaded * regenerate ids when needed via programmatic api, this makes sure for mermaid diagrams ids are regenerated * tweak * add option to transform viewport to scene coords in transform api * make opts optional and use 100% zoom when inserting to canvas * fix arrow bindings in safari and firefox * fix elements insert position and viewport centering * fix: Update start/end points by 0.5 so bindings don't overlap with start/end bound element coordinates. * defer rendering the preview * tweak text * fix tests * remove only * make design responsive * fix: show extra tools dropdown in mobile * fix mobile css * width auto * upgrade mermaid-to-excalidraw * don't pass appState in deps as its not used * upgrade mermaid-to-excalidraw to fix firefox issue * use types from mermaid-to-excalidraw * upgrade mermaid-to-excalidraw * use stable version of mermaid-to-excalidraw * upgrade mermaid-to-excalidraw * fix width of shapes toolbar for smaller screen size and also fix regression of mobile menu * use i18n * better api * enable test coverage in ui * Add tests * use common utils to update and get text editor * updgrade mermaid-to-excalidraw to support sequence diagrams * fix test * don't update arrow container height anytime in when redrawing text bounding box * increase size limit * increase size limit of vendor to 900kb * use openDialog for mermaid * upgrade mermaid-to-excalidraw * update frame id post generation * upgrade mermaid-to-excalidraw to add entity codes support * update size limit * upgrade mermaid-to-excalidraw package with frame api changes * upgrade mermaid-to-excalidraw to remove directive and use config * don't highlight mermaid tool and remove unused api setSelection * stop using loading state to update text area * move some styling to scss * review fixes * use modifiedTableIcon props and remove stale snap * css * dialog css * fix snap * use dialog border * change mermaidToExcalidrawLib to state * better styling of errors * make modal bigger * fix mobile * update snaps * fix icon color * fix dark mode insert button color * horizontally center spinner * render canvas conditionally on loaded state * rd tweaks * tweak class names * remove max height * typo in example * upgrade mermaid-to-excalidraw * simplify error state * fix height & overflow on vertical breakpoint * fix lint * show errors in overlay * set textarea font family * reduce opacity * update snap * upgrade to mermaid 0.1.2 --------- Co-authored-by: dwelle <luzar.david@gmail.com>
		
			
				
	
	
		
			136 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| declare global {
 | |
|   interface Window {
 | |
|     debug: typeof Debug;
 | |
|   }
 | |
| }
 | |
| 
 | |
| const lessPrecise = (num: number, precision = 5) =>
 | |
|   parseFloat(num.toPrecision(precision));
 | |
| 
 | |
| const getAvgFrameTime = (times: number[]) =>
 | |
|   lessPrecise(times.reduce((a, b) => a + b) / times.length);
 | |
| 
 | |
| const getFps = (frametime: number) => lessPrecise(1000 / frametime);
 | |
| 
 | |
| export class Debug {
 | |
|   public static DEBUG_LOG_TIMES = true;
 | |
| 
 | |
|   private static TIMES_AGGR: Record<string, { t: number; times: number[] }> =
 | |
|     {};
 | |
|   private static TIMES_AVG: Record<
 | |
|     string,
 | |
|     { t: number; times: number[]; avg: number | null }
 | |
|   > = {};
 | |
|   private static LAST_DEBUG_LOG_CALL = 0;
 | |
|   private static DEBUG_LOG_INTERVAL_ID: null | number = null;
 | |
| 
 | |
|   private static setupInterval = () => {
 | |
|     if (Debug.DEBUG_LOG_INTERVAL_ID === null) {
 | |
|       console.info("%c(starting perf recording)", "color: lime");
 | |
|       Debug.DEBUG_LOG_INTERVAL_ID = window.setInterval(Debug.debugLogger, 1000);
 | |
|     }
 | |
|     Debug.LAST_DEBUG_LOG_CALL = Date.now();
 | |
|   };
 | |
| 
 | |
|   private static debugLogger = () => {
 | |
|     if (
 | |
|       Date.now() - Debug.LAST_DEBUG_LOG_CALL > 600 &&
 | |
|       Debug.DEBUG_LOG_INTERVAL_ID !== null
 | |
|     ) {
 | |
|       window.clearInterval(Debug.DEBUG_LOG_INTERVAL_ID);
 | |
|       Debug.DEBUG_LOG_INTERVAL_ID = null;
 | |
|       for (const [name, { avg }] of Object.entries(Debug.TIMES_AVG)) {
 | |
|         if (avg != null) {
 | |
|           console.info(
 | |
|             `%c${name} run avg: ${avg}ms (${getFps(avg)} fps)`,
 | |
|             "color: blue",
 | |
|           );
 | |
|         }
 | |
|       }
 | |
|       console.info("%c(stopping perf recording)", "color: red");
 | |
|       Debug.TIMES_AGGR = {};
 | |
|       Debug.TIMES_AVG = {};
 | |
|       return;
 | |
|     }
 | |
|     if (Debug.DEBUG_LOG_TIMES) {
 | |
|       for (const [name, { t, times }] of Object.entries(Debug.TIMES_AGGR)) {
 | |
|         if (times.length) {
 | |
|           console.info(
 | |
|             name,
 | |
|             lessPrecise(times.reduce((a, b) => a + b)),
 | |
|             times.sort((a, b) => a - b).map((x) => lessPrecise(x)),
 | |
|           );
 | |
|           Debug.TIMES_AGGR[name] = { t, times: [] };
 | |
|         }
 | |
|       }
 | |
|       for (const [name, { t, times, avg }] of Object.entries(Debug.TIMES_AVG)) {
 | |
|         if (times.length) {
 | |
|           const avgFrameTime = getAvgFrameTime(times);
 | |
|           console.info(name, `${avgFrameTime}ms (${getFps(avgFrameTime)} fps)`);
 | |
|           Debug.TIMES_AVG[name] = {
 | |
|             t,
 | |
|             times: [],
 | |
|             avg:
 | |
|               avg != null ? getAvgFrameTime([avg, avgFrameTime]) : avgFrameTime,
 | |
|           };
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   public static logTime = (time?: number, name = "default") => {
 | |
|     Debug.setupInterval();
 | |
|     const now = performance.now();
 | |
|     const { t, times } = (Debug.TIMES_AGGR[name] = Debug.TIMES_AGGR[name] || {
 | |
|       t: 0,
 | |
|       times: [],
 | |
|     });
 | |
|     if (t) {
 | |
|       times.push(time != null ? time : now - t);
 | |
|     }
 | |
|     Debug.TIMES_AGGR[name].t = now;
 | |
|   };
 | |
|   public static logTimeAverage = (time?: number, name = "default") => {
 | |
|     Debug.setupInterval();
 | |
|     const now = performance.now();
 | |
|     const { t, times } = (Debug.TIMES_AVG[name] = Debug.TIMES_AVG[name] || {
 | |
|       t: 0,
 | |
|       times: [],
 | |
|     });
 | |
|     if (t) {
 | |
|       times.push(time != null ? time : now - t);
 | |
|     }
 | |
|     Debug.TIMES_AVG[name].t = now;
 | |
|   };
 | |
| 
 | |
|   private static logWrapper =
 | |
|     (type: "logTime" | "logTimeAverage") =>
 | |
|     <T extends any[], R>(fn: (...args: T) => R, name = "default") => {
 | |
|       return (...args: T) => {
 | |
|         const t0 = performance.now();
 | |
|         const ret = fn(...args);
 | |
|         Debug.logTime(performance.now() - t0, name);
 | |
|         return ret;
 | |
|       };
 | |
|     };
 | |
| 
 | |
|   public static logTimeWrap = Debug.logWrapper("logTime");
 | |
|   public static logTimeAverageWrap = Debug.logWrapper("logTimeAverage");
 | |
| 
 | |
|   public static perfWrap = <T extends any[], R>(
 | |
|     fn: (...args: T) => R,
 | |
|     name = "default",
 | |
|   ) => {
 | |
|     return (...args: T) => {
 | |
|       // eslint-disable-next-line no-console
 | |
|       console.time(name);
 | |
|       const ret = fn(...args);
 | |
|       // eslint-disable-next-line no-console
 | |
|       console.timeEnd(name);
 | |
|       return ret;
 | |
|     };
 | |
|   };
 | |
| }
 | |
| //@ts-ignore
 | |
| window.debug = Debug;
 |