Measure a hover marker against the drawing, not the box around it
Reported from the floor: some assets showed their hover mini-map marker way off to the left, outside the map, while the SAME asset sat correctly on the main map. The data was right; the preview was drawing it wrong. The preview is a fixed 390x300 box and the drawing was painted into it with object-fit: contain, which letterboxes or pillarboxes to keep the drawing's own aspect ratio. The marker, though, was positioned at a percentage of the BOX. So the marker and the drawing were measured in two different coordinate spaces, and they only agreed when the level's aspect ratio happened to be 390:300. A level near that ratio looked perfect - 3300x2550 is 1.294 against the box's 1.300 - which is why this read as "some devices" rather than "the feature is broken". A taller drawing pillarboxes, every marker's x shifts, and one near the left edge lands in the grey gutter beside the map. The image now SIZES the frame instead of filling it: the transform box shrink-wraps the image and the image scales down to fit. A percentage of the frame is therefore a percentage of the drawing by construction, at any aspect ratio, and the letterboxing moves out to the preview around it where it does no harm. dimensionsFor still converts the stored pixels to percentages - that part was always right. NOT visually confirmed against a live instance. The reasoning is traced and the build is clean, but the shape of this bug is that it looks correct on any level close to the old box ratio, so it wants a look at an asset that was landing left and one that was already fine. Related and NOT addressed: the wheel zoom applies translate percentages that resolve against the element and are then multiplied by scale, so a zoomed preview may still drift. At rest, which is the reported case, it is exact.
This commit is contained in:
@@ -111,6 +111,18 @@ const markerStyle = computed(() => ({
|
|||||||
transform: `translate(-50%, -50%) scale(${1 / zoom.value})`
|
transform: `translate(-50%, -50%) scale(${1 / zoom.value})`
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// The frame the marker's percentages are measured against MUST be the frame the
|
||||||
|
// drawing is painted in. The image used object-fit: contain inside a fixed
|
||||||
|
// 390x300 box, so a level whose drawing is not that aspect ratio was letterboxed
|
||||||
|
// or pillarboxed - and the marker, positioned at a percentage of the BOX, then
|
||||||
|
// sat in a different coordinate space from the drawing inside it. A tall
|
||||||
|
// drawing pillarboxes, every marker's x shifts, and one near the left edge
|
||||||
|
// lands in the grey gutter beside the map. Levels near 390:300 looked correct,
|
||||||
|
// which is why it only affected some assets.
|
||||||
|
//
|
||||||
|
// The fix is to let the IMAGE size the frame: the frame shrink-wraps the drawing,
|
||||||
|
// so a percentage of the frame IS a percentage of the drawing, whatever the
|
||||||
|
// level's aspect ratio. The letterboxing moves out to the preview around it.
|
||||||
// Transform style that centers on the marker and zooms toward it
|
// Transform style that centers on the marker and zooms toward it
|
||||||
const transformStyle = computed(() => {
|
const transformStyle = computed(() => {
|
||||||
// Calculate translation to center the marker in the preview
|
// Calculate translation to center the marker in the preview
|
||||||
@@ -253,6 +265,12 @@ watch(currentTheme, () => {
|
|||||||
|
|
||||||
.map-preview {
|
.map-preview {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
/* Centres the aspect-fitted frame, which is where the letterboxing now
|
||||||
|
happens. The frame carries the drawing AND the marker, so the two can no
|
||||||
|
longer disagree. */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
/* Smaller than it was: this is a glance-and-move-on preview, and at 500px it
|
/* Smaller than it was: this is a glance-and-move-on preview, and at 500px it
|
||||||
covered the row it was launched from. Aspect ratio kept. */
|
covered the row it was launched from. Aspect ratio kept. */
|
||||||
width: 390px;
|
width: 390px;
|
||||||
@@ -263,15 +281,23 @@ watch(currentTheme, () => {
|
|||||||
|
|
||||||
.map-transform {
|
.map-transform {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
/* Shrink-wraps the image rather than filling the preview, so the box the
|
||||||
height: 100%;
|
marker is positioned in is the box the drawing is painted in. */
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
transition: transform 0.15s ease-out;
|
transition: transform 0.15s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-image {
|
.map-image {
|
||||||
width: 100%;
|
/* Sizes itself from the drawing, scaled down to fit the preview. NOT
|
||||||
height: 100%;
|
width/height 100% with object-fit: contain - that painted the drawing
|
||||||
object-fit: contain;
|
letterboxed inside a box the marker was measured against, which put the two
|
||||||
|
in different coordinate spaces on any level that is not 390:300. */
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.marker-dot {
|
.marker-dot {
|
||||||
|
|||||||
Reference in New Issue
Block a user