CocoClass = require 'lib/CocoClass' module.exports = class Dimmer extends CocoClass subscriptions: 'level-disable-controls': 'onDisableControls' 'level-enable-controls': 'onEnableControls' 'level-highlight-sprites': 'onHighlightSprites' 'sprite:speech-updated': 'onSpriteSpeechUpdated' 'surface:frame-changed': 'onFrameChanged' 'camera:zoom-updated': 'onZoomUpdated' constructor: (options) -> super() options ?= {} @camera = options.camera @layer = options.layer console.error @toString(), "needs a camera." unless @camera console.error @toString(), "needs a layer." unless @layer @build() @updateDimMask = _.throttle @updateDimMask, 10 @highlightedThangIDs = [] @sprites = {} toString: -> "" build: -> @dimLayer = new createjs.Container() @dimLayer.mouseEnabled = @dimLayer.mouseChildren = false @dimLayer.layerIndex = -10 @dimLayer.addChild @dimScreen = new createjs.Shape() @dimLayer.addChild @dimMask = new createjs.Shape() @dimScreen.graphics.beginFill("rgba(0,0,0,0.5)").rect 0, 0, @camera.canvasWidth, @camera.canvasHeight @dimMask.compositeOperation = 'destination-out' @dimLayer.cache 0, 0, @camera.canvasWidth, @camera.canvasHeight onDisableControls: (e) -> return if @on or (e.controls and not ('surface' in e.controls)) @dim() onEnableControls: (e) -> return if not @on or (e.controls and not ('surface' in e.controls)) @undim() onSpriteSpeechUpdated: (e) -> @updateDimMask() if @on onFrameChanged: (e) -> @updateDimMask() if @on onZoomUpdated: (e) -> @updateDimMask() if @on onHighlightSprites: (e) -> @highlightedThangIDs = e.thangIDs ? [] @updateDimMask() if @on setSprites: (@sprites) -> console.log dim: -> @on = true @layer.addChild @dimLayer @layer.updateLayerOrder() sprite.setDimmed true for thangID, sprite of @sprites @updateDimMask() undim: -> @on = false @layer.removeChild @dimLayer sprite.setDimmed false for thangID, sprite of @sprites updateDimMask: => @dimMask.graphics.clear() for thangID, sprite of @sprites continue unless (thangID in @highlightedThangIDs) or sprite.isTalking?() or sprite.thang?.id is 'My Wizard' sup = x: sprite.displayObject.x, y: sprite.displayObject.y cap = @camera.surfaceToCanvas sup r = 50 * @camera.zoom # TODO: find better way to get the radius based on the sprite's size @dimMask.graphics.beginRadialGradientFill(["rgba(0,0,0,1)", "rgba(0,0,0,0)"], [0.5, 1], cap.x, cap.y, 0, cap.x, cap.y, r).drawCircle(cap.x, cap.y, r) @dimLayer.updateCache 0, 0, @camera.canvasWidth, @camera.canvasHeight