First let me state, this is my first time messing with any type of drawing utility and I am way outside of my wheelhouse. First I will describe the issue I am having, then what I am trying to do and then my code.
Issue:
After scaling and transforming the canvas, when I TOUCH the canvas area on the phone, then look at the 'location' point in the touch event in Visual Studio, its not the same location that the canvas drew something. I need the exact location I drew something to show the user a popup. If directly after drawing the image I reset the matrix then the rectangles are drawn in the right location but they do not scale. I thought, well I will ResetMatrix at the very end, but that doesn't seem to matter.
What I am trying to do:
I have an image that I scale and draw to the canvas. Then I draw a large red rectangle on the image and smaller rectangles inside the larger rectangle. When the user presses the zoom button I scale by an increasing factor giving the allusion that we are zooming in on the center. So essentially the image grows in size, the large rectangle grows in size and the little rectangles grow in size. This seems to work flawlessly...but I feel I have done something wrong being that when I touch one of the little rectangles, the location is not the same (x,y) it was drawn at.
Below is most of the code I am using put all in one function for simplicity. Any help would be much appreciated. I would think the SKCanvas View would be the same coordinates as the SKCanvas but obviously I am wrong. This code will not compile because you do not have certain classes that return objects...but they do not matter....the issue is Scaling and I am not sure why
public static void DrawLayout(SKImageInfo info, SKCanvas canvas, SKSvg svg, SetupViewModel vm)
var layout = vm.SelectedReticleLayout;
float yRatio;
float xRatio;
float widgetHeight = 75;
float widgetWidth = 170;
float availableWidth = 720;
float availableHeight = 1280;
var currentZoomScale = getScale();
canvas.Translate(info.Width / 2f, info.Height / 2f);
SKRect bounds = svg.ViewBox;
xRatio = (info.Width / bounds.Width) + ((info.Width / bounds.Width) * currentZoomScale);
yRatio = (info.Height / bounds.Height) + ((info.Height / bounds.Height) * currentZoomScale);
float ratio = Math.Min(xRatio, yRatio);
canvas.Scale(ratio);
canvas.Translate(-bounds.MidX, -bounds.MidY);
canvas.DrawPicture(svg.Picture, new SKPaint { Color = SKColors.White, Style = SKPaintStyle.Fill });
// now set the X,Y and Width and Height of the large Red Rectangle
float imageCenter = canvas.LocalClipBounds.Width / 2;
layout.RedBorderXOffSet = imageCenter - (imageCenter / 2.0f) + canvas.LocalClipBounds.Left;
float redBorderYOffSet = (float)(svg.Picture.CullRect.Top + Math.Ceiling(.0654450261780105f * svg.Picture.CullRect.Bottom));
layout.RedBorderYOffSet = (float)(canvas.LocalClipBounds.Top + Math.Ceiling(.0654450261780105f * canvas.LocalClipBounds.Bottom));
layout.RedBorderWidth = canvas.LocalClipBounds.Width / 2.0f;
layout.RedBorderWidthXOffSet = layout.RedBorderWidth + layout.RedBorderXOffSet;
layout.RedBorderHeight = (float)(canvas.LocalClipBounds.Bottom - Math.Ceiling(.0654450261780105f * canvas.LocalClipBounds.Bottom * 2)) - canvas.LocalClipBounds.Top;
layout.RedBorderHeightYOffSet = layout.RedBorderYOffSet + layout.RedBorderHeight;
// draw the large red rectangle
canvas.DrawRect(layout.RedBorderXOffSet, layout.RedBorderYOffSet, layout.RedBorderWidth, layout.RedBorderHeight, RedBorderPaint);
// clear the tracked widgets, tracked widgets are updated every time we draw the widgets
// base widgets contain the default size and location relative to the scope. base line widgets
// will need to be multiplied by the node scale height and width
layout.TrackedWidgets.Clear();
var widget = new widget
{
X = layout.RedBorderXOffSet + 5;
Y = layout.RedBorderYOffSet + layout.TrackedReticleWidgets[0].Height + 15;
Height = layout.RedBorderHeight * (widgetHeight / availableHeight);
Width = layout.RedBorderWdith * (widgetWidth / availableWidth);
}
// define colors for text and border colors for small rectangles (widgets)
public static SKPaint SelectedWidgetColor => new SKPaint { Color = SKColors.LightPink, Style = SKPaintStyle.StrokeAndFill, StrokeWidth = 3 };
public static SKPaint EmptyWidgetBorder => new SKPaint { Color = SKColors.DarkGray, Style = SKPaintStyle.Stroke, StrokeWidth = 3 };
public static SKPaint EmptyWidgetText => new SKPaint { Color = SKColors.Black, TextSize = 10, FakeBoldText = false, Style = SKPaintStyle.Stroke, Typeface = SKTypeface.FromFamilyName("Arial") };
public static SKPaint DefinedWidgetText => new SKPaint { Color = SKColors.DarkRed, FakeBoldText = false, Style = SKPaintStyle.Stroke };
// create small rectangle (widget) and draw the widget
var widgetRectangle = SKRect.Create(widget.X, widget.Y, widget.Width, widget.Height);
canvas.DrawRect(widgetRectangle, widget.IsSelected ? SelectedWidgetColor : EmptyWidgetBorder);
// now lets create the text to draw in the widget
string text = EnumUtility.GetDescription(widget.WidgetDataType);
float textWidth = EmptyWidgetText.MeasureText(text);
EmptyWidgetText.TextSize = widget.Width * GetUnscaledWidgetWith(widget) * EmptyWidgetText.TextSize / textWidth;
SKRect textBounds = new SKRect();
EmptyWidgetText.MeasureText(text, ref textBounds);
float xText = widgetRectangle.MidX - textBounds.MidX;
float yText = widgetRectangle.MidY - textBounds.MidY;
canvas.DrawText(text, xText, yText, EmptyWidgetText);
First let me state, this is my first time messing with any type of drawing utility and I am way outside of my wheelhouse. First I will describe the issue I am having, then what I am trying to do and then my code.
Issue:
After scaling and transforming the canvas, when I TOUCH the canvas area on the phone, then look at the 'location' point in the touch event in Visual Studio, its not the same location that the canvas drew something. I need the exact location I drew something to show the user a popup. If directly after drawing the image I reset the matrix then the rectangles are drawn in the right location but they do not scale. I thought, well I will ResetMatrix at the very end, but that doesn't seem to matter.
What I am trying to do:
I have an image that I scale and draw to the canvas. Then I draw a large red rectangle on the image and smaller rectangles inside the larger rectangle. When the user presses the zoom button I scale by an increasing factor giving the allusion that we are zooming in on the center. So essentially the image grows in size, the large rectangle grows in size and the little rectangles grow in size. This seems to work flawlessly...but I feel I have done something wrong being that when I touch one of the little rectangles, the location is not the same (x,y) it was drawn at.
Below is most of the code I am using put all in one function for simplicity. Any help would be much appreciated. I would think the SKCanvas View would be the same coordinates as the SKCanvas but obviously I am wrong. This code will not compile because you do not have certain classes that return objects...but they do not matter....the issue is Scaling and I am not sure why