import { h } from 'preact'; import { useRef, useEffect, useState } from 'preact/hooks'; import PropTypes from 'prop-types'; import { chatDrawPalettes } from '../../utilities/Constants'; import { Button } from '@crayons'; /** * Draw function is wrapped in this component * * @example * * * * @param {object} props * @param {function} props.sendCanvasImage */ function Draw({ sendCanvasImage }) { const canvasRef = useRef(null); const [isDrawing, setIsDrawing] = useState(false); const [drawColor, setDrawColor] = useState('#F58F8E'); const [coordinates, setCoordinates] = useState({}); const [sendButtonDisabled, setSendButtonDisabled] = useState(true); const prevCoordinates = usePrevious(coordinates); const handleCanvasSend = () => { const canvas = canvasRef.current; canvas.toBlob((blob) => { sendCanvasImage(new File([blob], 'draw.png')); }); }; const handleMouseDown = (e) => { setCoordinates({ x: e.offsetX, y: e.offsetY }); setIsDrawing(true); }; const handleImageDrop = (e) => { e.preventDefault(); if (!canvasRef.current) { return; } const canvas = canvasRef.current; const context = canvas.getContext('2d'); canvas.classList.remove('opacity-25'); const { files } = e.dataTransfer; const img = new Image(); img.src = URL.createObjectURL(files[0]); img.onload = () => { const scale = Math.min( canvas.width / img.width, canvas.height / img.height, ); setSendButtonDisabled(false); const x = canvas.width / 2 - (img.width / 2) * scale; const y = canvas.height / 2 - (img.height / 2) * scale; context.drawImage(img, x, y, img.width * scale, img.height * scale); }; }; const handleClearCanvas = () => { setSendButtonDisabled(true); if (!canvasRef.current) { return; } const context = canvasRef.current.getContext('2d'); context.clearRect(0, 0, canvasRef.current.width, canvasRef.current.height); }; const handleDragHover = (e) => { e.preventDefault(); canvasRef.current.classList.add('opacity-25'); }; const handleChangeColor = (e) => { setDrawColor(e.target.style.backgroundColor); }; const handleDragExit = (e) => { e.preventDefault(); canvasRef.current.classList.remove('opacity-25'); canvasRef.current.classList.add('opacity-100'); }; const handleMouseMove = (e) => { if (isDrawing) { setSendButtonDisabled(false); setCoordinates({ x: e.offsetX, y: e.offsetY }); } }; const handleMouseUp = () => { setCoordinates({}); setIsDrawing(false); }; useEffect(() => { if (!canvasRef.current) { return; } const context = canvasRef.current.getContext('2d'); if (isDrawing) { context.beginPath(); context.strokeStyle = drawColor; context.lineWidth = 2; context.moveTo(prevCoordinates.x, prevCoordinates.y); context.lineTo(coordinates.x, coordinates.y); context.stroke(); context.closePath(); } }, [drawColor, isDrawing, coordinates, prevCoordinates]); return (

Connect Draw

{chatDrawPalettes.map((color) => (
); } function usePrevious(value) { const ref = useRef(); useEffect(() => { ref.current = value; }, [value]); return ref.current; } Draw.propTypes = { sendCanvasImage: PropTypes.func.isRequired, }; export default Draw;