Compare commits

...

11 Commits

Author SHA1 Message Date
Vftdan 9d6f01a5e6 Merge remote-tracking branch 'origin/main' into export-options 2024-04-24 20:57:06 +02:00
ente 477e2adb31 added Johann150 to the thank you section in README.md 2024-04-24 20:12:56 +02:00
fotoente a7e4ce76d1 Merge pull request 'add direct link ability' (#12) from Johann150/neomojimixer:main into main
Reviewed-on: https://codeberg.org/fotoente/neomojimixer/pulls/12
2024-04-24 18:07:19 +00:00
fotoente 26a17cd4b4 Merge branch 'main' into main 2024-04-24 18:07:01 +00:00
Vftdan 9631a7a61a Added a download link with filename for exported images 2024-04-24 15:48:20 +02:00
Vftdan 16606663e9 Added export format & quality options 2024-04-24 15:43:56 +02:00
Johann150 90d156e3f2
output direct link for export 2024-04-23 23:31:35 +02:00
Johann150 2bd7ec3818
direct link ability
This allows to link directly to one variant of an emoji by using the
URL fragment, which will in turn be selected from the available boxes.
2024-04-23 23:31:33 +02:00
Johann150 4cc1f0d7ca
fix spacing 2024-04-23 23:31:13 +02:00
Johann150 709d211297 rename eye part image file
This totally isnt because Windows can't handle this file name and because
this is annoying when using a shell which interprets the less and greater
than signs as input/output redirection.
2024-04-23 23:30:18 +02:00
ente f2382a3d00 Added neobread emojis & links to olivybee 2024-04-23 22:45:48 +02:00
47 changed files with 137 additions and 15 deletions

View File

@ -58,9 +58,16 @@ YES! I actually do! creating the first 95 elements took me over six hours to mak
- For creating the [neopossum emojis](https://yiff.life/@EeveeEuphoria/112039918021786980)
- For letting me use them in this project!
[olivvybee](https://honeycomb.engineer/@olivvybee)
- For creating the [neobread emojis](https://github.com/olivvybee/neobread) and [blobbee emojis](https://github.com/olivvybee/blobbee/releases/latest)
- For letting me use them in this project!
[vftdan](https://mastodon.ml/@vftdan)
- For completly rewriting the JavaScript
- Adding drowpdown menus for the part selection
[Johann150](https://genau.qwertqwefsday.eu/@Johann150)
- For the permalink functionality
You
- For any feedback, bug report or pull request to improve this project!

View File

@ -5,7 +5,6 @@
<title>Neomojimixer (BETA)</title>
<link rel="shortcut icon" href="favicon.gif" type="image/gif" />
<link rel="stylesheet" href="neomojimixer.css">
</head>
<body>
<h2>Neomojimixer (BETA)</h2>
@ -23,19 +22,38 @@
<div class="mouth"><button id="mouth_left" onclick="NeomojiMixer.part_handlers.mouth.onClickPrev();" disabled><</button><select class="name" id="mouth_name" onchange="NeomojiMixer.part_handlers.mouth.onChangeDropdown();" disabled>name mouth</select><button id="mouth_right" onclick="NeomojiMixer.part_handlers.mouth.onClickNext();" disabled>></button></div>
<div class="arms"><button id="arms_left" onclick="NeomojiMixer.part_handlers.arms.onClickPrev();" disabled><</button><select class="name" id="arms_name" onchange="NeomojiMixer.part_handlers.arms.onChangeDropdown();" disabled>name arms</select><button id="arms_right" onclick="NeomojiMixer.part_handlers.arms.onClickNext();" disabled>></button></div>
<div class="random"><button id="random" onclick="NeomojiMixer.randomize();" disabled>Random</button></div>
<div class="export"><button id="export" onclick="NeomojiMixer.exportImage();" disabled>Export Image</button></div>
<div class="export">
<button id="export" onclick="NeomojiMixer.exportImage();" disabled>Export Image</button>
<label>
Export type:
<input type="text" id="export-mime" list="export-mime-list" value="image/png" />
<datalist id="export-mime-list">
<option value="image/png"></option>
<option value="image/webp"></option>
<option value="image/jpeg"></option>
</datalist>
</label>
<label>
<input type="checkbox" id="export-quality-enabled" />Quality:<input type="number" id="export-quality" min="0.0" max="1.0" step="0.1" value="1.0" />
</label>
</div>
</div>
<div id="stats">stats</div>
<canvas id="canvas_export" width="256" height="256" hidden name="test.png"></canvas>
<img id="imageExport" src="" hidden/>
<p id="exportSaveMessage" hidden>To save right click and choose "Save image as..."</p>
<input type="text" id="fullNeomojiName" name="" value="" readonly hidden/>
<p>
<a id="imageExportLink" download href="" target="_blank" hidden>Download</a>
</p>
<p id="exportSaveMessage" hidden>To save right click and choose "Save image as..." or click the "Download" link</p>
<a id="fullNeomojiName" hidden></a>
<p>Neomojis are from the following sources: </p>
<ul>
<li><b><a href="https://volpeon.ink/emojis/neofox/" target="_blank" class="links">Neofox</a></b> by <a href="https://is-a.wyvern.rip/@volpeon" target="_blank" class="links">Volpeon</a></li>
<li><b><a href="https://volpeon.ink/emojis/neocat/" target="_blank" class="links">Neocat</a></b> by Volpeon</li>
<li><b><a href="https://emoji-repo.absturztau.be/repo/neorat.zip" target="_blank" class="links">Neorat</a></b> by <a href="https://onemuri.nl/" target="_blank" class="links">Justje</a></li>
<li><b><a href="https://yiff.life/@EeveeEuphoria/112039918021786980" target="_blank" class="links">Neopossum</a></b> by <a href="https://yiff.life/@EeveeEuphoria" target="_blank" class="links">EeveeEuphoria</a></li>
<li><b><a href="https://github.com/olivvybee/neobread" target="_blank" class="links">Neobread</a></b> by <a href="https://honeycomb.engineer/@olivvybee" target="_blank" class="links">Olivvybee</a></li>
<li><b><a href="https://github.com/olivvybee/blobbee/releases/latest" target="_blank" class="links">Blobbee</a></b> by Olivvybee</li>
<li><b>Neoredpanda</b> by <a href="https://hat-eine.entenbru.st/@Erpel" target="_blank" class="links">Ente</a></li>
</ul>
<p>Sourcecode on Codeberg: <a href="https://codeberg.org/fotoente/neomojimixer" target="_blank">Neomojimixer</a>
@ -45,5 +63,3 @@
<script src="neomojimixer.js"></script>
</body>
</html>

View File

@ -34,16 +34,33 @@ img.arms {
width: 256px;
}
input, button, select {
box-sizing: border-box;
}
button {
width: 25px;
height: 25px;
}
button#random {
width: 250px;
input[type="checkbox"] {
margin: 4px;
width: 17px;
height: 17px;
}
button#export {
.export > label {
display: block;
width: 250px;
clear: both;
}
.export > label > input:not([type="checkbox"]) {
width: 125px;
float: right;
}
button#random, button#export {
width: 250px;
}

View File

@ -8,6 +8,7 @@ const NeomojiMixer = (function(NeomojiMixer) {
"red",
"white",
"yellow",
"lightbrown",
];
let selected_color = "blue";
let color_change_callbacks = [];
@ -16,6 +17,7 @@ const NeomojiMixer = (function(NeomojiMixer) {
const canvas = document.getElementById("canvas_export");
const export_img = document.getElementById("imageExport");
const export_img_download = document.getElementById("imageExportLink");
const neomoji_name = document.getElementById("fullNeomojiName");
//Stats
@ -224,6 +226,14 @@ const NeomojiMixer = (function(NeomojiMixer) {
//Randomize initial view
randomize();
// If there was a hash, restore as a direct permalink.
if (document.location.hash != "") {
loadFromHash(document.location.hash);
}
window.addEventListener("hashchange", () => {
loadFromHash(document.location.hash);
});
//Show little statistic
var sum = 0;
var variety = 1;
@ -243,6 +253,26 @@ const NeomojiMixer = (function(NeomojiMixer) {
}
function loadFromHash(hash) {
let parts = hash
.slice(1) // the first character is always the '#' sign
.split('+');
// define a constant order for the parts to appear in the hash
const parts_order = ["body", "eyes", "mouth", "arms"];
if (parts.length == parts_order.length) {
// convert the part names to part indices
parts = parts.map((name, i) =>
Array.from(part_handlers[parts_order[i]].name_element.options).findIndex(x => x.value === name)
);
if (parts.every(x => x != -1)) {
// all part names were found
parts.forEach((part_index, i) => part_handlers[parts_order[i]].setIndex(part_index));
}
}
}
function randomize() { //Randomize which parts are shown
for (const i in part_handlers) {
part_handlers[i].randomize();
@ -251,10 +281,18 @@ const NeomojiMixer = (function(NeomojiMixer) {
function exportImage() { //Export image so it can be saved as one PNG
let ctx=canvas.getContext("2d");
let export_mime = document.getElementById("export-mime").value;
let export_options = undefined;
if (document.getElementById("export-quality-enabled").checked) {
export_options = +document.getElementById("export-quality").value;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
neomoji_name.value = part_handlers.body.getSelectedEntry()[0] + "_" + part_handlers.eyes.getSelectedEntry()[0] + "_" + part_handlers.mouth.getSelectedEntry()[0] + "_" + part_handlers.arms.getSelectedEntry()[0]; //Set name for the emoji to use as the image name and to show as shortcode
//Set name for the emoji to use as the image name and to show as shortcode
let name = part_handlers.body.getSelectedEntry()[0] + "_" + part_handlers.eyes.getSelectedEntry()[0] + "_" + part_handlers.mouth.getSelectedEntry()[0] + "_" + part_handlers.arms.getSelectedEntry()[0];
neomoji_name.innerText = name;
neomoji_name.href = new URL("#" + part_handlers.body.getSelectedEntry()[0] + "+" + part_handlers.eyes.getSelectedEntry()[0] + "+" + part_handlers.mouth.getSelectedEntry()[0] + "+" + part_handlers.arms.getSelectedEntry()[0], document.location.href)
let export_layers = [
part_handlers.body.createExportImage(),
@ -274,13 +312,16 @@ const NeomojiMixer = (function(NeomojiMixer) {
export_layers.shift()
ctx.drawImage(layer, 0, 0, 256, 256);
}
let img = canvas.toDataURL("image/png");
let img = canvas.toDataURL(export_mime, export_options);
export_img.src = img;
export_img_download.href = img;
export_img_download.download = name + "." + (export_mime.match(/\/(\w+)/) || ["", "png"])[1];
}
setTimeout(layerCallback, 0); //Run asynchronously
export_img.hidden = false;
export_img_download.hidden = false;
neomoji_name.hidden = false;
document.getElementById("exportSaveMessage").hidden = false;
}

View File

@ -13,7 +13,7 @@
{"name": "devil", "url": "/parts/eyes_devil.png"},
{"name": "drowsy", "url": "/parts/eyes_drowsy.png"},
{"name": "evil", "url": "/parts/eyes_evil.png"},
{"name": ">_<", "url": "/parts/eyes_><.png"},
{"name": ">_<", "url": "/parts/eyes_squint.png"},
{"name": "cry", "url": "/parts/eyes_cry.png"},
{"name": "owo", "url": "/parts/eyes_owo.png"},
{"name": "sad", "url": "/parts/eyes_sad.png"},
@ -66,6 +66,16 @@
{"name": "neopossum_rainbow","url": "/parts/neopossum_rainbow.png", "color": "lightgrey"},
{"name": "neorat","url": "/parts/neorat.png", "color": "white"},
{"name": "neorat_frozen","url": "/parts/neorat_frozen.png", "color": "blue"},
{"name": "neobread","url": "/parts/neobread.png", "color": "lightbrown"},
{"name": "neobread_ace","url": "/parts/neobread_ace.png", "color": "lightbrown"},
{"name": "neobread_agender","url": "/parts/neobread_agender.png", "color": "lightbrown"},
{"name": "neobread_aro","url": "/parts/neobread_aro.png", "color": "lightbrown"},
{"name": "neobread_bi","url": "/parts/neobread_bi.png", "color": "lightbrown"},
{"name": "neobread_lesbian","url": "/parts/neobread_lesbian.png", "color": "lightbrown"},
{"name": "neobread_nb","url": "/parts/neobread_nb.png", "color": "lightbrown"},
{"name": "neobread_pan","url": "/parts/neobread_pan.png", "color": "lightbrown"},
{"name": "neobread_rainbow","url": "/parts/neobread_rainbow.png", "color": "lightbrown"},
{"name": "neobread_trans","url": "/parts/neobread_trans.png", "color": "lightbrown"},
{"name": "neofox","url": "/parts/neofox.png", "color": "orange"}
],
"mouth": [
@ -282,6 +292,37 @@
{"name": "book","url": "/parts/arms_book_yellow.png", "color": "yellow"},
{"name": "hold_burger","url": "/parts/arms_hold_burger_yellow.png", "color": "yellow"},
{"name": "hungry","url": "/parts/arms_hungry_yellow.png", "color": "yellow"},
{"name": "hide","url": "/parts/arms_hide_lightbrown.png", "color": "lightbrown"},
{"name": "aww","url": "/parts/arms_aww_lightbrown.png", "color": "lightbrown"},
{"name": "pleading","url": "/parts/arms_pleading_lightbrown.png", "color": "lightbrown"},
{"name": "reach","url": "/parts/arms_reach_lightbrown.png", "color": "lightbrown"},
{"name": "3c","url": "/parts/arms_3c_lightbrown.png", "color": "lightbrown"},
{"name": "facepalm","url": "/parts/arms_facepalm_lightbrown.png", "color": "lightbrown"},
{"name": "mug","url": "/parts/arms_mug_lightbrown.png", "color": "lightbrown"},
{"name": "knife","url": "/parts/arms_knife_lightbrown.png", "color": "lightbrown"},
{"name": "phone","url": "/parts/arms_phone_lightbrown.png", "color": "lightbrown"},
{"name": "fingerguns","url": "/parts/arms_fingerguns_lightbrown.png", "color": "lightbrown"},
{"name": "science","url": "/parts/arms_science_lightbrown.png", "color": "lightbrown"},
{"name": "sign_no","url": "/parts/arms_sign_no_lightbrown.png", "color": "lightbrown"},
{"name": "sign_aaa","url": "/parts/arms_sign_aaa_lightbrown.png", "color": "lightbrown"},
{"name": "sign_nya","url": "/parts/arms_sign_nya_lightbrown.png", "color": "lightbrown"},
{"name": "sign_thx","url": "/parts/arms_sign_thx_lightbrown.png", "color": "lightbrown"},
{"name": "sign_yes","url": "/parts/arms_sign_yes_lightbrown.png", "color": "lightbrown"},
{"name": "sign_yip","url": "/parts/arms_sign_yip_lightbrown.png", "color": "lightbrown"},
{"name": "sign_boobs","url": "/parts/arms_sign_boobs_lightbrown.png", "color": "lightbrown"},
{"name": "sign_butts","url": "/parts/arms_sign_butts_lightbrown.png", "color": "lightbrown"},
{"name": "sign_heart","url": "/parts/arms_heart_lightbrown.png", "color": "lightbrown"},
{"name": "solder","url": "/parts/arms_solder_lightbrown.png", "color": "lightbrown"},
{"name": "redlos","url": "/parts/arms_redlos_lightbrown.png", "color": "lightbrown"},
{"name": "think","url": "/parts/arms_think_lightbrown.png", "color": "lightbrown"},
{"name": "sweat","url": "/parts/arms_sweat_lightbrown.png", "color": "lightbrown"},
{"name": "verified","url": "/parts/arms_verified_lightbrown.png", "color": "lightbrown"},
{"name": "shocked","url": "/parts/arms_shocked_lightbrown.png", "color": "lightbrown"},
{"name": "thumbsdown","url": "/parts/arms_thumbsdown_lightbrown.png", "color": "lightbrown"},
{"name": "thumbsup","url": "/parts/arms_thumbsup_lightbrown.png", "color": "lightbrown"},
{"name": "book","url": "/parts/arms_book_lightbrown.png", "color": "lightbrown"},
{"name": "hold_burger","url": "/parts/arms_hold_burger_lightbrown.png", "color": "lightbrown"},
{"name": "hungry","url": "/parts/arms_hungry_lightbrown.png", "color": "lightbrown"},
{"name": "boop","url": "/parts/arms_boop.png", "color": ""},
{"name": "sip","url": "/parts/arms_sip.png", "color": ""},
{"name": "blank", "url": "/parts/blank.png", "color": ""}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
parts/neobread.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
parts/neobread_ace.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
parts/neobread_agender.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
parts/neobread_aro.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
parts/neobread_bi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
parts/neobread_lesbian.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
parts/neobread_nb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
parts/neobread_pan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
parts/neobread_rainbow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
parts/neobread_trans.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB