-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch to basic canvas operations to fix circle stroke position #1059
base: main
Are you sure you want to change the base?
Switch to basic canvas operations to fix circle stroke position #1059
Conversation
Also `circle-blur` is now possible so I added that also.
…anvas-rendering-for-circle
Although I think this will cause a decrease in performance when many circles are rendered, I'm in favor of this pull request because I don't think circles see much use compared to sprite symbols. |
Cool, thanks @ahocevar I'll get on it today. I think the performance would probably be very similar. Those canvas operations are probably as simple a we can make them so openlayer core would have to be doing something very similar (not 100% sure on that) and we still do caching, like before. I think the only difference would be the calling of a function + a bit of additional math. ol-mapbox-style/src/stylefunction.js Lines 1182 to 1192 in e392ac8
I assume the JS engine optimisation would do it's thing after a couple of thousand runs though making it a tiny perf loss. |
Another thing to consider is whether OpenLayers hit detection works with circles like these. |
Good shout on hit detection @ahocevar, I've added that now and all seems to be good. I've been testing on a few different devices using a modified apply('map', 'data/geojson-inline.json').then((map) => {
map.on('pointermove', (evt) => {
const features = [];
map.forEachFeatureAtPixel(
evt.pixel,
(feature) => {
features.push(feature);
},
{hitTolerance: 0}
);
console.log('features=', features);
});
}); This should be good to review/merge. |
I think this could be simplified by creating a separate canvas for the circle, and use it as image in an icon style. Then the whole hit detection code could go away. |
I'm not sure I understand @ahocevar. The hit detection needs to use a different render function than the normal render code. This is because a blur will have opacity from So for example we don't want hovering over an opacity of Thoughts? |
@orangemug I'm talking about a simpler approach altogether - instead of using canvas operations with a custom renderer, you could generate the circle once in a separate canvas, and use the separate canvas as |
Yeah @ahocevar I think I understand that. Sorry if I'm missing something, but how would your approach deal with blur (as mentioned in #1059 (comment) as why I took this approach) Blur needs to use a separate approach for hit boxes, which is the work in this PR. Also with regards to "circle once in a separate canvas" we already cache reused circles with the Does that make sense, or am I missing something all together 😄 |
The thing you're missing is that also for blur, you'd be creating a separate canvas (or image bitmap) which serves as an icon image in an Icon style. Hit detection will then just work on the image data, like with other icons. I had misread the code and thought your custom renderer would draw the circle to the canvas each time. Now that I see you're creating an Instead of calling |
This PR switches over to basic canvas rendering for circles to fix stroke position. Previously the stroke was positioned mid way along the line like so
Before
After
This also means that circles are visually the correct size. You can see the issue in these before screenshots from my (modified) spec helper, you can see that the total radius of the circle is incorrect because of the circle stroke sitting mid-way on the circle fill (rather than outside)
Because we're now using basic canvas operations I also added support for
circle-blur
@ahocevar if you're happy with the approach, let me know and I'll give it another good test prior to making it ready for merge.