Skip to main content

transparent_tap 0.1.0 copy "transparent_tap: ^0.1.0" to clipboard
transparent_tap: ^0.1.0 copied to clipboard

A Flutter widget that lets taps pass through the transparent pixels of an image, so only the visible (opaque) part of it is tappable.

example/lib/main.dart

import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:transparent_tap/transparent_tap.dart';

void main() => runApp(const ExampleApp());

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: DemoPage());
  }
}

class DemoPage extends StatefulWidget {
  const DemoPage({super.key});

  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  ui.Image? _ringImage;
  int _behindTaps = 0;
  int _ringTaps = 0;

  @override
  void initState() {
    super.initState();
    _generateRingImage();
  }

  // Draws a solid ring with a fully transparent center and transparent
  // corners, so we can demonstrate click-through without bundling an asset.
  Future<void> _generateRingImage() async {
    const size = 240.0;
    final recorder = ui.PictureRecorder();
    final canvas = Canvas(recorder);
    final paint = Paint()..color = Colors.deepPurple;

    canvas.drawCircle(const Offset(size / 2, size / 2), size / 2, paint);
    // Punch a transparent hole out of the middle.
    final clearPaint = Paint()..blendMode = BlendMode.clear;
    canvas.drawCircle(const Offset(size / 2, size / 2), size / 4, clearPaint);

    final picture = recorder.endRecording();
    final image = await picture.toImage(size.toInt(), size.toInt());
    setState(() => _ringImage = image);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('transparent_tap demo')),
      body: Center(
        child: Stack(
          alignment: Alignment.center,
          children: [
            // The "behind" layer — tapping the ring's transparent center
            // or corners should reach this.
            GestureDetector(
              onTap: () => setState(() => _behindTaps++),
              child: Container(
                width: 240,
                height: 240,
                color: Colors.amber.shade100,
                alignment: Alignment.center,
                child: Text('behind taps: $_behindTaps'),
              ),
            ),
            // The ring overlay — only the solid purple band is tappable.
            if (_ringImage != null)
              TransparentTap(
                image: _ringImage,
                child: GestureDetector(
                  onTap: () => setState(() => _ringTaps++),
                  child: SizedBox(
                    width: 240,
                    height: 240,
                    child: CustomPaint(
                      painter: _ImagePainter(_ringImage!),
                    ),
                  ),
                ),
              ),
            Positioned(
              bottom: 0,
              child: Text('ring taps: $_ringTaps'),
            ),
          ],
        ),
      ),
    );
  }
}

class _ImagePainter extends CustomPainter {
  _ImagePainter(this.image);
  final ui.Image image;

  @override
  void paint(Canvas canvas, Size size) {
    paintImage(
      canvas: canvas,
      rect: Offset.zero & size,
      image: image,
      fit: BoxFit.contain,
    );
  }

  @override
  bool shouldRepaint(covariant _ImagePainter oldDelegate) =>
      oldDelegate.image != image;
}
0
likes
160
points
30
downloads

Documentation

API reference

Publisher

verified publisherharipin.com

Weekly Downloads

A Flutter widget that lets taps pass through the transparent pixels of an image, so only the visible (opaque) part of it is tappable.

Repository (GitHub)
View/report issues

Topics

#widget #image #gesture

License

MIT (license)

Dependencies

flutter

More

Packages that depend on transparent_tap