/// <summary> /// It makes snapshot of the control before updating. It requires EndUpdate calling. /// </summary> /// <param name="control">Target control</param> /// <param name="parallel">Allows to animate it same time as other animations</param> /// <param name="animation">Personal animation</param> /// <param name="clipRectangle">Clip rectangle for animation</param> public void BeginUpdate(Control control, bool parallel = false, ZeroitAnimate_Animation animation = null, Rectangle clipRectangle = default(Rectangle)) { AddToQueue(control, AnimateMode.BeginUpdate, parallel, animation, clipRectangle); bool wait = false; do { wait = false; lock (queue) foreach (var item in queue) { if (item.control == control && item.mode == AnimateMode.BeginUpdate) { if (item.controller == null) { wait = true; } } } if (wait) { System.Windows.Forms.Application.DoEvents(); } } while (wait); }
/// <summary> /// Does the blind. /// </summary> /// <param name="e">The e.</param> /// <param name="animation">The animation.</param> public static void DoBlind(NonLinearTransfromNeededEventArg e, ZeroitAnimate_Animation animation) { if (animation.BlindCoeff == PointF.Empty) { return; } var pixels = e.Pixels; var sx = e.ClientRectangle.Width; var sy = e.ClientRectangle.Height; var s = e.Stride; var kx = animation.BlindCoeff.X; var ky = animation.BlindCoeff.Y; var a = (int)((sx * kx + sy * ky) * (1 - e.CurrentTime)); for (int x = 0; x < sx; x++) { for (int y = 0; y < sy; y++) { int i = y * s + x * bytesPerPixel; var d = x * kx + y * ky - a; if (d >= 0) { pixels[i + 3] = (byte)0; } } } }
/// <summary> /// Does the rotate. /// </summary> /// <param name="e">The e.</param> /// <param name="animation">The animation.</param> public static void DoRotate(TransfromNeededEventArg e, ZeroitAnimate_Animation animation) { var rect = e.ClientRectangle; var center = new PointF(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); e.Matrix.Translate(center.X, center.Y); if (e.CurrentTime > animation.RotateLimit) { e.Matrix.Rotate(360 * (e.CurrentTime - animation.RotateLimit) * animation.RotateCoeff); } e.Matrix.Translate(-center.X, -center.Y); }
/// <summary> /// Creates the double bitmap. /// </summary> /// <param name="control">The control.</param> /// <param name="mode">The mode.</param> /// <param name="animation">The animation.</param> /// <param name="clipRect">The clip rect.</param> /// <returns>Controller.</returns> private Controller CreateDoubleBitmap(Control control, AnimateMode mode, ZeroitAnimate_Animation animation, Rectangle clipRect) { var controller = new Controller(control, mode, animation, TimeStep, clipRect); controller.TransfromNeeded += OnTransformNeeded; if (NonLinearTransfromNeeded != null) { controller.NonLinearTransfromNeeded += OnNonLinearTransfromNeeded; } controller.MouseDown += OnMouseDown; controller.DoubleBitmap.Cursor = Cursor; controller.FramePainted += OnFramePainted; return(controller); }
/// <summary> /// Does the leaf. /// </summary> /// <param name="e">The e.</param> /// <param name="animation">The animation.</param> public static void DoLeaf(NonLinearTransfromNeededEventArg e, ZeroitAnimate_Animation animation) { if (animation.LeafCoeff == 0f) { return; } var pixels = e.Pixels; var sx = e.ClientRectangle.Width; var sy = e.ClientRectangle.Height; var s = e.Stride; var a = (int)((sx + sy) * (1 - e.CurrentTime * e.CurrentTime)); var count = pixels.Length; for (int x = 0; x < sx; x++) { for (int y = 0; y < sy; y++) { int i = y * s + x * bytesPerPixel; if (x + y >= a) { var newX = a - y; var newY = a - x; var d = a - x - y; if (d < -20) { d = -20; } int newI = newY * s + newX * bytesPerPixel; if (newX >= 0 && newY >= 0) { if (newI >= 0 && newI < count) { if (pixels[i + 3] > 0) { pixels[newI + 0] = (byte)Math.Min(255, d + 250 + pixels[i + 0] / 10); pixels[newI + 1] = (byte)Math.Min(255, d + 250 + pixels[i + 1] / 10); pixels[newI + 2] = (byte)Math.Min(255, d + 250 + pixels[i + 2] / 10); pixels[newI + 3] = 230; } } } pixels[i + 3] = (byte)(0); } } } }
/// <summary> /// Adds the specified a. /// </summary> /// <param name="a">a.</param> public void Add(ZeroitAnimate_Animation a) { SlideCoeff = new PointF(SlideCoeff.X + a.SlideCoeff.X, SlideCoeff.Y + a.SlideCoeff.Y); RotateCoeff += a.RotateCoeff; RotateLimit += a.RotateLimit; ScaleCoeff = new PointF(ScaleCoeff.X + a.ScaleCoeff.X, ScaleCoeff.Y + a.ScaleCoeff.Y); TransparencyCoeff += a.TransparencyCoeff; LeafCoeff += a.LeafCoeff; MosaicShift = new PointF(MosaicShift.X + a.MosaicShift.X, MosaicShift.Y + a.MosaicShift.Y); MosaicCoeff = new PointF(MosaicCoeff.X + a.MosaicCoeff.X, MosaicCoeff.Y + a.MosaicCoeff.Y); MosaicSize += a.MosaicSize; BlindCoeff = new PointF(BlindCoeff.X + a.BlindCoeff.X, BlindCoeff.Y + a.BlindCoeff.Y); TimeCoeff += a.TimeCoeff; Padding += a.Padding; }
/// <summary> /// Does the flip. /// </summary> /// <param name="e">The e.</param> /// <param name="animation">The animation.</param> public static void DoFlip(TransfromNeededEventArg e, ZeroitAnimate_Animation animation) { var cy = e.ClientRectangle.Height / 5; var sy = 1 - 2 * e.CurrentTime; if (sy < 0.01f && sy > -0.01f) { sy = 0.01f; } e.Matrix.Translate(0, cy); e.Matrix.Scale(1, sy); e.Matrix.Translate(0, -cy); }
/// <summary> /// Initializes this instance. /// </summary> protected virtual void Init() { AnimationType = Zeroit.Framework.Transitions.AnimationType.VertSlide; DefaultAnimation = new ZeroitAnimate_Animation(); MaxAnimationTime = 1500; TimeStep = 0.02f; Interval = 10; _width = 200; _height = 200; Disposed += new EventHandler(Animator_Disposed); timer = new System.Windows.Forms.Timer(); timer.Tick += new EventHandler(timer_Tick); timer.Interval = 1; timer.Start(); }
/// <summary> /// Does the scale. /// </summary> /// <param name="e">The e.</param> /// <param name="animation">The animation.</param> public static void DoScale(TransfromNeededEventArg e, ZeroitAnimate_Animation animation) { var rect = e.ClientRectangle; var center = new PointF(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); e.Matrix.Translate(center.X, center.Y); var kx = 1f - animation.ScaleCoeff.X * e.CurrentTime; var ky = 1f - animation.ScaleCoeff.X * e.CurrentTime; if (Math.Abs(kx) <= 0.001f) { kx = 0.001f; } if (Math.Abs(ky) <= 0.001f) { ky = 0.001f; } e.Matrix.Scale(kx, ky); e.Matrix.Translate(-center.X, -center.Y); }
/// <summary> /// Does the transparent. /// </summary> /// <param name="e">The e.</param> /// <param name="animation">The animation.</param> public static void DoTransparent(NonLinearTransfromNeededEventArg e, ZeroitAnimate_Animation animation) { if (animation.TransparencyCoeff == 0f) { return; } var opacity = 1f - animation.TransparencyCoeff * e.CurrentTime; if (opacity < 0f) { opacity = 0f; } if (opacity > 1f) { opacity = 1f; } var pixels = e.Pixels; for (int counter = 0; counter < pixels.Length; counter += bytesPerPixel) { pixels[counter + 3] = (byte)(pixels[counter + 3] * opacity); } }
/// <summary> /// Does the slide. /// </summary> /// <param name="e">The e.</param> /// <param name="animation">The animation.</param> public static void DoSlide(TransfromNeededEventArg e, ZeroitAnimate_Animation animation) { var k = e.CurrentTime; e.Matrix.Translate(-e.ClientRectangle.Width * k * animation.SlideCoeff.X, -e.ClientRectangle.Height * k * animation.SlideCoeff.Y); }
/// <summary> /// Does the mosaic. /// </summary> /// <param name="e">The e.</param> /// <param name="animation">The animation.</param> /// <param name="buffer">The buffer.</param> /// <param name="pixelsBuffer">The pixels buffer.</param> public static void DoMosaic(NonLinearTransfromNeededEventArg e, ZeroitAnimate_Animation animation, ref System.Drawing.Point[] buffer, ref byte[] pixelsBuffer) { if (animation.MosaicCoeff == PointF.Empty || animation.MosaicSize == 0) { return; } var pixels = e.Pixels; var sx = e.ClientRectangle.Width; var sy = e.ClientRectangle.Height; var s = e.Stride; var a = e.CurrentTime; var count = pixels.Length; var opacity = 1 - e.CurrentTime; if (opacity < 0f) { opacity = 0f; } if (opacity > 1f) { opacity = 1f; } var mkx = animation.MosaicCoeff.X; var mky = animation.MosaicCoeff.Y; if (buffer == null) { buffer = new System.Drawing.Point[pixels.Length]; for (int i = 0; i < pixels.Length; i++) { buffer[i] = new System.Drawing.Point((int)(mkx * (rnd.NextDouble() - 0.5)), (int)(mky * (rnd.NextDouble() - 0.5))); } } if (pixelsBuffer == null) { pixelsBuffer = (byte[])pixels.Clone(); } for (int i = 0; i < count; i += bytesPerPixel) { pixels[i + 0] = 255; pixels[i + 1] = 255; pixels[i + 2] = 255; pixels[i + 3] = 0; } var ms = animation.MosaicSize; var msx = animation.MosaicShift.X; var msy = animation.MosaicShift.Y; for (int y = 0; y < sy; y++) { for (int x = 0; x < sx; x++) { int yi = (y / ms); int xi = (x / ms); int i = y * s + x * bytesPerPixel; int j = yi * s + xi * bytesPerPixel; var newX = x + (int)(a * (buffer[j].X + xi * msx)); var newY = y + (int)(a * (buffer[j].Y + yi * msy)); if (newX >= 0 && newX < sx) { if (newY >= 0 && newY < sy) { int newI = newY * s + newX * bytesPerPixel; pixels[newI + 0] = pixelsBuffer[i + 0]; pixels[newI + 1] = pixelsBuffer[i + 1]; pixels[newI + 2] = pixelsBuffer[i + 2]; pixels[newI + 3] = (byte)(pixelsBuffer[i + 3] * opacity); } } } } }
/// <summary> /// Adds the contol to animation queue. /// </summary> /// <param name="control">Target control</param> /// <param name="mode">Animation mode</param> /// <param name="parallel">Allows to animate it same time as other animations</param> /// <param name="animation">Personal animation</param> /// <param name="clipRectangle">The clip rectangle.</param> public void AddToQueue(Control control, AnimateMode mode, bool parallel = true, ZeroitAnimate_Animation animation = null, Rectangle clipRectangle = default(Rectangle)) { if (animation == null) { animation = DefaultAnimation; } if (control is IFakeControl) { control.Visible = false; return; } var item = new QueueItem() { animation = animation, control = control, IsActive = parallel, mode = mode, clipRectangle = clipRectangle }; //check visible state switch (mode) { case AnimateMode.Show: if (control.Visible) //already showed { OnCompleted(new QueueItem { control = control, mode = mode }); return; } break; case AnimateMode.Hide: if (!control.Visible) //already hidden { OnCompleted(new QueueItem { control = control, mode = mode }); return; } break; } //add to queue lock (queue) queue.Add(item); lock (requests) requests.Add(item); }
/// <summary> /// Hides the control and waits while animation will be completed. As result the control will be hidden with animation. /// </summary> /// <param name="control">Target control</param> /// <param name="parallel">Allows to animate it same time as other animations</param> /// <param name="animation">Personal animation</param> public void HideSync(Control control, bool parallel = false, ZeroitAnimate_Animation animation = null) { Hide(control, parallel, animation); WaitAnimation(control); }
/// <summary> /// Hides the control. As result the control will be hidden with animation. /// </summary> /// <param name="control">Target control</param> /// <param name="parallel">Allows to animate it same time as other animations</param> /// <param name="animation">Personal animation</param> public void Hide(Control control, bool parallel = false, ZeroitAnimate_Animation animation = null) { AddToQueue(control, AnimateMode.Hide, parallel, animation); }
/// <summary> /// Initializes a new instance of the <see cref="Controller"/> class. /// </summary> /// <param name="control">The control.</param> /// <param name="mode">The mode.</param> /// <param name="animation">The animation.</param> /// <param name="timeStep">The time step.</param> /// <param name="controlClipRect">The control clip rect.</param> public Controller(Control control, AnimateMode mode, ZeroitAnimate_Animation animation, float timeStep, Rectangle controlClipRect) { if (control is System.Windows.Forms.Form) { DoubleBitmap = new DoubleBitmapForm(); } else { DoubleBitmap = new DoubleBitmapControl(); } (DoubleBitmap as IFakeControl).FramePainting += OnFramePainting; (DoubleBitmap as IFakeControl).FramePainted += OnFramePainting; (DoubleBitmap as IFakeControl).TransfromNeeded += OnTransfromNeeded; DoubleBitmap.MouseDown += OnMouseDown; this.animation = animation; this.AnimatedControl = control; this.mode = mode; this.CustomClipRect = controlClipRect; if (mode == AnimateMode.Show || mode == AnimateMode.BeginUpdate) { timeStep = -timeStep; } this.TimeStep = timeStep * (animation.TimeCoeff == 0f ? 1f : animation.TimeCoeff); if (this.TimeStep == 0f) { timeStep = 0.01f; } try { switch (mode) { case AnimateMode.Hide: { BgBmp = GetBackground(control); (DoubleBitmap as IFakeControl).InitParent(control, animation.Padding); ctrlBmp = GetForeground(control); DoubleBitmap.Visible = true; control.Visible = false; } break; case AnimateMode.Show: { BgBmp = GetBackground(control); (DoubleBitmap as IFakeControl).InitParent(control, animation.Padding); DoubleBitmap.Visible = true; DoubleBitmap.Refresh(); control.Visible = true; ctrlBmp = GetForeground(control); } break; case AnimateMode.BeginUpdate: case AnimateMode.Update: { (DoubleBitmap as IFakeControl).InitParent(control, animation.Padding); BgBmp = GetBackground(control, true); DoubleBitmap.Visible = true; } break; } } catch { Dispose(); } #if debug BgBmp.Save("c:\\bgBmp.png"); if (ctrlBmp != null) { ctrlBmp.Save("c:\\ctrlBmp.png"); } #endif CurrentTime = timeStep > 0 ? animation.MinTime : animation.MaxTime; }