├── 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 |
--------------------------------------------------------------------------------