public void DrawClock(Canvas canvas, DateTime tNow, int x, int y, int width, int height) { var swStart = DateTime.Now; int initSaveCount = canvas.SaveCount; this.hourAngle = 30 * tNow.Hour + (this.FlowHourHand ? 0.5f * tNow.Minute : 0); this.minuteAngle = 6 * tNow.Minute + (this.FlowMinuteHand ? 0.1f * tNow.Second : 0); this.secondAngle = 6 * tNow.Second + (this.FlowSecondHand ? 0.006f * tNow.Millisecond : 0); // Clear screen to pink. //paint.Color = Color.WhiteSmoke;// new Color (255, 204, 204); //canvas.DrawPaint(paint); //paint.Color = ColorBackground; //paint.SetStyle(Paint.Style.Fill); //canvas.DrawCircle(this.Width / 2, this.Height / 2, this.Height / 2, paint); // Overall transforms to shift (0, 0) to center and scale. canvas.Translate(x + width / 2, y + height / 2); float scale = Math.Min(width, height) / 2.0f / 100; canvas.Scale(scale, scale); // Attributes for tick marks. paint.Color = ColorTickMarks.ToAndroid(); paint.StrokeCap = Paint.Cap.Round; paint.SetStyle(Paint.Style.Stroke); // Set line dash to draw tick marks for every minute. paint.StrokeWidth = 3; paint.SetPathEffect(minuteTickDashEffect); canvas.DrawPath(tickMarks, paint); // Set line dash to draw tick marks for every hour. paint.StrokeWidth = 6; paint.SetPathEffect(hourTickDashEffect); canvas.DrawPath(tickMarks, paint); // Set attributes common to all clock hands. paint.StrokeWidth = 2; paint.SetPathEffect(null); // Draw hour hand. if (ShowHourHand) { canvas.Save(); canvas.Rotate(this.hourAngle); paint.Color = ColorHourHandFill.ToAndroid(); paint.SetStyle(Paint.Style.Fill); canvas.DrawPath(hourHand, paint); paint.Color = ColorHourHandStroke.ToAndroid(); paint.SetStyle(Paint.Style.Stroke); canvas.DrawPath(hourHand, paint); canvas.Restore(); } if (ShowMinuteHand) { // Draw minute hand. canvas.Save(); canvas.Rotate(this.minuteAngle); paint.Color = ColorMinuteHandFill.ToAndroid(); paint.SetStyle(Paint.Style.Fill); canvas.DrawPath(minuteHand, paint); paint.Color = ColorMinuteHandStroke.ToAndroid(); paint.SetStyle(Paint.Style.Stroke); canvas.DrawPath(minuteHand, paint); canvas.Restore(); } paint.StrokeWidth = 3; if (ShowSecondHand) { // Draw second hand. canvas.Save(); canvas.Rotate(this.secondAngle); paint.Color = ColorSecondHandStroke.ToAndroid(); paint.SetStyle(Paint.Style.Stroke); canvas.DrawPath(secondHand, paint); canvas.Restore(); } canvas.RestoreToCount(initSaveCount); TimeSpan tsDraw = DateTime.Now - swStart; iAllCount++; tsAllSum += tsDraw; if (tsMin > tsDraw) { tsMin = tsDraw; } if (tsMax < tsDraw) { tsMax = tsDraw; } }
public void DrawCanvas(SKCanvas canvas, double hour, double minute, double second, int width = 512, int height = 512, bool bDrawBackImage = false) { DateTime swStart = DateTime.Now; canvas.Clear(); int x = Math.Min(width, height); // Clock background fillPaint.Color = ColorBackground.ToSKColor(); if (bDrawBackImage && ColorBackground.A > 0) { canvas.DrawCircle(width / 2, height / 2, x / 2, fillPaint); } //Background image if (bDrawBackImage && !string.IsNullOrEmpty(BackgroundImage)) { //this is only for widget-preview!!! try { /*if (BackgroundImage.EndsWith(".svg")) * { * * // load the SVG * var svg = new SKSvg(); * svg.Load(BackgroundImage); * * float scale = (float)x / Math.Max(svg.Picture.CullRect.Width, svg.Picture.CullRect.Height); * var matrix = new SKMatrix * { * ScaleX = scale, * ScaleY = scale, * TransX = (width - x) / 2, * TransY = (height - x) / 2, * Persp2 = 1, * }; * * canvas.DrawPicture(svg.Picture, ref matrix); * } * else*/ { if (bmpBackCache == null) { using (var bitmap = SKBitmap.Decode(BackgroundImage)) { bmpBackCache = bitmap.Resize(new SKImageInfo(x, x), SKFilterQuality.High); } } if (bmpBackCache != null) { canvas.DrawBitmap(bmpBackCache, (width - bmpBackCache.Width) / 2, (height - bmpBackCache.Height) / 2); } } } catch { } } // Set scale to draw on a 1000*1000 points base canvas.Translate(width > height ? (width - height) / 2 : 0, height > width ? (height - width) / 2 : 0); canvas.Scale(Math.Min(width / 1000f, height / 1000f)); // Hour and minute marks if (TickMarkStyle != TickMarkStyle.None && ColorTickMarks.A > 0) { var tickPaint = new SKPaint { Color = ColorTickMarks.ToSKColor(), StrokeCap = SKStrokeCap.Round, IsAntialias = true }; if (ColorTickMarks.IsEmpty) { tickPaint.Color = ClockPath.GetBestColor(ColorTickMarks, ClockfaceInfo != null && !BackImageAllowsBackColor ? ClockfaceInfo.MainColor + " " + ClockfaceInfo.HandColorsBanned : ColorBackground.HexString, ClockfaceInfo?.HandColorSuggestion).ToSKColor(); } switch (TickMarkStyle) { case TickMarkStyle.Dotts: tickPaint.Style = SKPaintStyle.Fill; canvas.Translate(500, 500); for (int angle = 0; angle < 360; angle += 6) { canvas.DrawCircle(0, -460, angle % 30 == 0 ? 20 : 10, tickPaint); canvas.RotateDegrees(6); } canvas.Translate(-500, -500); break; case TickMarkStyle.Circle: tickPaint.Style = SKPaintStyle.Stroke; tickPaint.StrokeWidth = 20; canvas.DrawCircle(500, 500, 470, tickPaint); break; case TickMarkStyle.LinesSquare: tickPaint.StrokeCap = SKStrokeCap.Square; goto case TickMarkStyle.LinesRound; case TickMarkStyle.LinesButt: tickPaint.StrokeCap = SKStrokeCap.Butt; goto case TickMarkStyle.LinesRound; case TickMarkStyle.LinesRound: tickPaint.Style = SKPaintStyle.Stroke; canvas.Translate(500, 500); for (int angle = 0; angle < 360; angle += 6) { if (angle % 30 == 0) { tickPaint.StrokeWidth = 20; canvas.DrawLine(0, -450, 0, -470, tickPaint); } else { tickPaint.StrokeWidth = 10; canvas.DrawLine(0, -455, 0, -465, tickPaint); } canvas.RotateDegrees(6); } canvas.Translate(-500, -500); break; } } if (!FlowHourHand) { hour = Math.Truncate(hour); } if (!FlowMinuteHand) { minute = Math.Truncate(minute); } if (!FlowSecondHand) { second = Math.Truncate(second); } // Hour hand if (ShowHourHand && HourPathList != null) { canvas.RotateDegrees((float)(30 * hour), 500, 500); drawClockPaths(canvas, HourPathList, ColorHourHandStroke, ColorHourHandFill); canvas.RotateDegrees((float)(-30 * hour), 500, 500); } // Minute hand if (ShowMinuteHand && MinutePathList != null) { canvas.RotateDegrees((float)(6 * minute), 500, 500); drawClockPaths(canvas, MinutePathList, ColorMinuteHandStroke, ColorMinuteHandFill); canvas.RotateDegrees((float)(-6 * minute), 500, 500); } // Second hand if (ShowSecondHand && SecondPathList != null) { canvas.RotateDegrees((float)(6 * second), 500, 500); drawClockPaths(canvas, SecondPathList, ColorSecondHandStroke, ColorSecondHandFill); canvas.RotateDegrees((float)(-6 * second), 500, 500); } if (CapPathList != null) { drawClockPaths(canvas, CapPathList, ColorCenterCapStroke, ColorCenterCapFill); } TimeSpan tsDraw = DateTime.Now - swStart; iAllCount++; tsAllSum += tsDraw; if (tsMin > tsDraw) { tsMin = tsDraw; } if (tsMax < tsDraw) { tsMax = tsDraw; } }