Reverse the animation when popping the kick/ban notice.
This commit is contained in:
parent
ddd802d3ff
commit
5ea5b1e030
3 changed files with 55 additions and 13 deletions
|
@ -66,10 +66,27 @@ const MamiAudioContext = function() {
|
||||||
return await ctx.decodeAudioData(result.body());
|
return await ctx.decodeAudioData(result.body());
|
||||||
},
|
},
|
||||||
|
|
||||||
createSource: buffer => {
|
createSource: (buffer, reverse) => {
|
||||||
if(ctx === undefined || buffer === undefined)
|
if(ctx === undefined || buffer === undefined)
|
||||||
return new MamiAudioSourceDummy;
|
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();
|
const gain = ctx.createGain();
|
||||||
gain.connect(mainGain);
|
gain.connect(mainGain);
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,16 @@ const MamiForceDisconnectNotice = function(banInfo) {
|
||||||
marqueeElem.append(<div class="baka-marquee-text">{marqueeString}</div>);
|
marqueeElem.append(<div class="baka-marquee-text">{marqueeString}</div>);
|
||||||
|
|
||||||
const rng = new MamiRNG;
|
const rng = new MamiRNG;
|
||||||
let sfxBuf, sfxSrc, bgmSrc;
|
const rotate = rng.next(-20, 20);
|
||||||
|
let sfxBuf, bgmSrc;
|
||||||
|
|
||||||
const pub = {
|
const pub = {
|
||||||
getElement: () => html,
|
getElement: () => html,
|
||||||
onViewPush: async () => {
|
onViewPush: async () => {
|
||||||
try {
|
try {
|
||||||
sfxBuf = await mami.sound.library.loadBuffer('touhou:pichuun');
|
sfxBuf = await mami.sound.library.loadBuffer('touhou:pichuun');
|
||||||
sfxSrc = mami.sound.audio.createSource(sfxBuf);
|
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
sfxBuf = sfxSrc = undefined;
|
sfxBuf = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -48,16 +48,16 @@ const MamiForceDisconnectNotice = function(banInfo) {
|
||||||
},
|
},
|
||||||
onViewPop: async () => {
|
onViewPop: async () => {
|
||||||
bgmSrc?.stop();
|
bgmSrc?.stop();
|
||||||
bgmSrc = sfxBuf = sfxSrc = undefined;
|
bgmSrc = sfxBuf = undefined;
|
||||||
},
|
},
|
||||||
pushOn: async views => {
|
pushOn: async views => {
|
||||||
const rotate = rng.next(-20, 20);
|
|
||||||
|
|
||||||
await views.push(pub, ctx => MamiAnimate({
|
await views.push(pub, ctx => MamiAnimate({
|
||||||
async: true,
|
async: true,
|
||||||
duration: (sfxBuf?.duration ?? 1.4) * 1000,
|
duration: (sfxBuf?.duration ?? 1.4) * 1000,
|
||||||
start: () => {
|
start: () => {
|
||||||
sfxSrc?.play();
|
if(sfxBuf !== undefined)
|
||||||
|
mami.sound.audio.createSource(sfxBuf).play();
|
||||||
|
|
||||||
ctx.toElem.style.top = '-100%';
|
ctx.toElem.style.top = '-100%';
|
||||||
},
|
},
|
||||||
update: t => {
|
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;
|
return pub;
|
||||||
|
|
|
@ -391,12 +391,10 @@ Umi.UI.Settings = (function() {
|
||||||
type: 'button',
|
type: 'button',
|
||||||
invoke: async button => {
|
invoke: async button => {
|
||||||
button.disabled = true;
|
button.disabled = true;
|
||||||
await (new MamiForceDisconnectNotice({
|
const notice = new MamiForceDisconnectNotice({ perma: true, type: 'ban' });
|
||||||
perma: true,
|
await notice.pushOn(mami.views);
|
||||||
type: 'ban',
|
|
||||||
})).pushOn(mami.views);
|
|
||||||
await MamiSleep(5000);
|
await MamiSleep(5000);
|
||||||
await mami.views.pop();
|
await notice.popOff(mami.views);
|
||||||
button.disabled = false;
|
button.disabled = false;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue