import * as GCodePreview from 'gcode-preview' import PropTypes from 'prop-types' import { useCallback, useEffect, useRef } from 'react' import * as THREE from 'three' function GCodePreviewUI(props) { const { src, topLayerColor = '', lastSegmentColor = '', startLayer, endLayer, lineWidth, style = {} } = props const canvasRef = useRef(null) const previewRef = useRef(null) const resizePreview = useCallback(() => { previewRef.current?.resize() }, []) // Ex-ref methods removed; this component is now a regular functional component useEffect(() => { if (!canvasRef.current) return previewRef.current?.dispose?.() previewRef.current = GCodePreview.init({ canvas: canvasRef.current, startLayer, endLayer, lineWidth, topLayerColor: new THREE.Color(topLayerColor).getHex(), lastSegmentColor: new THREE.Color(lastSegmentColor).getHex(), buildVolume: { x: 250, y: 220, z: 150 }, initialCameraPosition: [0, 400, 450], allowDragNDrop: false }) window.addEventListener('resize', resizePreview) return () => { window.removeEventListener('resize', resizePreview) previewRef.current?.dispose?.() previewRef.current = null } }, [ endLayer, lastSegmentColor, lineWidth, startLayer, topLayerColor, resizePreview ]) useEffect(() => { let cancelled = false const loadFromSrc = async () => { const preview = previewRef.current if (!src || !preview) return try { const response = await fetch(src) const text = await response.text() if (cancelled || previewRef.current !== preview) return preview.processGCode(text) } catch (e) { if (cancelled) return console.error('Failed to load G-code from src', e) } } loadFromSrc() return () => { cancelled = true } }, [endLayer, lastSegmentColor, lineWidth, src, startLayer, topLayerColor]) return } GCodePreviewUI.propTypes = { src: PropTypes.string, topLayerColor: PropTypes.string, lastSegmentColor: PropTypes.string, startLayer: PropTypes.number, endLayer: PropTypes.number, lineWidth: PropTypes.number, style: PropTypes.object } export default GCodePreviewUI