1
0
Fork 0
mirror of https://github.com/voltbonn/profile-picture-generator.git synced 2024-12-22 15:55:08 +00:00
profile.volt.link/src/App.js

113 lines
3.6 KiB
JavaScript
Raw Normal View History

import { useState, useEffect, useCallback } from 'react'
import './App.css'
2021-01-21 15:57:02 +00:00
import download from 'downloadjs'
import { useDropzone } from 'react-dropzone'
2021-01-21 18:11:37 +00:00
import FrameChooser from './FrameChooser.js'
2021-01-21 18:16:17 +00:00
import HeaderImage from './HeaderImage.svg'
import mergeImages from 'merge-images'
const frameSize = 1080
2021-01-21 14:18:25 +00:00
function App() {
2021-01-21 18:11:37 +00:00
const [frameURL, setFrameURL] = useState(null)
const [originalPhoto, setOriginalPhoto] = useState(null)
const [photo, setPhoto] = useState(null)
const [combinedImage, setCombinedImage] = useState(null)
2021-01-21 18:11:37 +00:00
const handleFrameURL = useCallback(newFrameURL => {
setFrameURL(newFrameURL)
}, [setFrameURL])
const handleReadFile = useCallback(file => {
const reader = new FileReader()
reader.onload = reader_event => {
const img = new Image()
img.onload = function () {
const offscreenCanvas = document.createElement('canvas')
offscreenCanvas.width = frameSize
offscreenCanvas.height = frameSize
2021-01-21 19:56:34 +00:00
const offscreenCanvas_ctx = offscreenCanvas.getContext('2d', { alpha: true })
let width, height;
if (img.width < img.height) {
height = (img.height / img.width) * frameSize
width = frameSize
} else {
height = frameSize
width = (img.width / img.height) * frameSize
}
offscreenCanvas_ctx.drawImage(
img,
(frameSize - width) / 2,
(frameSize - height) / 2,
width,
height,
);
const pngUrl = offscreenCanvas.toDataURL()
setPhoto(pngUrl)
}
img.src = reader_event.target.result
setOriginalPhoto(reader_event.target.result)
}
reader.readAsDataURL(file)
}, [])
const handleImage = useCallback(files_event => {
handleReadFile(files_event.target.files[0])
}, [handleReadFile])
const onDrop = useCallback(acceptedFiles => {
handleReadFile(acceptedFiles[0])
}, [handleReadFile])
const { isDragActive, getRootProps } = useDropzone({
onDrop,
accept: 'image/*',
maxFiles: 1,
noKeyboard: true,
})
useEffect(() => {
mergeImages([
...(photo ? [photo] : []),
2021-01-21 18:11:37 +00:00
...(frameURL ? [frameURL] : []),
])
.then(b64 => setCombinedImage(b64))
2021-01-21 18:11:37 +00:00
}, [photo, frameURL])
return (
<div className="App" {...getRootProps()}>
2021-01-21 18:59:50 +00:00
<img src={HeaderImage} className="HeaderImage" alt="Volt Logo" />
<div className={isDragActive ? 'droparea active' : 'droparea'}>
Drop your photo here ...
</div>
2021-01-21 18:33:07 +00:00
<h2>Choose your Photo:</h2>
<p>It should best be a square image or your face in the middle. The photo is not saved and never leaves your computer.</p>
2021-01-21 18:33:07 +00:00
2021-01-21 18:31:57 +00:00
<label className="labelButton" tabIndex="0" style={{outline:'none'}}>
{!!photo ? <img src={originalPhoto} alt="Preview" /> : null}
<span>{!!photo ? 'Change Photo' : 'Load Photo'}</span>
2021-01-21 18:31:57 +00:00
<input onChange={handleImage} type="file" accept="image/*" style={{display: 'none'}} />
</label>
2021-01-21 18:11:37 +00:00
<FrameChooser onFrameChange={handleFrameURL} />
2021-01-21 18:33:07 +00:00
<h2>Download your Photo:</h2>
2021-01-21 18:32:45 +00:00
<img src={combinedImage} className="FinishedFrame" alt="Finished Frame" />
<button onClick={() => download(combinedImage, "volt-profile-picture.png", "image/png")}>Download Profile Picture</button>
2021-01-21 14:18:25 +00:00
</div>
)
2021-01-21 14:18:25 +00:00
}
export default App;