如何将图像从固定大小动画化为全屏?
How to animate image from fixed size to fullscreen?
有一个网站页面的高度和宽度等于浏览器视口的 100%(100vw 和 100vh)。
页面中央的绝对定位包装内有一张高质量图片 (3000x2857px)。图像包装器具有以像素为单位的最大宽度(例如 300 像素)。
此外,图像有叠加层。我通过单击覆盖将 .active
class 添加到图像包装器。 class 使图像包装器的最大宽度等于 100vw。
所以,我想制作动画。我向 max-width
、top
、transform
属性添加了过渡,但它很慢。我知道这是由于 top
和 max-width
属性导致的,因为浏览器的计算量很大。但是我不知道怎么用其他方式。
欢迎任何帮助!
P.S。当我写这个问题时,我发现这个实现在 Safari 中是有问题的。我认为转换过渡在此浏览器中不起作用,因此如果您建议在其中工作的代码会很棒:(
演示:https://codepen.io/ghettojezuz/pen/ExvGwJB
const imageWrapper = document.getElementById("image-wrapper");
const overlay = document.getElementById("overlay");
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 300px;
width: 100%;
transition: max-width .8s ease, top .8s ease, transform .8s ease;
}
.image-wrapper.active {
max-width: 100vw;
left: 50%;
top: 0;
transform: translate(-50%, 0);
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: background-color .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>
因此,我尝试了多种方法,例如不同的 css 属性、@keyframes
动画等。其中 None 有效。但是我发现当图像格式为SVG时,冻结消失了。我知道,并非所有图像都可以转换为 SVG,但看看你能做些什么。
我改变了顶部并用 flex 变换,现在当你点击时只有宽度变化,但我想在变换动画的情况下有时会出现延迟
const imageWrapper = document.getElementById("image-wrapper");
const overlay = document.getElementById("overlay");
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.img_container {
max-width:300px;
transition: .5s;
position:relative;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 0;
top: 0;
bottom:0;
right:0;
display:flex;
align-items:center;
justify-content:center;
width: 100%;
transition: .5s;
}
.image-wrapper.active .img_container {
max-width: 100vw;
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: background-color .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<div class="img_container">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>
</div>
似乎对过渡反应良好的一种方法是改变比例,而不是尝试重新定位和改变宽度等。
此代码段使图像居中并计算从初始宽度移动到 100vw 所需的比例。
注意:它删除了元素的边距以确保覆盖视口的整个宽度。
const imageWrapper = document.querySelector('.image-wrapper');
const overlay = document.querySelector('.image-overlay');
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
function init() {
const w = window.innerWidth;
const scale = w / imageWrapper.offsetWidth;
imageWrapper.style.setProperty('--scale', scale);
}
window.onload = init;
window.onresize = init;
* {
padding: 0;
margin: 0;
}
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 300px;
width: 100%;
transition: .8s ease;
}
.image-wrapper.active {
transform: translate(-50%, -50%) scale(var(--scale));
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: scale .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>
有一个网站页面的高度和宽度等于浏览器视口的 100%(100vw 和 100vh)。
页面中央的绝对定位包装内有一张高质量图片 (3000x2857px)。图像包装器具有以像素为单位的最大宽度(例如 300 像素)。
此外,图像有叠加层。我通过单击覆盖将 .active
class 添加到图像包装器。 class 使图像包装器的最大宽度等于 100vw。
所以,我想制作动画。我向 max-width
、top
、transform
属性添加了过渡,但它很慢。我知道这是由于 top
和 max-width
属性导致的,因为浏览器的计算量很大。但是我不知道怎么用其他方式。
欢迎任何帮助!
P.S。当我写这个问题时,我发现这个实现在 Safari 中是有问题的。我认为转换过渡在此浏览器中不起作用,因此如果您建议在其中工作的代码会很棒:(
演示:https://codepen.io/ghettojezuz/pen/ExvGwJB
const imageWrapper = document.getElementById("image-wrapper");
const overlay = document.getElementById("overlay");
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 300px;
width: 100%;
transition: max-width .8s ease, top .8s ease, transform .8s ease;
}
.image-wrapper.active {
max-width: 100vw;
left: 50%;
top: 0;
transform: translate(-50%, 0);
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: background-color .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>
因此,我尝试了多种方法,例如不同的 css 属性、@keyframes
动画等。其中 None 有效。但是我发现当图像格式为SVG时,冻结消失了。我知道,并非所有图像都可以转换为 SVG,但看看你能做些什么。
我改变了顶部并用 flex 变换,现在当你点击时只有宽度变化,但我想在变换动画的情况下有时会出现延迟
const imageWrapper = document.getElementById("image-wrapper");
const overlay = document.getElementById("overlay");
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.img_container {
max-width:300px;
transition: .5s;
position:relative;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 0;
top: 0;
bottom:0;
right:0;
display:flex;
align-items:center;
justify-content:center;
width: 100%;
transition: .5s;
}
.image-wrapper.active .img_container {
max-width: 100vw;
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: background-color .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<div class="img_container">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>
</div>
似乎对过渡反应良好的一种方法是改变比例,而不是尝试重新定位和改变宽度等。
此代码段使图像居中并计算从初始宽度移动到 100vw 所需的比例。
注意:它删除了元素的边距以确保覆盖视口的整个宽度。
const imageWrapper = document.querySelector('.image-wrapper');
const overlay = document.querySelector('.image-overlay');
function toggleImageWrapper() {
if (imageWrapper.classList.contains('active')) {
imageWrapper.classList.remove('active');
} else {
imageWrapper.classList.add('active');
}
}
overlay.addEventListener("click", () => {
toggleImageWrapper();
})
function init() {
const w = window.innerWidth;
const scale = w / imageWrapper.offsetWidth;
imageWrapper.style.setProperty('--scale', scale);
}
window.onload = init;
window.onresize = init;
* {
padding: 0;
margin: 0;
}
body {
min-height: 100vh;
overflow-x: hidden;
}
img {
width: 100%;
height: auto;
}
.wrapper {
width: 100vw;
min-height: 100vh;
height: 100%;
}
.image-wrapper {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 300px;
width: 100%;
transition: .8s ease;
}
.image-wrapper.active {
transform: translate(-50%, -50%) scale(var(--scale));
}
.image-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: transparent;
opacity: .7;
transition: scale .3s ease;
cursor: pointer;
}
.image-overlay:hover {
background-color: #000000;
}
<div class="wrapper">
<div class="image-wrapper" id="image-wrapper">
<img src="https://via.placeholder.com/3000x2857.webp" alt="">
<div class="image-overlay" id="overlay"></div>
</div>
</div>