-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Current bug behavior
ScaleDetector doesn't work when a Component with DragCallbacks is added.
Expected behavior
Scale gesture (pinch-to-zoom) should work regardless if a Component with DragCallbacks is registered. I'd expect to distinguish between two-finger scale gestures from one-finger tap and drag gestures.
In the example below you can drag the green rectangle but you cannot scale the board. When you remove DragCallbacks mixin, scale gesture starts working.
Steps to reproduce
- Use
ScaleDetectorwith FlutterGame - Add a child with
DragCallbacks - Notice
onScaleUpdateis not being called after scale gesture - Remove
DragCallbacksmixin and noticeonScaleUpdateis now being called
import 'package:flame/components.dart';
import 'package:flame/events.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flame/palette.dart';
import 'package:flutter/material.dart';
class ScaleDragGame extends StatelessWidget {
const ScaleDragGame({super.key});
@override
Widget build(BuildContext context) {
final game = ScaleDragFlameGame();
return GameWidget(game: game);
}
}
/// `onScale` methods are not called when a Component with DragCallbacks is added as a child.
/// Green rectangle can be dragged around but scale gestures don't work. But if I remove DragCallbacks from
/// [DraggableRectangle] scale gestures start to work.
class ScaleDragFlameGame extends FlameGame with ScaleDetector {
late final CameraComponent cameraComponent;
late double startZoom;
ScaleDragFlameGame();
@override
Color backgroundColor() => Colors.yellow;
@override
Future<void> onLoad() async {
final world = World();
cameraComponent = CameraComponent(world: world)
..viewfinder.anchor = Anchor.center
..viewport.anchor = Anchor.center;
addAll([world, cameraComponent]);
world.add(DraggableRectangle(
size: size / 4,
position: size / 6,
paint: BasicPalette.darkGreen.paint(),
));
}
@override
void onScaleStart(ScaleStartInfo info) {
startZoom = cameraComponent.viewfinder.zoom;
}
@override
void onScaleUpdate(ScaleUpdateInfo info) {
/// not called when Component with DragCallbacks was added
final currentScale = info.scale.global;
if (!currentScale.isIdentity()) {
final newZoom = (startZoom * currentScale.y).clamp(1.0, 6.0);
cameraComponent.viewfinder.zoom = newZoom;
} else {
final delta = info.delta.game;
cameraComponent.viewfinder.position.translate(-delta.x, -delta.y);
}
}
}
/// Remove [DragCallbacks] and see that pinch-to-zoom gestures start working
class DraggableRectangle extends RectangleComponent with DragCallbacks {
DraggableRectangle({
super.position,
super.size,
super.paint,
});
@override
void onDragUpdate(DragUpdateEvent event) {
super.onDragUpdate(event);
position += event.delta;
}
}
Flutter doctor output
[✓] Flutter (Channel stable, 3.10.5, on macOS 13.2.1 22D68 darwin-arm64, locale en-US)
• Flutter version 3.10.5 on channel stable at /Users/wojciechplesiak/Development/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 796c8ef792 (7 weeks ago), 2023-06-13 15:51:02 -0700
• Engine revision 45f6e00911
• Dart version 3.0.5
• DevTools version 2.23.1
More environment information
- Flame version: 1.8.1
- Platform affected: android
- Platform version affected: android 13
More information
I want to have draggable components placed on the zoomable board. Imagine you have a puzzle board and you want to zoom in to be able to drag the smaller pieces with precision. DragCallbacks is taking over all touch inputs even when they happen outside of the Component. I see under the hood that whenever a Component with DragCallbacks is added ImmediateMultiDragGestureRecognizer is registered as one of the gestureDetectors (here).