示例#1
0
        /// <summary>
        /// Finds point coordinates of an entry.
        /// </summary>
        /// <returns>The point.</returns>
        /// <param name="value">The value.</param>
        /// <param name="center">The center.</param>
        /// <param name="angle">The entry angle.</param>
        /// <param name="radius">The radius.</param>
        private SKPoint GetPoint(float value, SKPoint center, float angle, float radius)
        {
            var amount   = Math.Abs(value - AbsoluteMinimum) / ValueRange;
            var point    = new SKPoint(0, radius * amount);
            var rotation = SKMatrix.CreateRotation(angle);

            return(center + rotation.MapPoint(point));
        }
示例#2
0
        private protected SKMatrix CreateTransformMatrix(SKRect bounds)
        {
            var transform = SKMatrix.Identity;

            // Translate to origin
            if (CenterPoint != Vector2.Zero)
            {
                transform = SKMatrix.CreateTranslation(-CenterPoint.X, -CenterPoint.Y);
            }

            // Scaling
            if (Scale != Vector2.One)
            {
                transform = transform.PostConcat(SKMatrix.CreateScale(Scale.X, Scale.Y));
            }

            // Rotating
            if (RotationAngle != 0)
            {
                transform = transform.PostConcat(SKMatrix.CreateRotation(RotationAngle));
            }

            // Translating
            if (Offset != Vector2.Zero)
            {
                transform = transform.PostConcat(SKMatrix.CreateTranslation(Offset.X, Offset.Y));
            }

            // Translate back
            if (CenterPoint != Vector2.Zero)
            {
                transform = transform.PostConcat(SKMatrix.CreateTranslation(CenterPoint.X, CenterPoint.Y));
            }

            if (!TransformMatrix.IsIdentity)
            {
                transform = transform.PostConcat(TransformMatrix.ToSKMatrix());
            }

            var relativeTransform = RelativeTransformMatrix.IsIdentity ? SKMatrix.Identity : RelativeTransformMatrix.ToSKMatrix();

            if (!relativeTransform.IsIdentity)
            {
                relativeTransform.TransX *= bounds.Width;
                relativeTransform.TransY *= bounds.Height;

                transform = transform.PostConcat(relativeTransform);
            }

            return(transform);
        }
