dartlangeditorflutterflutter-appsflutter-examplesflutter-packageflutter-widgetquillquill-deltaquilljsreactquillrich-textrich-text-editorwysiwygwysiwyg-editor
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
2.7 KiB
69 lines
2.7 KiB
2 years ago
|
import 'package:flutter/foundation.dart';
|
||
|
import 'package:flutter/material.dart';
|
||
|
|
||
|
class CustomMagnifier extends StatelessWidget {
|
||
|
const CustomMagnifier({required this.magnifierInfo, super.key});
|
||
|
|
||
|
static const Size magnifierSize = Size(200, 200);
|
||
|
|
||
|
// This magnifier will consume some text data and position itself
|
||
|
// based on the info in the magnifier.
|
||
|
final ValueNotifier<MagnifierInfo> magnifierInfo;
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
// Use a value listenable builder because we want to rebuild
|
||
|
// every time the text selection info changes.
|
||
|
// `CustomMagnifier` could also be a `StatefulWidget` and call `setState`
|
||
|
// when `magnifierInfo` updates. This would be useful for more complex
|
||
|
// positioning cases.
|
||
|
return ValueListenableBuilder<MagnifierInfo>(
|
||
|
valueListenable: magnifierInfo,
|
||
|
builder: (context, currentMagnifierInfo, _) {
|
||
|
// We want to position the magnifier at the global position of the gesture.
|
||
|
var magnifierPosition = currentMagnifierInfo.globalGesturePosition;
|
||
|
|
||
|
// You may use the `MagnifierInfo` however you'd like:
|
||
|
// In this case, we make sure the magnifier never goes out of the current line bounds.
|
||
|
magnifierPosition = Offset(
|
||
|
clampDouble(
|
||
|
magnifierPosition.dx,
|
||
|
currentMagnifierInfo.currentLineBoundaries.left,
|
||
|
currentMagnifierInfo.currentLineBoundaries.right,
|
||
|
),
|
||
|
clampDouble(
|
||
|
magnifierPosition.dy,
|
||
|
currentMagnifierInfo.currentLineBoundaries.top,
|
||
|
currentMagnifierInfo.currentLineBoundaries.bottom,
|
||
|
),
|
||
|
);
|
||
|
|
||
|
// Finally, align the magnifier to the bottom center. The initial anchor is
|
||
|
// the top left, so subtract bottom center alignment.
|
||
|
magnifierPosition -= Alignment.bottomCenter.alongSize(magnifierSize);
|
||
|
|
||
|
return Positioned(
|
||
|
left: magnifierPosition.dx,
|
||
|
top: magnifierPosition.dy,
|
||
|
child: RawMagnifier(
|
||
|
magnificationScale: 2,
|
||
|
// The focal point starts at the center of the magnifier.
|
||
|
// We probably want to point below the magnifier, so
|
||
|
// offset the focal point by half the magnifier height.
|
||
|
focalPointOffset: Offset(0, magnifierSize.height / 2),
|
||
|
// Decorate it however we'd like!
|
||
|
decoration: const MagnifierDecoration(
|
||
|
shape: StarBorder(
|
||
|
side: BorderSide(
|
||
|
color: Colors.green,
|
||
|
width: 2,
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
size: magnifierSize,
|
||
|
),
|
||
|
);
|
||
|
});
|
||
|
}
|
||
|
}
|