import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { Texture } from 'fabric-texture'; import Skew from 'fabric-texture/modes/skew' import Perspective from 'fabric-texture/modes/perspective' import Warp from 'fabric-texture/modes/warp' import styles from './style.less'; import { DocsContext } from 'docs/docs'; /** * 创建倾斜图 */ const createSkewImage = (image: HTMLImageElement) => { const texture = new Texture(image); texture .setSplitUnit(1) .setSplitStrategy({ name: 'skew', execute: Skew.execute, }) .setVertexCoord(0, 0, 'tl', { x: image.naturalWidth * 0.2, y: 0 }) .setVertexCoord(0, 0, 'tr', { x: image.naturalWidth * 1.2, y: 0 }); const canvas = texture.create(); return new Promise((resolve) => { canvas.toBlob((blob) => { if (blob) { const url = URL.createObjectURL(blob); resolve(url); } }); }); }; /** * 创建透视图 */ const createPerspectiveImage = (image: HTMLImageElement) => { const texture = new Texture(image); // 透视 texture .setSplitUnit(0.01) .setSplitStrategy({ name: 'perspective', execute: Perspective.execute, }) .setVertexCoord(0, 0, 'tr', { x: image.naturalWidth, y: image.naturalHeight / 3 }) .setVertexCoord(0, 0, 'br', { x: image.naturalWidth, y: image.naturalHeight * (2 / 3) }); const canvas = texture.create(); return new Promise((resolve) => { canvas.toBlob((blob) => { if (blob) { const url = URL.createObjectURL(blob); resolve(url); } }); }); }; /** * 创建扭曲图 */ const createWarpImage = (image: HTMLImageElement) => { const texture = new Texture(image); texture .setSplitUnit(0.01) .setSplitStrategy({ name: 'warp', execute: Warp.execute, }) .setBoundCoords(0, 0, 'top', [ { x: 0, y: 0 }, { x: image.naturalWidth / 3, y: image.naturalHeight * 0.2 }, { x: image.naturalWidth * (2 / 3), y: image.naturalHeight * 0.2 }, { x: image.naturalWidth, y: 0 }, ]) .setBoundCoords(0, 0, 'bottom', [ { x: 0, y: image.naturalHeight }, { x: image.naturalWidth / 3, y: image.naturalHeight * 0.8 }, { x: image.naturalWidth * (2 / 3), y: image.naturalHeight * 0.8 }, { x: image.naturalWidth, y: image.naturalHeight }, ]); const canvas = texture.create(); return new Promise((resolve) => { canvas.toBlob((blob) => { if (blob) { const url = URL.createObjectURL(blob); resolve(url); } }); }); }; function EffectImages() { const { placeholder } = useContext(DocsContext); const [skewImageUrl, setSkewImageUrl] = useState(); const [perspectiveImageUrl, setPerspectiveImageUrl] = useState(); const [warpImageUrl, setWarpImageUrl] = useState(); const run = useCallback(async (image: HTMLImageElement) => { setSkewImageUrl(await createSkewImage(image)); setPerspectiveImageUrl(await createPerspectiveImage(image)); setWarpImageUrl(await createWarpImage(image)); }, []); useEffect(() => { if (placeholder) run(placeholder); }, [placeholder]); const images = useMemo(() => { return [ { label: 'Origin', labelCn: '原图', url: placeholder?.currentSrc, }, { label: 'Skew', labelCn: '倾斜', url: skewImageUrl, }, { label: 'Perspective', labelCn: '透视', url: perspectiveImageUrl, }, { label: 'Warp', labelCn: '扭曲', url: warpImageUrl, }, ]; }, [skewImageUrl, perspectiveImageUrl, warpImageUrl]); if (images.some((i) => !i.url)) return null; return (
{images.map((image) => (
{image.label}
({image.labelCn})
))}
); } export default EffectImages;