示例#3
0
        /// <summary>
        /// 单指操纵
        /// </summary>
        /// <param name="prevPoint"></param>
        /// <param name="newPoint"></param>
        /// <param name="pivotPoint"></param>
        /// <returns></returns>
        public SKMatrix OneFingerManipulate(SKPoint prevPoint, SKPoint newPoint, SKPoint pivotPoint)
        {
            if (Mode == TouchManipulationMode.None)
            {
                return(SKMatrix.CreateIdentity());
            }

            SKMatrix touchMatrix = SKMatrix.CreateIdentity();
            SKPoint  delta       = newPoint - prevPoint;

            if (Mode == TouchManipulationMode.ScaleDualRotate)  // One-finger rotation
            {
                SKPoint oldVector = prevPoint - pivotPoint;
                SKPoint newVector = newPoint - pivotPoint;

                float scale = Magnitude(newVector) / Magnitude(oldVector);


                // Avoid rotation if fingers are too close to center
                if (Magnitude(newVector) > 30 && Magnitude(oldVector) > 30)
                {
                    float prevAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
                    float newAngle  = (float)Math.Atan2(newVector.Y, newVector.X);

                    // Calculate rotation matrix
                    float angle = newAngle - prevAngle;
                    touchMatrix = SKMatrix.CreateRotation(angle, pivotPoint.X, pivotPoint.Y);

                    // Effectively rotate the old vector
                    float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
                    oldVector.X = magnitudeRatio * newVector.X;
                    oldVector.Y = magnitudeRatio * newVector.Y;

                    // Recalculate delta
                    delta = newVector - oldVector;
                }

                if (!float.IsNaN(scale) && !float.IsInfinity(scale))
                {
                    var tm = SKMatrix.CreateScale(scale, scale, pivotPoint.X, pivotPoint.Y);
                    touchMatrix.PostConcat(tm);
                }
            }

            // Multiply the rotation matrix by a translation matrix
            touchMatrix.PostConcat(SKMatrix.CreateTranslation(delta.X, delta.Y));

            return(touchMatrix);
        }
        /// <summary>
        /// 2本指での操作
        /// </summary>
        /// <param name="prevPoint"></param>
        /// <param name="newPoint"></param>
        /// <param name="pivotPoint"></param>
        /// <returns></returns>
        public SKMatrix TwoFingerManipulate(SKPoint prevPoint, SKPoint newPoint, SKPoint pivotPoint)
        {
            SKMatrix touchMatrix = SKMatrix.CreateIdentity();
            SKPoint  oldVector   = prevPoint - pivotPoint;
            SKPoint  newVector   = newPoint - pivotPoint;

            if (Mode == TouchManipulationMode.ScaleRotate ||
                Mode == TouchManipulationMode.ScaleDualRotate)
            {
                // Find angles from pivot point to touch points
                float oldAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
                float newAngle = (float)Math.Atan2(newVector.Y, newVector.X);

                // Calculate rotation matrix
                float angle = newAngle - oldAngle;
                touchMatrix = SKMatrix.CreateRotation(angle, pivotPoint.X, pivotPoint.Y);

                // Effectively rotate the old vector
                float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
                oldVector.X = magnitudeRatio * newVector.X;
                oldVector.Y = magnitudeRatio * newVector.Y;
            }

            float scaleX = 1;
            float scaleY = 1;

            if (Mode == TouchManipulationMode.AnisotropicScale)
            {
                scaleX = newVector.X / oldVector.X;
                scaleY = newVector.Y / oldVector.Y;
            }
            else if (Mode == TouchManipulationMode.IsotropicScale ||
                     Mode == TouchManipulationMode.ScaleRotate ||
                     Mode == TouchManipulationMode.ScaleDualRotate)
            {
                scaleX = scaleY = Magnitude(newVector) / Magnitude(oldVector);
            }

            if (!float.IsNaN(scaleX) && !float.IsInfinity(scaleX) &&
                !float.IsNaN(scaleY) && !float.IsInfinity(scaleY))
            {
                //SKMatrix.PostConcat(ref touchMatrix,
                //   SKMatrix.CreateScale(scaleX, scaleY, pivotPoint.X, pivotPoint.Y));
                touchMatrix = touchMatrix.PostConcat(SKMatrix.CreateScale(scaleX, scaleY, pivotPoint.X, pivotPoint.Y));
            }

            return(touchMatrix);
        }
示例#5
0
        private void DrawGrid(SKCanvas canvas, double dx, double dy, double zx, double zy)
        {
            float gw = (float)_view.Width;
            float gh = (float)_view.Height;
            float cw = 15.0f;
            float ch = 15.0f;

            canvas.Save();
            canvas.Translate((float)dx, (float)dy);
            canvas.Scale((float)zx, (float)zy);

            var hlattice = SKMatrix.CreateScale(cw, ch);

            hlattice = hlattice.PreConcat(SKMatrix.CreateRotation((float)(Math.PI * 0.0 / 180.0)));

            var vlattice = SKMatrix.CreateScale(cw, ch);

            vlattice = vlattice.PreConcat(SKMatrix.CreateRotation((float)(Math.PI * 90.0 / 180.0)));

            using (var heffect = SKPathEffect.Create2DLine((float)(1.0 / zx), hlattice))
                using (var veffect = SKPathEffect.Create2DLine((float)(1.0 / zx), vlattice))
                    using (var hpaint = new SKPaint())
                        using (var vpaint = new SKPaint())
                        {
                            hpaint.IsAntialias = false;
                            hpaint.Color       = SKColors.LightGray;
                            hpaint.PathEffect  = heffect;
                            canvas.DrawRect(SKRect.Create(0.0f, ch, gw, gh - ch), hpaint);
                            vpaint.IsAntialias = false;
                            vpaint.Color       = SKColors.LightGray;
                            vpaint.PathEffect  = veffect;
                            canvas.DrawRect(SKRect.Create(cw, 0.0f, gw - cw, gh), vpaint);
                        }

            using (SKPaint strokePaint = new SKPaint())
            {
                strokePaint.IsAntialias = false;
                strokePaint.StrokeWidth = (float)(1.0 / zx);
                strokePaint.Color       = SKColors.Red;
                strokePaint.Style       = SKPaintStyle.Stroke;
                canvas.DrawRect(SKRect.Create(0.0f, 0.0f, gw, gh), strokePaint);
            }

            canvas.Restore();
        }
