通过 js 检索和设置动态加载的图像大小
Retrieving and setting dynamically loaded image sizes via js
考虑这个 javascript 代码:
const profileImageURL = 'https://api.images.com/image/' + id +'/profile';
let profileImage = [];
async function getProfileImage() {
const response = await fetch(profileImageURL);
profileImage = await response.json();
};
和这个精巧的模板代码:
<div class="thumbImg">
{#await getProfileImage()}
<div class='spinnerHolder'
in:fade={{duration: 500}}
out:fade={{duration: 500}}
on:introstart={() => doneLoading = false}
on:outroend={() => doneLoading = true}
>
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>
</div>
{:then value}
{#if doneLoading}
<img transition:fade alt='profile-image' src={profileImage.url}/>
{/if}
{/await}
</div>
和css:
.thumbImg {
width: 64px;
height: 64px;
display:inline-block;
background-color: var(--border-color);
border: none;
border-radius: var(--large-radius);
overflow: hidden;
img {
min-width: 64px;
border-radius: var(--large-radius);
border-image-width: 0;
}
}
以上加载的图像到达不同的宽度和高度。一些肖像和一些风景。它们都需要显示在一个 64px x 64px 的正方形 1:1 框中,侧面或底部没有白色 space。我怎样才能保持这些动态加载图像的纵横比,以便它们根据需要填充宽度或高度?理想情况下,它们也会偏移,因此它们位于 1:1 框的中心。
问题的视觉示例:
您可以使用百分比值使图像相对于父级 div 的宽度和高度,或者只将图像设置为所需的最大宽度和最大高度
.thumbImg {
max-width: 64px;
max-height: 64px;
display:inline-block;
background-color: var(--border-color);
border: none;
border-radius: var(--large-radius);
overflow: hidden;
img {
max-width: 100%; //relative to the parent DIV
border-radius: var(--large-radius);
border-image-width: 0;
}
}
根据下面 Rich 的评论更新了答案
您可以结合使用 object-fit and object-position CSS 属性来微调图像在其内容框中的显示方式:
.thumbImg {
width: 64px;
height: 64px;
display:inline-block;
background-color: var(--border-color);
border: none;
border-radius: var(--large-radius);
overflow: hidden;
img {
height: 64px;
width: 64px;
object-fit: cover; // this will make the image cover the content box, clipping horizontally if the original image is landscape orientation, or vertically if it is portrait orientation
object-position: 50% 50%; // this will center the image in the content box (i.e. clip on the left & right if source is landscape and clip top & bottom if source is portrait)
}
}
有了这个,您就不需要再修改代码了。
原始答案,使用 CSS 背景图片
您可以使用背景图片 CSS 属性而不是 img
标签来实现所需的定位,例如:
.avatar {
height: 64px;
width: 64px;
background-size: cover; // this will make the image cover the div, clipping horizontally if the original image is landscape orientation, or vertically if it is portrait orientation
background-position: 50% 50%; // this will center the image (i.e. clip on the left & right if source is landscape and clip top & bottom if source is portrait)
}
有了这个,您所要做的就是用 <div class="avatar">
标签替换 <img>
标签,并动态设置背景图片源:
<div class="thumbImg">
{#await getProfileImage()}
<div class='spinnerHolder'
in:fade={{duration: 500}}
out:fade={{duration: 500}}
on:introstart={() => doneLoading = false}
on:outroend={() => doneLoading = true}
>
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>
</div>
{:then value}
{#if doneLoading}
<div
transition:fade
class="avatar"
alt="Profile image"
style="background-image: url('{profileImage.url}')"
/>
{/if}
{/await}
</div>
当然,缺点是您不再使用原生图像标签,也许这对您很重要。从好的方面来说,它无需使用基于 javascript 的 DOM 操作即可工作。
考虑这个 javascript 代码:
const profileImageURL = 'https://api.images.com/image/' + id +'/profile';
let profileImage = [];
async function getProfileImage() {
const response = await fetch(profileImageURL);
profileImage = await response.json();
};
和这个精巧的模板代码:
<div class="thumbImg">
{#await getProfileImage()}
<div class='spinnerHolder'
in:fade={{duration: 500}}
out:fade={{duration: 500}}
on:introstart={() => doneLoading = false}
on:outroend={() => doneLoading = true}
>
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>
</div>
{:then value}
{#if doneLoading}
<img transition:fade alt='profile-image' src={profileImage.url}/>
{/if}
{/await}
</div>
和css:
.thumbImg {
width: 64px;
height: 64px;
display:inline-block;
background-color: var(--border-color);
border: none;
border-radius: var(--large-radius);
overflow: hidden;
img {
min-width: 64px;
border-radius: var(--large-radius);
border-image-width: 0;
}
}
以上加载的图像到达不同的宽度和高度。一些肖像和一些风景。它们都需要显示在一个 64px x 64px 的正方形 1:1 框中,侧面或底部没有白色 space。我怎样才能保持这些动态加载图像的纵横比,以便它们根据需要填充宽度或高度?理想情况下,它们也会偏移,因此它们位于 1:1 框的中心。
问题的视觉示例:
您可以使用百分比值使图像相对于父级 div 的宽度和高度,或者只将图像设置为所需的最大宽度和最大高度
.thumbImg {
max-width: 64px;
max-height: 64px;
display:inline-block;
background-color: var(--border-color);
border: none;
border-radius: var(--large-radius);
overflow: hidden;
img {
max-width: 100%; //relative to the parent DIV
border-radius: var(--large-radius);
border-image-width: 0;
}
}
根据下面 Rich 的评论更新了答案
您可以结合使用 object-fit and object-position CSS 属性来微调图像在其内容框中的显示方式:
.thumbImg {
width: 64px;
height: 64px;
display:inline-block;
background-color: var(--border-color);
border: none;
border-radius: var(--large-radius);
overflow: hidden;
img {
height: 64px;
width: 64px;
object-fit: cover; // this will make the image cover the content box, clipping horizontally if the original image is landscape orientation, or vertically if it is portrait orientation
object-position: 50% 50%; // this will center the image in the content box (i.e. clip on the left & right if source is landscape and clip top & bottom if source is portrait)
}
}
有了这个,您就不需要再修改代码了。
原始答案,使用 CSS 背景图片
您可以使用背景图片 CSS 属性而不是 img
标签来实现所需的定位,例如:
.avatar {
height: 64px;
width: 64px;
background-size: cover; // this will make the image cover the div, clipping horizontally if the original image is landscape orientation, or vertically if it is portrait orientation
background-position: 50% 50%; // this will center the image (i.e. clip on the left & right if source is landscape and clip top & bottom if source is portrait)
}
有了这个,您所要做的就是用 <div class="avatar">
标签替换 <img>
标签,并动态设置背景图片源:
<div class="thumbImg">
{#await getProfileImage()}
<div class='spinnerHolder'
in:fade={{duration: 500}}
out:fade={{duration: 500}}
on:introstart={() => doneLoading = false}
on:outroend={() => doneLoading = true}
>
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>
</div>
{:then value}
{#if doneLoading}
<div
transition:fade
class="avatar"
alt="Profile image"
style="background-image: url('{profileImage.url}')"
/>
{/if}
{/await}
</div>
当然,缺点是您不再使用原生图像标签,也许这对您很重要。从好的方面来说,它无需使用基于 javascript 的 DOM 操作即可工作。