Example #1
0
        public void Start(Action <StrokeDash> onValueCallback)
        {
            _currStrokeDash = From;

            var anim = new Animation(_ => onValueCallback(_currStrokeDash));

            anim.Add(0, 1, new Animation(
                         callback: v => _currStrokeDash.Phase = (float)v,
                         start: From.Phase,
                         end: To.Phase,
                         easing: Easing));

            anim.Add(0, 1, new Animation(
                         callback: v => _currStrokeDash.Intervals[0] = (float)v,
                         start: From.Intervals[0],
                         end: To.Intervals[0],
                         easing: Easing));

            anim.Add(0, 1, new Animation(
                         callback: v => _currStrokeDash.Intervals[1] = (float)v,
                         start: From.Intervals[1],
                         end: To.Intervals[1],
                         easing: Easing));

            anim.Commit(
                owner: Application.Current.MainPage,
                name: "highlightAnimation",
                length: (uint)Duration.TotalMilliseconds);
        }
        void DrawDash(SKCanvasView skCanvasView, StrokeDash fromDash, StrokeDash toDash)
        {
            if (fromDash != null)
            {
                var anim = new StrokeDashAnimation(
                    from: fromDash,
                    to: toDash,
                    duration: _highlightSettings.AnimationDuration);

                anim.Start((strokeDashToDraw) => RequestDraw(skCanvasView, strokeDashToDraw));
            }
            else
            {
                RequestDraw(skCanvasView, toDash);
            }
        }
        public void Draw(SKCanvasView skCanvasView, SKCanvas skCanvas)
        {
            skCanvas.Clear();

            if (_highlightState == null)
            {
                return;
            }

            if (_skPaint == null)
            {
                _skPaint = CreateHighlightSkPaint(skCanvasView, _highlightSettings, _highlightState.HighlightPath);
            }

            StrokeDash strokeDash = _highlightState.StrokeDash;

            // Comment the next line to see whole path without dash effect
            _skPaint.PathEffect = SKPathEffect.CreateDash(strokeDash.Intervals, strokeDash.Phase);
            skCanvas.DrawPath(_highlightState.HighlightPath.Path, _skPaint);
        }
        public void HighlightElement(View viewToHighlight, SKCanvasView skCanvasView, Layout <View> formLayout)
        {
            IList <View> layoutChildren = formLayout.Children;

            if (_highlightState == null)
            {
                var path = HighlightPath.Create(skCanvasView, layoutChildren, _highlightSettings.StrokeWidth);
                _highlightState = new HighlightState()
                {
                    HighlightPath = path
                };
            }

            HighlightPath highlightPath = _highlightState.HighlightPath;

            int currHighlightViewId = _highlightState.CurrHighlightedViewId;
            int iViewIdToHighlight  = highlightPath.GetViewId(layoutChildren, viewToHighlight);

            if (currHighlightViewId == iViewIdToHighlight)
            {
                return;
            }

            StrokeDash fromDash;

            if (currHighlightViewId != -1)
            {
                fromDash = _highlightState.StrokeDash;
            }
            else
            {
                fromDash = new StrokeDash(highlightPath.GetDashForView(layoutChildren, iViewIdToHighlight));
            }

            _highlightState.CurrHighlightedViewId = iViewIdToHighlight;

            StrokeDash toDash = new StrokeDash(highlightPath.GetDashForView(layoutChildren, viewToHighlight));

            DrawDash(skCanvasView, fromDash, toDash);
        }
Example #5
0
        public static HighlightPath Create(SKCanvasView skCanvasView, IList <View> layoutChildren, double strokeWidth)
        {
            var path = new SKPath();

            var highlightPath = new HighlightPath()
            {
                Path = path
            };

            strokeWidth = (float)skCanvasView.FromPixels(new Point(0, strokeWidth)).Y;

            foreach (View view in layoutChildren)
            {
                int       iStrokeDashCount = highlightPath.DashCount;
                Rectangle viewBounds       = skCanvasView.FromPixels(view.Bounds);

                if (!(view is Entry) && !(view is Button))
                {
                    continue;
                }

                if (path.Points.Length == 0)
                {
                    // Move path point at the left and below of the view
                    path.MoveTo(
                        x: (float)viewBounds.X,
                        y: (float)viewBounds.Y + (float)viewBounds.Height + (float)strokeWidth / 2);
                }

                float xCurr = path.LastPoint.X;
                float yCurr = path.LastPoint.Y;

                // Add arch for views except first one
                if (iStrokeDashCount > 0)
                {
                    float d         = iStrokeDashCount % 2 == 0 ? -1 : 1;
                    float arcHeight = (float)viewBounds.Y + (float)viewBounds.Height - path.LastPoint.Y + (float)strokeWidth / 2;
                    path.ArcTo(new SKRect(xCurr - arcHeight / 2, yCurr, xCurr + arcHeight / 2, yCurr + arcHeight), -90, 180 * d, false);
                }

                float dashOffset = new SKPathMeasure(path).Length;

                // Add line below the view
                // If it's not the first view, the start point is the end from arc end point
                //  and line direction is either to view start or view end
                path.LineTo((float)viewBounds.X + (float)viewBounds.Width * (iStrokeDashCount % 2 == 0 ? 1 : 0), path.LastPoint.Y);

                if (view is Button)
                {
                    xCurr = path.LastPoint.X;
                    yCurr = path.LastPoint.Y;

                    // Draw arc from below button to above button
                    float d         = iStrokeDashCount % 2 == 0 ? -1 : 1;
                    float arcHeight = (float)viewBounds.Height + (float)strokeWidth;
                    path.ArcTo(new SKRect(xCurr - arcHeight / 2, yCurr - arcHeight, xCurr + arcHeight / 2, yCurr), 90, 180 * d, false);

                    // Draw horizontal line above the button
                    path.LineTo(xCurr + (float)viewBounds.Width * d, path.LastPoint.Y);

                    // Draw arc pointing down
                    xCurr = path.LastPoint.X;
                    yCurr = path.LastPoint.Y;
                    path.ArcTo(new SKRect(xCurr - arcHeight / 2, yCurr, xCurr + arcHeight / 2, yCurr + arcHeight), -90, 180 * d, false);
                }

                float solidDashLength = new SKPathMeasure(path).Length - dashOffset;

                var strokeDash = new StrokeDash(
                    intervals: new float[] { solidDashLength, 0 },
                    phase: -dashOffset);

                highlightPath.SetDashForView(layoutChildren, view, strokeDash);
            }

            // Compute the 2nd value of interval, which is the length of remaining path
            float pathLength = new SKPathMeasure(path).Length;

            for (int i = 0; i < highlightPath.DashCount; ++i)
            {
                StrokeDash d = highlightPath.GetDash(i);
                d.Intervals[1] = pathLength - d.Intervals[0];
            }

            return(highlightPath);
        }
Example #6
0
 public void SetDashForView(IList <View> layoutChildren, View view, StrokeDash strokeDash)
 => _strokeDashList[GetViewId(layoutChildren, view)] = strokeDash;
 void RequestDraw(SKCanvasView skCanvasView, StrokeDash strokeDashToDraw)
 {
     _highlightState.StrokeDash = strokeDashToDraw;
     skCanvasView.InvalidateSurface();
 }
 public StrokeDash(StrokeDash strokeDash)
     : this(strokeDash.Intervals, strokeDash.Phase)
 {
 }
Example #9
0
 public StrokeDashAnimation(StrokeDash from, StrokeDash to, TimeSpan duration)
 {
     From     = from;
     To       = to;
     Duration = duration;
 }