void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); int numVertices = 7; float radius = 0.45f * Math.Min(info.Width, info.Height); SKPoint[] vertices = new SKPoint[numVertices]; double vertexAngle = -0.5f * Math.PI; // straight up // Coordinates of the vertices of the polygon for (int vertex = 0; vertex < numVertices; vertex++) { vertices[vertex] = new SKPoint(radius * (float)Math.Cos(vertexAngle), radius * (float)Math.Sin(vertexAngle)); vertexAngle += 2 * Math.PI / numVertices; } float cornerRadius = 100; // Create the path using (SKPath path = new SKPath()) { path.AddPoly(vertices, true); // Render the path in the center of the screen using (SKPaint paint = new SKPaint()) { paint.Style = SKPaintStyle.Stroke; paint.Color = SKColors.Blue; paint.StrokeWidth = 10; // Set argument to half the desired corner radius! paint.PathEffect = SKPathEffect.CreateCorner(cornerRadius / 2); canvas.Translate(info.Width / 2, info.Height / 2); canvas.DrawPath(path, paint); // Uncomment DrawCircle call to verify corner radius float offset = cornerRadius / (float)Math.Sin(Math.PI * (numVertices - 2) / numVertices / 2); paint.Color = SKColors.Green; // canvas.DrawCircle(vertices[0].X, vertices[0].Y + offset, cornerRadius, paint); } } }
public RoomData(string id) { RoomId = id; ImageInfo = new SKImageInfo(800, 600); Image = SKImage.Create(new SKImageInfo(800, 600)); Surface = SKSurface.Create(ImageInfo); Paint = new SKPaint { IsAntialias = true, Color = new SKColor(0, 0, 0, 255), StrokeWidth = 4, PathEffect = SKPathEffect.CreateCorner(50), Style = SKPaintStyle.Stroke }; Path = new SKPath(); }
public static Tuple <SKPaint, IEnumerable <IDisposable> > CreatePaint(this XInkStroke stroke, SKPaintStyle paintStyle = SKPaintStyle.Stroke, SKBlendMode blendMode = SKBlendMode.SrcATop) { if (stroke == null) { throw new ArgumentNullException(nameof(stroke)); } var disposables = new List <IDisposable>(); SKShader shader = null; if (stroke.DrawingAttributes.Kind == XInkDrawingAttributesKind.Pencil) { var perlin = SKShader.CreatePerlinNoiseFractalNoise(0.01f, 0.01f, 1, 1.0f); var color = SKShader.CreateColor(stroke.DrawingAttributes.Color.ToSKColor().WithAlpha(0x7F)); disposables.Add(perlin); disposables.Add(color); shader = SKShader.CreateCompose( perlin, color, blendMode); } Tuple <SKPaint, IEnumerable <IDisposable> > tuple = null; SKPaint paint = null; if (!stroke.DrawingAttributes.IgnorePressure) { paintStyle = SKPaintStyle.Fill; } try { paint = new SKPaint { Color = stroke.DrawingAttributes.Kind == XInkDrawingAttributesKind.Default ? stroke.DrawingAttributes.Color.ToSKColor() : new SKColor(), StrokeWidth = stroke.DrawingAttributes.IgnorePressure? stroke.DrawingAttributes.Size : 0.0f, Style = paintStyle, IsAntialias = true, StrokeCap = stroke.DrawingAttributes.PenTip == Inking.XPenTipShape.Circle ? SKStrokeCap.Round : SKStrokeCap.Butt, PathEffect = SKPathEffect.CreateCorner(100) }; if (shader != null) { paint.Shader = shader; } tuple = Tuple.Create(paint, disposables as IEnumerable <IDisposable>); paint = null; } finally { paint?.Dispose(); } return(tuple); }
private void DrawBars(SKCanvas canvas, SKRect frame, SKRect chart) { // Selected bar width var selectedValueItems = ChartEntries.GetChartValueItemFromX(chart.GetInsideXValue(TouchedPoint.X), chart, chart.GetItemWidth(MaxItems)); var selectedTags = selectedValueItems?.Select(x => x.ChartValueItem.Tag); // Invoke command with selected items SelectedValuesCommand?.Execute(new SelectedChartValueItemArgs { ChartValueItems = selectedValueItems, TouchedPoint = new SKPoint(chart.GetInsideXValue(TouchedPoint.X), TouchedPoint.Y) }); using (var paint = new SKPaint { IsAntialias = true, Style = SKPaintStyle.StrokeAndFill, StrokeCap = SKStrokeCap.Butt, }) { var groupedItems = ChartEntries.Where(x => x.IsVisible).SelectMany(x => x.Items).GroupBy(x => x.Tag.ToString()).OrderBy(x => x.Key); // Calc max items in one group var maxItemsInGroups = groupedItems.Max(x => x.Count()); // Calc how many groups there is var groupCount = groupedItems.Count(); // Calc how many bars there will be var totalBars = groupCount * maxItemsInGroups; var internalGroupMargin = maxItemsInGroups == 1 ? BarMargin : GroupMargin; var internalBarMargin = maxItemsInGroups == 1 ? 0 : BarMargin; var internalBarWidth = MinimumBarWidth; float itemWidth; if (AllowScroll) { // Calc total item width itemWidth = internalBarWidth * maxItemsInGroups + ((maxItemsInGroups - 1) * barMargin); } else { itemWidth = chart.Width / groupCount; itemWidth -= internalGroupMargin; internalBarWidth = (itemWidth / maxItemsInGroups) - ((maxItemsInGroups - 1) * barMargin); } int groupIndex = 0; float scrollLeftPadding = 0; float left = 0; float groupLeft = 0; float right = 0; groupCenters = new List <GroupChartItem>(); foreach (var groupedItem in groupedItems) { int itemIndex = 0; groupLeft = left; if (!AllowScroll && IsSliderVisible && selectedTags?.Contains(groupedItem.Key) == true) { var item = groupedItem.OrderByDescending(x => x.Value).First(); paint.Color = SliderColor.ToSKColor(); paint.PathEffect = SKPathEffect.CreateCorner(SliderCornerRadius); var bounds = new SKRect( item.Point.X - (itemWidth * .5f) - (groupMargin * .5f), item.Point.Y - (itemWidth * .5f), item.Point.X + (itemWidth * .5f) + (groupMargin * .5f), chart.Bottom + HorizontalTextSize); paint.StrokeWidth = 0; canvas.DrawRect(bounds, paint); } foreach (var item in groupedItem) { var parent = ChartEntries.FirstOrDefault(x => x.Items.Contains(item)); SKRect bounds = new SKRect(); if (AllowScroll) { if (left == 0) { left = itemWidth.FromDpiAdjusted(); groupLeft = left; scrollLeftPadding = left; } else if (itemIndex != 0) { left += internalBarMargin; } right = left + internalBarWidth; bounds = new SKRect( left, item.Point.Y, right, chart.Bottom); left = right; } else { left = (item.Point.X - (itemWidth * .5f)) + (internalBarWidth * itemIndex) + (internalBarMargin * itemIndex); right = left + internalBarWidth; bounds = new SKRect( left, item.Point.Y, right, chart.Bottom); } paint.StrokeWidth = 0; if (parent.UseDashedEffect) { paint.Color = parent.Color.ToSKColor().AsTransparency(); paint.PathEffect = SKPathEffect.CreateCorner(BarCornerRadius); canvas.DrawRect(bounds, paint); paint.Color = parent.Color.ToSKColor(); paint.PathEffect = SKPathEffect.CreateDash(new float[] { StrokeDashFirst, StrokeDashSecond }, StrokeDashPhase); paint.StrokeWidth = bounds.Width; canvas.DrawLine(bounds.MidX, bounds.Bottom, bounds.MidX, bounds.Top, paint); } else { paint.Color = parent.Color.ToSKColor(); paint.PathEffect = SKPathEffect.CreateCorner(BarCornerRadius); canvas.DrawRect(bounds, paint); } itemIndex++; } left += internalGroupMargin; groupIndex++; var groupCenterPosition = groupLeft + (itemWidth / 2); groupCenters.Add(new GroupChartItem { Label = groupedItem.FirstOrDefault().Label, Position = groupCenterPosition.FromDpiAdjusted(), Tag = groupedItem.Key }); } if (AllowScroll) { var requestedWidth = right.FromDpiAdjusted() + frame.Left.FromDpiAdjusted(); if (requestedWidth != this.WidthRequest) { this.WidthRequest = requestedWidth; } else { SetStartPosition(groupCenters); IsInitialized = true; } if (ScrollComponent != null) { var deviceWidth = Xamarin.Essentials.DeviceDisplay.MainDisplayInfo.Width; var halfDeviceWidth = ((float)(deviceWidth / 2)).FromDpiAdjusted(); var frameLeftVal = frame.Left.FromDpiAdjusted(); var rectRightMarginVal = ChartRectMargin.Right.FromDpiAdjusted(); var leftPadding = halfDeviceWidth - frameLeftVal - scrollLeftPadding.FromDpiAdjusted(); var rightPadding = halfDeviceWidth - frameLeftVal - rectRightMarginVal - itemWidth.FromDpiAdjusted(); ScrollComponent.Padding = new Thickness(leftPadding, 0, rightPadding, 0); ScrollComponent.Margin = new Thickness(frame.Left.FromDpiAdjusted(), 0, ChartRectMargin.Right.FromDpiAdjusted(), 0); if (Selector != null) { Selector.WidthRequest = itemWidth.FromDpiAdjusted(); Selector.Margin = new Thickness(halfDeviceWidth, 0, 0, this.Height - frame.Bottom.FromDpiAdjusted()); } if (!isScrollEventActive) { ScrollComponent.Scrolled += ScrollComponent_Scrolled; isScrollEventActive = true; } } if (SwipeNotificationLeft != null) { SwipeNotificationLeft.Margin = new Thickness(frame.Left.FromDpiAdjusted(), 0, 0, this.Height - frame.Bottom.FromDpiAdjusted()); SwipeNotificationLeft.WidthRequest = ScrollComponent.Padding.Left; } if (SwipeNotificationRight != null) { SwipeNotificationRight.Margin = new Thickness(0, 0, ChartRectMargin.Right.FromDpiAdjusted(), this.Height - frame.Bottom.FromDpiAdjusted()); SwipeNotificationRight.WidthRequest = ScrollComponent.Padding.Left; } } } DrawHorizontalLabel(selectedValueItems?.FirstOrDefault()?.ChartValueItem, canvas, frame, chart); }