【问题标题】:Re-calculate CSS @keyframes (100vw and 100vh) after a window resize调整窗口大小后重新计算 CSS @keyframes(100vw 和 100vh)
【发布时间】:2021-08-12 19:26:55
【问题描述】:

我正在处理 div 内的图像 bouncing around

这个 div 有浏览器窗口的大小。

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

问题:

在调整浏览器窗口变小后,图像会在 outside div 上浮动。

当我使浏览器窗口变大时,图像在碰到窗口边缘之前会弹跳

结论:当我调整窗口大小时,图像在里面弹跳的 div 不会调整大小

可能的解决方案:

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

例如使浏览器窗口更大-> 框更大。使浏览器窗口更小 -> 框更小。

问题:

我能否最好地解决我的问题:

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

更新:

我刚刚尝试过的(没有运气):

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

更新 02:

我猜我可能不得不在调整窗口大小后以某种方式重置它:

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

我希望我可以让框流畅地跟随浏览器窗口的宽度和高度...

更新 03:

正如“A Haworth”在下面的 cmets 中指出的那样,此问题仅发生在 Safari 中,而不发生在 Chrome 中。

更新 04

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

    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>

【问题讨论】:

标签: jquery css css-animations


【解决方案1】:

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

我能看到的唯一问题是出现了改变“边缘”的滚动条。你真的不想要这些,所以将整个容器设置为overflow: hidden。在这个 sn-p 中,整个容器是 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>

【讨论】:

  • sn-p 有点不对劲,你是对的。我正在使用的页面没有滚动条和偏移量。只是图像在其中反弹的框,只是没有流畅地跟随窗口调整大小 -_- jordy.studio
  • 我已经调整了各个方向的大小,并且弹跳看起来很好。你能解释一下问题是什么(或者甚至是你所看到的小视频sn-p,因为它必须与我所看到的不同)。我使用的是 Windows 10 Chrome/Edge。
  • 添加了几行 JS 来强制在调整大小时重置动画。似乎至少可以在 iPad IOS 14 上的 Safari 上运行。
  • 您可能可以使用 requestAnimationFrame 以避免暂停,或者至少减少超时。那我觉得解决办法不是暂时的,我觉得你得强制 Safari 重置 GPU 设置。
  • 不,它没有。我已经为此苦苦挣扎,但看不出有办法让它这样做。也无法在网络上找到任何帮助,尽管我们不能成为第一个尝试解决这个问题的人!我玩弄了听animationEnds的想法,但无法理解时间问题。
【解决方案2】:

您可以使用@media 查询来解决这个问题,更多请参考以下链接 https://www.w3schools.com/cssref/css3_pr_mediaquery.asp

【讨论】:

  • img 反弹框的宽度是在第一页加载时设置的,我试图在窗口调整大小后重置框的大小。我觉得@media 我必须为每个可能的窗口大小设置一个固定的框宽度和高度。数千?希望我说得通!我在这里可能是错的......
  • @Jordy,你是对的。您永远无法使用媒体查询来预测所有可能的视口大小 - 它不仅是无数具有不同尺寸/纵横比的物理设备,而且 Windows 类型机器上的用户几乎可以将视口设置为任何东西。
  • 如果是这种情况意味着,你可以使用 flexbox 或 grid,这将是响应式的。
猜你喜欢
  • 2012-12-22
  • 2012-01-24
  • 1970-01-01
  • 2018-07-30
  • 2012-10-29
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多