evotars 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/app.d.ts +24 -0
  2. package/dist/config/constants.d.ts +1 -0
  3. package/dist/entities/EmoteSpitter.d.ts +15 -0
  4. package/dist/entities/Evotar.d.ts +78 -0
  5. package/dist/entities/Message.d.ts +27 -0
  6. package/dist/entities/Name.d.ts +14 -0
  7. package/dist/entities/SpriteContainer.d.ts +16 -0
  8. package/dist/entities/TrailEffect.d.ts +15 -0
  9. package/dist/evotars.d.ts +15 -0
  10. package/dist/evotars.js +705 -0
  11. package/dist/evotars.umd.cjs +1 -0
  12. package/dist/evotarsManager.d.ts +30 -0
  13. package/dist/helpers/timer.d.ts +14 -0
  14. package/dist/helpers/types.d.ts +10 -0
  15. package/dist/index.d.ts +1 -0
  16. package/dist/services/soundService.d.ts +14 -0
  17. package/dist/services/spriteService.d.ts +63 -0
  18. package/dist/types/dto/action.d.ts +56 -0
  19. package/{src/types/dto/chatter.ts → dist/types/dto/chatter.d.ts} +2 -2
  20. package/dist/types/dto/event.d.ts +9 -0
  21. package/dist/types/dto/message.d.ts +8 -0
  22. package/dist/types/dto/settings.d.ts +5 -0
  23. package/dist/types/dto/user.d.ts +12 -0
  24. package/package.json +30 -3
  25. package/.editorconfig +0 -13
  26. package/.prettierrc.json +0 -3
  27. package/index.html +0 -13
  28. package/index.ts +0 -1
  29. package/public/fonts/Rubik.ttf +0 -0
  30. package/public/sounds/jump.mp3 +0 -0
  31. package/public/sprites/agent/agent.json +0 -166
  32. package/public/sprites/agent/agent.png +0 -0
  33. package/public/sprites/cat/cat.json +0 -231
  34. package/public/sprites/cat/cat.png +0 -0
  35. package/public/sprites/dude/dude.json +0 -231
  36. package/public/sprites/dude/dude.png +0 -0
  37. package/public/sprites/girl/girl.json +0 -231
  38. package/public/sprites/girl/girl.png +0 -0
  39. package/public/sprites/nerd/nerd.json +0 -231
  40. package/public/sprites/nerd/nerd.png +0 -0
  41. package/public/sprites/senior/senior.json +0 -231
  42. package/public/sprites/senior/senior.png +0 -0
  43. package/public/sprites/sith/sith.json +0 -166
  44. package/public/sprites/sith/sith.png +0 -0
  45. package/src/app.ts +0 -63
  46. package/src/config/config.ts +0 -133
  47. package/src/config/constants.ts +0 -1
  48. package/src/dudes.ts +0 -71
  49. package/src/entities/Dude.ts +0 -453
  50. package/src/entities/DudeEmoteSpitter.ts +0 -60
  51. package/src/entities/DudeMessage.ts +0 -163
  52. package/src/entities/DudeName.ts +0 -39
  53. package/src/entities/DudeSpriteContainer.ts +0 -68
  54. package/src/entities/DudeTrailEffect.ts +0 -72
  55. package/src/helpers/timer.ts +0 -43
  56. package/src/helpers/types.ts +0 -11
  57. package/src/index.ts +0 -1
  58. package/src/main.ts +0 -75
  59. package/src/services/assetsLoader.ts +0 -27
  60. package/src/services/dudesManager.ts +0 -305
  61. package/src/services/soundService.ts +0 -28
  62. package/src/services/spriteProvider.ts +0 -93
  63. package/src/styles.css +0 -16
  64. package/src/types/dto/action.ts +0 -68
  65. package/src/types/dto/event.ts +0 -9
  66. package/src/types/dto/message.ts +0 -8
  67. package/src/types/dto/settings.ts +0 -5
  68. package/src/types/dto/user.ts +0 -13
  69. package/tsconfig.json +0 -23
  70. /package/{src/types/dto/index.ts → dist/types/dto/index.d.ts} +0 -0
  71. /package/{src/types/index.ts → dist/types/index.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ (function(l,d){typeof exports=="object"&&typeof module<"u"?d(exports,require("pixi.js"),require("tinycolor2"),require("@tweenjs/tween.js")):typeof define=="function"&&define.amd?define(["exports","pixi.js","tinycolor2","@tweenjs/tween.js"],d):(l=typeof globalThis<"u"?globalThis:l||self,d(l.evotars={},l.PIXI,l.tinycolor,l.TWEEN))})(this,function(l,d,x,T){"use strict";var B=Object.defineProperty;var H=(l,d,x)=>d in l?B(l,d,{enumerable:!0,configurable:!0,writable:!0,value:x}):l[d]=x;var s=(l,d,x)=>(H(l,typeof d!="symbol"?d+"":d,x),x);function E(r){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const e in r)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(r,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>r[e]})}}return t.default=r,Object.freeze(t)}const c=E(d),S=E(T),f=.02*1e3;class w{constructor(t=0,e){s(this,"isCompleted",!1);this.current=t,this.onComplete=e}tick(t=f){var e;this.isCompleted||(this.current-=t,this.current<0&&(this.isCompleted=!0,(e=this.onComplete)==null||e.call(this)))}}class z{constructor(){s(this,"timers",[])}add(t,e){this.timers.push(new w(t,e))}tick(t=f){const e=[];for(const i of this.timers)i.isCompleted||(i.tick(t),e.push(i));this.timers=e}}const A=new z,M=r=>r.name=="jump",R=r=>r.name=="color",k=r=>r.name=="grow",P=r=>r.name=="dash",F=r=>r.name=="sprite";class j{constructor(){s(this,"assets",{})}async initialize(t){this.assets=Object.fromEntries(Array.from(Object.entries(t??{})).map(([e,i])=>[e,new Audio(i.src)]))}play(t){const e=this.assets[t];e&&(e.volume=.2,e.pause(),e.currentTime=0,e.play())}}const D=new j;var p=(r=>(r.Idle="Idle",r.Jump="Jump",r.Fall="Fall",r.Land="Land",r.Run="Run",r.Die="Die",r))(p||{});class O{constructor(){s(this,"spriteLoaderFn");s(this,"sprites",{})}initialize(t){this.spriteLoaderFn=t}async getSpriteData(t){const e=await this.spriteLoaderFn(t);if(!e)return;if(this.sprites[t])return this.sprites[t];const i=await d.Assets.load(e.image),n=new d.Spritesheet({texture:i,data:e.sprite});return await n.parse(),this.sprites[t]={sheet:n,data:{...e.data,scale:e.data.scale??1}},this.sprites[t]}getAnimatedSprites(t){if(!t)throw Error("Sheet is not defined");if(!this.sprites[t])throw Error("Sprite is not loaded");const e=this.sprites[t].data,i=this.sprites[t].sheet,n={};for(const a of i.data.meta.frameTags??[]){if(!i.data.meta.layers)throw Error("Layers are not defined");const o={};for(const h of i.data.meta.layers){const u=[];for(let v=a.from;v<=a.to;v++){const X=v.toString(),I=e.name+"_"+h.name+"_"+X,Y=i.textures[I],Q=i.data.frames[I].duration;u.push({texture:Y,time:Q})}const C=new d.AnimatedSprite(u);C.texture.baseTexture.scaleMode=d.SCALE_MODES.NEAREST,o[h.name]=C}a.name&&(n[a.name]=o)}return n}}const b=new O;class V{constructor(){s(this,"container",new c.Container);s(this,"emotes",[]);s(this,"moveSpeed",50);s(this,"alphaSpeed",1);s(this,"scaleSpeed",.5);s(this,"timer")}add(t){const e=c.Sprite.from(t);e.anchor.set(.5,.5),e.scale.set(0,0),this.emotes.push(e)}update(t){var e;(e=this.timer)==null||e.tick(),(!this.timer||this.timer.isCompleted)&&this.emotes.length>0&&(this.timer=new w(2e3,()=>{const i=this.emotes.shift();i&&this.container.addChild(i)})),this.container.position.x=t.position.x??this.container.position.x,this.container.position.y=t.position.y??this.container.position.y;for(const i of this.container.children)i.position.y-=f*this.moveSpeed/1e3,i.scale.x+=f*this.scaleSpeed/1e3,i.scale.y+=f*this.scaleSpeed/1e3,i.scale.x>1&&(i.alpha-=f*this.alphaSpeed/1e3),i.alpha<=0&&this.container.removeChild(i)}}class _{constructor(t){s(this,"container",new c.Container);s(this,"animated",new c.Container);s(this,"text",new c.Text(void 0,{fontFamily:"Rubik",fontSize:20,fill:2236962,align:"left",breakWords:!0,wordWrap:!0,wordWrapWidth:200}));s(this,"padding",10);s(this,"borderRadius",10);s(this,"boxColor",15658734);s(this,"fadeShift",10);s(this,"isChecking",!0);s(this,"messageQueue",[]);s(this,"showTween");s(this,"hideTween");s(this,"timer");this.beforeShow=t,this.container.addChild(this.animated),this.text.anchor.set(.5,1),this.text.position.set(0,-this.padding)}trim(t){const e=c.TextMetrics.measureText(t.text,t.style);return e.lines.length>4?e.lines.slice(0,4).join(" ").slice(0,-3)+"...":t.text}update(t){var i,n,a,o,h;if((i=this.timer)==null||i.tick(),(n=this.showTween)==null||n.update(),(a=this.hideTween)==null||a.update(),this.isChecking&&this.messageQueue.length>0){this.isChecking=!1;const u=this.messageQueue.shift();u&&(this.beforeShow(),this.show(u))}this.container.position.x=t.position.x??this.container.position.x,this.container.position.y=t.position.y??this.container.position.y;const e=((o=this.showTween)==null?void 0:o.isPlaying())||((h=this.hideTween)==null?void 0:h.isPlaying());!this.isChecking&&!e&&this.timer&&(this.animated.position.y=Math.sin(this.timer.current*.0025)*4-2)}add(t){this.messageQueue.push(t)}drawBox(t){const e={x:t.x-this.padding-t.width*t.anchor.x,y:t.y-this.padding-t.height*t.anchor.y,w:t.width+this.padding*2,h:t.height+this.padding*2},i=new c.Graphics;return i.beginFill(this.boxColor),i.drawRoundedRect(e.x,e.y,e.w,e.h,this.borderRadius),i.drawPolygon({x:e.x+e.w/2-10,y:e.y+e.h},{x:e.x+e.w/2+10,y:e.y+e.h},{x:e.x+e.w/2,y:e.y+e.h+10-4}),i.endFill(),i}show(t){this.text.text=t,this.text.text=this.trim(this.text),this.animated.alpha=0,this.animated.position.y=this.fadeShift;const e=this.drawBox(this.text);this.animated.removeChildren(),this.animated.addChild(e,this.text);const i={alpha:1,y:this.animated.y-this.fadeShift},n={alpha:0,y:this.animated.y+this.fadeShift};this.hideTween=new T.Tween(this.animated).to(n,500).onComplete(()=>{this.isChecking=!0}),this.showTween=new T.Tween(this.animated).to(i,500).onComplete(()=>{this.timer=new w(1e4,()=>{var a;(a=this.hideTween)==null||a.start()})}),this.showTween.start()}}class L{constructor(){s(this,"text",new c.Text(void 0,{fontFamily:"Rubik",fontSize:18,fill:16777215,align:"center",lineJoin:"round",strokeThickness:4,stroke:"black"}));s(this,"rect",()=>({x:this.text.x,y:this.text.y,w:this.text.width,h:this.text.height}));this.text.anchor.set(.5,1),this.text.zIndex=100}update(t){this.text.text=t.name??"",this.text.visible=t.isVisible,this.text.position.x=t.position.x??this.text.position.x,this.text.position.y=t.position.y??this.text.position.y}}class J{constructor(t){s(this,"container",new c.Container);s(this,"sprites");this.sprites=t,this.container.sortableChildren=!0;let e=0;for(const i in this.sprites){const n=this.sprites[i];this.container.addChild(n),n.zIndex=++e,n.anchor.set(.5,0),n.autoUpdate=!1,n.play()}}update(t){for(const e in this.sprites){const i=this.sprites[e];if(t.play&&i.update(f*.06),t.color){for(const n in t.color)if(n==e){const a=t.color[n];a&&(i.alpha=a.alpha,i.tint=a)}}t.scale.x&&(i.animationSpeed=4/Math.abs(t.scale.x))}this.container.scale.set(t.scale.x,t.scale.y)}}class W{constructor(){s(this,"container",new c.Container);s(this,"timer");s(this,"sprite");s(this,"opacityStep",.1);s(this,"shadowStep",50);m.stage.addChild(this.container)}setSprite(t){this.sprite=t}update(t){for(const e of this.container.children)e.alpha>0&&(e.alpha=e.alpha-this.opacityStep);if(this.timer&&!this.timer.isCompleted)this.timer.tick();else if(t.play){this.timer=new w(this.shadowStep);const e=new c.Container;if(this.sprite)for(const i in this.sprite.sprites){const n=this.sprite.sprites[i],a=n.texture.clone(),o=new c.Sprite(a);o.anchor.set(.5,0),o.alpha=n.alpha,o.tint=n.tint,e.addChild(o),e.scale.set(this.sprite.container.scale.x,this.sprite.container.scale.y),e.pivot.set(this.sprite.container.pivot.x,this.sprite.container.pivot.y);const h=this.sprite.container.getGlobalPosition();e.position.set(h.x,h.y)}this.container.addChild(e)}}}class g{constructor(){s(this,"container",new c.Container);s(this,"userState",{});s(this,"state",{name:"",sprite:"",color:new c.Color("#969696"),direction:1,scale:1,isAnonymous:!1,zIndex:0});s(this,"animationState",p.Idle);s(this,"sprite");s(this,"spriteData",{name:"evotar",collider:{x:0,y:0,w:0,h:0},size:{w:0,h:0},scale:1,flip:!1,colored:[]});s(this,"animatedSprites");s(this,"trail",new W);s(this,"name",new L);s(this,"message",new _(()=>{this.state.zIndex=y.zIndexEvotarMax(this.container.zIndex)}));s(this,"emoteSpitter",new V);s(this,"velocity",{x:0,y:0});s(this,"runSpeed",.05);s(this,"gravity",.2);s(this,"dashAcc",3);s(this,"isJumping",!1);s(this,"isDashing",!1);s(this,"isDespawned",!1);s(this,"landTimer");s(this,"stateTimer");s(this,"scaleTimer");s(this,"spawnTween");s(this,"fadeTween");s(this,"scaleTween");this.container.addChild(this.name.text),this.container.addChild(this.emoteSpitter.container),this.container.addChild(this.message.container),this.container.sortableChildren=!0}spawn(t={isFalling:!1}){const e=this.spriteData.collider,i=-(e.y+e.h-this.spriteData.size.h/2),n=t.isFalling?i:m.renderer.height,a=this.spriteData.size.w*this.state.scale*this.spriteData.scale,o=t.positionX!=null?t.positionX*m.renderer.width:Math.random()*(m.renderer.width-a)+a/2,h=n*this.state.scale*this.spriteData.scale;if(this.container.x=o,this.container.y=h,this.state.direction=Math.random()>.5?1:-1,!t.isFalling){const u=y.zIndexEvotarMin(this.container.zIndex);this.state.zIndex=u,this.container.alpha=0,this.spawnTween=new S.Tween(this.container).to({alpha:1},500).onComplete(t.onComplete).start()}this.stateTimer=new w(5e3,()=>{this.isJumping||this.setAnimationState(p.Run)})}despawn(t={}){this.fadeTween&&this.fadeTween.isPlaying()||(this.fadeTween=new S.Tween(this.container).to({alpha:0},1e3).onComplete(()=>{this.isDespawned=!0,t.onComplete&&t.onComplete()}).start())}scale(t){this.scaleTween&&this.scaleTween.isPlaying()||this.scaleTimer&&!this.scaleTimer.isCompleted||(this.scaleTween=new S.Tween(this).to({state:{scale:t.value??2}},2e3).onComplete(()=>{this.scaleTimer=new w((t.duration??10)*1e3,()=>{this.scaleTween=new S.Tween(this).to({state:{scale:1}},2e3).start()})}).start())}jump(t){this.isDespawned||this.isJumping||(this.isJumping=!0,this.velocity.x=this.state.direction*(t.velocityX??3.5),this.velocity.y=t.velocityY??-8,this.setAnimationState(p.Jump),D.play("jump"))}dash(t){this.isDespawned||this.isDashing||(this.isDashing=!0,this.velocity.x=this.state.direction*(t.force??14))}async setSprite(t){if(t&&t!=this.state.sprite){const e=await b.getSpriteData(t);if(!e)return;this.spriteData=e.data,this.animatedSprites=b.getAnimatedSprites(t),this.setAnimationState(this.animationState,!0)}}async setProps(t){t.sprite&&await this.setSprite(t.sprite),this.state={...this.state,...t}}setUserProps(t){this.userState={...this.userState,...t}}move(){var i;const t=this.spriteData.collider,e={x:this.container.position.x,y:this.container.position.y};if(this.isDashing){const n=Math.sign(this.velocity.x);this.velocity.x=this.velocity.x-n*this.dashAcc/Math.abs(this.velocity.x),n!=Math.sign(this.velocity.x)?(this.isDashing=!1,this.velocity.x=0):e.x+=this.velocity.x}else{if((i=this.stateTimer)!=null&&i.isCompleted&&(this.stateTimer=new w(Math.random()*5e3,()=>{this.animationState==p.Idle?this.setAnimationState(p.Run):this.animationState==p.Run&&this.setAnimationState(p.Idle)})),this.animationState==p.Run){const n=this.runSpeed*this.state.direction;this.velocity.x=n*f}this.velocity.y=this.velocity.y+this.gravity,e.x+=this.velocity.x,e.y+=this.velocity.y,this.isOnGround(e.y)&&(this.velocity.y=0,this.velocity.x=0,e.y=m.renderer.height,this.animationState==p.Fall&&(this.setAnimationState(p.Land),this.landTimer=new w(200,()=>{this.setAnimationState(p.Idle),this.isJumping=!1}))),this.velocity.y>0&&this.setAnimationState(p.Fall)}if(this.animationState!=p.Idle||this.isDashing){const n=t.w/2*this.state.scale*this.spriteData.scale,a=this.container.x-n<0,o=this.container.x+n>m.renderer.width;(a||o)&&(this.state.direction=-this.state.direction,this.velocity.x=-this.velocity.x,a&&(e.x=n),o&&(e.x=m.renderer.width-n))}this.container.position.set(e.x,e.y)}update(){var e,i,n,a,o,h;if(this.isDespawned)return;(e=this.landTimer)==null||e.tick(),(i=this.stateTimer)==null||i.tick(),(n=this.scaleTimer)==null||n.tick(),(a=this.fadeTween)==null||a.update(),(o=this.spawnTween)==null||o.update(),(h=this.scaleTween)==null||h.update(),this.container.zIndex=this.state.zIndex;const t=this.spriteData.collider;if(this.name.update({name:this.state.name,isVisible:!this.state.isAnonymous,position:{y:-t.h*this.state.scale*this.spriteData.scale}}),this.message.update({position:{y:this.name.text.position.y-this.name.text.height-6}}),this.emoteSpitter.update({position:{y:this.message.container.position.y-this.message.container.height}}),this.move(),this.sprite){const u=Object.fromEntries(this.spriteData.colored.map(v=>[v,this.userState.color?this.userState.color:this.state.color])),C=this.spriteData.flip?this.state.direction:1;this.sprite.update({color:u,scale:{x:C*this.state.scale*this.spriteData.scale,y:this.state.scale*this.spriteData.scale},play:!this.isDashing})}this.trail.update({play:this.isDashing})}isOnGround(t){return t>m.renderer.height}addMessage(t){var e;this.message.add(t),this.state.isAnonymous=!1,(e=this.fadeTween)==null||e.stop(),this.fadeTween=void 0,this.container.alpha=1}spitEmotes(t){for(const e of t)this.emoteSpitter.add(e)}async setAnimationState(t,e=!1){if(this.animationState==t&&!e||!this.animatedSprites)return;this.animationState=t,this.sprite&&this.container.removeChild(this.sprite.container);const i=this.animatedSprites[this.animationState]??this.animatedSprites[p.Idle];this.sprite=new J(i),this.trail.setSprite(this.sprite),this.sprite.container.pivot.set(0,this.spriteData.collider.y+this.spriteData.collider.h),this.container.addChild(this.sprite.container)}}const U=1e3*60*5;class N{constructor(){s(this,"viewers",{});s(this,"raiders",[]);s(this,"lastEvotarActivity",{});s(this,"subscriptions",[]);s(this,"hasActivity",t=>!!this.lastEvotarActivity[t])}subscribe(t){this.subscriptions.push(t)}update(){for(const t in this.viewers){const e=this.viewers[t];e&&e.update()}for(const t of this.raiders)t.update()}processRaid(t){if(!m.settings.fallingRaiders)return;const e=1/t.viewers*5e3;for(let o=0;o<t.viewers;o++){const h=new g;h.setProps({isAnonymous:!0,zIndex:-1,sprite:"agent",color:new c.Color(t.broadcaster.info.color)}),A.add(e*o,()=>{this.addRaider(h),h.spawn({isFalling:!0})}),A.add(o*e+3e4,()=>{h.despawn({onComplete:()=>{this.deleteRaider(h)}})})}const i=this.viewers[t.broadcaster.id],n={...this.prepareEvotarProps(t.broadcaster.info.displayName,t.broadcaster.info.color),scale:8},a=()=>{const o=new g;o.setProps(n),this.addViewer(t.broadcaster.id,o),o.spawn({isFalling:!0,positionX:.5})};this.lastEvotarActivity[t.broadcaster.id]=performance.now(),i?i.despawn({onComplete:()=>{a()}}):a()}async processChatters(t){for(const e in this.viewers){const i=this.lastEvotarActivity[e],n=!!i&&performance.now()-i<U;if(t.every(a=>a.userId!=e)&&!n){const a=this.viewers[e];a&&a.despawn({onComplete:()=>{this.deleteViewer(e,a)}})}}if(m.settings.showAnonymousEvotars){for(const e of t)if(!this.viewers[e.userId]){const n={name:e.name,isAnonymous:!this.hasActivity(e.userId)},a=new g;await a.setProps(n),a.spawn(),this.addViewer(e.userId,a)}}}doAction(t,e){if(M(t)&&e.jump({velocityX:t.data.velocityX,velocityY:t.data.velocityY,cooldown:t.cooldown}),P(t)&&e.dash({force:t.data.force,cooldown:t.cooldown}),R(t)){const i=x(t.data.color);i&&i.isValid()&&e.setUserProps({color:new c.Color(t.data.color)})}k(t)&&e.scale({value:t.data.scale,duration:t.data.duration,cooldown:t.cooldown}),F(t)&&e.setSprite(t.data.sprite)}prepareEvotarProps(t,e,i){const n={name:t,isAnonymous:!1};if(i&&(n.sprite=i),e)try{n.color=new c.Color(e)}catch{}return n}async processAction(t){const e=this.viewers[t.userId],i=this.prepareEvotarProps(t.info.displayName,t.info.color,t.info.sprite);if(e)await e.setProps(i),this.doAction(t,e);else{const n=new g;await n.setProps(i),n.spawn({onComplete:()=>{const a=this.viewers[t.userId];a&&this.doAction(t,a)}}),this.addViewer(t.userId,n)}}async processMessage(t){const e=this.prepareEvotarProps(t.info.displayName,t.info.color,t.info.sprite);let i=this.viewers[t.userId];if(i)i.setProps(e);else{const n=m.settings.fallingEvotars?!this.hasActivity(t.userId):!1;i=new g,await i.setProps(e),i.spawn({isFalling:n}),this.addViewer(t.userId,i)}this.lastEvotarActivity[t.userId]=performance.now(),t.message&&i.addMessage(t.message),t.emotes.length>0&&i.spitEmotes(t.emotes)}addViewer(t,e){this.subscriptions.forEach(i=>i.onAdd(e)),this.viewers[t]=e}deleteViewer(t,e){this.subscriptions.forEach(i=>i.onDelete(e)),delete this.viewers[t]}addRaider(t){this.subscriptions.forEach(e=>e.onAdd(t)),this.raiders.push(t)}deleteRaider(t){this.subscriptions.forEach(e=>e.onDelete(t)),this.raiders=this.raiders.filter(e=>e!=t)}zIndexEvotarMax(t){return Object.values(this.viewers).reduce((e,i)=>i&&e<=i.container.zIndex?i.container.zIndex+1:e,t)}zIndexEvotarMin(t){return Object.values(this.viewers).reduce((e,i)=>i&&e>=i.container.zIndex?i.container.zIndex-1:e,t)}}const y=new N;class q{constructor(){s(this,"stage",new c.Container);s(this,"evotars",{});s(this,"chatterIds",[]);s(this,"settings",{});s(this,"renderer")}async initialize(t,e){b.initialize(e.spriteLoaderFn),D.initialize(e.sounds),this.renderer=new c.Renderer({width:t.clientWidth,height:t.clientHeight,backgroundAlpha:0}),t.appendChild(this.renderer.view),window.onresize=()=>{this.renderer.resize(t.clientWidth,t.clientHeight)},this.stage.sortableChildren=!0,y.subscribe({onAdd:i=>this.stage.addChild(i.container),onDelete:i=>{this.stage.removeChild(i.container),this.stage.removeChild(i.trail.container)}})}updateSettings(t){this.settings=t}update(){A.tick(),y.update(),this.renderer.render(this.stage)}}const m=new q;class G{constructor(t,e){s(this,"isRendered",!1);s(this,"processMessage",t=>y.processMessage(t));s(this,"processAction",t=>y.processAction(t));s(this,"processChatters",t=>y.processChatters(t));s(this,"processRaid",t=>y.processRaid(t));this.root=t,this.options=e}updateSettings(t){m.updateSettings(t)}async run(){if(this.isRendered)return;this.isRendered=!0,await(async()=>{await m.initialize(this.root,this.options),performance.now();let e=-1;const n=1e3/60;requestAnimationFrame(a);function a(o=performance.now()){const h=o-e|0;h>n&&(e=o-h%n,m.update()),requestAnimationFrame(a)}})()}}l.Evotars=G,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,30 @@
