Created
September 24, 2021 15:03
-
-
Save connor-davis/61672cc5dab5ce0da5b60b512113d21b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createSignal, onMount } from "solid-js"; | |
let Cropper = ({ src, onContinue = () => {}, onCancel = () => {} }) => { | |
let [base, setBase] = createSignal({}); | |
let [bounds, setBounds] = createSignal({}); | |
let [active, setActive] = createSignal(false); | |
onMount(() => { | |
let srcImage = document.getElementById("srcImage"); | |
let canvas = document.getElementById("cropper"); | |
let context = canvas.getContext("2d"); | |
let cropBox = document.getElementById("cropBox"); | |
if (srcImage instanceof HTMLImageElement) { | |
srcImage.onload = () => { | |
setBase({ | |
width: srcImage.offsetWidth, | |
height: srcImage.offsetHeight, | |
x: srcImage.offsetLeft, | |
y: srcImage.offsetTop, | |
}); | |
cropBox.style.width = `${srcImage.offsetHeight}px`; | |
cropBox.style.height = `${srcImage.offsetHeight}px`; | |
cropBox.style.position = "abolute"; | |
cropBox.style.top = "0px"; | |
cropBox.style.left = `${ | |
srcImage.offsetWidth / 2 - srcImage.offsetHeight / 2 | |
}px`; | |
srcImage.classList.add("hidden"); | |
context.drawImage(srcImage, 0, 0, canvas.width, canvas.height); | |
setBounds({ | |
width: cropBox.offsetWidth, | |
height: cropBox.offsetHeight, | |
x: cropBox.offsetLeft, | |
y: cropBox.offsetTop, | |
}); | |
}; | |
} | |
}); | |
let moveBox = ({ x, y }) => { | |
let cropBox = document.getElementById("cropBox"); | |
let mouseX = x; | |
cropBox.style.left = `${mouseX - base().x / 2}px`; | |
setBounds({ | |
width: cropBox.offsetWidth, | |
height: cropBox.offsetHeight, | |
x: cropBox.offsetLeft, | |
y: cropBox.offsetTop, | |
}); | |
}; | |
let crop = async () => { | |
let cropper = document.getElementById("cropper"); | |
let canvas = document.createElement("canvas"); | |
let context = canvas.getContext("2d"); | |
let url = cropper.toDataURL(); | |
let image = new Image(); | |
image.src = url; | |
image.onload = () => { | |
canvas.width = bounds().width; | |
canvas.height = bounds().height; | |
context.drawImage( | |
image, | |
0, | |
0, | |
bounds().width, | |
bounds().height, | |
0, | |
0, | |
bounds().width, | |
bounds().height | |
); | |
let url = canvas.toDataURL(); | |
onContinue(url); | |
}; | |
}; | |
return ( | |
<div class="absolute left-0 top-0 right-0 bottom-0 z-20"> | |
<div | |
class="absolute bg-black bg-opacity-50 w-full h-full z-10" | |
onClick={() => onCancel()} | |
></div> | |
<div class="absolute flex flex-col justify-center items-center w-full h-full z-30"> | |
<div class="relative flex flex-col w-96 h-auto space-y-5"> | |
<img id="srcImage" src={src} height={512} /> | |
<div | |
id="cropBox" | |
class="absolute flex border-l-2 border-t-2 border-r-2 border-b-2 border-white border-dashed" | |
onMouseDown={() => { | |
setActive(true); | |
}} | |
onMouseUp={() => { | |
setActive(false); | |
}} | |
onMouseMove={(event) => { | |
if (active()) moveBox({ x: event.offsetX, y: event.offsetY }); | |
}} | |
></div> | |
<canvas | |
id="cropper" | |
class="bg-black" | |
width={base().width} | |
height={base().height} | |
onMouseDown={() => { | |
setActive(true); | |
}} | |
onMouseUp={() => { | |
setActive(false); | |
}} | |
onMouseMove={(event) => { | |
if (active()) moveBox({ x: event.offsetX, y: event.offsetY }); | |
}} | |
></canvas> | |
<div class="flex justify-between items-center bg-gray-900 w-full h-auto p-2"> | |
<div | |
class="flex justify-center items-center px-3 py-1 text-gray-400 hover:text-blue-500 cursor-pointer" | |
onClick={() => onCancel()} | |
> | |
Cancel | |
</div> | |
<div | |
class="flex justify-center items-center px-3 py-1 text-gray-400 hover:text-blue-500 cursor-pointer" | |
onClick={() => { | |
crop(); | |
}} | |
> | |
Continue | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
); | |
}; | |
export default Cropper; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment