Skip to content

Instantly share code, notes, and snippets.

@AngelMunoz
Last active September 11, 2022 04:59
Show Gist options
  • Save AngelMunoz/6578bae546b0ec6c67553550b49785b6 to your computer and use it in GitHub Desktop.
Save AngelMunoz/6578bae546b0ec6c67553550b49785b6 to your computer and use it in GitHub Desktop.
A simple canvas based meme-like editor
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