Reverse the animation when popping the kick/ban notice.

This commit is contained in:
flash 2024-02-25 02:39:14 +00:00
parent ddd802d3ff
commit 5ea5b1e030
3 changed files with 55 additions and 13 deletions

View file

@ -66,10 +66,27 @@ const MamiAudioContext = function() {
return await ctx.decodeAudioData(result.body());
},
createSource: buffer => {
createSource: (buffer, reverse) => {
if(ctx === undefined || buffer === undefined)
return new MamiAudioSourceDummy;
if(reverse) {
const reverse = new AudioBuffer({
length: buffer.length,
numberOfChannels: buffer.numberOfChannels,
sampleRate: buffer.sampleRate,
});
const data = new Float32Array(buffer.length);
for(let i = 0; i < reverse.numberOfChannels; ++i) {
buffer.copyFromChannel(data, i, 0);
data.reverse();
reverse.copyToChannel(data, i, 0);
}
buffer = reverse;
}
const gain = ctx.createGain();
gain.connect(mainGain);

View file

@ -27,16 +27,16 @@ const MamiForceDisconnectNotice = function(banInfo) {
marqueeElem.append(<div class="baka-marquee-text">{marqueeString}</div>);
const rng = new MamiRNG;
let sfxBuf, sfxSrc, bgmSrc;
const rotate = rng.next(-20, 20);
let sfxBuf, bgmSrc;
const pub = {
getElement: () => html,
onViewPush: async () => {
try {
sfxBuf = await mami.sound.library.loadBuffer('touhou:pichuun');
sfxSrc = mami.sound.audio.createSource(sfxBuf);
} catch(ex) {
sfxBuf = sfxSrc = undefined;
sfxBuf = undefined;
}
try {
@ -48,16 +48,16 @@ const MamiForceDisconnectNotice = function(banInfo) {
},
onViewPop: async () => {
bgmSrc?.stop();
bgmSrc = sfxBuf = sfxSrc = undefined;
bgmSrc = sfxBuf = undefined;
},
pushOn: async views => {
const rotate = rng.next(-20, 20);
await views.push(pub, ctx => MamiAnimate({
async: true,
duration: (sfxBuf?.duration ?? 1.4) * 1000,
start: () => {
sfxSrc?.play();
if(sfxBuf !== undefined)
mami.sound.audio.createSource(sfxBuf).play();
ctx.toElem.style.top = '-100%';
},
update: t => {
@ -76,6 +76,33 @@ const MamiForceDisconnectNotice = function(banInfo) {
},
}));
},
popOff: async views => {
await views.pop(ctx => MamiAnimate({
async: true,
duration: (sfxBuf?.duration ?? 1.4) * 1000,
start: () => {
bgmSrc?.stop();
if(sfxBuf !== undefined)
mami.sound.audio.createSource(sfxBuf, true).play();
ctx.toElem.style.transform = `scale(1) rotate(${rotate}deg)`;
ctx.toElem.style.filter = 'grayscale(100%)';
},
update: t => {
const tOutBounce = MamiEasings.inBounce(t);
ctx.fromElem.style.top = `${tOutBounce * -100}%`;
const tOutExpo = MamiEasings.inExpo(t);
ctx.toElem.style.transform = `scale(${1 * tOutExpo}) rotate(${rotate - (rotate * tOutExpo)}deg)`;
ctx.toElem.style.filter = `grayscale(${100 - (tOutExpo * 100)}%)`;
},
end: () => {
ctx.fromElem.style.top = null;
ctx.toElem.style.transform = null;
ctx.toElem.style.filter = null;
},
}));
},
};
return pub;

View file

@ -391,12 +391,10 @@ Umi.UI.Settings = (function() {
type: 'button',
invoke: async button => {
button.disabled = true;
await (new MamiForceDisconnectNotice({
perma: true,
type: 'ban',
})).pushOn(mami.views);
const notice = new MamiForceDisconnectNotice({ perma: true, type: 'ban' });
await notice.pushOn(mami.views);
await MamiSleep(5000);
await mami.views.pop();
await notice.popOff(mami.views);
button.disabled = false;
},
},