示例#6
0
        protected override RBrush CreateLinearGradientBrush(RRect rect, RColor color1, RColor color2, double angle)
        {
            var rotation = (float)(angle / 180.0f * Math.PI);
            var angleX   = (float)(rect.Width / 2);
            var angleY   = (float)(rect.Height / 2);

            return(new BrushAdapter(new SKPaint
            {
                Style = SKPaintStyle.Fill,
                Shader = SKShader.CreateLinearGradient(
                    new SKPoint((float)rect.Left, (float)rect.Top),
                    new SKPoint((float)rect.Right, (float)rect.Bottom),
                    new[]
                {
                    Utils.Convert(color1), Utils.Convert(color2)
                }, new[] { 0.0f, 1.0f }, SKShaderTileMode.Repeat, SKMatrix.CreateRotation(rotation, angleX, angleY))
            }, true));
            // new LinearGradientBrush(Utils.Convert(rect), Utils.Convert(color1), Utils.Convert(color2),
            // (float) angle), true);
        }
示例#7
0
        protected override void OnDrawSample(SKCanvas canvas, int width, int height)
        {
            // load the image from the embedded resource stream
            using (var stream = new SKManagedStream(SampleMedia.Images.ColorWheel))
                using (var source = SKBitmap.Decode(stream))
                {
                    var matrix = SKMatrix.CreateRotation(30.0f);

                    // create the shader and paint
                    using (var shader = SKShader.CreateBitmap(source, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, matrix))
                        using (var paint = new SKPaint())
                        {
                            paint.IsAntialias = true;
                            paint.Shader      = shader;

                            // tile the bitmap
                            canvas.Clear(SKColors.White);
                            canvas.DrawPaint(paint);
                        }
                }
        }
示例#8
0
        public static SKMatrix CaculateOneFingerDraggedMatrix(SKPoint prevPoint, SKPoint curPoint, SKPoint pivotPoint, TouchManipulationMode mode)
        {
            if (mode == TouchManipulationMode.None)
            {
                return(SKMatrix.CreateIdentity());
            }

            SKMatrix touchMatrix = SKMatrix.CreateIdentity();
            SKPoint  delta       = curPoint - prevPoint;

            if (mode == TouchManipulationMode.ScaleDualRotate)  // One-finger rotation
            {
                SKPoint oldVector = prevPoint - pivotPoint;
                SKPoint newVector = curPoint - pivotPoint;

                // Avoid rotation if fingers are too close to center
                if (Magnitude(newVector) > 25 && Magnitude(oldVector) > 25)
                {
                    float prevAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
                    float newAngle  = (float)Math.Atan2(newVector.Y, newVector.X);

                    // Calculate rotation matrix
                    float angle = newAngle - prevAngle;
                    touchMatrix = SKMatrix.CreateRotation(angle, pivotPoint.X, pivotPoint.Y);

                    // Effectively rotate the old vector
                    float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
                    oldVector.X = magnitudeRatio * newVector.X;
                    oldVector.Y = magnitudeRatio * newVector.Y;

                    // Recalculate delta
                    delta = newVector - oldVector;
                }
            }

            // Multiply the rotation matrix by a translation matrix
            touchMatrix = touchMatrix.PostConcat(SKMatrix.CreateTranslation(delta.X, delta.Y));

            return(touchMatrix);
        }
