$(function () { const SEVENTV_GLOBAL_URL = "https://api.7tv.app/v2/emotes/global"; const SEVENTV_CHANNEL_URL = "https://api.7tv.app/v2/users/" + "..." + "/emotes"; const FFZ_GLOBAL_URL = "https://api.frankerfacez.com/v1/set/global"; const FFZ_CHANNEL_URL = "https://api.frankerfacez.com/v1/room/" + "..."; const BTTV_GLOBAL_URL = "https://api.betterttv.net/3/cached/emotes/global"; const BTTV_CHANNEL_URL = "https://api.betterttv.net/3/cached/users/twitch/" + "..."; const webSocket = window.socket; const emote_str = ["peepo", 'nod'] const emote_url = ['https://cdn.7tv.app/emote/603cac391cd55c0014d989be/2x', 'https://cdn.7tv.app/emote/60ae4bb30e35477634610fda/1x'] var img_map = {}; var lastframe = 0; var preloaded = false, initialized = false; var mode = "rain" || "bounce" || "explosion" || "firework" || "..."; var particles = []; const canvas = document.getElementById('wall'); const ctx = canvas.getContext('2d'); const resizeCanvas = () => { canvas.width = window.innerWidth-8; canvas.height = window.innerHeight-8; } window.addEventListener('resize', resizeCanvas, false); resizeCanvas(); function loadImages(strs, urls) { let loadcount = 0, loadtotal = urls.length; preloaded = false; var loadedimages = {}; for (let i=0; i (t<0 || t>8 )? 0 : (t<2 ? t/2 : (t>6 ? (8-t)/2 : 1)) class Particle { constructor(emote,data){ this.size = 64; this.data = data; this.x = Math.random() * canvas.width - this.size; this.y = Math.random() * canvas.height - this.size; this.vx = this.vy = 0; this.ax = this.ay = 0; this.emote = emote; this.time = 0; particles.push(this); setTimeout(()=>{particles.pop()}, 10000); } draw(){ ctx.globalAlpha = tWave(this.time); if(img_map[this.emote]) ctx.drawImage(img_map[this.emote], this.x, this.y, this.size, this.size); } update(tick){ this.time += tick; this.vx += tick * this.ax; this.vy += tick * this.ay; this.x += tick * this.vx * part_speed; this.y += tick * this.vy * part_speed; } } class RainP extends Particle { constructor(emote,data) { super(emote,data) this.x = Math.random() * canvas.width; this.y = - this.size; this.vx = 0; this.vy = 15; this.ax = 0, this.ay = 0; this.time = 2; } update(tick){ super.update(tick) } } class BounceP extends Particle { constructor(emote,data) { super(emote,data) this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; this.vx = (Math.random() * 2 - 1) *15; this.vy = (Math.random() * 2 - 1) * 15; this.ax = 0, this.ay = 0; } update(tick){ super.update(tick); if (this.x < 0) { this.vx = this.vx < 0 ? -this.vx * part_bounce_el : this.vx; this.x = 0; } else if (this.x + this.size > canvas.width) { this.vx = this.vx > 0 ? -this.vx * part_bounce_el : this.vx; this.x = canvas.width - this.size; } if (this.y <0) { this.vy = this.vy < 0 ? -this.vy * part_bounce_el : this.vy; this.y = 0; } else if (this.y + this.size > canvas.height) { this.vy = this.vy > 0 ? -this.vy * part_bounce_el : this.vy; this.y = canvas.height - this.size; } } } class BounceGP extends BounceP { constructor(emote,data) { super(emote,data) this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; this.vx = Math.random() * 20 - 10; this.vy = Math.random() * 20 - 10; this.ax = 0, this.ay = 10; } update(tick){ super.update(tick); } } class FireworkP extends Particle { constructor(emote,data) { super(emote,data) this.x = canvas.width/2; this.y = canvas.height; this.vx = 0; this.vy = -15; this.ax = 0; this.ay = 0; this.time=4; this.boom = false; } update(tick){ super.update(tick); if(this.y <= canvas.height/4 && !this.boom){ let angle = Math.random() *2 * Math.PI; this.vx = Math.sin(angle) * (Math.random()*4 + 10); this.vy = Math.cos(angle) * (Math.random()*4 + 10); this.ay = 10; this.boom = true; } } } function init() { new RainP('peepo', {}); new RainP('peepo', {}); new RainP('peepo', {}); new RainP('peepo', {}); new RainP('peepo', {}); new BounceGP('nod', {}); new BounceP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); new FireworkP('nod', {}); main(0); } function main(tframe) { window.requestAnimationFrame(main); var dt = (tframe - lastframe) / 1000; lastframe = tframe; ctx.clearRect(0, 0, canvas.width, canvas.height); if (!initialized) { if (preloaded) { setTimeout(function(){initialized = true;}, 1000); } } else { particles.forEach((particle) => { particle.update(dt); }); particles.forEach((particle) => { particle.draw(); }); } } init() const handleSocketMessage = (e)=>{ try { let rawMessage = e.data, message = JSON.parse(rawMessage); if(!message.hasOwnProperty('eventFamily') || message.eventFamily != 'emotewall' || !message.hasOwnProperty('eventType') || !message.hasOwnProperty('data')) return; console.log(message.eventType, message.data) if(message.eventType == 'message') { //.... } } catch (ex) { console.log(ex) } }; jQuery(async ()=>{ try{ socket.addFamilyHandler("overlay", handleSocketMessage); if(socket){ while(socket.getReadyState() === 0){ await new Promise(r => setTimeout(r, 500)); } } }catch(e) {console.log(e)} }) });