// Drool. function Logo (is_looping = false) { this.el = document.createElement('splash') this.el.style.position = 'fixed' this.el.style.top = '0px' this.el.style.left = '0px' this.el.style.width = '100vw' this.el.style.height = '100vh' this.el.style.backgroundColor = '#000' this.el.style.zIndex = '9999' this.el.style.display = 'block' this.el.style.transition = 'all 1000ms' this.el.style.opacity = '1' this.canvas = document.createElement('canvas') this.canvas.style.display = 'block' this.el.appendChild(this.canvas) var is_looping = is_looping this.size = null this.is_playing = true this.install = function (size) { document.body.appendChild(this.el) this.size = size this.canvas.width = 600 this.canvas.height = 600 this.canvas.style.width = '300px' this.canvas.style.height = '300px' this.canvas.style.display = 'block' this.canvas.style.margin = 'calc(50vh - 150px) auto' this.canvas.style.transition = 'all 1000ms' this.canvas.style.opacity = '1' this.create_tiles() animate() var timer = setInterval(this.draw, 17) } this.remove = function () { this.canvas.style.opacity = 0 setTimeout(() => { this.el.style.opacity = 0 }, 500) setTimeout(() => { document.body.removeChild(this.el) }, 1500) } this.context = function () { return this.canvas.getContext('2d') } this.clear = function () { this.context().clearRect(0, 0, this.canvas.width, this.canvas.height) } this.stop = function () { if (logo.is_playing == false) { return } setTimeout(function () { logo.draw(true) }, 50) this.is_playing = false } this.frame = 0 this.draw = function (override = false) { if (override == false && !tiles_still_moving()) { logo.stop(); return } logo.clear() var offset = 200 for (i = 0; i < tiles.length; i++) { var tile = tiles[i] var max_size = (tile.size / 2) - 2 var progress_toward_end = 1 - clamp(tile.distance_from_end() / (max_size * 4), 0, 1) var progress_fade = clamp(logo.frame / 10000, 0, 1) var size = clamp(progress_toward_end * progress_fade, 0, 1) * max_size logo.frame += 1 logo.context().beginPath() logo.context().arc(tile.el_pos.x + offset, tile.el_pos.y + offset, size, 0, 2 * Math.PI, false) logo.context().fillStyle = 'white' logo.context().fill() logo.context().closePath() logo.frame += 1 } } var tiles = [] this.create_tiles = function () { for (x = 0; x < 10; x++) { for (y = 0; y < 10; y++) { var pos = { x: x, y: y } tiles.push(new Tile(pos, this.size / 5)) } } } function scare_tiles (steps) { for (s = 0; s < steps; s++) { for (t = 0; t < tiles.length; t++) { tiles[t].flee() } } } function return_tiles_to (step) { for (i = 0; i < tiles.length; i++) { tiles[i].move_to(tiles[i].history[step]) tiles[i].update() } } function animate_return_to (step, id) { if (id == -1) { return } tiles[id].animate_until(tiles[id].history[step]) setTimeout(function () { animate_return_to(step, id - 1) }, 10) } function animate_to (step, id) { if (id == 100) { return } tiles[id].animate_until(tiles[id].history[step]) setTimeout(function () { animate_to(step, id + 1) }, 10) } function tiles_still_moving () { for (i = 0; i < tiles.length; i++) { var tile = tiles[i] if (tile.offset().x != 0 || tile.offset().y != 0) { logo.is_playing = true; return true } } return false } function animate () { scare_tiles(6) return_tiles_to(5) var speed = 300 setTimeout(function () { animate_return_to(9, 99) }, 0) setTimeout(function () { animate_return_to(8, 99) }, 1 * speed) setTimeout(function () { animate_return_to(7, 99) }, 2 * speed) setTimeout(function () { animate_return_to(6, 99) }, 3 * speed) setTimeout(function () { animate_return_to(5, 99) }, 4 * speed) setTimeout(function () { animate_return_to(4, 99) }, 5 * speed) setTimeout(function () { animate_return_to(3, 99) }, 6 * speed) setTimeout(function () { animate_return_to(2, 99) }, 7 * speed) setTimeout(function () { animate_return_to(1, 99) }, 8 * speed) if (is_looping == true) { setTimeout(function () { scare_tiles(6) }, 6000) setTimeout(function () { return_tiles_to(1) }, 6000) setTimeout(function () { animate_to(2, 0) }, 6500) setTimeout(function () { animate_to(3, 0) }, 7500) setTimeout(function () { animate_to(4, 0) }, 8000) setTimeout(function () { animate_to(5, 0) }, 8500) setTimeout(function () { animate() }, 11500) } } // Generate function Tile (pos, size) { this.pos = pos this.size = size this.el_pos = { x: this.pos.x * this.size, y: this.pos.y * this.size } this.origin = { x: this.pos.x * this.size, y: this.pos.y * this.size } this.history = [] this.history.push({ x: this.pos.x, y: this.pos.y }) function tile_at (target_pos, neighboors) { for (t2 = 0; t2 < neighboors.length; t2++) { if (neighboors[t2].pos.x == target_pos.x && neighboors[t2].pos.y == target_pos.y) { return neighboors[t2] } } return null } this.move_to = function (target_pos) { this.pos.x = target_pos.x this.pos.y = target_pos.y } var target_pos = null this.animate_until = function (target_pos) { if (!target_pos) { return } this.target_pos = target_pos var target_el_pos = { x: target_pos.x * this.size, y: target_pos.y * this.size } var to_move = { x: target_el_pos.x - this.el_pos.x, y: target_el_pos.y - this.el_pos.y } if (to_move.x > 0) { this.el_pos.x += 1 } else if (to_move.x < 0) { this.el_pos.x -= 1 } if (to_move.y > 0) { this.el_pos.y += 1 } else if (to_move.y < 0) { this.el_pos.y -= 1 } if (target_el_pos.x != this.el_pos.x || target_el_pos.y != this.el_pos.y) { var target = this setTimeout(function () { target.animate_until(target_pos) }, 5) } } this.update = function () { this.el_pos = { x: pos.x * this.size, y: pos.y * this.size } } this.offset = function () { if (!this.target_pos) { return { x: 0, y: 0 } } var target_el_pos = { x: this.target_pos.x * this.size, y: this.target_pos.y * this.size } return { x: target_el_pos.x - this.el_pos.x, y: target_el_pos.y - this.el_pos.y } } this.neighboor_left = function () { return tile_at({ x: pos.x - 1, y: pos.y }, tiles) } this.neighboor_right = function () { return tile_at({ x: pos.x + 1, y: pos.y }, tiles) } this.neighboor_top = function () { return tile_at({ x: pos.x, y: pos.y + 1 }, tiles) } this.neighboor_down = function () { return tile_at({ x: pos.x, y: pos.y - 1 }, tiles) } this.distance_from_end = function () { var a = this.origin.x - this.el_pos.x var b = this.origin.y - this.el_pos.y return Math.sqrt(a * a + b * b) } this.flee = function () { var random = Math.random() this.history.push({ x: this.pos.x, y: this.pos.y }) if (random < 0.25 && !this.neighboor_top()) { this.pos.y += 1 } else if (random < 0.5 && !this.neighboor_down()) { this.pos.y -= 1 } else if (random < 0.75 && !this.neighboor_right()) { this.pos.x += 1 } else if (!this.neighboor_left()) { this.pos.x -= 1 } } } function clamp (v, min, max) { return v < min ? min : v > max ? max : v } }