示例#9
0
        public static void Draw(SKCanvas canvas, IReadOnlyViewport viewport, VectorStyle vectorStyle, IFeature feature,
                                Polygon polygon, float opacity, ISymbolCache?symbolCache = null)
        {
            float lineWidth        = 1;
            var   lineColor        = Color.Black;       // default
            var   fillColor        = Color.Gray;        // default
            var   strokeCap        = PenStrokeCap.Butt; // default
            var   strokeJoin       = StrokeJoin.Miter;  // default
            var   strokeMiterLimit = 4f;                // default
            var   strokeStyle      = PenStyle.Solid;    // default

            float[]? dashArray = null;                  // default
            float dashOffset = 0;                       // default

            if (vectorStyle.Outline != null)
            {
                lineWidth        = (float)vectorStyle.Outline.Width;
                lineColor        = vectorStyle.Outline.Color;
                strokeCap        = vectorStyle.Outline.PenStrokeCap;
                strokeJoin       = vectorStyle.Outline.StrokeJoin;
                strokeMiterLimit = vectorStyle.Outline.StrokeMiterLimit;
                strokeStyle      = vectorStyle.Outline.PenStyle;
                dashArray        = vectorStyle.Outline.DashArray;
                dashOffset       = vectorStyle.Outline.DashOffset;
            }

            if (vectorStyle.Fill != null)
            {
                fillColor = vectorStyle.Fill?.Color;
            }

            using (var path = polygon.ToSkiaPath(viewport, canvas.LocalClipBounds, lineWidth))
                using (var paintFill = new SKPaint {
                    IsAntialias = true
                })
                {
                    // Is there a FillStyle?
                    if (vectorStyle.Fill?.FillStyle == FillStyle.Solid)
                    {
                        paintFill.StrokeWidth = 0;
                        paintFill.Style       = SKPaintStyle.Fill;
                        paintFill.PathEffect  = null;
                        paintFill.Shader      = null;
                        paintFill.Color       = fillColor.ToSkia(opacity);
                        canvas.DrawPath(path, paintFill);
                    }
                    else
                    {
                        paintFill.StrokeWidth = 1;
                        paintFill.Style       = SKPaintStyle.Stroke;
                        paintFill.Shader      = null;
                        paintFill.Color       = fillColor.ToSkia(opacity);
                        var scale = 10.0f;
                        using var fillPath = new SKPath();
                        var matrix = SKMatrix.CreateScale(scale, scale);

                        switch (vectorStyle.Fill?.FillStyle)
                        {
                        case FillStyle.Cross:
                            fillPath.MoveTo(scale * 0.8f, scale * 0.8f);
                            fillPath.LineTo(0, 0);
                            fillPath.MoveTo(0, scale * 0.8f);
                            fillPath.LineTo(scale * 0.8f, 0);
                            paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                            break;

                        case FillStyle.DiagonalCross:
                            fillPath.MoveTo(scale, scale);
                            fillPath.LineTo(0, 0);
                            fillPath.MoveTo(0, scale);
                            fillPath.LineTo(scale, 0);
                            paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                            break;

                        case FillStyle.BackwardDiagonal:
                            fillPath.MoveTo(0, scale);
                            fillPath.LineTo(scale, 0);
                            paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                            break;

                        case FillStyle.ForwardDiagonal:
                            fillPath.MoveTo(scale, scale);
                            fillPath.LineTo(0, 0);
                            paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                            break;

                        case FillStyle.Dotted:
                            paintFill.Style = SKPaintStyle.StrokeAndFill;
                            fillPath.AddCircle(scale * 0.5f, scale * 0.5f, scale * 0.35f);
                            paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                            break;

                        case FillStyle.Horizontal:
                            fillPath.MoveTo(0, scale * 0.5f);
                            fillPath.LineTo(scale, scale * 0.5f);
                            paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                            break;

                        case FillStyle.Vertical:
                            fillPath.MoveTo(scale * 0.5f, 0);
                            fillPath.LineTo(scale * 0.5f, scale);
                            paintFill.PathEffect = SKPathEffect.Create2DPath(matrix, fillPath);
                            break;

                        case FillStyle.Bitmap:
                            paintFill.Style = SKPaintStyle.Fill;
                            var image = GetImage(symbolCache, vectorStyle.Fill.BitmapId);
                            if (image != null)
                            {
                                paintFill.Shader = image.ToShader(SKShaderTileMode.Repeat, SKShaderTileMode.Repeat);
                            }
                            break;

                        case FillStyle.BitmapRotated:
                            paintFill.Style = SKPaintStyle.Fill;
                            image           = GetImage(symbolCache, vectorStyle.Fill.BitmapId);
                            if (image != null)
                            {
                                paintFill.Shader = image.ToShader(SKShaderTileMode.Repeat,
                                                                  SKShaderTileMode.Repeat,
                                                                  SKMatrix.CreateRotation((float)(viewport.Rotation * System.Math.PI / 180.0f), image.Width >> 1, image.Height >> 1));
                            }
                            break;

                        default:
                            paintFill.PathEffect = null;
                            break;
                        }

                        // Do this, because if not, path isn't filled complete
                        using (new SKAutoCanvasRestore(canvas))
                        {
                            canvas.ClipPath(path);
                            var bounds = path.Bounds;
                            // Make sure, that the brush starts with the correct position
                            var inflate = ((int)path.Bounds.Width * 0.3f / scale) * scale;
                            bounds.Inflate(inflate, inflate);
                            // Draw rect with bigger size, which is clipped by path
                            canvas.DrawRect(bounds, paintFill);
                        }
                    }

                    if (vectorStyle.Outline != null)
                    {
                        using (var paintStroke = new SKPaint {
                            IsAntialias = true
                        })
                        {
                            paintStroke.Style       = SKPaintStyle.Stroke;
                            paintStroke.StrokeWidth = lineWidth;
                            paintStroke.Color       = lineColor.ToSkia(opacity);
                            paintStroke.StrokeCap   = strokeCap.ToSkia();
                            paintStroke.StrokeJoin  = strokeJoin.ToSkia();
                            paintStroke.StrokeMiter = strokeMiterLimit;
                            if (strokeStyle != PenStyle.Solid)
                            {
                                paintStroke.PathEffect = strokeStyle.ToSkia(lineWidth, dashArray, dashOffset);
                            }
                            else
                            {
                                paintStroke.PathEffect = null;
                            }
                            canvas.DrawPath(path, paintStroke);
                        }
                    }
                }
        }
