function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function moveObject(object, amountX, amountY, time) { let counter = 0; const step = time / 1000 * 60; const stepX = amountX / step; const stepY = amountY / step; let goalX; let goalY; if (object.hasOwnProperty('cx') && object.hasOwnProperty('cy')) { goalX = object.cx + amountX; goalY = object.cy + amountY; } else { goalX = object.x + amountX; goalY = object.y + amountY; } const interval = setInterval(() => { if (object.hasOwnProperty('cx') && object.hasOwnProperty('cy')) { object.cx += stepX; object.cy += stepY; } else { object.x += stepX; object.y += stepY; } counter++; if (counter >= step) { clearInterval(interval); if (object.hasOwnProperty('cx') && object.hasOwnProperty('cy')) { object.cx = goalX; object.cy = goalY; } else { object.x = goalX; object.y = goalY; } } }, 1000 / 60); } function calculateColor(number) { const hue = (number / 150 * (360 - 35) + 35) % 360; return `hsl(${hue}, 100%, 50%)`; } function cbElementPos(event) { event = event || window.event; let obj = event.target || event.srcElement, x = 0, y = 0; while (obj.offsetParent) { x += obj.offsetLeft; y += obj.offsetTop; obj = obj.offsetParent; } return {x, y}; } function cbMousePos(event) { event = event || window.event; return { x: event.pageX || event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft, y: event.pageY || event.clientY + document.body.scrollTop + document.documentElement.scrollTop, } } function cbRelMousePos(event) { const elem = cbElementPos(event), mouse = cbMousePos(event); return { x: (mouse.x - elem.x), y: (mouse.y - elem.y), }; } window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) { return setTimeout(callback, 1000 / 60); }; Math.clamp = function (a, b, c) { return Math.max(b, Math.min(c, a)); }; CanvasRenderingContext2D.prototype.fillCircle = function (cx, cy, radius) { this.beginPath(); this.arc(cx, cy, radius, 0, 2 * Math.PI); this.fill(); };