Last active
September 11, 2022 04:59
-
-
Save AngelMunoz/6578bae546b0ec6c67553550b49785b6 to your computer and use it in GitHub Desktop.
A simple canvas based meme-like editor
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
const sizeOrMax\((size: number, max: number) => number) = | |
do(size,max) size > max ? max : size | |
export tag MemeEditor | |
css .row | |
d: flex; fld: column | |
css footer | |
d:flex; fld:column; m:auto | |
css canvas | |
d:flex; m:auto; py: 1em | |
prop defaultSize = $memeCnv.width | |
prop topContent = "" | |
prop bottomContent = "" | |
prop fontSize = 24 | |
prop fontFamily = "system-ui" | |
prop fontColor = 'white' | |
def fileChanged | |
const file = $fileInput.files..item 0 | |
#canEdit = !!file | |
unless #canEdit | |
return | |
const options = | |
resizeWidth: defaultSize | |
resizeQuality: 'high' | |
#bitmap = await window.createImageBitmap(file, options) | |
$memeCnv.height = sizeOrMax(#bitmap.height, defaultSize) | |
drawText! | |
def drawText | |
const ctx = $memeCnv.getContext('2d') | |
const top = topContent ?? "" | |
const bottom = bottomContent ?? "" | |
const x = $memeCnv.width / 2 | |
const topY = $memeCnv.height * 0.05 | |
const bottomY = $memeCnv.height | |
const maxWidth = $memeCnv.width - fontSize | |
ctx.clearRect(0, 0, $memeCnv.width, $memeCnv.height); | |
ctx.drawImage(#bitmap, 0, 0) | |
ctx.font = `{fontSize}px {fontFamily}` | |
ctx.textAlign = 'center' | |
ctx.fillStyle = fontColor ?? 'white' | |
ctx.fillText(top, x, topY + fontSize, maxWidth) | |
ctx.fillText(bottom, x, bottomY - fontSize, maxWidth) | |
<self [d:flex; fld: column]> | |
<div.row [m:auto]> | |
<label> "Select a picture" | |
<input$fileInput type='file' accept='image' @change=fileChanged> | |
<canvas$memeCnv> | |
if #canEdit | |
<footer> | |
<div.row> | |
<label> "Top Text" | |
<input type='text' bind=topContent @keyup.debounce=drawText> | |
<div.row> | |
<label> "Bottom Text" | |
<input type='text' bind=bottomContent @keyup.debounce=drawText> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment