Compare commits

...

2 commits

11 changed files with 271 additions and 134 deletions

View file

@ -15,6 +15,7 @@
@include setting.css; @include setting.css;
@include sidebar.css; @include sidebar.css;
@include umi.css; @include umi.css;
@include youare.css;
@include colpick.css; @include colpick.css;

43
src/mami.css/youare.css Normal file
View file

@ -0,0 +1,43 @@
@keyframes youareanim {
0% {
color: #000;
background-color: #fff;
}
100% {
color: #fff;
background-color: #000;
}
}
.youare {
font-size: 16px;
font-family: 'Times New Roman', serif;
animation: .95s steps(2, jump-none) youareanim infinite;
}
.youare-content {
width: 100%;
height: 100%;
border: 1vh solid;
display: flex;
flex-direction: column;
justify-content: center;
}
.youare-text {
display: flex;
align-items: baseline;
justify-content: center;
line-height: 15vw;
}
.youare-big {
font-size: 10vw;
}
.youare-smiles {
display: flex;
font-size: 20vw;
line-height: 15vw;
justify-content: center;
}

View file

@ -1,3 +1,5 @@
#include easings.js
const MamiAnimate = function(info) { const MamiAnimate = function(info) {
if(typeof info !== 'object') if(typeof info !== 'object')
throw 'info must be an object'; throw 'info must be an object';
@ -40,12 +42,10 @@ const MamiAnimate = function(info) {
const easingType = typeof easing; const easingType = typeof easing;
if(easingType !== 'function') { if(easingType !== 'function') {
if(easingType === 'string' if(easingType === 'string' && easing in MamiEasings)
&& easing.substring(0, 4) === 'ease' easing = MamiEasings[easing];
&& easing in MamiAnimate)
easing = MamiAnimate[easing];
else else
easing = MamiAnimate.easeLinear; easing = MamiEasings.linear;
} }
let tStart, tLast, let tStart, tLast,
@ -136,123 +136,3 @@ const MamiAnimate = function(info) {
}, },
}; };
}; };
// Yoinked from https://easings.net/
MamiAnimate.C1 = 1.70158;
MamiAnimate.C2 = MamiAnimate.C1 + 1.525;
MamiAnimate.C3 = MamiAnimate.C1 + 1;
MamiAnimate.C4 = (2 * Math.PI) / 3;
MamiAnimate.C5 = (2 * Math.PI) / 4.5;
MamiAnimate.D1 = 2.75;
MamiAnimate.N1 = 7.5625;
MamiAnimate.easeLinear = function(x) { return x; };
MamiAnimate.easeInSine = function(x) { return 1 - Math.cos((x * Math.PI) / 2); };
MamiAnimate.easeOutSine = function(x) { return Math.sin((x * Math.PI) / 2); };
MamiAnimate.easeInOutSine = function(x) { return -(Math.cos(Math.PI * x) - 1) / 2; };
MamiAnimate.easeInCubic = function(x) { return x * x * x; };
MamiAnimate.easeOutCubic = function(x) { return 1 - Math.pow(1 - x, 3); };
MamiAnimate.easeInOutCubic = function(x) {
return x < .5
? (4 * x * x * x)
: (1 - Math.pow(-2 * x + 2, 3) / 2);
};
MamiAnimate.easeInQuint = function(x) { return x * x * x * x * x; };
MamiAnimate.easeOutQuint = function(x) { return 1 - Math.pow(1 - x, 5); };
MamiAnimate.easeInOutQuint = function(x) {
return x < .5
? (16 * x * x * x * x * x)
: (1 - Math.pow(-2 * x + 2, 5) / 2);
};
MamiAnimate.easeInCirc = function(x) { return 1 - Math.sqrt(1 - Math.pow(x, 2)); };
MamiAnimate.easeOutCirc = function(x) { return Math.sqrt(1 - Math.pow(x - 1, 2)); };
MamiAnimate.easeInOutCirc = function(x) {
return x < .5
? ((1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2)
: ((Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2);
};
MamiAnimate.easeInElastic = function(x) {
if(x === 0.0)
return 0;
if(x === 1.0)
return 1;
return -Math.pow(2, 10 * x - 10) * Math.sin((x * 10 - 10.75) * MamiAnimate.C4);
};
MamiAnimate.easeOutElastic = function(x) {
if(x === 0.0)
return 0;
if(x === 1.0)
return 1;
return Math.pow(2, -10 * x) * Math.sin((x * 10 - .75) * MamiAnimate.C4) + 1;
};
MamiAnimate.easeInOutElastic = function(x) {
if(x === 0.0)
return 0;
if(x === 1.0)
return 1;
return x < .5
? (-(Math.pow(2, 20 * x - 10) * Math.sin((20 * x - 11.125) * MamiAnimate.C5)) / 2)
: ((Math.pow(2, -20 * x + 10) * Math.sin((20 * x - 11.125) * MamiAnimate.C5)) / 2 + 1);
};
MamiAnimate.easeInQuad = function(x) { return x * x; };
MamiAnimate.easeOutQuad = function(x) { return 1 - (1 - x) * (1 - x); };
MamiAnimate.easeInOutQuad = function(x) {
return x < .5
? (2 * x * x)
: (1 - Math.pow(-2 * x + 2, 2) / 2);
};
MamiAnimate.easeInQuart = function(x) { return x * x * x * x; };
MamiAnimate.easeOutQuart = function(x) { return 1 - Math.pow(1 - x, 4); };
MamiAnimate.easeInOutQuart = function(x) {
return x < .5
? (8 * x * x * x * x)
: (1 - Math.pow(-2 * x + 2, 4) / 2);
};
MamiAnimate.easeInExpo = function(x) {
if(x === 0.0)
return 0;
return Math.pow(2, 10 * x - 10);
};
MamiAnimate.easeOutExpo = function(x) {
if(x === 1.0)
return 1;
return 1 - Math.pow(2, -10 * x);
};
MamiAnimate.easeInOutExpo = function(x) {
if(x === 0.0)
return 0;
if(x === 1.0)
return 1;
return x < .5
? (Math.pow(2, 20 * x - 10) / 2)
: ((2 - Math.pow(2, -20 * x + 10)) / 2);
};
MamiAnimate.easeInBack = function(x) { return MamiAnimate.C3 * x * x * x - MamiAnimate.C1 * x * x; };
MamiAnimate.easeOutBack = function(x) { return 1 + MamiAnimate.C3 * Math.pow(x - 1, 3) + MamiAnimate.C1 * Math.pow(x - 1, 2); };
MamiAnimate.easeInOutBack = function(x) {
return x < .5
? ((Math.pow(2 * x, 2) * ((MamiAnimate.C2 + 1) * 2 * x - MamiAnimate.C2)) / 2)
: ((Math.pow(2 * x - 2, 2) * ((MamiAnimate.C2 + 1) * (x * 2 - 2) + MamiAnimate.C2) + 2) / 2);
};
MamiAnimate.easeInBounce = function(x) { return 1 - MamiAnimate.easeOutBounce(1 - x); };
MamiAnimate.easeOutBounce = function(x) {
if(x < 1 / MamiAnimate.D1)
return MamiAnimate.N1 * x * x;
if(x < 2 / MamiAnimate.D1) {
x -= 1.5;
return MamiAnimate.N1 * (x / MamiAnimate.D1) * x + .75;
}
if(x < 2.5 / MamiAnimate.D1) {
x -= 2.25;
return MamiAnimate.N1 * (x / MamiAnimate.D1) * x + .9375;
}
x -= 2.625;
return MamiAnimate.N1 * (x / MamiAnimate.D1) * x + .984375;
};
MamiAnimate.easeInOutBounce = function(x) {
return x < .5
? ((1 - MamiAnimate.easeOutBounce(1 - 2 * x)) / 2)
: ((1 + MamiAnimate.easeOutBounce(2 * x - 1)) / 2);
};

View file

@ -48,6 +48,8 @@ const MamiViewsControl = function(options) {
if(!views.includes(elementInfo)) if(!views.includes(elementInfo))
views.push(elementInfo); views.push(elementInfo);
if(typeof elementInfo.onViewPush === 'function')
await elementInfo.onViewPush();
const element = extractElement(elementInfo); const element = extractElement(elementInfo);
element.classList.toggle('hidden', false); element.classList.toggle('hidden', false);
@ -57,6 +59,9 @@ const MamiViewsControl = function(options) {
if(!targetBody.contains(element)) if(!targetBody.contains(element))
targetBody.appendChild(element); targetBody.appendChild(element);
if(typeof elementInfo.onViewForeground === 'function')
await elementInfo.onViewForeground();
updateZIncides(); updateZIncides();
if(views.length > 1) { if(views.length > 1) {
@ -65,6 +70,9 @@ const MamiViewsControl = function(options) {
prevElem.classList.toggle('views-background', true); prevElem.classList.toggle('views-background', true);
if(typeof prevElemInfo.onViewBackground === 'function')
await prevElemInfo.onViewBackground();
await doTransition(transition, { await doTransition(transition, {
toInfo: elementInfo, toInfo: elementInfo,
toElem: element, toElem: element,
@ -74,7 +82,6 @@ const MamiViewsControl = function(options) {
prevElem.classList.toggle('hidden', true); prevElem.classList.toggle('hidden', true);
} }
}; };
const pop = async transition => { const pop = async transition => {
@ -93,6 +100,9 @@ const MamiViewsControl = function(options) {
nextElem.classList.toggle('hidden', false); nextElem.classList.toggle('hidden', false);
nextElem.classList.toggle('views-background', false); nextElem.classList.toggle('views-background', false);
if(typeof nextElemInfo.onViewForeground === 'function')
await nextElemInfo.onViewForeground();
await doTransition(transition, { await doTransition(transition, {
toInfo: nextElemInfo, toInfo: nextElemInfo,
toElem: nextElem, toElem: nextElem,
@ -101,11 +111,17 @@ const MamiViewsControl = function(options) {
}); });
} }
if(typeof elementInfo.onViewBackground === 'function')
await elementInfo.onViewBackground();
element.classList.toggle('hidden', true); element.classList.toggle('hidden', true);
if(targetBody.contains(element)) if(targetBody.contains(element))
targetBody.removeChild(element); targetBody.removeChild(element);
if(typeof elementInfo.onViewPop === 'function')
await elementInfo.onViewPop();
updateZIncides(); updateZIncides();
return elementInfo; return elementInfo;
@ -163,6 +179,9 @@ const MamiViewsControl = function(options) {
if(targetBody.contains(element)) if(targetBody.contains(element))
targetBody.removeChild(element); targetBody.removeChild(element);
if(typeof elementInfo.onViewPop === 'function')
await elementInfo.onViewPop();
updateZIncides(); updateZIncides();
return elementInfo; return elementInfo;

121
src/mami.js/easings.js Normal file
View file

@ -0,0 +1,121 @@
// Yoinked from https://easings.net/
const MamiEasings = (() => {
const elasticConst = 2 * Math.PI / .3;
const elasticConst2 = .3 / 4;
const backConst = 1.70158;
const backConst2 = backConst * 1.525;
const bounceConst = 1 / 2.75;
const expoOffset = Math.pow(2, -10);
const elasticOffsetFull = Math.pow(2, -11);
const elasticOffsetHalf = Math.pow(2, -10) * Math.sin((.5 - elasticConst2) * elasticConst);
const elasticOffsetQuarter = Math.pow(2, -10) * Math.sin((.25 - elasticConst2) * elasticConst);
const inOutElasticOffset = Math.pow(2, -10) * Math.sin((1 - elasticConst2 * 1.5) * elasticConst / 1.5);
let outBounce;
return {
linear: t => t,
inQuad: t => t * t,
outQuad: t => t * (2 - t),
inOutQuad: t => {
if(t < .5)
return t * t * 2;
return --t * t * -2 + 1;
},
inCubic: t => t * t * t,
outCubic: t => --t * t * t + 1,
inOutCubic: t => {
if(t < .5)
return t * t * t * 4;
return --t * t * t * 4 + 1;
},
inQuart: t => t * t * t * t,
outQuart: t => 1 - --t * t * t * t,
inOutQuart: t => {
if(t < .5)
return t * t * t * t * 8;
return --t * t * t * t * -8 + 1;
},
inQuint: t => t * t * t * t * t,
outQuint: t => --t * t * t * t * t + 1,
inOutQuint: t => {
if(t < .5)
return t * t * t * t * t * 16;
return --t * t * t * t * t * 16 + 1;
},
inSine: t => 1 - Math.cos(t * Math.PI * .5),
outSine: t => Math.sin(t * Math.PI * .5),
inOutSine: t => .5 - .5 * Math.cos(Math.PI * t),
inCirc: t => 1 - Math.sqrt(1 - t * t),
outCirc: t => Math.sqrt(1 - --t * t),
inOutCirc: t => {
if((t *= 2) < 1)
return .5 - .5 * Math.sqrt(1 - t * t);
return .5 * Math.sqrt(1 - (t -= 2) * t) + .5;
},
inElastic: t => -Math.pow(2, -10 + 10 * t) * Math.sin((1 - elasticConst2 - t) * elasticConst) + elasticOffsetFull * (1 - t),
outElastic: t => Math.pow(2, -10 * t) * Math.sin((t - elasticConst2) * elasticConst) + 1 - elasticOffsetFull * t,
outElasticHalf: t => Math.pow(2, -10 * t) * Math.sin((.5 * t - elasticConst2) * elasticConst) + 1 - elasticOffsetHalf * t,
outElasticQuarter: t => Math.pow(2, -10 * t) * Math.sin((.25 * t - elasticConst2) * elasticConst) + 1 - elasticOffsetQuarter * t,
inOutElastic: t => {
if((t *= 2) < 1)
return -.5 * (Math.pow(2, -10 + 10 * t) * Math.sin((1 - elasticConst2 * 1.5 - t) * elasticConst / 1.5) - inOutElasticOffset * (1 - t));
return .5 * (Math.pow(2, -10 * --t) * Math.sin((t - elasticConst2 * 1.5) * elasticConst / 1.5) - inOutElasticOffset * t) + 1;
},
inExpo: t => Math.pow(2, 10 * (t - 1)) + expoOffset * (t - 1),
outExpo: t => -Math.pow(2, -10 * t) + 1 + expoOffset * t,
inOutExpo: t => {
if(t < .5)
return .5 * (Math.pow(2, 20 * t - 10)) + expoOffset * (2 * t - 1);
return 1 - .5 * (Math.pow(2, -20 * t + 10)) + expoOffset * (-2 * t + 1);
},
inBack: t => t * t * ((backConst + 1) * t - backConst),
outBack: t => --t * t * ((backConst + 1) * t + backConst) + 1,
inOutBack: t => {
if((t *= 2) < 1)
return .5 * t * t * ((backConst2 + 1) * t - backConst2);
return .5 * ((t -= 2) * t * ((backConst2 + 1) * t + backConst2) + 2);
},
inBounce: t => {
t = 1 - t;
if(t < bounceConst)
return 1 - 7.5625 * t * t;
if(t < 2 * bounceConst)
return 1 - (7.5625 * (t -= 1.5 * bounceConst) * t + .75);
if(t < 2.5 * bounceConst)
return 1 - (7.5625 * (t -= 2.25 * bounceConst) * t + .9375);
return 1 - (7.5625 * (t -= 2.625 * bounceConst) * t + .984375);
},
outBounce: (() => {
return outBounce = t => {
if(t < bounceConst)
return 7.5625 * t * t;
if(t < 2 * bounceConst)
return 7.5625 * (t -= 1.5 * bounceConst) * t + .75;
if(t < 2.5 * bounceConst)
return 7.5625 * (t -= 2.25 * bounceConst) * t + .9375;
return 7.5625 * (t -= 2.625 * bounceConst) * t + .984375;
};
})(),
inOutBounce: t => {
if(t < .5)
return .5 - .5 * outBounce(1 - t * 2);
return outBounce((t - .5) * 2) * .5 + .5;
},
outPow10: t => --t * Math.pow(t, 10) + 1,
};
})();

View file

@ -129,8 +129,8 @@ const Umi = { UI: {} };
settings.define('soundEnableError', 'boolean', true); settings.define('soundEnableError', 'boolean', true);
settings.define('soundEnableServer', 'boolean', true); settings.define('soundEnableServer', 'boolean', true);
settings.define('soundEnableIncoming', 'boolean', true); settings.define('soundEnableIncoming', 'boolean', true);
settings.define('onlySoundOnMention', 'boolean', true); settings.define('onlySoundOnMention', 'boolean', false);
settings.define('soundEnableOutgoing', 'boolean', false); settings.define('soundEnableOutgoing', 'boolean', true);
settings.define('soundEnablePrivate', 'boolean', true); settings.define('soundEnablePrivate', 'boolean', true);
settings.define('soundEnableForceLeave', 'boolean', true); settings.define('soundEnableForceLeave', 'boolean', true);
settings.define('minecraft', ['no', 'yes', 'old'], 'no'); settings.define('minecraft', ['no', 'yes', 'old'], 'no');
@ -371,7 +371,7 @@ const Umi = { UI: {} };
sidebarAnimation = MamiAnimate({ sidebarAnimation = MamiAnimate({
duration: 500, duration: 500,
easing: 'easeOutExpo', easing: 'outExpo',
update: update, update: update,
}); });
} }

View file

@ -452,7 +452,7 @@ Umi.Protocol.SockChat.Protocol = function(views, settings) {
views.pop(ctx => MamiAnimate({ views.pop(ctx => MamiAnimate({
async: true, async: true,
duration: 120, duration: 120,
easing: 'easeInOutSine', easing: 'inOutSine',
start: () => { start: () => {
ctx.toElem.style.zIndex = '100'; ctx.toElem.style.zIndex = '100';
ctx.fromElem.style.pointerEvents = 'none'; ctx.fromElem.style.pointerEvents = 'none';
@ -876,7 +876,7 @@ Umi.Protocol.SockChat.Protocol = function(views, settings) {
MamiAnimate({ MamiAnimate({
duration: 550, duration: 550,
easing: 'easeOutExpo', easing: 'outExpo',
start: function() { start: function() {
playBannedBgm(true); playBannedBgm(true);
playBannedSfx(); playBannedSfx();

View file

@ -2,6 +2,7 @@
#include common.js #include common.js
#include emotes.js #include emotes.js
#include utility.js #include utility.js
#include youare.jsx
#include settings/backup.js #include settings/backup.js
#include ui/emotes.js #include ui/emotes.js
#include ui/menus.js #include ui/menus.js
@ -386,6 +387,15 @@ Umi.UI.Settings = (function() {
title: 'Skip domain pop up thing', title: 'Skip domain pop up thing',
type: 'checkbox', type: 'checkbox',
}, },
{
title: 'You are an idiot!',
type: 'button',
invoke: async button => {
button.disabled = true;
await (new MamiYouAreAnIdiot()).pushOn(mami.getViews());
button.disabled = false;
},
},
], ],
} }
]; ];
@ -506,7 +516,7 @@ Umi.UI.Settings = (function() {
// todo: actually make cancellable // todo: actually make cancellable
MamiAnimate({ MamiAnimate({
duration: 500, duration: 500,
easing: 'easeOutExpo', easing: 'outExpo',
start: start, start: start,
update: update, update: update,
end: end, end: end,

View file

@ -56,7 +56,7 @@ Umi.UI.Users = (function() {
// todo: actually make cancellable // todo: actually make cancellable
MamiAnimate({ MamiAnimate({
duration: 500, duration: 500,
easing: 'easeOutExpo', easing: 'outExpo',
start: start, start: start,
update: update, update: update,
end: end, end: end,

View file

@ -31,7 +31,7 @@ Umi.UI.View = (function() {
available = Object.keys(accentColours), available = Object.keys(accentColours),
name = settings.get('style'), name = settings.get('style'),
compact = 'chat--compact', compact = 'chat--compact',
classes = ['umi']; classes = ['views-item', 'umi'];
if(available.indexOf(name) < 0) if(available.indexOf(name) < 0)
return; return;

63
src/mami.js/youare.jsx Normal file
View file

@ -0,0 +1,63 @@
#include animate.js
const MamiYouAreAnIdiot = function() {
const html = <div class="youare">
<div class="youare-content">
<div class="youare-text">
<div class="youare-big">you are an idiot</div>
<div class="youare-small">!</div>
</div>
<div class="youare-smiles">
<div class="youare-smile"></div>
<div class="youare-smile"></div>
<div class="youare-smile"></div>
</div>
</div>
</div>;
let soundSrc;
const pub = {
getElement: () => html,
onViewPush: () => {
return new Promise((resolve, reject) => {
const soundMgr = mami.getSound();
const soundSrcs = mami.getSoundLibrary().getSound('misc:youare').getSources();
soundMgr.load('youarebgm', soundSrcs, (success, buffer) => {
if(success) {
soundSrc = buffer.createSource();
soundSrc.setMuted(true);
soundSrc.setLoopStart(0.21);
soundSrc.setLoopEnd(5);
soundSrc.setLoop();
soundSrc.play();
resolve();
} else reject();
});
});
},
onViewForeground: async () => {
if(soundSrc !== undefined)
soundSrc.setMuted(false);
},
onViewBackground: async () => {
if(soundSrc !== undefined)
soundSrc.setMuted(true);
},
onViewPop: async () => {
if(soundSrc !== undefined)
soundSrc.stop();
soundSrc = undefined;
},
pushOn: async views => views.push(pub, ctx => MamiAnimate({
async: true,
duration: 1500,
easing: 'outBounce',
start: () => ctx.toElem.style.top = '-100%',
update: t => ctx.toElem.style.top = `${-100 + (t * 100)}%`,
end: () => ctx.toElem.style.top = null,
})),
};
return pub;
};