【发布时间】:2020-11-04 01:17:49
【问题描述】:
我想使图像适合视口,保持纵横比和浏览器的默认缩放行为。基本上,想要的行为就像用 Chrome 或 Firefox 打开本地图像一样。 这是我的项目的详细信息:
- 我有一个比例为 4896x3264 的巨大 Unsplash 图像
- 我想创建一种“Waldo 在哪里”游戏,用户必须放大以检查图像的每个细节。默认情况下,我希望图像适合屏幕(在这种情况下,最大高度为 100%)。然后用户可以使用 ctrl + 滚动(或任何其他快捷键)放大/缩小。
- 它显示在 Angular 9 应用程序中,组件的 html 简单地是:
<img src="../../assets/img/Background.webp"/>我用我的<router-outlet>访问这个 html。
因此,现在当导航到此页面时,图像会以其原始尺寸 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 的图像拟合到视口的主题,但我找不到像我的项目这样的东西。由于英语不是我的母语,我可能无法很好地在网上搜索,如果已经解决了类似问题,请告诉我。
实际行为截图:https://ibb.co/DLChrtp
想要的默认行为截图:https://ibb.co/p0hLDxn
提前感谢您的帮助。
编辑: 我不确定我是否全面描述了想要的行为(我的词汇限制了我)。查看@NVRM 答案了解更多详情
编辑解决方法:
因为我没有找到开箱即用的东西,所以我用 Typescript + CSS 重新创建了这个行为。我的想法只是将 ngClass 从响应式类(最大高度:100%)切换到没有宽度和高度限制的原始类。在我的游戏中,我必须检索点击的确切位置,我也将它与 scrollTo 一起使用,以便将视图置于所需坐标的中心。
我不得不使用lifecycleHook AfterViewChecked,因为我需要在切换类后滚动视图。
我必须使用滚动标志(布尔值),否则当我单击scrollOut 时也会触发scrollTo(x,y)。
我知道这不是一个干净的解决方案(我实际上有比下面更多的代码,处理 dblclick 等其他东西,所以某些部分对你来说可能不是最佳的)但它确实是想要的行为,所以我现在会坚持下去.
在.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;
}
【问题讨论】:
-
@NVRM 使用背景大小时,我得到的结果与现在相同。我仍然无法放大/缩小,图像将始终适合屏幕 100% 的高度
标签: javascript html css angular image