# AnnotatedRegionLayers return local position relative to clipping region

> Provide annotation searches with reliable and meaningful local positions.




:::important
These breaking change docs are accurate, as of the release
under which they are published. Over time, the
workarounds described here might become inaccurate.
We don't, in general, keep these breaking change docs up
to date as of each release.

这些破坏性改动文档的准确性仅限于其发布时对应的版本。
随着时间的推移，文档中描述的方案可能会逐渐失效。
通常情况下，我们不会在每次发布新版本时都对这些文档进行同步更新。

The [breaking change index file](/release/breaking-changes)
lists the docs created for each release.

[破坏性改动列表](/release/breaking-changes) 
列出了每个版本的文档。

:::


## Summary

The local position returned by `AnnotatedRegionLayers` in an
annotation search has been changed to be relative to the clipping
region instead of the layer. This makes the local position more
meaningful and reliable, but breaks code that directly performs
annotation searches and uses the local position.

## Context

Annotations are metadata that are assigned during the
rendering phase to regions on the screen.
Searching the annotations with a location gives the
contextual information that contains that location.
They are used to detect mouse events and the theme of app bars.

When `localPosition` was first added to the search result,
it was defined as relative to the layer that owned the annotation,
which turned out to be a design mistake.
The offset from the layer is meaningless and unreliable.
For example, a `Transform` widget draws on the same layer
with an offset if the transform matrix is a simple translation,
or push a dedicated `TransformLayer` if the matrix is non-trivial.
The former case keeps the previous coordinate origin
(for example, the top left corner of the app),
while the latter case moves the position origin since
it's on a new layer. The two cases might not produce noticeable
visual differences, since the extra layer might just be a scale of
99%, despite that the annotation search returns different results.
In order to make this local position reliable, we have to choose
one of the results to stick to.

## Description of change

The `localPosition` returned by an `AnnotatedRegionLayer`
is now the local position it received subtracted by `offset`,
where `offset` is the location of the clipping area relative
to the layer.

```dart
class AnnotatedRegionLayer<T> extends ContainerLayer {
  @override
  bool findAnnotations<S>(AnnotationResult<S> result, Offset localPosition, { required bool onlyFirst }) {
    ...
    if (/* shouldAddAnnotation */) {
      result.add(AnnotationEntry<S>(
        annotation: typedValue,
        // Used to be:
        // localPosition: localPosition,
        localPosition: localPosition - offset,
      ));
    }
    ...
  }
}
```

Conceptually, this has changed how `AnnotatedRegionLayer.offset`
and `size` are defined. They used to mean
"the clipping rectangle that restricts the annotation search",
while they now jointly represent
"the region of the annotation object".

## Migration guide

Code that is actively using this local position is probably
directly interacting with layers, since using render objects or
widgets have already made this result unreliable. In order to
preserve the previous behavior, you can reimplement
`AnnotatedRegionLayer` to return a local position without
subtracting the offset.

## Timeline

Landed in version: 1.15.2<br>
In stable release: 1.17

## References

API documentation:

* [`AnnotatedRegionLayer`][]
* [`AnnotationEntry`][]

Relevant issues:

* [Issue #49568][]

Relevant PR:

* [Make Annotation's localPosition relative to object][]

[`AnnotatedRegionLayer`]: https://api.flutter-io.cn/flutter/rendering/AnnotatedRegionLayer-class.html
[`AnnotationEntry`]: https://api.flutter-io.cn/flutter/rendering/AnnotationEntry-class.html
[Issue #49568]: https://github.com/flutter/flutter/issues/49568
[Make Annotation's localPosition relative to object]: https://github.com/flutter/flutter/pull/50157

