I would recommend use of getBoundingClientRect().
When the browser do a re-flow/update this method returns the position (relative to view-port) of the element.
It's widely supported cross-browser so there is really no reason not to use it IMO. Though, if you need backward-compatibility to support old browsers you should use a different method.
However, there are a few of things you need to be aware of when using this method:
- Element CSS padding affects the position relative to canvas if > 0.
- Element CSS border width affects the position relative to canvas if > 0.
- The resulting object is static, ie. it is not updated even if for example view-port changed before you use the object.
You need to add the widths of those, top and left, to your position manually. These are included by the method which means you need to compensate for this to get the position to be relative to canvas.
If you don't use border and/or padding it's straightforward. But when you do you either need to add the absolute widths of those in pixels, or if they are unknown or dynamic, you would need to mess with getComputedStyle method and getPropertyValue to get those (these gives the size always in pixels even if the original definition of the border/padding was in a different unit).
These are values you can cache for the most part if used, unless border and padding is also changing but in most use-cases this is not the case.
You clarified that performance isn't the issue and you are correct in doing so as none of these methods you list are the real bottlenecks (but of course fully possible to measure if you know how to do performance testing). Which method you use becomes in essence a personal taste rather than a performance issue as the bottleneck lays in pushing the events themselves through the event chain.
But the most "modern" (if we define modern as newer and more convenient) is getBoundingClientRect() and avoiding border/padding on the element makes it a breeze to use.