1
+ import { Evotar } from './entities/Evotar';
2
+ import { MessageEntity, RaidData, TwitchChatterEntity, UserActionEntity } from './types';
3
+
4
+ type EvotarsManagerSubscription = {
5
+ onAdd: (evotar: Evotar) => void;
6
+ onDelete: (evotar: Evotar) => void;
7
+ };
8
+ declare class EvotarsManager {
9
+ private viewers;
10
+ private raiders;
11
+ private lastEvotarActivity;
12
+ private subscriptions;
13
+ subscribe(subscription: EvotarsManagerSubscription): void;
14
+ update(): void;
15
+ processRaid(data: RaidData): void;
16
+ processChatters(data: TwitchChatterEntity[]): Promise<void>;
17
+ private hasActivity;
18
+ doAction(action: UserActionEntity, evotar: Evotar): void;
19
+ private prepareEvotarProps;
20
+ processAction(action: UserActionEntity): Promise<void>;
21
+ processMessage(data: MessageEntity): Promise<void>;
22
+ addViewer(id: string, evotar: Evotar): void;
23
+ deleteViewer(id: string, evotar: Evotar): void;
24
+ addRaider(evotar: Evotar): void;
25
+ deleteRaider(evotar: Evotar): void;
26
+ zIndexEvotarMax(from: number): number;
27
+ zIndexEvotarMin(from: number): number;
28
+ }
29
+ export declare const evotarsManager: EvotarsManager;
30
+ export {};
@@ -0,0 +1,14 @@
1
+ export declare class Timer {
2
+ current: number;
3
+ private onComplete?;
4
+ isCompleted: boolean;
5
+ constructor(current?: number, onComplete?: (() => void) | undefined);
6
+ tick(delta?: number): void;
7
+ }
8
+ declare class Timers {
9
+ private timers;
10
+ add(current?: number, onComplete?: () => void): void;
11
+ tick(delta?: number): void;
12
+ }
13
+ export declare const timers: Timers;
14
+ export {};
@@ -0,0 +1,10 @@
1
+ export type Point = {
2
+ x?: number;
3
+ y?: number;
4
+ };
5
+ export type Rect = {
6
+ x: number;
7
+ y: number;
8
+ w: number;
9
+ h: number;
10
+ };
@@ -0,0 +1 @@
1
+ export * from './evotars';
@@ -0,0 +1,14 @@
1
+ export type SoundOptions = {
2
+ jump?: {
3
+ src: string;
4
+ };
5
+ };
6
+ declare class SoundService {
7
+ assets: {
8
+ [key: string]: HTMLAudioElement;
9
+ };
10
+ initialize(options?: SoundOptions): Promise<void>;
11
+ play(name: string): void;
12
+ }
13
+ export declare const soundService: SoundService;
14
+ export {};
@@ -0,0 +1,63 @@
1
+ import { AnimatedSprite, ISpritesheetData, ISpritesheetFrameData, Spritesheet } from 'pixi.js';
2
+
3
+ export type EvotarSpriteData = {
4
+ name: string;
5
+ collider: Collider;
6
+ size: SpriteSize;
7
+ scale: number;
8
+ flip: boolean;
9
+ colored: string[];
10
+ };
11
+ export type SpriteLoaderFn = (name: string) => Promise<{
12
+ sprite: SpritesheetData;
13
+ data: EvotarSpriteData;
14
+ image: string;
15
+ } | undefined>;
16
+ export type Collider = {
17
+ x: number;
18
+ y: number;
19
+ w: number;
20
+ h: number;
21
+ };
22
+ export interface SpritesheetFrameData extends ISpritesheetFrameData {
23
+ duration: number;
24
+ }
25
+ export interface SpritesheetData extends ISpritesheetData {
26
+ frames: Record<string, SpritesheetFrameData>;
27
+ }
28
+ export type EvotarLayerSprites = {
29
+ [layer in string]: AnimatedSprite;
30
+ };
31
+ export type EvotarAnimatedSprites = {
32
+ [tag in string]: EvotarLayerSprites;
33
+ };
34
+ export declare enum EvotarSpriteTags {
35
+ Idle = "Idle",
36
+ Jump = "Jump",
37
+ Fall = "Fall",
38
+ Land = "Land",
39
+ Run = "Run",
40
+ Die = "Die"
41
+ }
42
+ export type FrameTag = {
43
+ from: number;
44
+ name: string;
45
+ to: number;
46
+ direction: string;
47
+ };
48
+ export type SpriteSize = {
49
+ w: number;
50
+ h: number;
51
+ };
52
+ export type SpriteData = {
53
+ sheet: Spritesheet<SpritesheetData>;
54
+ data: EvotarSpriteData;
55
+ };
56
+ export declare class SpriteService {
57
+ private spriteLoaderFn;
58
+ private sprites;
59
+ initialize(spriteLoaderFn: SpriteLoaderFn): void;
60
+ getSpriteData(name: string): Promise<SpriteData | undefined>;
61
+ getAnimatedSprites(name: string): EvotarAnimatedSprites;
62
+ }
63
+ export declare const spriteService: SpriteService;
@@ -0,0 +1,56 @@
1
+ import { UserInfo } from './user';
2
+
3
+ export type ActionData = Record<string, string | number | undefined>;
4
+ export type ActionableData = {
5
+ arguments: string[];
6
+ action: ActionData;
7
+ };
8
+ export type ActionEntity = {
9
+ id: number;
10
+ name: string;
11
+ title: string;
12
+ description: string;
13
+ data: ActionData;
14
+ };
15
+ export type UserActionEntity = {
16
+ userId: string;
17
+ cooldown: number;
18
+ info: UserInfo;
19
+ } & ActionEntity;
20
+ export type JumpUserActionEntity = {
21
+ name: 'jump';
22
+ data: {
23
+ velocityX: number;
24
+ velocityY: number;
25
+ };
26
+ } & UserActionEntity;
27
+ export type ColorUserActionEntity = {
28
+ name: 'color';
29
+ data: {
30
+ color: string;
31
+ };
32
+ } & UserActionEntity;
33
+ export type GrowUserActionEntity = {
34
+ name: 'grow';
35
+ data: {
36
+ duration: number;
37
+ scale: number;
38
+ };
39
+ } & UserActionEntity;
40
+ export type DashUserActionEntity = {
41
+ name: 'dash';
42
+ data: {
43
+ force: number;
44
+ };
45
+ } & UserActionEntity;
46
+ export type SpriteUserActionEntity = {
47
+ name: 'sprite';
48
+ data: {
49
+ sprite: string;
50
+ };
51
+ } & UserActionEntity;
52
+ export declare const isJumpUserActionEntity: (entity: ActionEntity) => entity is JumpUserActionEntity;
53
+ export declare const isColorUserActionEntity: (entity: ActionEntity) => entity is ColorUserActionEntity;
54
+ export declare const isGrowUserActionEntity: (entity: ActionEntity) => entity is GrowUserActionEntity;
55
+ export declare const isDashUserActionEntity: (entity: ActionEntity) => entity is DashUserActionEntity;
56
+ export declare const isSpriteUserActionEntity: (entity: ActionEntity) => entity is SpriteUserActionEntity;
@@ -1,4 +1,4 @@
1
1
  export type TwitchChatterEntity = {
2
- userId: string;
3
- name: string;
2
+ userId: string;
3
+ name: string;
4
4
  };
