Я хочу подогнать изображение под область просмотра, сохраняя соотношение сторон и стандартное поведение масштабирования браузера. По сути, желаемое поведение точно такое же, как при открытии локального образа с помощью Chrome или Firefox. Вот подробности моего проекта:
- У меня есть огромное Unspla sh изображение с соотношением сторон 4896x3264
- Я хочу создать что-то вроде игры «Где находится Уолдо», где пользователь должен увеличить масштаб, чтобы проверить каждую деталь изображения. По умолчанию я хочу, чтобы изображение соответствовало экрану (в данном случае максимальная высота 100%). Затем пользователь может увеличивать / уменьшать масштаб с помощью ctrl + scroll (или любого другого ярлыка).
- Он отображается в приложении angular 9, html компонента просто:
<img src="../../assets/img/Background.webp"/>
И Я получаю доступ к этому html с моим <router-outlet>
.
Итак, прямо сейчас при переходе на эту страницу изображение отображается с исходным размером 4896x3264, что слишком велико для обычного экрана. С помощью CSS я могу установить высоту и ширину в соответствии с размером окна просмотра (и центрировать его) следующим образом:
img {
max-height: 100%;
display: block;
}
Однако с этим решением я больше не могу увеличивать масштаб, чтобы увидеть детали изображения . Даже если я увеличу масштаб до 500%, изображение останется подходящим (на моем экране с разрешением 1536 x 722).
При открытии локального изображения в браузере (Chrome или Firefox) я получаю именно то, что нужно поведение: По умолчанию (100% масштаб) он подходит для 1017x678. Я могу увеличить изображение до 4896x3264, щелкнув по нему. И я могу постепенно увеличивать масштаб с помощью ctrl + scroll. При осмотре консоли я вижу, что ширина и высота автоматически меняются при увеличении и уменьшении масштаба: <img style="-webkit-user-select: none;margin: auto;cursor: zoom-in;"src="file:///D:/Videotec/Background.webp" width="1083" height="722">
Есть ли способ добиться такого поведения в моем приложении? Я нашел много тем о подгонке изображений с css в область просмотра, но не смог найти ничего похожего на свой проект. Поскольку английский sh не является моим родным языком, я, возможно, плохо искал в Интернете, дайте мне знать, если что-то подобное уже было решено. *
Снимок экрана требуемого поведения по умолчанию: https://ibb.co/p0hLDxn
Заранее благодарим за вашу помощь.
РЕДАКТИРОВАТЬ : Я не уверен, что Я подробно описал желаемое поведение (мой словарный запас меня ограничивает). Обратитесь к ответу @NVRM для получения более подробной информации.
РЕДАКТИРОВАТЬ Обходной путь : Поскольку я не нашел ничего из коробки, я воссоздал поведение с помощью Typescript + CSS. Моя идея заключалась в том, чтобы просто переключить ngClass из адаптивного класса (max-height: 100%) в необработанный класс без ограничений по ширине и высоте. Как и в моей игре, мне нужно получить точное положение щелчка, которое я также использовал с scrollTo, чтобы центрировать представление по нужным координатам. Мне пришлось использовать lifecycleHook AfterViewChecked, так как мне нужно было прокручивать представление после переключения класса. Мне пришлось использовать флаг с прокруткой (логический), иначе scrollTo (x, y) также запускался, когда я нажимал для scrollOut. Я знаю, что это не чистое решение (на самом деле у меня больше кода, чем ниже, он обрабатывает другие вещи, такие как dblclick et c., Поэтому какая-то часть может показаться вам не оптимальной), но оно выполняет именно то, что нужно, поэтому я буду придерживаться это пока.
дюймы html
<div #videotecContainer class="videotec-container">
<img
#videotecImage
src="../../assets/img/Videotec.webp"
[ngClass]="zoomed ? 'zoomedIn' : 'zoomedOut'"
(click)="onClick($event)"
/>
</div>
дюймы TS:
zoomed: boolean = false;
scrolled: boolean = false;
xPosition: number;
yPosition: number;
@ViewChild("videotecImage", { static: true }) videotecImage: ElementRef;
@ViewChild("videotecContainer", { static: true }) videotecContainer: ElementRef;
onClick(event: any) {
const coordinates = this.getPixelPositions(event);
this.xPosition = coordinates.px - coordinates.clientWidth / 2;
this.yPosition = coordinates.py - coordinates.clientHeight / 2;
this.zoomImage();
}
zoomImage() {
if (this.zoomed && this.scrolled) this.scrolled = false;
this.zoomed = !this.zoomed;
}
ngAfterViewChecked() {
if (this.zoomed && !this.scrolled) {
this.videotecContainer.nativeElement.scrollTo(
this.xPosition,
this.yPosition
);
this.scrolled = true;
}
getPixelPositions(event) {
//do some calculation based on Wolfgang Fahl answer here :
//questions/34867066
}
дюймы css:
.zoomedOut {
max-height: 100%;
max-width: 100%;
display: block;
margin: auto;
}
.zoomedIn {
display: block;
}
#videotecImage {
overflow: scroll;
}
.videotec-container {
height: 100vh;
overflow: scroll;
background-color: black;
}