UNPKG

@gechiui/block-editor

Version:
163 lines (142 loc) 3.53 kB
/** * GeChiUI dependencies */ import { useCallback, useEffect, useMemo, useState } from '@gechiui/element'; import { applyFilters } from '@gechiui/hooks'; function useTransformState( { url, naturalWidth, naturalHeight } ) { const [ editedUrl, setEditedUrl ] = useState(); const [ crop, setCrop ] = useState(); const [ position, setPosition ] = useState( { x: 0, y: 0 } ); const [ zoom, setZoom ] = useState(); const [ rotation, setRotation ] = useState(); const [ aspect, setAspect ] = useState(); const [ defaultAspect, setDefaultAspect ] = useState(); const initializeTransformValues = useCallback( () => { setPosition( { x: 0, y: 0 } ); setZoom( 100 ); setRotation( 0 ); setAspect( naturalWidth / naturalHeight ); setDefaultAspect( naturalWidth / naturalHeight ); }, [ naturalWidth, naturalHeight, setPosition, setZoom, setRotation, setAspect, setDefaultAspect, ] ); const rotateClockwise = useCallback( () => { const angle = ( rotation + 90 ) % 360; let naturalAspectRatio = naturalWidth / naturalHeight; if ( rotation % 180 === 90 ) { naturalAspectRatio = naturalHeight / naturalWidth; } if ( angle === 0 ) { setEditedUrl(); setRotation( angle ); setAspect( 1 / aspect ); setPosition( { x: -( position.y * naturalAspectRatio ), y: position.x * naturalAspectRatio, } ); return; } function editImage( event ) { const canvas = document.createElement( 'canvas' ); let translateX = 0; let translateY = 0; if ( angle % 180 ) { canvas.width = event.target.height; canvas.height = event.target.width; } else { canvas.width = event.target.width; canvas.height = event.target.height; } if ( angle === 90 || angle === 180 ) { translateX = canvas.width; } if ( angle === 270 || angle === 180 ) { translateY = canvas.height; } const context = canvas.getContext( '2d' ); context.translate( translateX, translateY ); context.rotate( ( angle * Math.PI ) / 180 ); context.drawImage( event.target, 0, 0 ); canvas.toBlob( ( blob ) => { setEditedUrl( URL.createObjectURL( blob ) ); setRotation( angle ); setAspect( 1 / aspect ); setPosition( { x: -( position.y * naturalAspectRatio ), y: position.x * naturalAspectRatio, } ); } ); } const el = new window.Image(); el.src = url; el.onload = editImage; const imgCrossOrigin = applyFilters( 'media.crossOrigin', undefined, url ); if ( typeof imgCrossOrigin === 'string' ) { el.crossOrigin = imgCrossOrigin; } }, [ rotation, naturalWidth, naturalHeight, setEditedUrl, setRotation, setAspect, setPosition, ] ); return useMemo( () => ( { editedUrl, setEditedUrl, crop, setCrop, position, setPosition, zoom, setZoom, rotation, setRotation, rotateClockwise, aspect, setAspect, defaultAspect, initializeTransformValues, } ), [ editedUrl, setEditedUrl, crop, setCrop, position, setPosition, zoom, setZoom, rotation, setRotation, rotateClockwise, aspect, setAspect, defaultAspect, initializeTransformValues, ] ); } export default function useTransformImage( imageProperties, isEditing ) { const transformState = useTransformState( imageProperties ); const { initializeTransformValues } = transformState; useEffect( () => { if ( isEditing ) { initializeTransformValues(); } }, [ isEditing, initializeTransformValues ] ); return transformState; }