mirror of
https://iceshrimp.dev/limepotato/jormungandr-bite.git
synced 2024-11-21 17:37:29 -07:00
revert c2c4a19938
revert revert52da7595f7
revert revert3ff2626f64
revert feat: oneko Signed-off-by: limepotato <limepot@protonmail.ch>
This commit is contained in:
parent
7924ab0442
commit
4773ef4502
6 changed files with 0 additions and 258 deletions
|
@ -181,7 +181,6 @@ loginFailed: "Failed to sign in"
|
||||||
showOnRemote: "Open original page"
|
showOnRemote: "Open original page"
|
||||||
general: "General"
|
general: "General"
|
||||||
accountMoved: "Creature has moved to a new account:"
|
accountMoved: "Creature has moved to a new account:"
|
||||||
oneko: "Cat friend :3"
|
|
||||||
wallpaper: "Wallpaper"
|
wallpaper: "Wallpaper"
|
||||||
setWallpaper: "Set wallpaper"
|
setWallpaper: "Set wallpaper"
|
||||||
removeWallpaper: "Remove wallpaper"
|
removeWallpaper: "Remove wallpaper"
|
||||||
|
|
|
@ -1,246 +0,0 @@
|
||||||
<!--
|
|
||||||
SPDX-FileCopyrightText: kopper and other Sharkey contributors
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
-->
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div ref="nekoEl" :class="$style.oneko" aria-hidden="true"></div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
// oneko.js: https://github.com/adryd325/oneko.js
|
|
||||||
// modified to be a vue component by ShittyKopper :3
|
|
||||||
|
|
||||||
import { shallowRef, onMounted } from 'vue';
|
|
||||||
|
|
||||||
const nekoEl = shallowRef<HTMLDivElement>();
|
|
||||||
|
|
||||||
let nekoPosX = 32;
|
|
||||||
let nekoPosY = 32;
|
|
||||||
|
|
||||||
let mousePosX = 0;
|
|
||||||
let mousePosY = 0;
|
|
||||||
|
|
||||||
let frameCount = 0;
|
|
||||||
let idleTime = 0;
|
|
||||||
let idleAnimation: string|null = null;
|
|
||||||
let idleAnimationFrame = 0;
|
|
||||||
let lastFrameTimestamp;
|
|
||||||
|
|
||||||
const nekoSpeed = 10;
|
|
||||||
const spriteSets = {
|
|
||||||
idle: [[-3, -3]],
|
|
||||||
alert: [[-7, -3]],
|
|
||||||
scratchSelf: [
|
|
||||||
[-5, 0],
|
|
||||||
[-6, 0],
|
|
||||||
[-7, 0],
|
|
||||||
],
|
|
||||||
scratchWallN: [
|
|
||||||
[0, 0],
|
|
||||||
[0, -1],
|
|
||||||
],
|
|
||||||
scratchWallS: [
|
|
||||||
[-7, -1],
|
|
||||||
[-6, -2],
|
|
||||||
],
|
|
||||||
scratchWallE: [
|
|
||||||
[-2, -2],
|
|
||||||
[-2, -3],
|
|
||||||
],
|
|
||||||
scratchWallW: [
|
|
||||||
[-4, 0],
|
|
||||||
[-4, -1],
|
|
||||||
],
|
|
||||||
tired: [[-3, -2]],
|
|
||||||
sleeping: [
|
|
||||||
[-2, 0],
|
|
||||||
[-2, -1],
|
|
||||||
],
|
|
||||||
N: [
|
|
||||||
[-1, -2],
|
|
||||||
[-1, -3],
|
|
||||||
],
|
|
||||||
NE: [
|
|
||||||
[0, -2],
|
|
||||||
[0, -3],
|
|
||||||
],
|
|
||||||
E: [
|
|
||||||
[-3, 0],
|
|
||||||
[-3, -1],
|
|
||||||
],
|
|
||||||
SE: [
|
|
||||||
[-5, -1],
|
|
||||||
[-5, -2],
|
|
||||||
],
|
|
||||||
S: [
|
|
||||||
[-6, -3],
|
|
||||||
[-7, -2],
|
|
||||||
],
|
|
||||||
SW: [
|
|
||||||
[-5, -3],
|
|
||||||
[-6, -1],
|
|
||||||
],
|
|
||||||
W: [
|
|
||||||
[-4, -2],
|
|
||||||
[-4, -3],
|
|
||||||
],
|
|
||||||
NW: [
|
|
||||||
[-1, 0],
|
|
||||||
[-1, -1],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
function init() {
|
|
||||||
if (!nekoEl.value) return;
|
|
||||||
|
|
||||||
nekoEl.value.style.left = `${nekoPosX - 16}px`;
|
|
||||||
nekoEl.value.style.top = `${nekoPosY - 16}px`;
|
|
||||||
|
|
||||||
document.addEventListener('mousemove', (event) => {
|
|
||||||
mousePosX = event.clientX;
|
|
||||||
mousePosY = event.clientY;
|
|
||||||
});
|
|
||||||
|
|
||||||
window.requestAnimationFrame(onAnimationFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onAnimationFrame(timestamp) {
|
|
||||||
// Stops execution if the neko element is removed from DOM
|
|
||||||
if (!nekoEl.value?.isConnected) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!lastFrameTimestamp) {
|
|
||||||
lastFrameTimestamp = timestamp;
|
|
||||||
}
|
|
||||||
if (timestamp - lastFrameTimestamp > 100) {
|
|
||||||
lastFrameTimestamp = timestamp;
|
|
||||||
frame();
|
|
||||||
}
|
|
||||||
window.requestAnimationFrame(onAnimationFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-shadow
|
|
||||||
function setSprite(name, frame) {
|
|
||||||
if (!nekoEl.value) return;
|
|
||||||
|
|
||||||
const sprite = spriteSets[name][frame % spriteSets[name].length];
|
|
||||||
nekoEl.value.style.backgroundPosition = `${sprite[0] * 32}px ${sprite[1] * 32}px`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetIdleAnimation() {
|
|
||||||
idleAnimation = null;
|
|
||||||
idleAnimationFrame = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function idle() {
|
|
||||||
idleTime += 1;
|
|
||||||
|
|
||||||
// every ~ 20 seconds
|
|
||||||
if (
|
|
||||||
idleTime > 10 &&
|
|
||||||
Math.floor(Math.random() * 200) === 0 &&
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
||||||
idleAnimation == null
|
|
||||||
) {
|
|
||||||
let avalibleIdleAnimations = ['sleeping', 'scratchSelf'];
|
|
||||||
if (nekoPosX < 32) {
|
|
||||||
avalibleIdleAnimations.push('scratchWallW');
|
|
||||||
}
|
|
||||||
if (nekoPosY < 32) {
|
|
||||||
avalibleIdleAnimations.push('scratchWallN');
|
|
||||||
}
|
|
||||||
if (nekoPosX > window.innerWidth - 32) {
|
|
||||||
avalibleIdleAnimations.push('scratchWallE');
|
|
||||||
}
|
|
||||||
if (nekoPosY > window.innerHeight - 32) {
|
|
||||||
avalibleIdleAnimations.push('scratchWallS');
|
|
||||||
}
|
|
||||||
idleAnimation =
|
|
||||||
avalibleIdleAnimations[Math.floor(Math.random() * avalibleIdleAnimations.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (idleAnimation) {
|
|
||||||
case 'sleeping':
|
|
||||||
if (idleAnimationFrame < 8) {
|
|
||||||
setSprite('tired', 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
setSprite('sleeping', Math.floor(idleAnimationFrame / 4));
|
|
||||||
if (idleAnimationFrame > 192) {
|
|
||||||
resetIdleAnimation();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'scratchWallN':
|
|
||||||
case 'scratchWallS':
|
|
||||||
case 'scratchWallE':
|
|
||||||
case 'scratchWallW':
|
|
||||||
case 'scratchSelf':
|
|
||||||
setSprite(idleAnimation, idleAnimationFrame);
|
|
||||||
if (idleAnimationFrame > 9) {
|
|
||||||
resetIdleAnimation();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setSprite('idle', 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
idleAnimationFrame += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function frame() {
|
|
||||||
if (!nekoEl.value) return;
|
|
||||||
|
|
||||||
frameCount += 1;
|
|
||||||
const diffX = nekoPosX - mousePosX;
|
|
||||||
const diffY = nekoPosY - mousePosY;
|
|
||||||
const distance = Math.sqrt(diffX ** 2 + diffY ** 2);
|
|
||||||
|
|
||||||
if (distance < nekoSpeed || distance < 48) {
|
|
||||||
idle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
idleAnimation = null;
|
|
||||||
idleAnimationFrame = 0;
|
|
||||||
|
|
||||||
if (idleTime > 1) {
|
|
||||||
setSprite('alert', 0);
|
|
||||||
// count down after being alerted before moving
|
|
||||||
idleTime = Math.min(idleTime, 7);
|
|
||||||
idleTime -= 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let direction;
|
|
||||||
direction = diffY / distance > 0.5 ? 'N' : '';
|
|
||||||
direction += diffY / distance < -0.5 ? 'S' : '';
|
|
||||||
direction += diffX / distance > 0.5 ? 'W' : '';
|
|
||||||
direction += diffX / distance < -0.5 ? 'E' : '';
|
|
||||||
setSprite(direction, frameCount);
|
|
||||||
|
|
||||||
nekoPosX -= (diffX / distance) * nekoSpeed;
|
|
||||||
nekoPosY -= (diffY / distance) * nekoSpeed;
|
|
||||||
|
|
||||||
nekoPosX = Math.min(Math.max(16, nekoPosX), window.innerWidth - 16);
|
|
||||||
nekoPosY = Math.min(Math.max(16, nekoPosY), window.innerHeight - 16);
|
|
||||||
|
|
||||||
nekoEl.value.style.left = `${nekoPosX - 16}px`;
|
|
||||||
nekoEl.value.style.top = `${nekoPosY - 16}px`;
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(init);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style module>
|
|
||||||
.oneko {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
position: fixed;
|
|
||||||
pointer-events: none;
|
|
||||||
image-rendering: pixelated;
|
|
||||||
z-index: 2147483647;
|
|
||||||
background-image: var(--oneko-image, url(/client-assets/oneko.gif));
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -176,9 +176,6 @@
|
||||||
<FormSwitch v-model="useSystemFont" class="_formBlock">{{
|
<FormSwitch v-model="useSystemFont" class="_formBlock">{{
|
||||||
i18n.ts.useSystemFont
|
i18n.ts.useSystemFont
|
||||||
}}</FormSwitch>
|
}}</FormSwitch>
|
||||||
<FormSwitch v-model="oneko" class="_formBlock">{{
|
|
||||||
i18n.ts.oneko
|
|
||||||
}}</FormSwitch>
|
|
||||||
<FormSwitch v-model="useOsNativeEmojis" class="_formBlock">
|
<FormSwitch v-model="useOsNativeEmojis" class="_formBlock">
|
||||||
{{ i18n.ts.useOsNativeEmojis }}
|
{{ i18n.ts.useOsNativeEmojis }}
|
||||||
<div>
|
<div>
|
||||||
|
@ -325,7 +322,6 @@ const disableDrawer = computed(defaultStore.makeGetterSetter("disableDrawer"));
|
||||||
const disableShowingAnimatedImages = computed(
|
const disableShowingAnimatedImages = computed(
|
||||||
defaultStore.makeGetterSetter("disableShowingAnimatedImages"),
|
defaultStore.makeGetterSetter("disableShowingAnimatedImages"),
|
||||||
);
|
);
|
||||||
const oneko = computed(defaultStore.makeGetterSetter('oneko'));
|
|
||||||
const loadRawImages = computed(defaultStore.makeGetterSetter("loadRawImages"));
|
const loadRawImages = computed(defaultStore.makeGetterSetter("loadRawImages"));
|
||||||
const imageNewTab = computed(defaultStore.makeGetterSetter("imageNewTab"));
|
const imageNewTab = computed(defaultStore.makeGetterSetter("imageNewTab"));
|
||||||
const nsfw = computed(defaultStore.makeGetterSetter("nsfw"));
|
const nsfw = computed(defaultStore.makeGetterSetter("nsfw"));
|
||||||
|
|
|
@ -107,7 +107,6 @@ const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [
|
||||||
"reportError",
|
"reportError",
|
||||||
"squareAvatars",
|
"squareAvatars",
|
||||||
"numberOfPageCache",
|
"numberOfPageCache",
|
||||||
"oneko",
|
|
||||||
"showUpdates",
|
"showUpdates",
|
||||||
"swipeOnMobile",
|
"swipeOnMobile",
|
||||||
"swipeOnDesktop",
|
"swipeOnDesktop",
|
||||||
|
|
|
@ -295,10 +295,6 @@ export const defaultStore = markRaw(
|
||||||
where: "device",
|
where: "device",
|
||||||
default: 5,
|
default: 5,
|
||||||
},
|
},
|
||||||
oneko: {
|
|
||||||
where: 'device',
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
enterSendsMessage: {
|
enterSendsMessage: {
|
||||||
where: "device",
|
where: "device",
|
||||||
default: true,
|
default: true,
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
<!-- <div v-if="pendingApiRequestsCount > 0" id="wait"></div> -->
|
<!-- <div v-if="pendingApiRequestsCount > 0" id="wait"></div> -->
|
||||||
|
|
||||||
<div v-if="dev" id="devTicker"><span>DEV BUILD</span></div>
|
<div v-if="dev" id="devTicker"><span>DEV BUILD</span></div>
|
||||||
<MkOneko v-if="defaultStore.state.oneko"/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
@ -25,7 +24,6 @@ import { uploads } from "@/scripts/upload";
|
||||||
import * as sound from "@/scripts/sound";
|
import * as sound from "@/scripts/sound";
|
||||||
import { $i } from "@/account";
|
import { $i } from "@/account";
|
||||||
import { stream } from "@/stream";
|
import { stream } from "@/stream";
|
||||||
import SkOneko from '@/components/MkOneko.vue';
|
|
||||||
|
|
||||||
const XStreamIndicator = defineAsyncComponent(
|
const XStreamIndicator = defineAsyncComponent(
|
||||||
() => import("./stream-indicator.vue"),
|
() => import("./stream-indicator.vue"),
|
||||||
|
|
Loading…
Reference in a new issue