@@ -0,0 +1,9 @@
1
+ import { UserInfo } from './user';
2
+
3
+ export type RaidData = {
4
+ broadcaster: {
5
+ id: string;
6
+ info: UserInfo;
7
+ };
8
+ viewers: number;
9
+ };
@@ -0,0 +1,8 @@
1
+ import { UserInfo } from './user';
2
+
3
+ export type MessageEntity = {
4
+ userId: string;
5
+ message: string;
6
+ emotes: string[];
7
+ info: UserInfo;
8
+ };
@@ -0,0 +1,5 @@
1
+ export type SettingsEntity = {
2
+ showAnonymousEvotars?: boolean;
3
+ fallingEvotars?: boolean;
4
+ fallingRaiders?: boolean;
5
+ };
@@ -0,0 +1,12 @@
1
+ export type UserEntity = {
2
+ userId: number;
3
+ guid: string;
4
+ displayName: string;
5
+ profileImageUrl: string;
6
+ previewUrl: string;
7
+ };
8
+ export type UserInfo = {
9
+ displayName: string;
10
+ color?: string;
11
+ sprite?: string;
12
+ };
package/package.json CHANGED
@@ -1,20 +1,47 @@
1
1
  {
2
+ "version": "0.0.4",
2
3
  "name": "evotars",
3
- "version": "0.0.2",
4
+ "description": "Show animated characters on stream",
5
+ "author": "Mikhail Morozov",
6
+ "url": "https://github.com/inferst/evotars",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/inferst/evotars"
10
+ },
11
+ "keywords": [
12
+ "stream",
13
+ "avatars",
14
+ "chatters"
15
+ ],
4
16
  "scripts": {
5
17
  "dev": "vite",
6
18
  "build": "tsc && vite build",
7
19
  "preview": "vite preview",
8
20
  "lint": "tsc --noEmit"
9
21
  },
