Использование background-size: cover
чрезвычайно ограничивает количество координат, которые могут быть отцентрированы из-за того, как работает cover
.
background-size: cover
увеличивает (или уменьшает размер) изображение, чтобы всегда отображать как можно большую часть изображения, сохраняя при этом возможность охватить весь контейнер.
Давайте представим несколько примеров:

В Случай # 1, изображение необходимо увеличить, чтобы width
изображения соответствовало width
.
контейнера.
В Случай № 2, изображение необходимо увеличить, чтобы height
изображения соответствовало height
.
контейнера.
В случае # 3, изображение необходимо сжать, чтобы height
изображения совпадало с height
.
контейнера.


Как вы уже могли заметить, изображение всегда будет центрировано уже по одной оси. Это означает, что вы можете центрировать изображение только на оставшейся оси. Кроме того, только координаты, которые находятся между двумя красными точками или красной линией , , которая в действительности имеет ширину 1px
, могут быть центрированы, иначе изображение не сможет охватить весь контейнер .
background: cover
недостаточно. Вам нужно использовать JS.
Подход Javascript
Чтобы найти решение, вам нужно знать ...
- внутренние размеры изображения , чтобы сохранить его пропорции.
- размеры контейнера в любой момент времени, , который является переменной.
- координаты, которые мы хотим отцентрировать, , который также является переменной.
После того, как я потратил часы, пытаясь понять это, я буквально осознал, что делать то, что вы хотите, совершенно нецелесообразно, потому что выходное изображение будет становиться бесконечно больше по мере приближения желаемых координат центра к краю исходного изображения. , Было действительно сложно вычислить формулу для получения правильного масштаба выходного изображения, потому что масштаб также является переменной. Единственный практический способ добиться этого - действительно ограничить то, какие координаты могут быть отцентрированы, скажем, применяя запретную зону вокруг внешних краев изображения, как границы (т.е. что-либо в этой области не может или не должно центрироваться) , Ширина так называемой границы будет полностью зависеть от разрешения изображения.

Вот то, над чем я работал. Вы можете продолжить с того места, где я остановился, хотя я должен предупредить вас, что код сейчас в беспорядке. Я занимался тем, как правильно масштабировать и позиционировать изображение, сохраняя состояние обложки. Фон в математике поможет большое время. Удачи.
const
srcImg = document.querySelector('#source-image'),
output = document.querySelector('#output')
let
srcImgWidth, srcImgHeight
const
test = document.querySelector('#test')
window.onload = ()=>{
srcImgWidth = srcImg.width
srcImgHeight = srcImg.height
}
srcImg.onclick = function(e){
const
ctrWidth = output.offsetWidth,
ctrHeight = output.offsetHeight,
compAxisX = ctrWidth / srcImgWidth,
compAxisY = ctrHeight / srcImgHeight,
rect = srcImg.getBoundingClientRect(),
x = e.clientX - rect.left,
y = e.clientY - rect.top
// create cover
if (compAxisX > compAxisY){
//console.log('width grow/shrink to match width')
output.style.backgroundSize = `${ctrWidth}px ${ctrWidth / srcImgWidth * srcImgHeight}px`
} else if (compAxisY > compAxisX) {
//console.log('height grow/shrink to match height')
output.style.backgroundSize = `${ctrHeight / srcImgHeight * srcImgWidth}px ${ctrHeight}px`
} else {
// square in square ???
output.style.backgroundSize = `${ctrWidth}px ${ctrHeight}px`
}
// determine scale of image
const
compAxisX1 = ctrWidth / 2 / x,
compAxisY1 = ctrHeight / 2 / y
let
qtrImplicitViewportX,
qtrImplicitViewportY,
scale
// cover container with implicit viewport
if (compAxisX1 > compAxisY1){
//console.log('width grow/shrink to match width')
qtrImplicitViewportX = ctrWidth / 2
qtrImplicitViewportY = ctrWidth / 2 / x * y
//srcImgWidth / x * scale * srcImgWidth + 'px'
//srcImgHeight / y * scale * srcImgHeight + 'px'
// x / srcImgWidth === qtrImplicitViewportY
newWidth = qtrImplicitViewportX / (x / srcImgWidth)
newHeight = qtrImplicitViewportY / (y / srcImgHeight)
console.log(newWidth, newHeight)
output.style.backgroundSize = `${newWidth}px ${newHeight}px`
output.style.backgroundPosition = '0% 100%'
} else if (compAxisY1 > compAxisX1){
//console.log('height grow/shrink to match height')
//qtrImplicitViewportX = ctrHeight / 2 / y * x
qtrImplicitViewportY = ctrHeight / 2
//srcImgWidth / x * scale * srcImgWidth + 'px'
//srcImgHeight / y * scale * srcImgHeight + 'px'
// x / srcImgWidth === qtrImplicitViewportY
newWidth = qtrImplicitViewportX / (x / srcImgWidth)
newHeight = qtrImplicitViewportY / (y / srcImgHeight)
console.log(newWidth, newHeight)
output.style.backgroundSize = `${newWidth}px ${newHeight}px`
output.style.backgroundPosition = '0% 100%'
} else {
}
test.style.width = newWidth + 'px'
test.style.height = newHeight + 'px'
test.style.bottom = output.getBoundingClientRect().bottom
test.style.left = output.getBoundingClientRect().left
}
#input-container {
padding: 10px;
display: inline-block;
background: grey;
}
#output {
width: 256px;
height: 377px;
resize: both;
position: relative;
overflow: auto;
box-sizing: border-box;
border: solid red 3px;
background-image: url('https://i.postimg.cc/s2PnSDmR/test0.png');
background-size: cover;
background-repeat: no-repeat;
}
#test {
z-index: -1;
width: 256px;
height: 377px;
position: absolute;
transform: translateY(-100%);
background: orange;
background-image: url('https://i.postimg.cc/s2PnSDmR/test0.png');
background-size: cover;
background-repeat: no-repeat;
}
<div id='input-container'>
<div>Click the Image to Center on Click Point</div>
<img id='source-image' src='https://i.postimg.cc/s2PnSDmR/test0.png' />
</div>
<div id='output'></div>
<div id='test'></div>