示例#10
0
 public static SKMatrix Rotate(this SKMatrix m, float angle)
 => m.Concat(SKMatrix.CreateRotation(angle));
示例#11
0
        public override void DrawContent(SKCanvas canvas, int width, int height)
        {
            var total = Entries?.Count() ?? 0;

            if (total > 0)
            {
                var captionHeight = Entries.Max(x =>
                {
                    var result = 0.0f;

                    var hasLabel      = !string.IsNullOrEmpty(x.Label);
                    var hasValueLabel = !string.IsNullOrEmpty(x.ValueLabel);

                    if (hasLabel || hasValueLabel)
                    {
                        var hasOffset     = hasLabel && hasValueLabel;
                        var captionMargin = LabelTextSize * 0.60f;
                        var space         = hasOffset ? captionMargin : 0;

                        if (hasLabel)
                        {
                            result += LabelTextSize;
                        }

                        if (hasValueLabel)
                        {
                            result += LabelTextSize;
                        }
                    }

                    return(result);
                });

                var center     = new SKPoint(width / 2, height / 2);
                var radius     = ((Math.Min(width, height) - (2 * Margin)) / 2) - captionHeight;
                var rangeAngle = (float)((Math.PI * 2) / total);
                var startAngle = (float)Math.PI;

                DrawBorder(canvas, center, radius);

                using (var clip = new SKPath())
                {
                    clip.AddCircle(center.X, center.Y, radius);


                    for (int i = 0; i < total; i++)
                    {
                        var angle = startAngle + (rangeAngle * i);
                        var entry = Entries.ElementAt(i);


                        int nextIndex = (i + 1) % total;
                        var nextAngle = startAngle + (rangeAngle * nextIndex);
                        var nextEntry = Entries.ElementAt(nextIndex);
                        while (!nextEntry.Value.HasValue)
                        {
                            nextIndex = (nextIndex + 1) % total;
                            nextAngle = startAngle + (rangeAngle * nextIndex);
                            nextEntry = Entries.ElementAt(nextIndex);
                        }

                        canvas.Save();
                        if (entry.Value.HasValue)
                        {
                            var point     = GetPoint(entry.Value.Value * AnimationProgress, center, angle, radius);
                            var nextPoint = GetPoint(nextEntry.Value.Value * AnimationProgress, center, nextAngle, radius);

                            canvas.ClipPath(clip);

                            // Border center bars
                            using (var paint = new SKPaint()
                            {
                                Style = SKPaintStyle.Stroke,
                                StrokeWidth = BorderLineSize,
                                Color = BorderLineColor,
                                IsAntialias = true,
                            })
                            {
                                var borderPoint = GetPoint(MaxValue, center, angle, radius);
                                canvas.DrawLine(point.X, point.Y, borderPoint.X, borderPoint.Y, paint);
                            }

                            // Values points and lines
                            using (var paint = new SKPaint()
                            {
                                Style = SKPaintStyle.Stroke,
                                StrokeWidth = BorderLineSize,
                                Color = entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f * AnimationProgress)),
                                PathEffect = SKPathEffect.CreateDash(new[] { BorderLineSize, BorderLineSize * 2 }, 0),
                                IsAntialias = true,
                            })
                            {
                                var amount = Math.Abs(entry.Value.Value - AbsoluteMinimum) / ValueRange;
                                canvas.DrawCircle(center.X, center.Y, radius * amount, paint);
                            }

                            canvas.DrawGradientLine(center, entry.Color.WithAlpha(0), point, entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f)), LineSize);
                            canvas.DrawGradientLine(point, entry.Color, nextPoint, nextEntry.Color, LineSize);
                            canvas.DrawPoint(point, entry.Color, PointSize, PointMode);
                        }
                        canvas.Restore();

                        // Labels
                        var labelPoint = new SKPoint(0, radius + LabelTextSize + (PointSize / 2));
                        var rotation   = SKMatrix.CreateRotation(angle);
                        labelPoint = center + rotation.MapPoint(labelPoint);
                        var alignment = SKTextAlign.Left;

                        if ((Math.Abs(angle - (startAngle + Math.PI)) < Epsilon) || (Math.Abs(angle - Math.PI) < Epsilon))
                        {
                            alignment = SKTextAlign.Center;
                        }
                        else if (angle > (float)(startAngle + Math.PI))
                        {
                            alignment = SKTextAlign.Right;
                        }

                        canvas.DrawCaptionLabels(entry.Label, entry.TextColor, entry.ValueLabel, entry.Color.WithAlpha((byte)(255 * AnimationProgress)), LabelTextSize, labelPoint, alignment, base.Typeface, out var _);
                    }
                }
            }
        }