22
+ "files": [
23
+ "dist",
24
+ "LICENSE",
25
+ "README.md"
26
+ ],
27
+ "main": "./dist/evotars.umd.cjs",
28
+ "exports": {
29
+ ".": {
30
+ "import": "./dist/evotars.js",
31
+ "require": "./dist/evotars.umd.cjs"
32
+ }
33
+ },
34
+ "type": "module",
35
+ "types": "./dist/index.d.ts",
10
36
  "devDependencies": {
11
37
  "@types/tinycolor2": "^1.4.6",
12
38
  "typescript": "^5.0.2",
13
- "vite": "^5.2.9"
39
+ "vite": "^5.2.9",
40
+ "vite-plugin-dts": "^3.8.3"
14
41
  },
15
42
  "dependencies": {
16
43
  "@tweenjs/tween.js": "^23.1.1",
17
44
  "pixi.js": "^7.3.1",
18
- "zod": "^3.22.5"
45
+ "tinycolor2": "^1.6.0"
19
46
  }
20
47
  }
package/.editorconfig DELETED
@@ -1,13 +0,0 @@
1
- # Editor configuration, see http://editorconfig.org
2
- root = true
3
-
4
- [*]
5
- charset = utf-8
6
- indent_style = space
7
- indent_size = 2
8
- insert_final_newline = true
9
- trim_trailing_whitespace = true
10
-
11
- [*.md]
12
- max_line_length = off
13
- trim_trailing_whitespace = false
package/.prettierrc.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "singleQuote": true
3
- }
package/index.html DELETED
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Evotars</title>
7
- </head>
8
- <body>
9
- <div id="root"></div>
10
- <script type="module" src="/src/main.ts"></script>
11
- </body>
12
- </html>
13
-
package/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './src/';
Binary file
Binary file
@@ -1,166 +0,0 @@
1
- { "frames": {
2
- "agent_Body_0": {
3
- "frame": { "x": 0, "y": 0, "w": 32, "h": 32 },
4
- "rotated": false,
5
- "trimmed": false,
6
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
7
- "sourceSize": { "w": 32, "h": 32 },
8
- "duration": 300
9
- },
10
- "agent_Body_1": {
11
- "frame": { "x": 32, "y": 0, "w": 32, "h": 32 },
12
- "rotated": false,
13
- "trimmed": false,
14
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
15
- "sourceSize": { "w": 32, "h": 32 },
16
- "duration": 300
17
- },
18
- "agent_Body_2": {
19
- "frame": { "x": 64, "y": 0, "w": 32, "h": 32 },
20
- "rotated": false,
21
- "trimmed": false,
22
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
23
- "sourceSize": { "w": 32, "h": 32 },
24
- "duration": 300
25
- },
26
- "agent_Body_3": {
27
- "frame": { "x": 96, "y": 0, "w": 32, "h": 32 },
28
- "rotated": false,
29
- "trimmed": false,
30
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
31
- "sourceSize": { "w": 32, "h": 32 },
32
- "duration": 100
33
- },
34
- "agent_Body_4": {
35
- "frame": { "x": 128, "y": 0, "w": 32, "h": 32 },
36
- "rotated": false,
37
- "trimmed": false,
38
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
39
- "sourceSize": { "w": 32, "h": 32 },
40
- "duration": 100
41
- },
42
- "agent_Body_5": {
43
- "frame": { "x": 160, "y": 0, "w": 32, "h": 32 },
44
- "rotated": false,
45
- "trimmed": false,
46
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
47
- "sourceSize": { "w": 32, "h": 32 },
48
- "duration": 100
49
- },
50
- "agent_Body_6": {
51
- "frame": { "x": 192, "y": 0, "w": 32, "h": 32 },
52
- "rotated": false,
53
- "trimmed": false,
54
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
55
- "sourceSize": { "w": 32, "h": 32 },
56
- "duration": 100
57
- },
58
- "agent_Body_7": {
59
- "frame": { "x": 224, "y": 0, "w": 32, "h": 32 },
60
- "rotated": false,
61
- "trimmed": false,
62
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
63
- "sourceSize": { "w": 32, "h": 32 },
64
- "duration": 100
65
- },
66
- "agent_Body_8": {
67
- "frame": { "x": 256, "y": 0, "w": 32, "h": 32 },
68
- "rotated": false,
69
- "trimmed": false,
70
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
71
- "sourceSize": { "w": 32, "h": 32 },
72
- "duration": 100
73
- },
74
- "agent_Eyes_0": {
75
- "frame": { "x": 0, "y": 32, "w": 32, "h": 32 },
76
- "rotated": false,
77
- "trimmed": false,
78
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
79
- "sourceSize": { "w": 32, "h": 32 },
80
- "duration": 300
81
- },
82
- "agent_Eyes_1": {
83
- "frame": { "x": 32, "y": 32, "w": 32, "h": 32 },
84
- "rotated": false,
85
- "trimmed": false,
86
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
87
- "sourceSize": { "w": 32, "h": 32 },
88
- "duration": 300
89
- },
90
- "agent_Eyes_2": {
91
- "frame": { "x": 64, "y": 32, "w": 32, "h": 32 },
92
- "rotated": false,
93
- "trimmed": false,
94
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
95
- "sourceSize": { "w": 32, "h": 32 },
96
- "duration": 300
97
- },
98
- "agent_Eyes_3": {
99
- "frame": { "x": 96, "y": 32, "w": 32, "h": 32 },
100
- "rotated": false,
101
- "trimmed": false,
102
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
103
- "sourceSize": { "w": 32, "h": 32 },
104
- "duration": 100
105
- },
106
- "agent_Eyes_4": {
107
- "frame": { "x": 128, "y": 32, "w": 32, "h": 32 },
108
- "rotated": false,
109
- "trimmed": false,
110
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
111
- "sourceSize": { "w": 32, "h": 32 },
112
- "duration": 100
113
- },
114
- "agent_Eyes_5": {
115
- "frame": { "x": 160, "y": 32, "w": 32, "h": 32 },
116
- "rotated": false,
117
- "trimmed": false,
118
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
119
- "sourceSize": { "w": 32, "h": 32 },
120
- "duration": 100
121
- },
122
- "agent_Eyes_6": {
123
- "frame": { "x": 192, "y": 32, "w": 32, "h": 32 },
124
- "rotated": false,
125
- "trimmed": false,
126
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
127
- "sourceSize": { "w": 32, "h": 32 },
128
- "duration": 100
129
- },
130
- "agent_Eyes_7": {
131
- "frame": { "x": 224, "y": 32, "w": 32, "h": 32 },
132
- "rotated": false,
133
- "trimmed": false,
134
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
135
- "sourceSize": { "w": 32, "h": 32 },
136
- "duration": 100
137
- },
138
- "agent_Eyes_8": {
139
- "frame": { "x": 256, "y": 32, "w": 32, "h": 32 },
140
- "rotated": false,
141
- "trimmed": false,
142
- "spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
143
- "sourceSize": { "w": 32, "h": 32 },
144
- "duration": 100
145
- }
146
- },
147
- "meta": {
148
- "app": "https://www.aseprite.org/",
149
- "version": "1.x-dev",
150
- "image": "agent.png",
151
- "format": "RGBA8888",
152
- "size": { "w": 288, "h": 64 },
153
- "scale": "1",
154
- "frameTags": [
155
- { "name": "Idle", "from": 0, "to": 2, "direction": "forward", "color": "#000000ff" },
156
- { "name": "Jump", "from": 3, "to": 3, "direction": "forward", "color": "#000000ff" },
157
- { "name": "Fall", "from": 4, "to": 4, "direction": "forward", "color": "#000000ff" },
158
- { "name": "Land", "from": 5, "to": 5, "direction": "forward", "color": "#000000ff" },
159
- { "name": "Run", "from": 6, "to": 8, "direction": "forward", "color": "#000000ff" }
160
- ],
161
- "layers": [
162
- { "name": "Body", "opacity": 255, "blendMode": "normal" },
163
- { "name": "Eyes", "opacity": 255, "blendMode": "normal" }
164
- ]
165
- }
166
- }
Binary file