implemented oneko
This commit is contained in:
parent
3d30ed1caa
commit
34437e8491
242
searx/static/themes/simple/js/oneko-ie6.js
Normal file
242
searx/static/themes/simple/js/oneko-ie6.js
Normal file
@ -0,0 +1,242 @@
|
||||
function neko() {
|
||||
var nekoEl = document.createElement("div");
|
||||
|
||||
var nekoPosX = 32;
|
||||
var nekoPosY = 32;
|
||||
|
||||
var mousePosX = 0;
|
||||
var mousePosY = 0;
|
||||
|
||||
var frameCount = 0;
|
||||
var idleTime = 0;
|
||||
var idleAnimation = null;
|
||||
var idleAnimationFrame = 0;
|
||||
var direction;
|
||||
|
||||
var IE = document.all ? true : false;
|
||||
|
||||
var nekoSpeed = 10;
|
||||
var 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() {
|
||||
nekoEl.id = "oneko";
|
||||
nekoEl.ariaHidden = true;
|
||||
nekoEl.style.width = "32px";
|
||||
nekoEl.style.height = "32px";
|
||||
nekoEl.style.position = "absolute";
|
||||
nekoEl.style.pointerEvents = "none";
|
||||
nekoEl.style.backgroundImage = "url('oneko.gif')";
|
||||
nekoEl.style.imageRendering = "pixelated";
|
||||
nekoEl.style.left = nekoPosX - 16 + "px";
|
||||
nekoEl.style.top = nekoPosY - 16 + "px";
|
||||
nekoEl.style.zIndex = Number.MAX_VALUE;
|
||||
|
||||
document.body.appendChild(nekoEl);
|
||||
function mousePos(event) {
|
||||
if (IE) {
|
||||
event = window.event;
|
||||
}
|
||||
mousePosX = event.clientX;
|
||||
mousePosY = event.clientY - 16;
|
||||
}
|
||||
document.onmousemove = mousePos;
|
||||
window.onekoInterval = setInterval(frame, 100);
|
||||
}
|
||||
|
||||
function setSprite(name, frame) {
|
||||
var length = spriteSets[name].length;
|
||||
if (IE) {
|
||||
length = 0;
|
||||
// Internet explorer is really fucking dumb
|
||||
while (length < spriteSets[name].length) {
|
||||
if (spriteSets[name][length] != null) {
|
||||
length = length + 1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
var sprite = spriteSets[name][frame % length];
|
||||
nekoEl.style.backgroundPosition =
|
||||
sprite["0"] * 32 + "px " + sprite["1"] * 32 + "px";
|
||||
}
|
||||
|
||||
function resetIdleAnimation() {
|
||||
idleAnimation = null;
|
||||
idleAnimationFrame = 0;
|
||||
}
|
||||
|
||||
function idle() {
|
||||
idleTime = idleTime + 1;
|
||||
|
||||
// every ~ 20 seconds
|
||||
if (
|
||||
idleTime > 10 &&
|
||||
Math.floor(Math.random() * 200) == 0 &&
|
||||
idleAnimation == null
|
||||
) {
|
||||
var 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 = idleAnimationFrame + 1;
|
||||
}
|
||||
|
||||
function frame() {
|
||||
frameCount = frameCount + 1;
|
||||
var diffX = nekoPosX - mousePosX;
|
||||
var diffY = nekoPosY - mousePosY;
|
||||
var distance = Math.sqrt(Math.pow(diffX, 2) + Math.pow(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 = idleTime - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
direction = "";
|
||||
if (diffY / distance > 0.5) {
|
||||
direction = "N";
|
||||
} else if (diffY / distance < -0.5) {
|
||||
direction = "S";
|
||||
}
|
||||
if (diffX / distance > 0.5) {
|
||||
direction = direction + "W";
|
||||
} else if (diffX / distance < -0.5) {
|
||||
direction = direction + "E";
|
||||
}
|
||||
setSprite(direction, frameCount);
|
||||
|
||||
if (distance > nekoSpeed) {
|
||||
nekoPosX = nekoPosX - (diffX / distance) * nekoSpeed;
|
||||
nekoPosY = nekoPosY - (diffY / distance) * nekoSpeed;
|
||||
} else {
|
||||
nekoPosX = mousePosX;
|
||||
nekoPosY = mousePosY;
|
||||
}
|
||||
|
||||
nekoPosX = Math.min(
|
||||
Math.max(16, nekoPosX),
|
||||
document.getElementsByTagName("body")[0].clientWidth - 16
|
||||
);
|
||||
nekoPosY = Math.min(
|
||||
Math.max(16, nekoPosY),
|
||||
document.getElementsByTagName("body")[0].clientHeight - 16
|
||||
);
|
||||
|
||||
nekoEl.style.left = nekoPosX - 16 + "px";
|
||||
nekoEl.style.top = nekoPosY - 16 + "px";
|
||||
}
|
||||
init();
|
||||
}
|
||||
neko();
|
||||
291
searx/static/themes/simple/js/oneko-webring.js
Normal file
291
searx/static/themes/simple/js/oneko-webring.js
Normal file
@ -0,0 +1,291 @@
|
||||
// oneko.js: https://github.com/adryd325/oneko.js (webring variant)
|
||||
|
||||
(function oneko() {
|
||||
const isReducedMotion =
|
||||
window.matchMedia(`(prefers-reduced-motion: reduce)`) === true ||
|
||||
window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true;
|
||||
|
||||
if (isReducedMotion) return;
|
||||
|
||||
const nekoEl = document.createElement("div");
|
||||
|
||||
let nekoPosX = 32;
|
||||
let nekoPosY = 32;
|
||||
|
||||
let mousePosX = 0;
|
||||
let mousePosY = 0;
|
||||
|
||||
// please use data-neko="true" on your A elements that link to another site with oneko-webring.js instead of this
|
||||
// this is deprecated and will eventually be removed
|
||||
const nekoSites = [
|
||||
"localhost",
|
||||
];
|
||||
|
||||
try {
|
||||
const searchParams = location.search
|
||||
.replace("?", "")
|
||||
.split("&")
|
||||
.map((keyvaluepair) => keyvaluepair.split("="));
|
||||
// This is so much repeated code, I don't like it
|
||||
tmp = searchParams.find((a) => a[0] == "catx");
|
||||
if (tmp && tmp[1]) nekoPosX = parseInt(tmp[1]);
|
||||
tmp = searchParams.find((a) => a[0] == "caty");
|
||||
if (tmp && tmp[1]) nekoPosY = parseInt(tmp[1]);
|
||||
tmp = searchParams.find((a) => a[0] == "catdx");
|
||||
if (tmp && tmp[1]) mousePosX = parseInt(tmp[1]);
|
||||
tmp = searchParams.find((a) => a[0] == "catdy");
|
||||
if (tmp && tmp[1]) mousePosY = parseInt(tmp[1]);
|
||||
} catch (e) {
|
||||
console.error("oneko.js: failed to parse query params.");
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
function onClick(event) {
|
||||
const target = event.target.closest("A");
|
||||
if (target === null || !target.getAttribute("href")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let newLocation;
|
||||
try {
|
||||
newLocation = new URL(target.href);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
(nekoSites.includes(newLocation.host) && newLocation.pathname == "/") ||
|
||||
target.dataset.neko
|
||||
) {
|
||||
newLocation.searchParams.append("catx", Math.floor(nekoPosX));
|
||||
newLocation.searchParams.append("caty", Math.floor(nekoPosY));
|
||||
newLocation.searchParams.append("catdx", Math.floor(mousePosX));
|
||||
newLocation.searchParams.append("catdy", Math.floor(mousePosY));
|
||||
event.preventDefault();
|
||||
window.location.href = newLocation.toString();
|
||||
}
|
||||
}
|
||||
document.addEventListener("click", onClick);
|
||||
|
||||
let frameCount = 0;
|
||||
let idleTime = 0;
|
||||
let idleAnimation = null;
|
||||
let idleAnimationFrame = 0;
|
||||
|
||||
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() {
|
||||
nekoEl.id = "oneko";
|
||||
nekoEl.ariaHidden = true;
|
||||
nekoEl.style.width = "32px";
|
||||
nekoEl.style.height = "32px";
|
||||
nekoEl.style.position = "fixed";
|
||||
nekoEl.style.pointerEvents = "none";
|
||||
nekoEl.style.imageRendering = "pixelated";
|
||||
nekoEl.style.left = `${nekoPosX - 16}px`;
|
||||
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||
nekoEl.style.zIndex = Number.MAX_VALUE;
|
||||
|
||||
let nekoFile = "./oneko.gif"
|
||||
const curScript = document.currentScript
|
||||
if (curScript && curScript.dataset.cat) {
|
||||
nekoFile = curScript.dataset.cat
|
||||
}
|
||||
nekoEl.style.backgroundImage = `url(${nekoFile})`;
|
||||
|
||||
document.body.appendChild(nekoEl);
|
||||
|
||||
document.addEventListener("mousemove", function (event) {
|
||||
mousePosX = event.clientX;
|
||||
mousePosY = event.clientY;
|
||||
});
|
||||
|
||||
window.requestAnimationFrame(onAnimationFrame);
|
||||
}
|
||||
|
||||
let lastFrameTimestamp;
|
||||
|
||||
function onAnimationFrame(timestamp) {
|
||||
// Stops execution if the neko element is removed from DOM
|
||||
if (!nekoEl.isConnected) {
|
||||
return;
|
||||
}
|
||||
if (!lastFrameTimestamp) {
|
||||
lastFrameTimestamp = timestamp;
|
||||
}
|
||||
if (timestamp - lastFrameTimestamp > 100) {
|
||||
lastFrameTimestamp = timestamp
|
||||
frame()
|
||||
}
|
||||
|
||||
window.requestAnimationFrame(onAnimationFrame);
|
||||
}
|
||||
|
||||
function setSprite(name, frame) {
|
||||
const sprite = spriteSets[name][frame % spriteSets[name].length];
|
||||
nekoEl.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 &&
|
||||
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() {
|
||||
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.style.left = `${nekoPosX - 16}px`;
|
||||
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||
}
|
||||
|
||||
init();
|
||||
})();
|
||||
BIN
searx/static/themes/simple/js/oneko.gif
Normal file
BIN
searx/static/themes/simple/js/oneko.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
239
searx/static/themes/simple/js/oneko.js
Normal file
239
searx/static/themes/simple/js/oneko.js
Normal file
@ -0,0 +1,239 @@
|
||||
// oneko.js: https://github.com/adryd325/oneko.js
|
||||
|
||||
(function oneko() {
|
||||
const isReducedMotion =
|
||||
window.matchMedia(`(prefers-reduced-motion: reduce)`) === true ||
|
||||
window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true;
|
||||
|
||||
if (isReducedMotion) return;
|
||||
|
||||
const nekoEl = document.createElement("div");
|
||||
|
||||
let nekoPosX = 32;
|
||||
let nekoPosY = 32;
|
||||
|
||||
let mousePosX = 0;
|
||||
let mousePosY = 0;
|
||||
|
||||
let frameCount = 0;
|
||||
let idleTime = 0;
|
||||
let idleAnimation = null;
|
||||
let idleAnimationFrame = 0;
|
||||
|
||||
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() {
|
||||
nekoEl.id = "oneko";
|
||||
nekoEl.ariaHidden = true;
|
||||
nekoEl.style.width = "32px";
|
||||
nekoEl.style.height = "32px";
|
||||
nekoEl.style.position = "fixed";
|
||||
nekoEl.style.pointerEvents = "none";
|
||||
nekoEl.style.imageRendering = "pixelated";
|
||||
nekoEl.style.left = `${nekoPosX - 16}px`;
|
||||
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||
nekoEl.style.zIndex = 2147483647;
|
||||
|
||||
let nekoFile = "./oneko.gif"
|
||||
const curScript = document.currentScript
|
||||
if (curScript && curScript.dataset.cat) {
|
||||
nekoFile = curScript.dataset.cat
|
||||
}
|
||||
nekoEl.style.backgroundImage = `url(${nekoFile})`;
|
||||
|
||||
document.body.appendChild(nekoEl);
|
||||
|
||||
document.addEventListener("mousemove", function (event) {
|
||||
mousePosX = event.clientX;
|
||||
mousePosY = event.clientY;
|
||||
});
|
||||
|
||||
window.requestAnimationFrame(onAnimationFrame);
|
||||
}
|
||||
|
||||
let lastFrameTimestamp;
|
||||
|
||||
function onAnimationFrame(timestamp) {
|
||||
// Stops execution if the neko element is removed from DOM
|
||||
if (!nekoEl.isConnected) {
|
||||
return;
|
||||
}
|
||||
if (!lastFrameTimestamp) {
|
||||
lastFrameTimestamp = timestamp;
|
||||
}
|
||||
if (timestamp - lastFrameTimestamp > 100) {
|
||||
lastFrameTimestamp = timestamp
|
||||
frame()
|
||||
}
|
||||
window.requestAnimationFrame(onAnimationFrame);
|
||||
}
|
||||
|
||||
function setSprite(name, frame) {
|
||||
const sprite = spriteSets[name][frame % spriteSets[name].length];
|
||||
nekoEl.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 &&
|
||||
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() {
|
||||
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.style.left = `${nekoPosX - 16}px`;
|
||||
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||
}
|
||||
|
||||
init();
|
||||
})();
|
||||
7
searx/static/themes/simple/js/oneko.js-main/LICENSE
Normal file
7
searx/static/themes/simple/js/oneko.js-main/LICENSE
Normal file
@ -0,0 +1,7 @@
|
||||
Copyright © 2022 adryd
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
19
searx/static/themes/simple/js/oneko.js-main/README.md
Normal file
19
searx/static/themes/simple/js/oneko.js-main/README.md
Normal file
@ -0,0 +1,19 @@
|
||||
# oneko.js
|
||||
|
||||
A hacky script I wrote to put a cat on my site.
|
||||
|
||||
The default image is `oneko.gif` in the same directory as the script. This can be changed by adding `data-cat="yourimage.png"` to your `<script>` tag.
|
||||
|
||||
demo: https://adryd.com
|
||||
|
||||
This script is meant to be simple so that it can easily be extended upon. Pull requests adding features not seen in the [original neko program
|
||||
](https://en.wikipedia.org/wiki/Neko_(software)) will probably not be merged.
|
||||
|
||||
implemented in a few different places
|
||||
- Userscript: https://openuserjs.org/scripts/sjehuda/Oneko_WebMate
|
||||
- Vencord: https://vencord.dev/plugins/oneko
|
||||
- Spicetify: https://github.com/kyrie25/spicetify-oneko
|
||||
|
||||
feature forks
|
||||
- Pet the cat: https://github.com/tylxr59/oneko.js/tree/main
|
||||
- Move the cat using scroll wheel: https://github.com/rozbrajaczpoziomow/fork-oneko.js/tree/main
|
||||
17
searx/static/themes/simple/js/oneko.js-main/demo.html
Normal file
17
searx/static/themes/simple/js/oneko.js-main/demo.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>oneko.js</title>
|
||||
</head>
|
||||
<body>
|
||||
<!--[if IE]>
|
||||
<script src="./oneko-ie6.js"></script>
|
||||
<![endif]-->
|
||||
<!--[if !IE]><!-->
|
||||
<script src="./oneko.js"></script>
|
||||
<!--<![endif]-->
|
||||
</body>
|
||||
</html>
|
||||
@ -5,6 +5,12 @@
|
||||
"src": "js/searxng.head.js",
|
||||
"isEntry": true
|
||||
},
|
||||
"js/oneko.js": {
|
||||
"file": "js/oneko.js",
|
||||
"name": "js/oneko.js",
|
||||
"src": "js/oneko.js",
|
||||
"isEntry": true
|
||||
},
|
||||
"js/searxng.js": {
|
||||
"file": "js/searxng.min.js",
|
||||
"name": "js/searxng.min",
|
||||
@ -26,4 +32,4 @@
|
||||
"src": "less/style-rtl.less",
|
||||
"isEntry": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,6 +84,7 @@
|
||||
</footer>
|
||||
<!--[if gte IE 9]>-->
|
||||
<script src="{{ url_for('static', filename='js/searxng.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/oneko.js') }}"></script>
|
||||
<!--<![endif]-->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user