Merge pull request #131 from PretendoNetwork/feature-mii-editor

feature: mii editor
This commit is contained in:
Jonathan Barrow 2022-08-01 21:39:08 -04:00 committed by GitHub
commit 50daf65329
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 11001 additions and 419 deletions

View File

@ -19,6 +19,9 @@ button:hover,
.button:hover {
background: var(--bg-shade-4);
}
button.inactive {
pointer-events: none;
}
button.primary,
.button.primary {
background: var(--accent-shade-0);
@ -144,3 +147,44 @@ input:focus {
outline: none;
transition: 150ms;
}
input[type="range"] {
background: transparent;
cursor: pointer;
width: 100%;
box-sizing: border-box;
}
input[type="range"]::-webkit-slider-runnable-track {
background: var(--bg-shade-3);
height: 1rem;
border-radius: 1rem;
}
input[type="range"]::-moz-range-track {
background: var(--bg-shade-3);
border-radius: 1rem;
height: 1rem;
}
input[type="range"]::-webkit-slider-thumb {
appearance: none;
-webkit-appearance: none;
width: 1.5rem;
height: 3rem;
margin-top: -1rem;
background-color: var(--accent-shade-1);
border-radius: 0.5rem;
}
input[type="range"]::-moz-range-thumb {
width: 1.5rem;
height: 3rem;
border: none;
border-radius: 0.5rem;
background-color: var(--accent-shade-1);
}
input[type="range"]:focus {
outline: none;
}
input[type="range"]:focus::-webkit-slider-thumb {
background-color: var(--accent-shade-3);
}
input[type="range"]:focus::-moz-range-thumb {
background-color: var(--accent-shade-3);
}

View File

@ -1,32 +1,57 @@
html,
body,
div.main-body {
height: 100%;
}
body,
div.main-body,
.miieditor-wrapper {
z-index: -1;
user-select: none;
background: var(--bg-shade-0);
}
svg.logotype {
position: absolute;
width: 120px;
top:42px;
left:162px;
top: 42px;
left: 60px;
}
.miieditor-wrapper {
position: relative;
display: grid;
grid-template-columns: 2fr 3fr;
background: var(--bg-shade-0);
width: 100vw;
height: 100vh;
grid-template-columns: auto auto;
width: 95vw;
max-width: 1920px;
height: 100%;
margin: auto;
gap: 0 48px;
}
.params-wrapper::before {
content: "";
display: block;
position: absolute;
background: var(--bg-shade-1);
border-radius: 100%;
width: 1300px;
height: 1700px;
top: 50%;
transform: translateY(-50%);
left: -200px;
z-index: -1;
}
.miieditor-wrapper::after {
content: "";
display: block;
position: absolute;
background: radial-gradient(closest-side, var(--bg-shade-1) 0%, transparent 100%);
background: radial-gradient(
closest-side,
var(--bg-shade-1) 0%,
rgba(27, 31, 59, 0) 100%
);
width: 200vh;
height: 200vh;
top: -100vh;
@ -37,120 +62,163 @@ svg.logotype {
div.mii-img-wrapper {
position: relative;
margin: auto;
max-width: 512px;
width: 26vw;
height: auto;
display: flex;
justify-content: center;
width: 512px;
left: -48px;
height: 100%;
max-height: 384px;
}
img#mii-img {
position: relative;
width: 512px;
height: auto;
position: absolute;
bottom: 0;
width: auto;
height: 512px;
z-index: 2;
}
div.mii-img-wrapper .shadow {
div.mii-img-wrapper::before {
content: "";
position: absolute;
bottom: -18px;
left: 6px;
bottom: -22px;
height: 72px;
width: 512px;
background: radial-gradient(farthest-side, var(--bg-shade-2) 0%, transparent 100%);
width: 100%;
background: radial-gradient(
farthest-side,
var(--bg-shade-2) 0%,
rgba(35, 39, 74, 0) 100%
);
}
div.params-wrapper {
position: relative;
overflow-x: visible;
margin: auto;
margin-top: 150px;
margin-right: 100px;
display: grid;
z-index: 3;
}
div.tabs {
display: grid;
grid-auto-flow: column;
width: fit-content;
gap: 2px;
background: #0A0C19;
grid-template-columns: repeat(11, 1fr);
width: 100%;
box-sizing: border-box;
background: #0a0c19;
padding: 6px;
gap: 6px;
border-radius: 6px;
margin-bottom: 32px;
margin-bottom: 2rem;
}
div.tabs .tabbtn {
min-width: 42px;
min-height: 42px;
border: none;
display: flex;
align-items: center;
justify-content: center;
aspect-ratio: 1;
border-radius: 6px;
cursor: pointer;
background: none;
color: var(--text-shade-3);
padding: 0;
}
div.tabs .tabbtn::after {
content: "";
display: block;
width: 12px;
height: 12px;
background: url("/assets/images/miieditor.svg");
background-position: calc(var(--assetcol) * -12px) -312px;
transform: scale(2.9);
}
div.tabs .tabbtn:hover,
div.tabs .tabbtn.active {
background: var(--bg-shade-1);
background: var(--bg-shade-2);
}
div.subtabs {
position: relative;
grid-column: 1 / span 2;
display: flex;
width: fit-content;
}
div.subtabs .subtabbtn {
position: relative;
border: none;
padding: 12px;
display: flex;
align-items: center;
justify-content: center;
width: 60px;
border-radius: 6px;
cursor: pointer;
background: none;
padding: 0;
color: var(--text-shade-3);
aspect-ratio: 1;
}
div.subtabs .subtabbtn::after {
content: "";
display: block;
width: 12px;
height: 12px;
background: url("/assets/images/miieditor.svg");
background-position: calc(var(--assetcol) * -12px) -324px;
transform: scale(2.9);
}
div.subtabs .subtabbtn.active::before,
div.subtabs .subtabbtn.active:hover::before {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
bottom: -2px;
left: 5%;
width: 90%;
height: 5px;
background: var(--accent-shade-1);
border-radius: 6px;
}
.subtab.has-sliders {
grid-template-columns: 1fr 1fr;
.has-sliders {
grid-template-columns: 60px auto;
gap: 12px;
}
.has-sliders label {
position: relative;
display: flex;
width: 60px;
height: 60px;
align-items: center;
justify-content: center;
}
.has-sliders label::after {
content: "";
display: block;
width: 16px;
height: 16px;
background: url("/assets/images/miieditor.svg");
background-position: calc(var(--assetcol) * -16px) -336px;
transform: scale(3);
}
form.params {
grid-template-columns: repeat(2, auto);
height: 618px;
width: 582px;
}
form.params .tab {
display: none;
grid-template-columns: 534px 258px;
gap: 48px;
gap: 4rem 0;
}
form.params .tab.active {
display: grid;
}
fieldset {
fieldset,
fieldset.has-subpages .subpage {
appearance: none;
border: none;
padding: 0;
margin: 0;
display: none;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(4, 1fr);
gap: 18px;
width: fit-content;
width: 100%;
height: fit-content;
grid-row: 2;
}
fieldset.active {
display: grid;
}
fieldset.color {
grid-template-columns: repeat(2, 1fr);
display: grid;
grid-column: 2;
}
fieldset input[type="radio"] {
display: none;
}
@ -161,44 +229,48 @@ fieldset input[type="radio"] + label {
cursor: pointer;
border-radius: 18px;
background: var(--bg-shade-3);
width: 120px;
height: 120px;
width: 100%;
aspect-ratio: 1;
}
fieldset input[type="radio"]:checked + label {
background: var(--bg-shade-4);
font-weight: bold;
box-shadow: inset 0 0 0 4px var(--accent-shade-1);
}
fieldset.color input[type="radio"]:checked + label {
box-shadow: inset 0 0 0 4px var(--accent-shade-1), inset 0 0 0 6px var(--bg-shade-1);
}
div.colorSidebar {
margin: auto;
}
fieldset.has-subpages.active {
display: block;
}
fieldset.has-subpages .subpage {
display: none;
grid-template-columns: repeat(4, 1fr);
gap: 18px;
width: fit-content;
height: fit-content;
}
fieldset.has-subpages .subpage.active {
display: grid;
}
fieldset:not(.color, #favoriteColor) input[type="radio"] + label::after {
content: "";
display: block;
width: 24px;
height: 24px;
background: url("/assets/images/miieditor.svg");
background-position: calc(
((var(--assetcol) + (var(--subpage, 0) * 12)) * -24px)
)
calc(var(--assetrow) * -24px);
transform: scale(4.5);
}
fieldset input[type="radio"]:checked + label {
background: var(--bg-shade-4);
box-shadow: inset 0 0 0 4px var(--accent-shade-1);
}
fieldset.color input[type="radio"]:checked + label,
fieldset#favoriteColor input[type="radio"]:checked + label {
box-shadow: inset 0 0 0 4px var(--accent-shade-1),
inset 0 0 0 6px var(--bg-shade-1);
}
input[type="range"].invert {
direction: rtl;
}
.pagination {
display: flex;
flex-flow: row;
width: max-content;
grid-column: 3 / span 2;
height: fit-content;
grid-column: 1 / span 4;
grid-row: 4;
margin-left: auto;
align-items: center;
@ -210,19 +282,26 @@ input[type="range"].invert {
font-weight: bold;
color: var(--text-shade-3);
width: 18px;
margin-right: 0.7ch;
margin-right: 0.5ch;
text-align: right;
}
.page-btn {
appearance: none;
border: none;
background: none;
cursor: pointer;
padding: 0;
margin-left: 8px;
}
.page-btn svg{
.page-btn:hover {
background: none;
}
.page-btn:hover svg path {
fill: var(--accent-shade-3);
}
.page-btn svg {
height: 36px;
margin: 6px
margin: 6px;
}
.page-btn.disabled {
pointer-events: none;
@ -231,20 +310,370 @@ input[type="range"].invert {
fill: var(--bg-shade-3);
}
.tab#saveTab {
gap: 2rem 0;
}
.tab#saveTab p.save-prompt {
margin-bottom: 0;
text-align: center;
}
.mii-comparison-animation-wrapper {
position: relative;
height: fit-content;
}
.mii-comparison {
position: relative;
display: grid;
grid-template-columns: repeat(3, auto);
align-items: center;
width: 100%;
}
.mii-comparison.confirmed {
position: absolute;
height: 100%;
top: 0;
left: 0;
opacity: 0;
overflow: hidden;
}
.mii-comparison img {
display: block;
width: 100%;
aspect-ratio: 1;
background: var(--bg-shade-3);
border-radius: 24px;
}
.mii-comparison .new-mii-wrapper {
position: relative;
transition: right 500ms, transform 500ms;
right: 0;
}
.mii-comparison .new-mii-wrapper::after {
position: absolute;
content: "";
display: block;
box-shadow: inset 0 0 0 8px var(--accent-shade-1);
border-radius: 24px;
margin: 0;
right: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.mii-comparison svg {
width: 72px;
height: 72px;
}
.mii-comparison svg path {
fill: var(--accent-shade-1);
}
.fade-in {
animation: fadeIn 0.25s forwards;
}
.fade-out {
animation: fadeOut 0.5s forwards;
}
.mii-comparison div.new-mii-wrapper.centered-mii-img {
position: absolute;
right: 50%;
transform: translateX(50%);
height: 100%;
aspect-ratio: 1;
width: auto;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
button * {
pointer-events: none;
}
.miieditor-wrapper::before {
content: "";
display: block;
position: absolute;
background: var(--bg-shade-1);
border-radius: 100%;
width: 1308px;
height: 1707px;
top: 50%;
transform: translateY(-50%);
right: -200px;
z-index: 0;
@media screen and (max-width: 1400px) {
form.params {
height: 562px;
width: 512px;
}
fieldset,
fieldset.has-subpages .subpage {
gap: 12px;
}
div.mii-img-wrapper {
left: -36px;
}
div.params-wrapper {
margin-right: 24px;
}
.params-wrapper::before {
left: -150px;
}
div.tabs {
padding: 4px;
gap: 2px;
}
}
@media screen and (max-width: 1280px) {
form.params {
height: 492px;
width: 480px;
}
fieldset,
fieldset.has-subpages .subpage {
gap: 8px;
}
div.mii-img-wrapper {
left: -36px;
}
div.params-wrapper {
margin-right: 24px;
}
.params-wrapper::before {
left: -150px;
}
fieldset:not(.color, #favoriteColor) input[type="radio"] + label::after {
transform: scale(4);
}
div.subtabs .subtabbtn::after,
div.tabs .tabbtn::after {
transform: scale(2.4);
}
div.subtabs .subtabbtn {
width: 48px;
}
.params-wrapper::before {
left: -100px;
}
div.tabs {
margin-bottom: 1rem;
}
form.params .tab {
gap: 2rem 0;
}
}
@media screen and (max-width: 1120px) {
form.params {
height: 444px;
width: 420px;
}
fieldset,
fieldset.has-subpages .subpage {
gap: 6px;
}
}
@media screen and (max-width: 1080px) {
div.mii-img-wrapper {
left: 0;
top: 0;
}
img#mii-img {
max-height: 150%;
}
svg.logotype {
left: 0;
}
.miieditor-wrapper {
grid-template-columns: auto;
grid-template-rows: auto fit-content(100%);
margin: auto;
max-width: 360px;
width: 90vw;
}
div.params-wrapper {
width: 100%;
margin: 0 auto;
display: flex;
flex-flow: column;
}
div.tabs,
div.subtabs {
order: 2;
margin-top: 1rem;
}
div.mii-img-wrapper {
width: 100%;
max-width: 512px;
}
fieldset {
order: 1;
}
form.params {
width: 100%;
height: 100%;
order: 1;
}
fieldset input[type="radio"] + label {
width: 100%;
height: auto;
border-radius: 8px;
aspect-ratio: 1;
}
fieldset:not(.color, #favoriteColor) input[type="radio"] + label::after {
transform: scale(3.5);
}
.has-sliders {
overflow-y: auto;
overflow-x: hidden;
height: 100%;
gap: 2px 6px;
scrollbar-width: thin;
scrollbar-color: var(--text-shade-1) var(--bg-shade-3);
}
.has-sliders::-webkit-scrollbar {
width: 12px;
background: var(--bg-shade-3);
border-radius: 9px;
}
.has-sliders::-webkit-scrollbar-thumb {
background: var(--text-shade-1);
border-radius: 9px;
}
.params-wrapper::before {
top: -12px;
left: -100vw;
width: 300vw;
border-radius: 0;
background: var(--bg-shade-2);
transform: none;
}
fieldset,
fieldset.has-subpages .subpage {
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr) 48px;
width: 100%;
gap: 8px;
}
.pagination {
grid-column: 1 / span 4;
grid-row: 4;
}
fieldset:not(.has-sliders) {
position: relative;
margin-bottom: -60px;
}
div.tabs {
margin-bottom: 1rem;
}
form.params .tab {
gap: 0;
height: 100%;
}
div.subtabs {
z-index: 4;
}
form.params {
grid-template-columns: repeat(2, auto);
}
div.tabs .tabbtn::after,
div.subtabs .subtabbtn::after,
.has-sliders label::after {
transform: scale(2);
}
div.subtabs .subtabbtn {
width: 48px;
height: 48px;
}
}
@media screen and (max-width: 424px) {
fieldset:not(.color, #favoriteColor) input[type="radio"] + label::after {
transform: scale(2.8);
}
}
@media screen and (max-width: 396px) {
div.tabs .tabbtn::after,
div.subtabs .subtabbtn::after,
.has-sliders label::after {
transform: scale(1.5);
}
div.tabs .tabbtn {
width: 24px;
height: 24px;
}
div.subtabs .subtabbtn {
width: 36px;
height: 36px;
}
}
@media screen and (max-width: 360px) {
fieldset,
fieldset.has-subpages .subpage {
gap: 4px;
}
fieldset input[type="radio"]:checked + label {
box-shadow: inset 0 0 0 3px var(--accent-shade-1);
}
}
@media screen and (max-width: 344px) {
fieldset:not(.color, #favoriteColor) input[type="radio"] + label::after {
transform: scale(2);
}
}
@media screen and (max-width: 320px) {
div.tabs .tabbtn {
width: 18px;
height: 18px;
}
div.tabs .tabbtn::after {
transform: scale(1.25);
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 570 KiB

View File

@ -2,11 +2,10 @@
// Prevent the user from reloading or leaving the page
window.addEventListener('beforeunload', function (e) {
e.preventDefault();
e?.preventDefault();
e.returnValue = '';
});
const Mii = require('./MiiClass.js');
// MII RENDERER
@ -16,24 +15,44 @@ const encodedUserMiiData = document.querySelector(
'script#encodedUserMiiData'
).textContent;
document.querySelector('script#encodedUserMiiData').remove();
// We initialize the Mii object with the encoded data and render the Mii
const mii = new Mii(Buffer.from(encodedUserMiiData, 'base64'));
renderMii();
const oldMiiStudioData = mii.toStudioMii().toString('hex');
// initial setup for saving animation
document.querySelector('.mii-comparison img.old-mii').src = `https://studio.mii.nintendo.com/miis/image.png?data=${oldMiiStudioData}&type=face&expression=normal&width=512&bgColor=13173300`;
document.querySelector('.mii-comparison.confirmed img.old-mii').src = `https://studio.mii.nintendo.com/miis/image.png?data=${oldMiiStudioData}&type=face&expression=sorrow&width=512&bgColor=13173300`;
// This function renders the Mii on the page
function renderMii(type) {
type = type || 'all_body'; // Can be 'all_body' or 'face'
const newMii = mii.toStudioMii().toString('hex');
const miiStudioData = mii.toStudioMii().toString('hex');
document.querySelector(
'img#mii-img'
).src = `https://studio.mii.nintendo.com/miis/image.png?data=${newMii}&type=${type}&expression=normal&width=512&bgColor=CAB1FB00`;
).src = `https://studio.mii.nintendo.com/miis/image.png?data=${miiStudioData}&type=${type}&expression=normal&width=512&bgColor=13173300`;
// This updates the offset of the shadow of the Mii
document.querySelector('div.mii-img-wrapper .shadow').style.bottom = `${
mii.height * mii.height * 0.0035 - mii.height * 0.162 - 18
// sets the new mii in the save tab to the new mii
document.querySelector(
'.mii-comparison img.new-mii'
).src = `https://studio.mii.nintendo.com/miis/image.png?data=${miiStudioData}&type=face&expression=normal&width=512&bgColor=13173300`;
document.querySelector(
'.mii-comparison.confirmed img.new-mii'
).src = `https://studio.mii.nintendo.com/miis/image.png?data=${miiStudioData}&type=face&expression=smile&width=512&bgColor=13173300`;
// this sets the mii height so that the face width stays the same
document.querySelector('img#mii-img').style.height = `${
mii.height * mii.height * 0.0023 + mii.height * 1.058 + 384
}px`;
// this sets the bottom position so that the mii's feet stay in the same position
document.querySelector('img#mii-img').style.bottom = `${
mii.height * mii.height * -0.00468135 + mii.height * 0.28 - 0.052435
}px`;
console.log(mii);
}
// This function updates a prop of the Mii and rerenders it
@ -41,7 +60,6 @@ function updateMii(e, type) {
const prop = e.target.name;
const value = e.target.value;
mii[prop] = parseInt(value);
console.log(mii);
renderMii(type);
}
@ -95,6 +113,9 @@ document.querySelectorAll('input[type=\'range\']').forEach((fieldset) => {
'eyeStretch',
'noseVertical',
'noseSize',
'mouthVertical',
'mouthSize',
'mouthStretch',
'glassesVertical',
'glassesSize',
'facialHairVertical',
@ -200,3 +221,28 @@ document.querySelectorAll('span.current-page-index').forEach((el) => {
document.querySelectorAll('button.page-btn').forEach((el) => {
el.addEventListener('click', paginationHandler);
});
// mii saving business (animation jank & actual saving)
document.querySelector('#saveTab #saveButton').addEventListener('click', (e) => {
e.preventDefault();
document.querySelector('#saveTab #saveButton').classList.add('inactive', 'fade-out');
document.querySelector('.tabs').style.pointerEvents = 'none';
document.querySelector('.mii-comparison.confirmed').style.opacity = 1;
document.querySelector('#saveTab p.save-prompt').classList.add('fade-out');
setTimeout(() => {
document.querySelector('.mii-comparison.unconfirmed').style.opacity = 0;
}, 500);
setTimeout(() => {
document.querySelector('.mii-comparison.confirmed .old-mii').classList.add('fade-out');
document.querySelector('.mii-comparison.confirmed svg').classList.add('fade-out');
}, 1500);
setTimeout(() => {
document.querySelector('.mii-comparison.confirmed .new-mii-wrapper').classList.add('centered-mii-img');
}, 2000);
});

39
src/json/miieditor.json Normal file
View File

@ -0,0 +1,39 @@
{
"face": [0, 1, 8, 2, 3, 9, 4, 5, 10, 6, 7, 11],
"hairs": [
[33, 47, 40, 37, 32, 107, 48, 51, 55, 70, 44, 66],
[52, 50, 38, 49, 43, 31, 56, 68, 62, 115, 76, 119],
[64, 81, 116, 121, 22, 58, 60, 87, 125, 117, 73, 75],
[42, 89, 57, 54, 80, 34, 23, 86, 88, 118, 39, 36],
[45, 67, 59, 65, 41, 30, 12, 16, 10, 82, 128, 129],
[14, 95, 105, 100, 6, 20, 93, 102, 27, 4, 17, 110],
[123, 8, 106, 72, 3, 21, 0, 98, 63, 90, 11, 120],
[5, 74, 108, 94, 124, 25, 99, 69, 35, 13, 122, 113],
[53, 24, 85, 83, 71, 131, 96, 101, 29, 7, 15, 112],
[79, 1, 109, 127, 91, 26, 61, 103, 2, 77, 18, 92],
[84, 9, 19, 130, 97, 104, 46, 78, 28, 114, 126, 111]
],
"eyebrows": [
[6, 0, 12, 1, 9, 19, 7, 21, 8, 17, 5, 4],
[11, 10, 2, 3, 14, 20, 15, 13, 22, 18, 16, 23]
],
"eyes": [
[2, 4, 0, 8, 39, 17, 1, 26, 16, 15, 27, 20],
[33, 11, 19, 32, 9, 12, 23, 34, 21, 25, 40, 35],
[5, 41, 13, 36, 37, 6, 24, 30, 31, 18, 28, 46],
[7, 44, 38, 42, 45, 29, 3, 43, 22, 10, 14, 47],
[48, 49, 50, 53, 59, 56, 54, 58, 57, 55, 51, 52]
],
"nose": [
[1, 10, 2, 3, 6, 0, 5, 4, 8, 9, 7, 11],
[13, 14, 12, 17, 16, 15]
],
"mouth": [
[23, 1, 19, 21, 22, 5, 0, 8, 10, 16, 6, 13],
[7, 9, 2, 17, 3, 4, 15, 11, 20, 18, 14, 12],
[27, 30, 24, 25, 29, 28, 26, 35, 31, 34, 33, 32]
],
"arrayOf6": [0, 1, 2, 3, 4, 5],
"arrayOf9": [0, 1, 2, 3, 4, 5, 6, 7, 8],
"arrayOf12": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
}

View File

@ -12,6 +12,7 @@ const cache = require('../cache');
const util = require('../util');
const logger = require('../logger');
const config = require('../../config.json');
const editorJSON = require('../json/miieditor.json');
const { Router } = express;
@ -217,50 +218,9 @@ router.post('/online-files', requireLoginMiddleware, async (request, response) =
router.get('/miieditor', requireLoginMiddleware, async (request, response) => {
const { account } = request;
// Adapted from https://www.3dbrew.org/wiki/Mii#Mapped_Editor_.3C-.3E_Hex_values
const editorToHex = {
'face': [
0x00,0x01,0x08,0x02,0x03,0x09,0x04,0x05,0x0a,0x06,0x07,0x0b
],
'hairs': [
[0x21,0x2f,0x28,0x25,0x20,0x6b,0x30,0x33,0x37,0x46,0x2c,0x42],
[0x34,0x32,0x26,0x31,0x2b,0x1f,0x38,0x44,0x3e,0x73,0x4c,0x77],
[0x40,0x51,0x74,0x79,0x16,0x3a,0x3c,0x57,0x7d,0x75,0x49,0x4b],
[0x2a,0x59,0x39,0x36,0x50,0x22,0x17,0x56,0x58,0x76,0x27,0x24],
[0x2d,0x43,0x3b,0x41,0x29,0x1e,0x0c,0x10,0x0a,0x52,0x80,0x81],
[0x0e,0x5f,0x69,0x64,0x06,0x14,0x5d,0x66,0x1b,0x04,0x11,0x6e],
[0x7b,0x08,0x6a,0x48,0x03,0x15,0x00,0x62,0x3f,0x5a,0x0b,0x78],
[0x05,0x4a,0x6c,0x5e,0x7c,0x19,0x63,0x45,0x23,0x0d,0x7a,0x71],
[0x35,0x18,0x55,0x53,0x47,0x83,0x60,0x65,0x1d,0x07,0x0f,0x70],
[0x4f,0x01,0x6d,0x7f,0x5b,0x1a,0x3d,0x67,0x02,0x4d,0x12,0x5c],
[0x54,0x09,0x13,0x82,0x61,0x68,0x2e,0x4e,0x1c,0x72,0x7e,0x6f]
],
'eyebrows': [
[0x06,0x00,0x0c,0x01,0x09,0x13,0x07,0x15,0x08,0x11,0x05,0x04],
[0x0b,0x0a,0x02,0x03,0x0e,0x14,0x0f,0x0d,0x16,0x12,0x10,0x17]
],
'eyes': [
[0x02,0x04,0x00,0x08,0x27,0x11,0x01,0x1a,0x10,0x0f,0x1b,0x14],
[0x21,0x0b,0x13,0x20,0x09,0x0c,0x17,0x22,0x15,0x19,0x28,0x23],
[0x05,0x29,0x0d,0x24,0x25,0x06,0x18,0x1e,0x1f,0x12,0x1c,0x2e],
[0x07,0x2c,0x26,0x2a,0x2d,0x1d,0x03,0x2b,0x16,0x0a,0x0e,0x2f],
[0x30,0x31,0x32,0x35,0x3b,0x38,0x36,0x3a,0x39,0x37,0x33,0x34]
],
'nose': [
[0x01,0x0a,0x02,0x03,0x06,0x00, 0x05,0x04,0x08,0x09,0x07,0x0B],
[0x0d,0x0e,0x0c,0x11,0x10,0x0f]
],
'mouth': [
[0x17,0x01,0x13,0x15,0x16,0x05,0x00,0x08,0x0a,0x10,0x06,0x0d],
[0x07,0x09,0x02,0x11,0x03,0x04,0x0f,0x0b,0x14,0x12,0x0e,0x0c],
[0x1b,0x1e,0x18,0x19,0x1d,0x1c,0x1a,0x23,0x1f,0x22,0x21,0x20]
]
};
response.render('account/miieditor', {
encodedUserMiiData: account.mii.data,
editorToHex
editorJSON
});
});

View File

@ -26,67 +26,39 @@
<div class="mii-img-wrapper">
<img id="mii-img" draggable="false" />
<div class="shadow"></div>
</div>
<div class="params-wrapper">
<div class="tabs">
<button class="tabbtn active" id="faceTypeButton">
face
</button>
<button class="tabbtn" id="hairTypeButton">
hair
</button>
<button class="tabbtn" id="eyebrowTypeButton">
eyebrow
</button>
<button class="tabbtn" id="eyeTypeButton">
eye
</button>
<button class="tabbtn" id="noseTypeButton">
nose
</button>
<button class="tabbtn" id="mouthTypeButton">
mouth
</button>
<button class="tabbtn" id="glassesTypeButton">
glasses
</button>
<button class="tabbtn" id="facialHairTypeButton">
facialHair
</button>
<button class="tabbtn" id="moleEnableButton">
mole
</button>
<button class="tabbtn" id="sizeButton">
size
</button>
<button class="tabbtn" id="miiscButton">
miisc
</button>
<button class="tabbtn active" id="faceTypeButton" style="--assetcol: 0"></button>
<button class="tabbtn" id="hairTypeButton" style="--assetcol: 1"></button>
<button class="tabbtn" id="eyebrowTypeButton" style="--assetcol: 2"></button>
<button class="tabbtn" id="eyeTypeButton" style="--assetcol: 3"></button>
<button class="tabbtn" id="noseTypeButton" style="--assetcol: 4"></button>
<button class="tabbtn" id="mouthTypeButton" style="--assetcol: 5"></button>
<button class="tabbtn" id="glassesTypeButton" style="--assetcol: 6"></button>
<button class="tabbtn" id="facialHairTypeButton"style="--assetcol: 7"></button>
<button class="tabbtn" id="moleEnableButton" style="--assetcol: 8"></button>
<button class="tabbtn" id="miiscButton" style="--assetcol: 9"></button>
<button class="tabbtn" id="saveButton" style="--assetcol: 10"></button>
</div>
<form class="params">
<div class="tab active" id="faceTypeTab">
<div class="subtabs">
<button class="subtabbtn active" id="faceTypeSubButton">
faceType
</button>
<button class="subtabbtn" id="faceMakeupSubButton">
faceMakeup
</button>
<button class="subtabbtn" id="faceWrinklesSubButton">
faceWrinkles
</button>
<button class="subtabbtn active" id="faceTypeSubButton" style="--assetcol: 0"></button>
<button class="subtabbtn" id="faceMakeupSubButton" style="--assetcol: 1"></button>
<button class="subtabbtn" id="faceWrinklesSubButton" style="--assetcol: 2"></button>
<button class="subtabbtn" id="faceColorSubButton" style="--assetcol: 12"></button>
</div>
<fieldset class="subtab active" id="faceType">
{{#each editorToHex.face}}
<fieldset class="subtab active" id="faceType" style="--assetrow: 0">
{{#each editorJSON.face}}
<input type="radio" name="faceType" id="faceType{{this}}" value="{{this}}" />
<label for="faceType{{this}}">{{this}}</label>
<label for="faceType{{this}}" style="--assetcol: {{@key}}"></label>
{{/each}}
</fieldset>
<fieldset id="faceColor" class="color">
<fieldset id="faceColor" class="subtab color">
<input type="radio" name="faceColor" id="faceColor0" value="0" />
<label for="faceColor0" style="background: #FFCE98 !important;" ></label>
<input type="radio" name="faceColor" id="faceColor1" value="1" />
@ -101,69 +73,33 @@
<label for="faceColor5" style="background: #752E17 !important;" ></label>
</fieldset>
<fieldset id="faceMakeup" class="subtab">
<input type="radio" name="faceMakeup" id="faceMakeup0" value="0" />
<label for="faceMakeup0">0</label>
<input type="radio" name="faceMakeup" id="faceMakeup1" value="1" />
<label for="faceMakeup1">1</label>
<input type="radio" name="faceMakeup" id="faceMakeup2" value="2" />
<label for="faceMakeup2">2</label>
<input type="radio" name="faceMakeup" id="faceMakeup3" value="3" />
<label for="faceMakeup3">3</label>
<input type="radio" name="faceMakeup" id="faceMakeup4" value="4" />
<label for="faceMakeup4">4</label>
<input type="radio" name="faceMakeup" id="faceMakeup5" value="5" />
<label for="faceMakeup5">5</label>
<input type="radio" name="faceMakeup" id="faceMakeup6" value="6" />
<label for="faceMakeup6">6</label>
<input type="radio" name="faceMakeup" id="faceMakeup7" value="7" />
<label for="faceMakeup7">7</label>
<input type="radio" name="faceMakeup" id="faceMakeup8" value="8" />
<label for="faceMakeup8">8</label>
<input type="radio" name="faceMakeup" id="faceMakeup9" value="9" />
<label for="faceMakeup9">9</label>
<input type="radio" name="faceMakeup" id="faceMakeup10" value="10" />
<label for="faceMakeup10">10</label>
<input type="radio" name="faceMakeup" id="faceMakeup11" value="11" />
<label for="faceMakeup11">11</label>
<fieldset id="faceMakeup" class="subtab" style="--assetrow: 1">
{{#each editorJSON.arrayOf12}}
<input type="radio" name="faceMakeup" id="faceMakeup{{this}}" value="{{this}}" />
<label for="faceMakeup{{this}}" style="--assetcol: {{@key}}"></label>
{{/each}}
</fieldset>
<fieldset id="faceWrinkles" class="subtab">
<input type="radio" name="faceWrinkles" id="faceWrinkles0" value="0" />
<label for="faceWrinkles0">0</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles1" value="1" />
<label for="faceWrinkles1">1</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles2" value="2" />
<label for="faceWrinkles2">2</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles3" value="3" />
<label for="faceWrinkles3">3</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles4" value="4" />
<label for="faceWrinkles4">4</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles5" value="5" />
<label for="faceWrinkles5">5</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles6" value="6" />
<label for="faceWrinkles6">6</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles7" value="7" />
<label for="faceWrinkles7">7</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles8" value="8" />
<label for="faceWrinkles8">8</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles9" value="9" />
<label for="faceWrinkles9">9</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles10" value="10" />
<label for="faceWrinkles10">10</label>
<input type="radio" name="faceWrinkles" id="faceWrinkles11" value="11" />
<label for="faceWrinkles11">11</label>
<fieldset id="faceWrinkles" class="subtab" style="--assetrow: 2">
{{#each editorJSON.arrayOf12}}
<input type="radio" name="faceWrinkles" id="faceWrinkles{{this}}" value="{{this}}" />
<label for="faceWrinkles{{this}}" style="--assetcol: {{@key}}"></label>
{{/each}}
</fieldset>
</div>
<div class="tab" id="hairTypeTab">
<fieldset id="hairType" class="has-subpages active">
{{#each editorToHex.hairs}}
<div class="subpage">
<div class="tab" id="hairTypeTab" style="--assetrow: 3">
<div class="subtabs">
<button class="subtabbtn active" id="hairTypeSubButton" style="--assetcol: 9"></button>
<button class="subtabbtn" id="hairColorSubButton" style="--assetcol: 12"></button>
</div>
<fieldset id="hairType" class="subtab has-subpages active">
{{#each editorJSON.hairs}}
<div class="subpage" style="--subpage: {{@key}}">
{{#each this}}
<input type="radio" name="hairType" id="hairType{{this}}" value="{{this}}" />
<label for="hairType{{this}}">{{this}}</label>
<label for="hairType{{this}}" style="--assetcol: {{@key}}"></label>
{{/each}}
<div class="pagination">
<button class="previous page-btn index-{{@index}} {{#if @first }}disabled{{/if}}">
@ -186,7 +122,7 @@
{{/each}}
</fieldset>
<fieldset id="hairColor" class="color">
<fieldset id="hairColor" class="subtab color">
<input type="radio" name="hairColor" id="hairColor0" value="0" />
<label for="hairColor0" style="background: #0A0A09 !important;" ></label>
<input type="radio" name="hairColor" id="hairColor1" value="1" />
@ -208,19 +144,16 @@
<div class="tab" id="eyebrowTypeTab">
<div class="subtabs">
<button class="subtabbtn active" id="eyebrowTypeSubButton">
eyebrowType
</button>
<button class="subtabbtn" id="eyebrowPositionSubButton">
eyebrowPosition
</button>
<button class="subtabbtn active" id="eyebrowTypeSubButton" style="--assetcol: 3"></button>
<button class="subtabbtn" id="eyebrowPositionSubButton" style="--assetcol: 13"></button>
<button class="subtabbtn" id="eyebrowColorSubButton" style="--assetcol: 12"></button>
</div>
<fieldset id="eyebrowType" class="subtab has-subpages active">
{{#each editorToHex.eyebrows}}
<div class="subpage">
<fieldset id="eyebrowType" class="subtab has-subpages active" style="--assetrow: 4">
{{#each editorJSON.eyebrows}}
<div class="subpage" style="--subpage: {{@key}}">
{{#each this}}
<input type="radio" name="eyebrowType" id="eyebrowType{{this}}" value="{{this}}" />
<label for="eyebrowType{{this}}">{{this}}</label>
<label for="eyebrowType{{this}}" style="--assetcol: {{@key}}"><div></div></label>
{{/each}}
<div class="pagination">
<button class="previous page-btn index-{{@index}} {{#if @first }}disabled{{/if}}">
@ -240,19 +173,19 @@
</fieldset>
<fieldset id="eyebrowPosition" class="subtab has-sliders">
<input type="range" class="invert" name="eyebrowVertical" id="eyebrowVertical" min="3" max="18" />
<label for="eyebrowVertical">eyebrowVertical</label>
<input type="range" name="eyebrowHorizontal" id="eyebrowHorizontal" min="0" max="12" />
<label for="eyebrowHorizontal">eyebrowHorizontal</label>
<input type="range" name="eyebrowRotation" id="eyebrowRotation" min="0" max="11" />
<label for="eyebrowRotation">eyebrowRotation</label>
<input type="range" name="eyebrowSize" id="eyebrowSize" min="0" max="8" />
<label for="eyebrowSize">eyebrowSize</label>
<input type="range" name="eyebrowStretch" id="eyebrowStretch" min="0" max="6" />
<label for="eyebrowStretch">eyebrowStretch</label>
<label for="eyebrowVertical" style="--assetcol: 2"></label>
<input type="range" list="tickmarks" class="invert" name="eyebrowVertical" id="eyebrowVertical" min="3" max="18" />
<label for="eyebrowHorizontal" style="--assetcol: 4"></label>
<input type="range" list="tickmarks" name="eyebrowHorizontal" id="eyebrowHorizontal" min="0" max="12" />
<label for="eyebrowRotation" style="--assetcol: 5"></label>
<input type="range" list="tickmarks" class="invert" name="eyebrowRotation" id="eyebrowRotation" min="0" max="11" />
<label for="eyebrowSize" style="--assetcol: 6"></label>
<input type="range" list="tickmarks" name="eyebrowSize" id="eyebrowSize" min="0" max="8" />
<label for="eyebrowStretch" style="--assetcol: 7"></label>
<input type="range" list="tickmarks" name="eyebrowStretch" id="eyebrowStretch" min="0" max="6" />
</fieldset>
<fieldset id="eyebrowColor" class="color">
<fieldset id="eyebrowColor" class="subtab color">
<input type="radio" name="eyebrowColor" id="eyebrowColor0" value="0" />
<label for="eyebrowColor0" style="background: #0A0A09 !important;" ></label>
<input type="radio" name="eyebrowColor" id="eyebrowColor1" value="1" />
@ -274,19 +207,16 @@
<div class="tab" id="eyeTypeTab">
<div class="subtabs">
<button class="subtabbtn active" id="eyeTypeSubButton">
eyeType
</button>
<button class="subtabbtn" id="eyePositionSubButton">
eyePosition
</button>
<button class="subtabbtn active" id="eyeTypeSubButton" style="--assetcol: 4"></button>
<button class="subtabbtn" id="eyePositionSubButton" style="--assetcol: 13"></button>
<button class="subtabbtn" id="eyeColorSubButton" style="--assetcol: 12"></button>
</div>
<fieldset id="eyeType" class="subtab has-subpages active">
{{#each editorToHex.eyes}}
<div class="subpage">
<fieldset id="eyeType" class="subtab has-subpages active" style="--assetrow: 5">
{{#each editorJSON.eyes}}
<div class="subpage" style="--subpage: {{@key}}">
{{#each this}}
<input type="radio" name="eyeType" id="eyeType{{this}}" value="{{this}}" />
<label for="eyeType{{this}}">{{this}}</label>
<label for="eyeType{{this}}" style="--assetcol: {{@key}}"></label>
{{/each}}
<div class="pagination">
<button class="previous page-btn index-{{@index}} {{#if @first }}disabled{{/if}}">
@ -305,7 +235,7 @@
{{/each}}
</fieldset>
<fieldset id="eyeColor" class="color">
<fieldset id="eyeColor" class="subtab color">
<input type="radio" name="eyeColor" id="eyeColor0" value="0" />
<label for="eyeColor0" style="background: #070606 !important;" ></label>
<input type="radio" name="eyeColor" id="eyeColor1" value="1" />
@ -321,34 +251,30 @@
</fieldset>
<fieldset id="eyePosition" class="subtab has-sliders">
<input type="range" class="invert" name="eyeVertical" id="eyeVertical" min="0" max="18" />
<label for="eyeVertical">eyeVertical</label>
<input type="range" name="eyeHorizontal" id="eyeHorizontal" min="0" max="12" />
<label for="eyeHorizontal">eyeHorizontal</label>
<input type="range" name="eyeRotation" id="eyeRotation" min="0" max="7" />
<label for="eyeRotation">eyeRotation</label>
<input type="range" name="eyeSize" id="eyeSize" min="0" max="7" />
<label for="eyeSize">eyeSize</label>
<input type="range" name="eyeStretch" id="eyeStretch" min="0" max="6" />
<label for="eyeStretch">eyeStretch</label>
<label for="eyeVertical" style="--assetcol: 2"></label>
<input type="range" list="tickmarks" class="invert" name="eyeVertical" id="eyeVertical" min="0" max="18" />
<label for="eyeHorizontal" style="--assetcol: 4"></label>
<input type="range" list="tickmarks" name="eyeHorizontal" id="eyeHorizontal" min="0" max="12" />
<label for="eyeRotation" style="--assetcol: 5"></label>
<input type="range" class="invert" list="tickmarks" name="eyeRotation" id="eyeRotation" min="0" max="7" />
<label for="eyeSize" style="--assetcol: 6"></label>
<input type="range" list="tickmarks" name="eyeSize" id="eyeSize" min="0" max="7" />
<label for="eyeStretch" style="--assetcol: 7"></label>
<input type="range" list="tickmarks" name="eyeStretch" id="eyeStretch" min="0" max="6" />
</fieldset>
</div>
<div class="tab" id="noseTypeTab">
<div class="subtabs">
<button class="subtabbtn active" id="noseTypeSubButton">
noseType
</button>
<button class="subtabbtn" id="nosePositionSubButton">
nosePosition
</button>
<button class="subtabbtn active" id="noseTypeSubButton" style="--assetcol: 5"></button>
<button class="subtabbtn" id="nosePositionSubButton" style="--assetcol: 13"></button>
</div>
<fieldset id="noseType" class="subtab has-subpages active">
{{#each editorToHex.nose}}
<div class="subpage">
<fieldset id="noseType" class="subtab has-subpages active" style="--assetrow: 6">
{{#each editorJSON.nose}}
<div class="subpage" style="--subpage: {{@key}}">
{{#each this}}
<input type="radio" name="noseType" id="noseType{{this}}" value="{{this}}" />
<label for="noseType{{this}}">{{this}}</label>
<label for="noseType{{this}}" style="--assetcol: {{@key}}"></label>
{{/each}}
<div class="pagination">
<button class="previous page-btn index-{{@index}} {{#if @first }}disabled{{/if}}">
@ -368,28 +294,26 @@
</fieldset>
<fieldset id="nosePosition" class="subtab has-sliders">
<input type="range" class="invert" name="noseVertical" id="noseVertical" min="0" max="18" />
<label for="noseVertical">noseVertical</label>
<input type="range" name="noseSize" id="noseSize" min="0" max="8" />
<label for="noseSize">noseSize</label>
<label for="noseVertical" style="--assetcol: 2"></label>
<input type="range" list="tickmarks" class="invert" name="noseVertical" id="noseVertical" min="0" max="18" />
<label for="noseSize" style="--assetcol: 6"></label>
<input type="range" list="tickmarks" name="noseSize" id="noseSize" min="0" max="8" />
</fieldset>
</div>
<div class="tab" id="mouthTypeTab">
<div class="subtabs">
<button class="subtabbtn active" id="mouthTypeSubButton">
mouthType
</button>
<button class="subtabbtn" id="mouthPositionSubButton">
mouthPosition
</button>
<button class="subtabbtn active" id="mouthTypeSubButton" style="--assetcol: 6"></button>
<button class="subtabbtn" id="mouthPositionSubButton" style="--assetcol: 13"></button>
<button class="subtabbtn" id="mouthColorSubButton" style="--assetcol: 12"></button>
</div>
<fieldset id="mouthType" class="subtab has-subpages active">
{{#each editorToHex.mouth}}
<div class="subpage">
<fieldset id="mouthType" class="subtab has-subpages active" style="--assetrow: 7">
{{#each editorJSON.mouth}}
<div class="subpage" style="--subpage: {{@key}}">
{{#each this}}
<input type="radio" name="mouthType" id="mouthType{{this}}" value="{{this}}" />
<label for="mouthType{{this}}">{{this}}</label>
<label for="mouthType{{this}}" style="--assetcol: {{@key}}"></label>
{{/each}}
<div class="pagination">
<button class="previous page-btn index-{{@index}} {{#if @first }}disabled{{/if}}">
@ -408,7 +332,7 @@
{{/each}}
</fieldset>
<fieldset id="mouthColor" class="color">
<fieldset id="mouthColor" class="subtab color">
<input type="radio" name="mouthColor" id="mouthColor0" value="0" />
<label for="mouthColor0" style="background: #FF5D0C !important;" ></label>
<input type="radio" name="mouthColor" id="mouthColor1" value="1" />
@ -422,44 +346,29 @@
</fieldset>
<fieldset id="mouthPosition" class="subtab has-sliders">
<input type="range" class="invert" name="mouthVertical" id="mouthVertical" min="0" max="18" />
<label for="mouthVertical">mouthVertical</label>
<input type="range" name="mouthSize" id="mouthSize" min="0" max="8" />
<label for="mouthSize">mouthSize</label>
<label for="mouthVertical" style="--assetcol: 2"></label>
<input type="range" list="tickmarks" class="invert" name="mouthVertical" id="mouthVertical" min="0" max="18" />
<label for="mouthSize" style="--assetcol: 6"></label>
<input type="range" list="tickmarks" name="mouthSize" id="mouthSize" min="0" max="8" />
<label for="mouthStretch" style="--assetcol: 7"></label>
<input type="range" list="tickmarks" name="mouthStretch" id="mouthStretch" min="0" max="6" />
</fieldset>
</div>
<div class="tab" id="glassesTypeTab">
<div class="subtabs">
<button class="subtabbtn active" id="glassesTypeSubButton">
glassesType
</button>
<button class="subtabbtn" id="glassesPositionSubButton">
glassesPosition
</button>
<button class="subtabbtn active" id="glassesTypeSubButton" style="--assetcol: 7"></button>
<button class="subtabbtn" id="glassesPositionSubButton" style="--assetcol: 13"></button>
<button class="subtabbtn" id="glassesColorSubButton" style="--assetcol: 12"></button>
</div>
<fieldset id="glassesType" class="subtab active">
<input type="radio" name="glassesType" id="glassesType0" value="0" />
<label for="glassesType0">0</label>
<input type="radio" name="glassesType" id="glassesType1" value="1" />
<label for="glassesType1">1</label>
<input type="radio" name="glassesType" id="glassesType2" value="2" />
<label for="glassesType2">2</label>
<input type="radio" name="glassesType" id="glassesType3" value="3" />
<label for="glassesType3">3</label>
<input type="radio" name="glassesType" id="glassesType4" value="4" />
<label for="glassesType4">4</label>
<input type="radio" name="glassesType" id="glassesType5" value="5" />
<label for="glassesType5">5</label>
<input type="radio" name="glassesType" id="glassesType6" value="6" />
<label for="glassesType6">6</label>
<input type="radio" name="glassesType" id="glassesType7" value="7" />
<label for="glassesType7">7</label>
<input type="radio" name="glassesType" id="glassesType8" value="8" />
<label for="glassesType8">8</label>
<fieldset id="glassesType" class="subtab active" style="--assetrow: 8">
{{#each editorJSON.arrayOf9}}
<input type="radio" name="glassesType" id="glassesType{{this}}" value="{{this}}" />
<label for="glassesType{{this}}" style="--assetcol: {{@key}}"></label>
{{/each}}
</fieldset>
<fieldset id="glassesColor" class="color">
<fieldset id="glassesColor" class="subtab color">
<input type="radio" name="glassesColor" id="glassesColor0" value="0" />
<label for="glassesColor0" style="background: #000000 !important;" ></label>
<input type="radio" name="glassesColor" id="glassesColor1" value="1" />
@ -475,41 +384,29 @@
</fieldset>
<fieldset id="glassesPosition" class="subtab has-sliders">
<input type="range" class="invert" name="glassesVertical" id="glassesVertical" min="0" max="20" />
<label for="glassesVertical">glassesVertical</label>
<input type="range" name="glassesSize" id="glassesSize" min="0" max="7" />
<label for="glassesSize">glassesSize</label>
<label for="glassesVertical" style="--assetcol: 2"></label>
<input type="range" list="tickmarks" class="invert" name="glassesVertical" id="glassesVertical" min="0" max="20" />
<label for="glassesSize" style="--assetcol: 6"></label>
<input type="range" list="tickmarks" name="glassesSize" id="glassesSize" min="0" max="7" />
</fieldset>
</div>
<div class="tab" id="facialHairTypeTab">
<div class="subtabs">
<button class="subtabbtn active" id="facialHairTypeSubButton">
facialHairType
</button>
<button class="subtabbtn" id="facialHairMustacheSubButton">
facialHairMustache
</button>
<button class="subtabbtn" id="facialHairPositionSubButton">
facialHairPosition
</button>
<button class="subtabbtn active" id="facialHairTypeSubButton" style="--assetcol: 8"></button>
<button class="subtabbtn" id="facialHairMustacheSubButton" style="--assetcol: 9"></button>
<button class="subtabbtn" id="facialHairPositionSubButton" style="--assetcol: 13"></button>
<button class="subtabbtn" id="facialHairColorSubButton" style="--assetcol: 12"></button>
</div>
<fieldset id="facialHairType" class="subtab active">
<input type="radio" name="facialHairType" id="facialHairType0" value="0" />
<label for="facialHairType0">0</label>
<input type="radio" name="facialHairType" id="facialHairType1" value="1" />
<label for="facialHairType1">1</label>
<input type="radio" name="facialHairType" id="facialHairType2" value="2" />
<label for="facialHairType2">2</label>
<input type="radio" name="facialHairType" id="facialHairType3" value="3" />
<label for="facialHairType3">3</label>
<input type="radio" name="facialHairType" id="facialHairType4" value="4" />
<label for="facialHairType4">4</label>
<input type="radio" name="facialHairType" id="facialHairType5" value="5" />
<label for="facialHairType5">5</label>
<fieldset id="facialHairType" class="subtab active" style="--assetrow: 9">
{{#each editorJSON.arrayOf6}}
<input type="radio" name="facialHairType" id="facialHairType{{this}}" value="{{this}}" />
<label for="facialHairType{{this}}" style="--assetcol: {{@key}}"></label>
{{/each}}
</fieldset>
<fieldset id="facialHairColor" class="color">
<fieldset id="facialHairColor" class="subtab color">
<input type="radio" name="facialHairColor" id="facialHairColor0" value="0" />
<label for="facialHairColor0" style="background: #0A0A09 !important;" ></label>
<input type="radio" name="facialHairColor" id="facialHairColor1" value="1" />
@ -528,78 +425,62 @@
<label for="facialHairColor7" style="background: #FEB454 !important;" ></label>
</fieldset>
<fieldset id="facialHairMustache" class="subtab">
<input type="radio" name="facialHairMustache" id="facialHairMustache0" value="0" />
<label for="facialHairMustache0">0</label>
<input type="radio" name="facialHairMustache" id="facialHairMustache1" value="1" />
<label for="facialHairMustache1">1</label>
<input type="radio" name="facialHairMustache" id="facialHairMustache2" value="2" />
<label for="facialHairMustache2">2</label>
<input type="radio" name="facialHairMustache" id="facialHairMustache3" value="3" />
<label for="facialHairMustache3">3</label>
<input type="radio" name="facialHairMustache" id="facialHairMustache4" value="4" />
<label for="facialHairMustache4">4</label>
<input type="radio" name="facialHairMustache" id="facialHairMustache5" value="5" />
<label for="facialHairMustache5">5</label>
<fieldset id="facialHairMustache" class="subtab active" style="--assetrow: 10">
{{#each editorJSON.arrayOf6}}
<input type="radio" name="facialHairMustache" id="facialHairMustache{{this}}" value="{{this}}" />
<label for="facialHairMustache{{this}}" style="--assetcol: {{@key}}"></label>
{{/each}}
</fieldset>
<fieldset id="facialHairPosition" class="subtab has-sliders">
<input type="range" class="invert" name="facialHairVertical" id="facialHairVertical" min="0" max="16" />
<label for="facialHairVertical">facialHairVertical</label>
<input type="range" name="facialHairSize" id="facialHairSize" min="0" max="8" />
<label for="facialHairSize">facialHairSize</label>
<label for="facialHairVertical" style="--assetcol: 2"></label>
<input type="range" list="tickmarks" class="invert" name="facialHairVertical" id="facialHairVertical" min="0" max="16" />
<label for="facialHairSize" style="--assetcol: 6"></label>
<input type="range" list="tickmarks" name="facialHairSize" id="facialHairSize" min="0" max="8" />
</fieldset>
</div>
<div class="tab" id="moleEnableTab">
<div class="subtabs">
<button class="subtabbtn active" id="moleEnableSubButton">
moleEnable
</button>
<button class="subtabbtn" id="molePositionSubButton">
moleEnablePosition
</button>
<button class="subtabbtn active" id="moleEnableSubButton" style="--assetcol: 10"></button>
<button class="subtabbtn" id="molePositionSubButton" style="--assetcol: 13"></button>
</div>
<fieldset id="moleEnable" class="subtab active">
<fieldset id="moleEnable" class="subtab active" style="--assetrow: 11">
<input type="radio" name="moleEnable" id="moleEnable0" value="0" />
<label for="moleEnable0">0</label>
<label for="moleEnable0" style="--assetcol: 0"></label>
<input type="radio" name="moleEnable" id="moleEnable1" value="1" />
<label for="moleEnable1">1</label>
<label for="moleEnable1" style="--assetcol: 1"></label>
</fieldset>
<fieldset id="molePosition" class="subtab has-sliders">
<input type="range" class="invert" name="moleVertical" id="moleVertical" min="0" max="30" />
<label for="moleVertical">moleVertical</label>
<input type="range" name="moleHorizontal" id="moleHorizontal" min="0" max="16" />
<label for="moleHorizontal">moleHorizontal</label>
<input type="range" name="moleSize" id="moleSize" min="0" max="8" />
<label for="moleSize">moleSize</label>
</fieldset>
</div>
<div class="tab" id="sizeTab">
<fieldset id="size" class="active has-sliders">
<input type="range" name="height" id="height" min="0" max="127" />
<label for="height">height</label>
<input type="range" name="build" id="build" min="0" max="127" />
<label for="build">build</label>
<label for="moleVertical" style="--assetcol: 2"></label>
<input type="range" list="tickmarks" class="invert" name="moleVertical" id="moleVertical" min="0" max="30" />
<label for="moleHorizontal" style="--assetcol: 3"></label>
<input type="range" list="tickmarks" name="moleHorizontal" id="moleHorizontal" min="0" max="16" />
<label for="moleSize" style="--assetcol: 6"></label>
<input type="range" list="tickmarks" name="moleSize" id="moleSize" min="0" max="8" />
</fieldset>
</div>
<div class="tab" id="miiscTab"><!--Get it it's funny 'cause 'mii' and 'misc'-->
<div class="subtabs">
<button class="subtabbtn active" id="genderSubButton">
dress
</button>
<button class="subtabbtn" id="favoriteColorSubButton">
favcolor
</button>
<button class="subtabbtn active" id="sizeSubButton" style="--assetcol: 14"></button>
<button class="subtabbtn" id="genderSubButton" style="--assetcol: 11"></button>
<button class="subtabbtn" id="favoriteColorSubButton" style="--assetcol: 12"></button>
</div>
<fieldset id="gender" class="subtab active">
<fieldset id="size" class="subtab active has-sliders">
<label for="height" style="--assetcol: 0"></label>
<input type="range" list="tickmarks" name="height" id="height" min="0" max="127" />
<label for="build" style="--assetcol: 1"></label>
<input type="range" list="tickmarks" name="build" id="build" min="0" max="127" />
</fieldset>
<fieldset id="gender" class="subtab" style="--assetrow: 12">
<input type="radio" name="gender" id="gender0" value="0" />
<label for="gender0">0</label>
<label for="gender0" style="--assetcol: 0"></label>
<input type="radio" name="gender" id="gender1" value="1" />
<label for="gender1">1</label>
<label for="gender1" style="--assetcol: 1"></label>
</fieldset>
<fieldset id="favoriteColor" class="subtab">
@ -629,6 +510,27 @@
<label for="favoriteColor11" style="background: #1D1A15 !important;" ></label>
</fieldset>
</div>
<div class="tab" id="saveTab">
<p class="save-prompt">Save Mii? This will permanently overwrite your current Mii.</p>
<div class="mii-comparison-animation-wrapper">
<div class="mii-comparison unconfirmed">
<img class="old-mii" src=""></img>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="#888888" d="M4 15V9h8V4.16L19.84 12L12 19.84V15H4Z"></path></svg>
<div class="new-mii-wrapper">
<img class="new-mii" src=""></img>
</div>
</div>
<div class="mii-comparison confirmed">
<img class="old-mii" src=""></img>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--mdi" width="32" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="#888888" d="M4 15V9h8V4.16L19.84 12L12 19.84V15H4Z"></path></svg>
<div class="new-mii-wrapper">
<img class="new-mii" src=""></img>
</div>
</div>
</div>
<button class="button primary" id="saveButton">Save!</button>
</div>
</form>
</div>
</div>