From 1b5bc4901d4cb4a2655b53ea2f3c51aff7d4ea0e Mon Sep 17 00:00:00 2001 From: co0ontty Date: Fri, 29 Dec 2023 15:33:16 +0800 Subject: [PATCH] fix: download image radius --- src/pages/img_radius.tsx | 180 ++++++++++++++++++++++++++------------- 1 file changed, 122 insertions(+), 58 deletions(-) diff --git a/src/pages/img_radius.tsx b/src/pages/img_radius.tsx index f37572f..72dafbe 100644 --- a/src/pages/img_radius.tsx +++ b/src/pages/img_radius.tsx @@ -1,81 +1,145 @@ -import React, { useState } from 'react'; +import React, { useState, useRef, useEffect } from 'react'; import MainContent from '@/components/MainContent'; - -import { - Slider, - Grid, - ImageList, - ImageListItem, - IconButton, -} from '@mui/material'; +import { Slider, Grid, Button, Box, IconButton } from '@mui/material'; import AddPhotoAlternateIcon from '@mui/icons-material/AddPhotoAlternate'; function ImageWithBorderRadiusTool() { - const [imagePreviewUrl, setImagePreviewUrl] = useState(''); - const [borderRadius, setBorderRadius] = useState(5); + const [imageFile, setImageFile] = useState(null); + const [imagePreviewUrl, setImagePreviewUrl] = useState(''); + const [borderRadius, setBorderRadius] = useState(55); + const canvasRef = useRef(null); + const fileInputRef = useRef(null); - const handleImageChange = (e: any) => { - e.preventDefault(); + const drawImage = () => { + if (!imageFile) return; + + const img = new Image(); + img.onload = () => { + const canvas = canvasRef.current; + if (!canvas) return; + const ctx = canvas.getContext('2d'); + canvas.width = img.width; + canvas.height = img.height; - const reader = new FileReader(); - const file = e.target.files[0]; + // Draw rounded image + if (!ctx) return; + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.beginPath(); + ctx.moveTo(borderRadius, 0); + ctx.lineTo(canvas.width - borderRadius, 0); + ctx.quadraticCurveTo(canvas.width, 0, canvas.width, borderRadius); + ctx.lineTo(canvas.width, canvas.height - borderRadius); + ctx.quadraticCurveTo( + canvas.width, + canvas.height, + canvas.width - borderRadius, + canvas.height + ); + ctx.lineTo(borderRadius, canvas.height); + ctx.quadraticCurveTo(0, canvas.height, 0, canvas.height - borderRadius); + ctx.lineTo(0, borderRadius); + ctx.quadraticCurveTo(0, 0, borderRadius, 0); + ctx.closePath(); + ctx.clip(); - reader.onloadend = () => { - setImagePreviewUrl(reader.result); + ctx.drawImage(img, 0, 0); + setImagePreviewUrl(canvas.toDataURL()); }; + img.src = URL.createObjectURL(imageFile); + }; + + useEffect(() => { + drawImage(); + }, [borderRadius, imageFile]); + + const handleImageChange = (e: any) => { + e.preventDefault(); + if (e.target.files && e.target.files[0]) { + setImageFile(e.target.files[0]); + } + }; - reader.readAsDataURL(file); + const handleDownload = () => { + const link = document.createElement('a'); + link.download = 'rounded-image.png'; + link.href = imagePreviewUrl; + link.click(); }; return ( <> - - - + + + + fileInputRef.current?.click()} + > + + - + `${value}%`} - valueLabelDisplay='auto' - step={1} - marks - min={0} - max={100} value={borderRadius} - onChange={(event, newValue) => - setBorderRadius(newValue as number) - } + onChange={(e, newValue) => setBorderRadius(newValue as number)} + min={0} + max={300} /> + + + - - - - {imagePreviewUrl && ( - preview - )} - - + + {imagePreviewUrl && ( + Preview + )} + + );