protected override void OnPaint(PaintEventArgs e) { const float EXTENUATED_MOVEMENT_FACTOR = 0.6f; e.Graphics.Clear(BackColor); e.Graphics.CompositingMode = _compositingMode; e.Graphics.CompositingQuality = _compositingQuality; e.Graphics.PixelOffsetMode = _pixelOffsetMode; e.Graphics.SmoothingMode = _smoothingMode; e.Graphics.InterpolationMode = _interpolationMode; base.OnPaint(e); if (Slices?.Count < 1) { return; } var offsetAlpha = Math.Max(Math.Min((Math.Abs(Offset.X) + Math.Abs(Offset.Y)) / 25, 50), 0); var zoomAlpha = Zoom == 0 ? 0 : Math.Min(Zoom / 10, 50); var depthAlpha = Depth == 0 ? 0 : Math.Min(Depth / 10, 50); var sliceAlpha = new[] { offsetAlpha, zoomAlpha, depthAlpha }.Max(); using (var sliceBackBrush = new SolidBrush(Color.FromArgb(sliceAlpha, Color.Black))) using (var sliceBorderPen = new Pen(Color.FromArgb(20, Color.Black))) { var maxSliceSize = new Size(Slices.Max(l => l.Width), Slices.Max(l => l.Height)); var originLeft = (Width - maxSliceSize.Width) / 2; var originTop = (Height - maxSliceSize.Height) / 2; for (int i = 0; i < Slices.Count; i++) { var slice = Slices[i]; var offsetAffectFactor = 0.0d; if (TwoWaySpring) { offsetAffectFactor = (((double)i - (double)(Slices.Count / 2)) / (double)Slices.Count * 2); } else { offsetAffectFactor = (double)i / (double)Slices.Count; } var zoomAffectFactor = (double)(i + 1 /* +1 makes the last slice move with the zoom as well */) / (double)Slices.Count; if (Zoom < 0) { zoomAffectFactor = Zoom; } var depthAffectFactor = ((double)Slices.Count - (double)(i + 1)) * EXTENUATED_MOVEMENT_FACTOR / (double)Slices.Count; var left = originLeft + (int)(offsetAffectFactor * Offset.X); var top = originTop + (int)(offsetAffectFactor * Offset.Y); var rect = new Rectangle(left, top, slice.Width, slice.Height); var infateBy = (Zoom * zoomAffectFactor) - (Depth * depthAffectFactor); var ratio = ((double)slice.Width / (double)slice.Height); rect.Inflate((int)(infateBy * ratio), (int)(infateBy)); if (rect.Height > Height || rect.Width > Width) { continue; } e.Graphics.FillRectangle(sliceBackBrush, rect); e.Graphics.DrawImage(slice, rect); if (sliceAlpha > 0) { e.Graphics.DrawRectangle(sliceBorderPen, rect); } } } }