From 4ece0c9f3bebd0b9e2c997b72db07a9c30770ee3 Mon Sep 17 00:00:00 2001 From: flashwave Date: Tue, 23 Jan 2024 01:24:24 +0000 Subject: [PATCH] Added event handlers for views and rewrote easing functions. --- src/mami.css/main.css | 1 + src/mami.css/youare.css | 43 +++++++++++ src/mami.js/animate.js | 130 ++-------------------------------- src/mami.js/controls/views.js | 21 +++++- src/mami.js/easings.js | 121 +++++++++++++++++++++++++++++++ src/mami.js/sockchat_old.js | 4 +- src/mami.js/ui/settings.jsx | 12 +++- src/mami.js/ui/users.js | 2 +- src/mami.js/ui/view.js | 2 +- src/mami.js/youare.jsx | 63 ++++++++++++++++ 10 files changed, 268 insertions(+), 131 deletions(-) create mode 100644 src/mami.css/youare.css create mode 100644 src/mami.js/easings.js create mode 100644 src/mami.js/youare.jsx diff --git a/src/mami.css/main.css b/src/mami.css/main.css index 95c31c1..c7b84d0 100644 --- a/src/mami.css/main.css +++ b/src/mami.css/main.css @@ -15,6 +15,7 @@ @include setting.css; @include sidebar.css; @include umi.css; +@include youare.css; @include colpick.css; diff --git a/src/mami.css/youare.css b/src/mami.css/youare.css new file mode 100644 index 0000000..5cf482a --- /dev/null +++ b/src/mami.css/youare.css @@ -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; +} diff --git a/src/mami.js/animate.js b/src/mami.js/animate.js index 612ed2d..dd913e4 100644 --- a/src/mami.js/animate.js +++ b/src/mami.js/animate.js @@ -1,3 +1,5 @@ +#include easings.js + const MamiAnimate = function(info) { if(typeof info !== 'object') throw 'info must be an object'; @@ -40,12 +42,10 @@ const MamiAnimate = function(info) { const easingType = typeof easing; if(easingType !== 'function') { - if(easingType === 'string' - && easing.substring(0, 4) === 'ease' - && easing in MamiAnimate) - easing = MamiAnimate[easing]; + if(easingType === 'string' && easing in MamiEasings) + easing = MamiEasings[easing]; else - easing = MamiAnimate.easeLinear; + easing = MamiEasings.linear; } 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); -}; diff --git a/src/mami.js/controls/views.js b/src/mami.js/controls/views.js index ab4fcb3..bf5ae52 100644 --- a/src/mami.js/controls/views.js +++ b/src/mami.js/controls/views.js @@ -48,6 +48,8 @@ const MamiViewsControl = function(options) { if(!views.includes(elementInfo)) views.push(elementInfo); + if(typeof elementInfo.onViewPush === 'function') + await elementInfo.onViewPush(); const element = extractElement(elementInfo); element.classList.toggle('hidden', false); @@ -57,6 +59,9 @@ const MamiViewsControl = function(options) { if(!targetBody.contains(element)) targetBody.appendChild(element); + if(typeof elementInfo.onViewForeground === 'function') + await elementInfo.onViewForeground(); + updateZIncides(); if(views.length > 1) { @@ -65,6 +70,9 @@ const MamiViewsControl = function(options) { prevElem.classList.toggle('views-background', true); + if(typeof prevElemInfo.onViewBackground === 'function') + await prevElemInfo.onViewBackground(); + await doTransition(transition, { toInfo: elementInfo, toElem: element, @@ -74,7 +82,6 @@ const MamiViewsControl = function(options) { prevElem.classList.toggle('hidden', true); } - }; const pop = async transition => { @@ -93,6 +100,9 @@ const MamiViewsControl = function(options) { nextElem.classList.toggle('hidden', false); nextElem.classList.toggle('views-background', false); + if(typeof nextElemInfo.onViewForeground === 'function') + await nextElemInfo.onViewForeground(); + await doTransition(transition, { toInfo: nextElemInfo, toElem: nextElem, @@ -101,11 +111,17 @@ const MamiViewsControl = function(options) { }); } + if(typeof elementInfo.onViewBackground === 'function') + await elementInfo.onViewBackground(); + element.classList.toggle('hidden', true); if(targetBody.contains(element)) targetBody.removeChild(element); + if(typeof elementInfo.onViewPop === 'function') + await elementInfo.onViewPop(); + updateZIncides(); return elementInfo; @@ -163,6 +179,9 @@ const MamiViewsControl = function(options) { if(targetBody.contains(element)) targetBody.removeChild(element); + if(typeof elementInfo.onViewPop === 'function') + await elementInfo.onViewPop(); + updateZIncides(); return elementInfo; diff --git a/src/mami.js/easings.js b/src/mami.js/easings.js new file mode 100644 index 0000000..f96eb04 --- /dev/null +++ b/src/mami.js/easings.js @@ -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, + }; +})(); diff --git a/src/mami.js/sockchat_old.js b/src/mami.js/sockchat_old.js index 97ff380..4b5a685 100644 --- a/src/mami.js/sockchat_old.js +++ b/src/mami.js/sockchat_old.js @@ -452,7 +452,7 @@ Umi.Protocol.SockChat.Protocol = function(views, settings) { views.pop(ctx => MamiAnimate({ async: true, duration: 120, - easing: 'easeInOutSine', + easing: 'inOutSine', start: () => { ctx.toElem.style.zIndex = '100'; ctx.fromElem.style.pointerEvents = 'none'; @@ -876,7 +876,7 @@ Umi.Protocol.SockChat.Protocol = function(views, settings) { MamiAnimate({ duration: 550, - easing: 'easeOutExpo', + easing: 'outExpo', start: function() { playBannedBgm(true); playBannedSfx(); diff --git a/src/mami.js/ui/settings.jsx b/src/mami.js/ui/settings.jsx index 3f23649..65de000 100644 --- a/src/mami.js/ui/settings.jsx +++ b/src/mami.js/ui/settings.jsx @@ -2,6 +2,7 @@ #include common.js #include emotes.js #include utility.js +#include youare.jsx #include settings/backup.js #include ui/emotes.js #include ui/menus.js @@ -386,6 +387,15 @@ Umi.UI.Settings = (function() { title: 'Skip domain pop up thing', 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 MamiAnimate({ duration: 500, - easing: 'easeOutExpo', + easing: 'outExpo', start: start, update: update, end: end, diff --git a/src/mami.js/ui/users.js b/src/mami.js/ui/users.js index cb0bc4a..9f858c4 100644 --- a/src/mami.js/ui/users.js +++ b/src/mami.js/ui/users.js @@ -56,7 +56,7 @@ Umi.UI.Users = (function() { // todo: actually make cancellable MamiAnimate({ duration: 500, - easing: 'easeOutExpo', + easing: 'outExpo', start: start, update: update, end: end, diff --git a/src/mami.js/ui/view.js b/src/mami.js/ui/view.js index 175d5cd..e5b1758 100644 --- a/src/mami.js/ui/view.js +++ b/src/mami.js/ui/view.js @@ -31,7 +31,7 @@ Umi.UI.View = (function() { available = Object.keys(accentColours), name = settings.get('style'), compact = 'chat--compact', - classes = ['umi']; + classes = ['views-item', 'umi']; if(available.indexOf(name) < 0) return; diff --git a/src/mami.js/youare.jsx b/src/mami.js/youare.jsx new file mode 100644 index 0000000..112b59d --- /dev/null +++ b/src/mami.js/youare.jsx @@ -0,0 +1,63 @@ +#include animate.js + +const MamiYouAreAnIdiot = function() { + const html =
+
+
+
you are an idiot
+
!
+
+
+
+
+
+
+
+
; + + 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; +};