Hover mini-map marker in box coordinates
This commit is contained in:
@@ -97,11 +97,15 @@ const blueprintUrl = computed(() => {
|
|||||||
// the wrong level's dimensions is precisely how a marker ends up plausibly
|
// the wrong level's dimensions is precisely how a marker ends up plausibly
|
||||||
// placed and wrong.
|
// placed and wrong.
|
||||||
const markerX = computed(() => {
|
const markerX = computed(() => {
|
||||||
return (props.left / dimensionsFor(props.levelid).width) * 100
|
const fraction = props.left / dimensionsFor(props.levelid).width
|
||||||
|
const { offsetX, scaleX } = paintedBox.value
|
||||||
|
return (offsetX + fraction * scaleX) * 100
|
||||||
})
|
})
|
||||||
|
|
||||||
const markerY = computed(() => {
|
const markerY = computed(() => {
|
||||||
return (props.top / dimensionsFor(props.levelid).height) * 100
|
const fraction = props.top / dimensionsFor(props.levelid).height
|
||||||
|
const { offsetY, scaleY } = paintedBox.value
|
||||||
|
return (offsetY + fraction * scaleY) * 100
|
||||||
})
|
})
|
||||||
|
|
||||||
// Marker style with counter-scale to maintain constant size
|
// Marker style with counter-scale to maintain constant size
|
||||||
@@ -120,9 +124,33 @@ const markerStyle = computed(() => ({
|
|||||||
// lands in the grey gutter beside the map. Levels near 390:300 looked correct,
|
// lands in the grey gutter beside the map. Levels near 390:300 looked correct,
|
||||||
// which is why it only affected some assets.
|
// which is why it only affected some assets.
|
||||||
//
|
//
|
||||||
// The fix is to let the IMAGE size the frame: the frame shrink-wraps the drawing,
|
// The preview is a fixed box and object-fit: contain paints the drawing inside it
|
||||||
// so a percentage of the frame IS a percentage of the drawing, whatever the
|
// at the drawing's own aspect ratio, so the drawing does not fill the box: it is
|
||||||
// level's aspect ratio. The letterboxing moves out to the preview around it.
|
// letterboxed on one axis. A marker placed at a percentage of the BOX therefore
|
||||||
|
// lands somewhere else than the same percentage of the DRAWING, on any level
|
||||||
|
// whose shape is not the box's.
|
||||||
|
//
|
||||||
|
// So convert: work out where the painted drawing sits inside the box, then map
|
||||||
|
// the marker into box coordinates. Doing it here rather than by resizing the
|
||||||
|
// frame keeps the centring transform below honest - its percentages resolve
|
||||||
|
// against the element, so the element has to stay the size of the box.
|
||||||
|
const PREVIEW_WIDTH = 390 // keep in step with .map-preview in the styles
|
||||||
|
const PREVIEW_HEIGHT = 300
|
||||||
|
const PREVIEW_ASPECT = PREVIEW_WIDTH / PREVIEW_HEIGHT
|
||||||
|
|
||||||
|
// Fraction of the box the drawing covers, and the gap before it, per axis.
|
||||||
|
const paintedBox = computed(() => {
|
||||||
|
const { width, height } = dimensionsFor(props.levelid)
|
||||||
|
const levelAspect = width / height
|
||||||
|
if (levelAspect >= PREVIEW_ASPECT) {
|
||||||
|
// Wider than the box: full width, bars above and below.
|
||||||
|
const scale = PREVIEW_ASPECT / levelAspect
|
||||||
|
return { scaleX: 1, offsetX: 0, scaleY: scale, offsetY: (1 - scale) / 2 }
|
||||||
|
}
|
||||||
|
// Taller than the box: full height, bars left and right.
|
||||||
|
const scale = levelAspect / PREVIEW_ASPECT
|
||||||
|
return { scaleX: scale, offsetX: (1 - scale) / 2, scaleY: 1, offsetY: 0 }
|
||||||
|
})
|
||||||
// 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
|
||||||
@@ -265,12 +293,6 @@ 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;
|
||||||
@@ -281,23 +303,21 @@ watch(currentTheme, () => {
|
|||||||
|
|
||||||
.map-transform {
|
.map-transform {
|
||||||
position: relative;
|
position: relative;
|
||||||
/* Shrink-wraps the image rather than filling the preview, so the box the
|
/* Fills the preview. The centring transform translates by percentages, which
|
||||||
marker is positioned in is the box the drawing is painted in. */
|
resolve against THIS element, so it must stay the size of the box it is
|
||||||
max-width: 100%;
|
centring within. The letterbox is accounted for in the marker maths. */
|
||||||
max-height: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
transition: transform 0.15s ease-out;
|
transition: transform 0.15s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-image {
|
.map-image {
|
||||||
/* Sizes itself from the drawing, scaled down to fit the preview. NOT
|
width: 100%;
|
||||||
width/height 100% with object-fit: contain - that painted the drawing
|
height: 100%;
|
||||||
letterboxed inside a box the marker was measured against, which put the two
|
/* contain, so a level of any shape is shown whole and undistorted. Where the
|
||||||
in different coordinate spaces on any level that is not 390:300. */
|
bars fall is computed in paintedBox and folded into the marker position. */
|
||||||
|
object-fit: contain;
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
width: auto;
|
|
||||||
height: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.marker-dot {
|
.marker-dot {
|
||||||
|
|||||||
Reference in New Issue
Block a user