├── readme.md ├── style.css ├── index.html └── script.js /readme.md: -------------------------------------------------------------------------------- 1 | # Emoji Intensifies tool 2 | A quick and simple tool to make shaky "intensifies" emoji. You can see it live [here](https://tholman.com/emoji-intensifies). 3 | 4 | ## Q/A 5 | **Why???** Believe me, I hate them more than you do. But whats worse than a shakey emoji is one that doesn't have a transparent background, so at least I've got that covered. 6 | 7 | **How???** The HTML5 `canvas`, and this amazing [canvas -> gif converter by Matt DesLauriers](https://github.com/mattdesl/gifenc) 8 | 9 | ## License 10 | MIT 11 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | font-family: Roboto Mono, monospace; 8 | } 9 | 10 | h1 { 11 | margin-top: 0; 12 | margin-bottom: 20px; 13 | } 14 | 15 | .bg { 16 | width: 100vw; 17 | height: 100vh; 18 | position: fixed; 19 | opacity: 0.2; 20 | background-size: 50px; 21 | background-position: center center; 22 | } 23 | 24 | @media (prefers-reduced-motion) { 25 | .bg { 26 | background-image: none !important; 27 | } 28 | } 29 | 30 | .wrapper { 31 | width: 100vw; 32 | height: 100vh; 33 | display: flex; 34 | justify-content: center; 35 | align-items: center; 36 | flex-direction: column; 37 | gap: 30px; 38 | } 39 | 40 | .cool-box { 41 | display: flex; 42 | flex-direction: column; 43 | max-width: 500px; 44 | padding: 50px; 45 | border: 1px solid #ddd; 46 | box-shadow: 5px 5px black; 47 | background: #f9f9f9; 48 | z-index: 2; 49 | } 50 | 51 | .control { 52 | display: flex; 53 | align-items: center; 54 | justify-content: space-between; 55 | margin-bottom: 10px; 56 | min-height: 40px; 57 | } 58 | 59 | .fancy-download { 60 | text-align: center; 61 | font-weight: bold; 62 | color: currentColor; 63 | } 64 | 65 | input[type=text] { 66 | text-align: center; 67 | font-size: 30px; 68 | border: 0; 69 | width: 35px; 70 | border-bottom: 2px solid #eee; 71 | background: #f9f9f9; 72 | } 73 | 74 | input[type=range] { 75 | width: 70px; 76 | } 77 | 78 | canvas, img { 79 | width: 32px; 80 | height: 32px; 81 | } 82 | 83 | .github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}} -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Intensifying Emoji Generator 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |

Intensifying Emoji Generator

19 |

A simple and quick tool to help you add some shaky-shaky to your emoji.

20 |
21 |
22 | Type your emoji here: 23 | 24 |
25 |
26 | Adjust Intensity here: 27 |
28 | 31 |
32 |
33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | import { GIFEncoder, quantize, applyPalette } from "https://unpkg.com/gifenc"; 2 | 3 | function makeTextAnImage(value) { 4 | 5 | // Canvas dimensions 6 | const canvas = document.createElement("canvas"); 7 | canvas.width = 64; 8 | canvas.height = 64; 9 | 10 | let context = canvas.getContext("2d"); 11 | context.font = "24px monospace"; 12 | 13 | let tryUntil = 60; 14 | let startSize = 24; 15 | 16 | // // Size up until it fits nicely 17 | let measurements = context.measureText(value); 18 | for (let i = startSize; i < tryUntil; i++) { 19 | context.font = `${i}px monospace`; 20 | 21 | let measurementTest = context.measureText(value); 22 | if (measurementTest.width > canvas.width) { 23 | context.font = `${i - 1}px monospace`; 24 | measurements = context.measureText(value); 25 | break; 26 | } 27 | } 28 | 29 | // Try to center align 30 | context.textAlign = "center"; 31 | context.textBaseline = "middle"; 32 | 33 | context.fillText( 34 | value, 35 | canvas.width / 2, 36 | canvas.height / 2 + (measurements.fontBoundingBoxDescent || 2) 37 | ); 38 | 39 | return canvas; 40 | } 41 | 42 | // Random + or - int between range rounded 43 | function getRandomInt(min, max) { 44 | min = Math.ceil(min); 45 | max = Math.floor(max); 46 | return Math.round(Math.floor(Math.random() * (max - min + 1)) + min); 47 | } 48 | 49 | // Make the shaky image 50 | function makeShakyBoi(char, intensity) { 51 | 52 | if(!char) return 53 | 54 | // Get emoji as canvas 55 | const emojiInCanvas = makeTextAnImage(char); 56 | 57 | // Use this canvas to create frames 58 | const fgCanvas = document.createElement('canvas') 59 | const fgContext = fgCanvas.getContext("2d"); 60 | fgCanvas.width = 64; 61 | fgCanvas.height = 64; 62 | 63 | // Gif Encoder 64 | const gif = GIFEncoder(); 65 | for (let i = 0; i < 42; i++) { 66 | fgCanvas.width = fgCanvas.width; 67 | fgContext.drawImage( 68 | emojiInCanvas, 69 | getRandomInt(-intensity, intensity), 70 | getRandomInt(-intensity, intensity) 71 | ); 72 | 73 | const data = fgContext.getImageData(0, 0, fgCanvas.width, fgCanvas.height) 74 | .data; 75 | 76 | const palette = quantize(data, 256, { format: "rgba4444"}); 77 | const index = applyPalette(data, palette, "rgba4444"); 78 | 79 | gif.writeFrame(index, fgCanvas.width, fgCanvas.height, { 80 | palette, 81 | delay: 20, 82 | transparent: true 83 | }); 84 | } 85 | 86 | gif.finish(); 87 | 88 | const buffer = gif.bytesView(); 89 | const blob = buffer instanceof Blob ? buffer : new Blob([buffer], { type: "image/gif" }); 90 | const dataUrl = URL.createObjectURL(blob); 91 | 92 | document.getElementById("image").src = dataUrl 93 | document.querySelector('.bg').style.backgroundImage = `url(${dataUrl})` 94 | document.querySelector('.fancy-download').href = dataUrl; 95 | } 96 | 97 | 98 | let intensityVal = 2 99 | 100 | const textInput = document.querySelector("input[type=text]") 101 | textInput.addEventListener('input', (e) => { 102 | textInput.value = e.data 103 | makeShakyBoi(e.data, intensityVal) 104 | }) 105 | 106 | const slider = document.querySelector("input[type=range]") 107 | slider.addEventListener('change', () => { 108 | intensityVal = slider.value 109 | makeShakyBoi(textInput.value, intensityVal) 110 | }) 111 | 112 | const randomStarts = ['👀', '🤡', '🤫', '😐', '🥶'] 113 | 114 | textInput.value = randomStarts[Math.floor(Math.random() * randomStarts.length)] 115 | 116 | makeShakyBoi(textInput.value, intensityVal) 117 | 118 | 119 | 120 | 121 | --------------------------------------------------------------------------------