will Touch event be fired on a transparent SKGLView or SKCanvasView ?

I want to draw a triangle control with two SKCanvasViews, one to simply draw and another to be controlled with Touch event.
So it's obviously necessary that the control view path is to be transparent at best.
Could any one tell me if it is possible.

thx!

Best Answer

Answers

  • mattleibowmattleibow ZAXamarin Team Xamurai

    It should be. To be honest I have not tested it, but the canvas is basically always transparent, and my touch has been working.

    Another question, why do you need two canvases? You should be able to have touch and draw on the same canvas - these two actions aren't mutually exclusive.

  • jamessmith.2438jamessmith.2438 USMember ✭✭

    @mattleibow
    i guess, as canvas is a rectangle with a triangle RED path, when i touch the transparent part of the canvas, it is obvious reasonable that the canvas should not fire anythings.

    the way i want to do is simply to decouple the actual drawing layer and the actual touch layer of a control,.

    so i think there should be an option that a transparent triangle path could be fired to action while the rest canvas part won't.

  • jamessmith.2438jamessmith.2438 USMember ✭✭

    @mattleibow btw, it's impossble to use system.draw for forms, is there a solution to do the hit-test?

  • mattleibowmattleibow ZAXamarin Team Xamurai

    You could do something like this:

    private SKBitmap buffer;
    
    private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
    {
        // make sure the buffer is set up
        if (buffer == null || buffer.Info.Size != e.Info.Size)
        {
            buffer?.Dispose();
            buffer = new SKBitmap(e.Info);
        }
    
        // we draw to our buffer, and only our buffer
        using (var canvas = new SKCanvas(buffer))
        {
            canvas.Clear(SKColors.Transparent);
    
            var circleFill = new SKPaint
            {
                IsAntialias = true,
                Style = SKPaintStyle.Fill,
                Color = SKColors.Blue
            };
            canvas.DrawCircle(100, 100, 40, circleFill);
            var circleBorder = new SKPaint
            {
                IsAntialias = true,
                Style = SKPaintStyle.Stroke,
                Color = SKColors.Red,
                StrokeWidth = 5
            };
            canvas.DrawCircle(100, 100, 40, circleBorder);
        }
    
        // drar the buffer to the screen
        e.Surface.Canvas.DrawBitmap(buffer, 0, 0);
    }
    
    private void OnTouch(object sender, SKTouchEventArgs e)
    {
        var hit = false;
        var title = "Miss";
    
        // make sure we are over the canvas
        var x = (int)e.Location.X;
        var y = (int)e.Location.Y;
        if (x >= 0 && x < buffer.Width && y >= 0 && y < buffer.Height)
        {
            // get the pixel from the buffer
            var pixel = buffer?.GetPixel(x, y) ?? SKColors.Transparent;
    
            // check to see if this pixel is transparent
            hit = pixel.Alpha != 0;
    
            if (hit)
            {
                // update the title
                title = $"Hit {pixel}";
            }
        }
    
        // update the title
        Title = title;
    
        // we only want to handle the event if there is something
        e.Handled = hit;
    }
    
  • dingdingdingding USMember

    @mattleibow ur answer is really helpful, and i guess that a control buffer which is never actually drawn could be my solution, but will it be a little heavier?

  • jamessmith.2438jamessmith.2438 USMember ✭✭

    @mattleibow ur answer is really helpful, and i guess that a control buffer which is never actually drawn could be my solution, but will it be a little heavier?

Sign In or Register to comment.