private void OnDraw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
        {
            if (Map == null)
                return;

            var g = args.DrawingSession;

            // Interpolate towards target values for ZoomLevel and CameraPosition
            var deltaTime = (float)args.Timing.ElapsedTime.TotalSeconds;
            CurrentZoomLevel = Mathf.Lerp(CurrentZoomLevel, ZoomLevel, _zoomLevelDamping * deltaTime);
            CurrentCameraPosition = Vector2.Lerp(CurrentCameraPosition, CameraPosition, _cameraPositionDamping * deltaTime);

            // Update coordinate system
            _coords.DipsPerUnit = 200;
            _coords.CameraPosition = CurrentCameraPosition;
            _coords.ZoomLevel = CurrentZoomLevel;
            _coords.CanvasSize = sender.Size.ToVector2();

            // Determine the viewport so that only visible tiles/entities are drawn
            var corner1 = _coords.CanvasToGamePoint(Vector2.Zero);
            var corner2 = _coords.CanvasToGamePoint(_coords.CanvasSize);
            var xMin = (int)Math.Min(corner1.X, corner2.X);
            var xMax = (int)Math.Max(corner1.X, corner2.X);
            var yMin = (int)Math.Min(corner1.Y, corner2.Y);
            var yMax = (int)Math.Max(corner1.Y, corner2.Y);

            using (var spriteBatch = g.CreateSpriteBatch(CanvasSpriteSortMode.None))
            {
                // Draw tiles
                for (var y = yMin; y <= yMax; y++)
                {
                    for (var x = xMin; x <= xMax; x++)
                    {
                        var position = new Point(x, y);
                        var chunkIndex = position / Chunk.Size;
                        var chunk = Map.ChunkLoader.Chunks.TryGetValue(chunkIndex);

                        if (chunk == null)
                            continue;

                        var tileInfo = chunk[position % Chunk.Size];

                        //DrawSprite(g, tileInfo.Tile, position.ToVector2());
                        DrawSpriteBatched(spriteBatch, tileInfo.Tile, position.ToVector2());

                        if (DisplayDebugInfo)
                        {
                            // Draw tile version for testing purposes
                            var textPosition = _coords.GameToCanvasPoint(position.ToVector2());
                            var textRect = new F.Rect(textPosition.X, textPosition.Y, CurrentZoomLevel, CurrentZoomLevel);
                            g.DrawText(tileInfo.Version.ToString(), textRect, Colors.Yellow, _textFormat);
                        }
                    }
                }

                // Draw and animate entities
                lock (_entitiesLock)
                {
                    for (var i = 0; i < _entities.Count; i++)
                    {
                        var entityInfo = _entities[i];
                        var isDespawned = entityInfo.Advance(args.Timing.ElapsedTime);

                        if (isDespawned)
                        {
                            _entities.Remove(entityInfo);
                            i--;
                        }
                        else
                        {

                            if (Mathf.Within(entityInfo.CurrentPosition.X, xMin, xMax) &&
                                Mathf.Within(entityInfo.CurrentPosition.Y, yMin, yMax))
                            {
                                //DrawSprite(g, entityInfo.Entity, entityInfo.CurrentPosition);
                                DrawSpriteBatched(spriteBatch, entityInfo.Entity, entityInfo.CurrentPosition);
                            }
                        }
                    }
                }
            }

            var fps = (int)Math.Round(1000 / args.Timing.ElapsedTime.TotalMilliseconds);
            g.DrawText(fps + " fps", Vector2.Zero, Colors.Yellow);

            var pluginDrawArgs = new PluginDrawEventArgs(args, this);
            Plugins.RaiseOnDraw(pluginDrawArgs);
        }
 public void OnDraw(PluginDrawEventArgs e)
 {
 }