anchor.diff:  				canvas.style.transform = "translateX(${left}px) translateY(${top}px) scale3d(-1,1,1)";
   		}
   
  -		if(intersect(camera.visibleRect,entityRect))
  +		if(intersect(camera.visibleRect, entityRect))
   			animation.updateSourceRect(dt);
   	}
   
  -	render()
  -	{
  -		if(ready && animation.dirty)
  -		{
  -			if(!firstRender)
  -			{
  +	render() {
  +		if(ready && (animation.dirty || dirty)) {
  +			if(!firstRender) {
   				//if the entity is not visible, don't render it
  -				if(!intersect(camera.visibleRect,entityRect))
  +				if(!intersect(camera.visibleRect, entityRect))
   					return;
   			}
   
  
positive.code: 			//source: http://jsperf.com/ctx-clearrect-vs-canvas-width-canvas-width/6
  			canvas.context2D.clearRect(0, 0, animation.width, animation.height);
  
  			if(glow)
              {
              	canvas.context2D.shadowColor = "rgba(0, 0, 255, 0.2)";
               	canvas.context2D.shadowBlur = 20;
               	canvas.context2D.shadowOffsetX = 0;
               	canvas.context2D.shadowOffsetY = -5;
              }
              else
              {
              	canvas.context2D.shadowColor = "0";
              	canvas.context2D.shadowBlur = 0;
              	canvas.context2D.shadowOffsetX = 0;
              	canvas.context2D.shadowOffsetY = 0;
              }
  
      		canvas.context2D.drawImageToRect(animation.spritesheet, destRect, sourceRect: animation.sourceRect);
      		animation.dirty = false;
  		}
  	}
  }
negative.code: 			id = map['id'];
  
  			canvas = new CanvasElement();
  			canvas.id = map["id"];
  			canvas.attributes['actions'] = JSON.encode(map['actions']);
  			canvas.attributes['type'] = map['type'];
  			canvas.classes.add("npc");
  			canvas.classes.add('entity');
  			canvas.width = map["width"];
  			canvas.height = map["height"];
  			canvas.style.position = "absolute";
  			canvas.attributes['translatex'] = left.toString();
  			canvas.attributes['translatey'] = top.toString();
  			canvas.attributes['width'] = canvas.width.toString();
  			canvas.attributes['height'] = canvas.height.toString();
  			view.playerHolder.append(canvas);
  			ready = true;
  			_animationLoaded.add(true);
  		});
  	}
  
  	update(double dt) {
  		if(!ready)
  			return;
  
  		super.update(dt);
  
  		RegExp movementWords = new RegExp(r'(walk|fly|move)');
  		if(firstRender || animation.url.contains(movementWords)) {
  			if(facingRight)
  				left += speed * dt;
  			else
  				left -= speed * dt;
  
  			if(left < 0)
  				left = 0.0;
  			if(left > currentStreet.bounds.width - canvas.width)
  				left = (currentStreet.bounds.width - canvas.width).toDouble();
  
  			canvas.attributes['translatex'] = left.toString();
  			canvas.attributes['translatey'] = top.toString();
  
  			if(facingRight)
  				canvas.style.transform = "translateX(${left}px) translateY(${top}px) scale3d(1,1,1)";
  