Skip to content

Instantly share code, notes, and snippets.

@gingershaped
Last active May 9, 2023 19:33
Show Gist options
  • Save gingershaped/41598febc6859446df7fe7f90dade37c to your computer and use it in GitHub Desktop.
Save gingershaped/41598febc6859446df7fe7f90dade37c to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<template id="stripe-template">
<div class="stripe">
<div class="order-buttons">
<button class="up-button">&uparrow;</button>
<button class="down-button">&downarrow;</button>
</div>
<input type="color">
<div class="end-buttons">
<button class="duplicate-button">x2</button>
<button class="delete-button">X</button>
</div>
</div>
</template>
<title>Prideifier</title>
</head>
<body>
<style>
body {
font-family: 'Atkinson Hyperlegible', sans-serif;
display: flex;
flex-direction: column;
gap: 5px;
margin: 5px auto;
align-items: center;
width: 256px;
}
input[type="file"] {
height: 0;
width: 0;
padding: 0;
opacity: 0;
display: none;
}
label,
button {
margin: 1px;
appearance: none;
border: 1px solid #444;
outline: 1px solid #444;
font-weight: bold;
font-size: 11px;
padding: 6px;
cursor: pointer;
background-color: inherit;
text-align: center;
line-height: 1.5;
display: inline-block;
}
label:hover,
button:hover {
background-color: #ddd;
}
canvas {
border: 1px solid gray;
}
#stripe-container {
border: 1px solid gray;
align-self: stretch;
min-height: 64px;
padding: 5px;
}
#buttons {
display: flex;
align-self: stretch;
justify-content: space-around;
}
#buttons>* {
margin: 0px 5px;
flex: 1 1 100%;
}
.stripe {
border-bottom: 1px solid gray;
border-left: 1px solid gray;
display: flex;
align-items: center;
}
.stripe input[type="color"] {
margin-left: 10%;
}
.stripe:last-child {
border-bottom: none;
}
.order-buttons {
flex: 0.1;
}
.end-buttons {
margin-left: auto;
}
.order-buttons button {
display: block;
width: 15px;
height: 15px;
padding: 2px;
margin: 5px;
line-height: 0;
}
</style>
<h1>Prideifier</h1>
<canvas height="256" width="256"></canvas>
<div id="stripe-container">
</div>
<div id="buttons">
<label for="upload">Upload</label>
<input type="file" id="upload" />
<button id="new-stripe">Add Stripe</button>
<button id="download">Download</button>
</div>
<script type="text/javascript">
const canvas = document.querySelector("canvas")
const ctx = canvas.getContext("2d")
function reorderElement(element, direction) {
if (direction === -1 && element.previousElementSibling) {
element.parentNode.insertBefore(element, element.previousElementSibling);
} else if (direction === 1 && element.nextElementSibling) {
element.parentNode.insertBefore(element.nextElementSibling, element);
}
}
function addStripe(color = null) {
const stripe = document.getElementById("stripe-template").content.cloneNode(true).querySelector(".stripe")
stripe.querySelector("input[type='color']").addEventListener("input", redraw)
stripe.querySelector(".up-button").addEventListener("click", () => {
reorderElement(stripe, -1)
redraw()
})
stripe.querySelector(".down-button").addEventListener("click", () => {
reorderElement(stripe, 1)
redraw()
})
stripe.querySelector(".delete-button").addEventListener("click", () => {
stripe.parentNode.removeChild(stripe)
redraw()
})
stripe.querySelector(".duplicate-button").addEventListener("click", () => {
addStripe(stripe.querySelector("input[type='color']").value)
redraw()
})
stripe.querySelector("input[type='color']").value = color ?? "black"
document.getElementById("stripe-container").appendChild(stripe)
redraw()
}
function redraw() {
if (window.image != null) {
ctx.clearRect(0, 0, 256, 256)
ctx.drawImage(window.image, 0, 0, 256, 256)
const colors = Array.from(document.querySelectorAll(".stripe input[type='color']").values()).map((v) => v.value)
if (colors.length != 0) {
const barHeight = Math.round(256 / colors.length)
colors.forEach((color, index) => {
ctx.fillStyle = color + "80"
ctx.fillRect(0, index * barHeight, 256, barHeight)
})
}
}
}
function updateImage() {
ctx.clearRect(0, 0, 256, 256)
ctx.fillText("Loading", 0, 16)
createImageBitmap(document.getElementById("upload").files[0]).then((image) => {
window.image = image
redraw()
})
}
function download() {
var link = document.createElement("a");
link.download = "image.png"
link.href = canvas.toDataURL()
link.click();
}
function init() {
document.getElementById("new-stripe").addEventListener("click", addStripe)
document.getElementById("upload").addEventListener("input", updateImage)
document.getElementById("download").addEventListener("click", download)
ctx.font = "16px sans-serif"
ctx.fillStyle = "black"
ctx.fillText("No image", 0, 16)
}
init()
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment