Skip to content

Latest commit

 

History

History
206 lines (175 loc) · 5.79 KB

index.md

File metadata and controls

206 lines (175 loc) · 5.79 KB
layout search_exclude image
home
true
/images/mario_animation.png

{% assign sprite_file = site.baseurl | append: page.image %} <!--- Liquid concatentation ---> {% assign hash = site.data.mario_metadata %} <!--- Liquid list variable created from a file containing mario metatdata for sprite ---> {% assign pixels = 256 %} <!--- Liquid integer assignment --->

<style> /*CSS style rules for the id and class of the element above... */ .sprite { height: {{pixels}}px; width: {{pixels}}px; background-image: url('{{sprite_file}}'); background-repeat: no-repeat; } /*background position of sprite element */ #mario { background-position: calc({{animations[0].col}} * {{pixels}} * -1px) calc({{animations[0].row}} * {{pixels}}* -1px); } </style> <script> ////////// convert yml hash to javascript key value objects ///////// var mario_metadata = {}; //key, value object {% for key in hash %} var key = "{{key | first}}" //key var values = {} //values object values["row"] = {{key.row}} values["col"] = {{key.col}} values["frames"] = {{key.frames}} mario_metadata[key] = values; //key with values added {% endfor %} ////////// animation control object ///////// class Mario { constructor(meta_data) { this.tID = null; //capture setInterval() task ID this.positionX = 0; // current position of sprite in X direction this.currentSpeed = 0; this.marioElement = document.getElementById("mario"); //HTML element of sprite this.pixels = {{pixels}}; //pixel offset of images in the sprite, set by liquid constant this.interval = 100; //animation time interval this.obj = meta_data; this.marioElement.style.position = "absolute"; } animate(obj, speed) { let frame = 0; const row = obj.row * this.pixels; this.currentSpeed = speed; this.tID = setInterval(() => { const col = (frame + obj.col) * this.pixels; this.marioElement.style.backgroundPosition = `-${col}px -${row}px`; this.marioElement.style.left = `${this.positionX}px`; this.positionX += speed; frame = (frame + 1) % obj.frames; const viewportWidth = window.innerWidth; if (this.positionX > viewportWidth - this.pixels) { document.documentElement.scrollLeft = this.positionX - viewportWidth + this.pixels; } }, this.interval); } startWalking() { this.stopAnimate(); this.animate(this.obj["Walk"], 3); } startWalkingLeft() { this.stopAnimate(); this.animate(this.obj["WalkL"], -3); } startRunning() { this.stopAnimate(); this.animate(this.obj["Run1"], 6); } startRunningLeft() { this.stopAnimate(); this.animate(this.obj["Run1L"], -6); } startPuffing() { this.stopAnimate(); this.animate(this.obj["Puff"], 0); } startCheering() { this.stopAnimate(); this.animate(this.obj["Cheer"], 0); } startFlipping() { this.stopAnimate(); this.animate(this.obj["Flip"], 0); } startResting() { this.stopAnimate(); this.animate(this.obj["Rest"], 0); } stopAnimate() { clearInterval(this.tID); } } const mario = new Mario(mario_metadata); ////////// event control ///////// window.addEventListener("keydown", (event) => { if (event.key === "ArrowRight"||event.key==="d") { event.preventDefault(); if (event.repeat) { mario.startCheering(); } else { if (mario.currentSpeed === 0) { mario.startWalking(); } else if (mario.currentSpeed === 3) { mario.startRunning(); } else if (mario.currentSpeed === -3) { mario.startWalking(); } else if (mario.currentSpeed === -6) { mario.startWalking(); } } } else if (event.key === "s"||event.key==="ArrowDown") { event.preventDefault(); if (event.repeat) { mario.stopAnimate(); } else { mario.startPuffing(); } } else if (event.key === "ArrowLeft"||event.key==="a") { event.preventDefault(); if (event.repeat) { mario.startCheering(); } else { if (mario.currentSpeed === 0) { mario.startWalkingLeft(); } else if (mario.currentSpeed === -3) { mario.startRunningLeft(); } else if (mario.currentSpeed === 3) { mario.startWalkingLeft(); } else if (mario.currentSpeed === 6) { mario.startWalkingLeft(); } } } }); //touch events that enable animations window.addEventListener("touchstart", (event) => { event.preventDefault(); // prevent default browser action if (event.touches[0].clientX > window.innerWidth / 2) { // move right if (currentSpeed === 0) { // if at rest, go to walking mario.startWalking(); } else if (currentSpeed === 3) { // if walking, go to running mario.startRunning(); } } else { // move left mario.startPuffing(); } }); //stop animation on window blur window.addEventListener("blur", () => { mario.stopAnimate(); }); //start animation on window focus window.addEventListener("focus", () => { mario.startFlipping(); }); //start animation on page load or page refresh document.addEventListener("DOMContentLoaded", () => { // adjust sprite size for high pixel density devices const scale = window.devicePixelRatio; const sprite = document.querySelector(".sprite"); sprite.style.transform = `scale(${2*scale})`; mario.startResting(); });