在 window 调整大小后重新计算 CSS @关键帧(100vw 和 100vh)

Re-calculate CSS @keyframes (100vw and 100vh) after a window resize

我正在 div.

中处理图像 bouncing around

此 div 具有浏览器 window 的大小。

(div 的大小为 100vw100vh 的大小为 CSS。)

问题:

调整浏览器大小后,图像漂浮在外部 div window 变小.

当我将浏览器 window 变大 时,图像在到达 window 的边缘 之前会反弹 ].

结论:当我调整window的大小时,div的图像在内部跳动不调整大小.

可能的解决方案:

在 window 调整大小后重新计算 CSS 关键帧(100vw 和 100vh)。

例如使浏览器 window 更大 -> 盒子更大。使浏览器 window 更小 -> 盒子更小。

问题:

我能否通过以下方式最好地解决我的问题:

  1. 使用 jQuery?
  2. window 调整大小后重新加载整个页面
  3. 通过检测 window 调整大小来重置 CSS 中的 vwvh
  4. ???

更新:

我刚才试过的(运气不好):

    $(window).resize(function() {
      $(".box").css('width','100%');
      $(".box").css('height','calc(100% - 160px)');
    });

更新 02:

我猜我可能必须在 window 调整大小后以某种方式重置它:

    @keyframes box {
      100% { transform: translateX( calc(100vw - 80px)); }
    }
    
    @keyframes smile {
      100% { transform: translateY( calc(100vh - 160px)); }
    }

我希望我能让盒子流畅地跟随浏览器 window 宽度和高度...

更新 03:

正如 'A Haworth' 在下面的评论中指出的,这个问题只发生在 Safari 而不是 Chrome。

更新 04

我目前正在使用 'A Haworth' 的临时解决方案,并仅在用户使用 Safari 时重新加载 window 调整大小的动画。

    const box = document.querySelector('.box');
    const smile = document.querySelector('.smile');

    if (
        navigator.userAgent.indexOf('Safari') != -1 && 
        navigator.userAgent.indexOf('Chrome') == -1 && 
        navigator.userAgent.indexOf('CriOS/') == -1
        )  { 

            function resize() {
                box.style.animationName = 'none';
                smile.style.animationName = 'none';
                $('.smile').hide();
                setTimeout(function () {
                    box.style.animationName = 'box';
                    smile.style.animationName = 'smile';
                    $('.smile').fadeIn('slow');
                }, 1000);
            }
            window.onresize = resize;
            }

片段:

body {
  overflow: hidden;
  padding: 0;
  margin: 0;
}

.box {
  position: absolute;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

.smile {
  height:  80px;
  width:  80px;
  margin: 0;
  padding: 0;
}

.box {
  animation: box 13s linear infinite alternate;
}

.smile {
  animation: smile 7s linear infinite alternate;
}

@keyframes box {
  100% {
    transform: translateX( calc(100vw - 80px));
  }
}

@keyframes smile {
  100% {
    transform: translateY( calc(100vh - 80px));
  }
}
<div class="box">
        <img class="smile" src="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/240/apple/285/smiling-face-with-sunglasses_1f60e.png" />
</div>

你可以使用@media查询来解决这个问题,更多的参考下面link https://www.w3schools.com/cssref/css3_pr_mediaquery.asp

由于您已经在使用在视口调整大小时自动更改的单位,因此您不需要进行任何重新计算。

我能看到的唯一问题是出现了改变 'edge' 的滚动条。你真的不想要这些,所以将整个容器设置为 overflow: hidden。在此代码段中,整个容器是 body 元素。

它还将填充和边距设置为 0,否则它看起来好像表情符号太早到达顶部。

更新:尝试通过删除动画并在一秒钟后再次设置它来强制动画重置为新的尺寸(应该能够使用 requestAnimationFrame 但目前还没有奏效)。这是在出现问题的Safari上试用。

const box = document.querySelector('.box');
const smile = document.querySelector('.smile');
function resize() {
  box.style.animationName = 'none';
  smile.style.animationName = 'none';
  setTimeout(function () {
    box.style.animationName = 'box';
    smile.style.animationName = 'smile';
  }, 1000);
}
window.onresize = resize;
body {
  overflow: hidden;
  padding: 0;
  margin: 0;
}
.box {
  position: absolute;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

.smile {
  height:  80px;
  width:  80px;
  margin: 0;
  padding: 0;
}

.box {
  animation: box 13s linear infinite alternate;
}

.smile {
  animation: smile 7s linear infinite alternate;
}

@keyframes box {
  100% {
    transform: translateX( calc(100vw - 80px));
  }
}

@keyframes smile {
  100% {
    transform: translateY( calc(100vh - 80px));
  }
}
<body>
<div class="box">
        <img class="smile" src="https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/240/apple/285/smiling-face-with-sunglasses_1f60e.png" />
</div>
</body>