Files
portfolio.sorlinv.fr/www/static/Shimeji.js

160 lines
4.7 KiB
JavaScript

class Vector2 {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class Shimeji {
constructor(url_path) {
this.url_path = url_path;
this.x = 0;
this.y = 0;
this.offset = null;
this.mouseHover = false;
this.mouseDown = false;
this.isFalling = true;
this.isWalking = false;
this.oldRect = null;
this.rect = null;
this.mousePos = new Vector2(0,0);
this.frame_duration = 200;
this.lastmove = Date.now();
//Animations
this.anim_fast_grap = ["/shime9.png"];
this.anim_slow_grap = ["/shime7.png"];
this.anim_idle_grap = ["/shime5.png"];
this.anim_falling = ["/shime4.png"];
this.anim_idle = ["/shime1.png"];
this.anim_walk = ["/shime2.png", "/shime3.png"];
this.renderElem = document.createElement("img");
this.renderElem.src = this.url_path + "/shime1.png";
this.renderElem.style.position = "fixed";
this.renderElem.style.zIndex = 1021;
this.renderElem.setAttribute("draggable", "false");
document.body.appendChild(this.renderElem);
this.updateInterval = setInterval(this.update.bind(this), 50);
this.move(0, 0);
this.renderElem.addEventListener("mouseenter", this.onMouseEnter.bind(this));
this.renderElem.addEventListener("mouseleave", this.onMouseLeave.bind(this));
this.renderElem.addEventListener("contextmenu", this.onContextMenu.bind(this));
window.addEventListener("mousedown", this.onMouseDown.bind(this));
window.addEventListener("mouseup", this.onMouseUp.bind(this));
window.addEventListener("mousemove", this.onMouseMove.bind(this));
}
move(x, y) {
this.x = x;
this.y = y;
this.renderElem.style.left = x + "px";
this.renderElem.style.top = y + "px";
}
onMouseMove(e) {
this.lastmove = Date.now();
this.mousePos = new Vector2(e.clientX, e.clientY);
const rect = this.renderElem.getBoundingClientRect();
if(this.mouseDown && (this.mouseHover || this.offset)) {
if(this.offset == null) {
this.offset = new Vector2(e.clientX - rect.left, e.clientY - rect.top);
}
this.move(e.clientX - this.offset.x, e.clientY - this.offset.y);
} else {
this.offset = null;
}
this.previewsEvent = e;
}
onMouseDown(e) {
this.mouseDown = true;
}
onMouseUp(e) {
this.mouseDown = false;
this.offset = null;
}
onMouseEnter(e) {
this.mouseHover = true;
}
onMouseLeave(e) {
this.mouseHover = false;
}
onContextMenu(e) {
e.preventDefault();
}
randomMove() {
this.lastmove = Date.now();
this.rect = this.renderElem.getBoundingClientRect();
this.mousePos = new Vector2(Math.round(Math.random() * window.innerWidth), Math.round(Math.random() * window.innerHeight));
console.log(this.mousePos);
}
update() {
this.rect = this.renderElem.getBoundingClientRect();
if(Date.now() - this.lastmove > 5000) {
this.randomMove();
}
if(this.offset == null) {
if(this.rect.bottom <= window.innerHeight -1) {
this.isFalling = true;
this.move(this.rect.x, Math.min(this.rect.y + 10, window.innerHeight - this.rect.height));
} else {
this.isFalling = false;
if(Math.abs(this.rect.x - this.mousePos.x + (this.rect.width / 2)) > 5) {
this.isWalking = true;
this.move(this.rect.x + (5 * -Math.sign(this.rect.x - this.mousePos.x + (this.rect.width / 2))), this.rect.y);
} else {
this.isWalking = false;
}
}
}
this.animate();
this.oldRect = this.rect;
}
getCurrenFrame(frame_array) {
let animeIndex = Math.floor((new Date().getTime() / this.frame_duration) % frame_array.length);
return frame_array[animeIndex];
}
animate() {
let new_frame = this.renderElem.src;
if(this.oldRect == null) this.oldRect = this.rect;
let diffX = this.oldRect.x - this.rect.x;
if(this.offset) {
// grap animation
if(Math.abs(diffX) > 20) {
new_frame = this.url_path + this.getCurrenFrame(this.anim_fast_grap); // fast grap
} else if(Math.abs(diffX) > 10){
new_frame = this.url_path + this.getCurrenFrame(this.anim_slow_grap); // slow grap
} else {
new_frame = this.url_path + this.getCurrenFrame(this.anim_idle_grap); // idle grap
}
this.renderElem.style.transform = diffX > 0 ? "scaleX(-1)" : "scaleX(1)";
} else if (this.isFalling) {
// falling animation
new_frame = this.url_path + this.getCurrenFrame(this.anim_falling); // falling
} else {
// on floor animation
if(diffX == 0) {
new_frame = this.url_path + this.getCurrenFrame(this.anim_idle); // idle floor
} else {
new_frame = this.url_path + this.getCurrenFrame(this.anim_walk); //walk
this.renderElem.style.transform = diffX > 0 ? "scaleX(1)" : "scaleX(-1)";
}
}
if(new_frame != this.renderElem.getAttribute("src")) {
console.log("change design");
this.renderElem.src = new_frame;
}
}
}
console.log("LibShimeji from sorlinv.fr is loaded");