我在CSS中设置了一个关键帧动画.将它附加到DOM元素并将其设置为暂停.使用javascript(jQuery),我正在改变动画延迟,0s以便100s在滚动时实现漂亮的动画.
这适用于所有浏览器,但不适用于Safari(版本11.1.1(13605.2.8)).
$(document).ready(function() {
fluider([
{
selector: '.manualAnim',
start: 100,
end: 500
},
{
selector: '.manualAnim2',
start: 500,
end: 1000
},
{
selector: '.manualAnim3',
start: 0,
end: 1500
}
])
})
function fluider(o) {
for(var i = 0; i < o.length; i++) {
$(o[i].selector).css('animation-play-state','paused');
$(o[i].selector).css('animation-duration','100s');
}
$(window).scroll(function() {
var h = $(window).scrollTop();
for(var i = 0; i < o.length; i++) {
$(o[i].selector).css('animation-delay',-clamp(0,100,((h-o[i].start)/o[i].end * 100)) + 's');
}
});
}
function clamp(from, to, val) {
if(val >= from) {
if(val <= to) {
return val;
}
else {
return to;
}
}
else {
return from;
}
}Run Code Online (Sandbox Code Playgroud)
body {
height: 1000vh;
}
.manualAnim {
position: fixed;
display: block;
width: 100px;
height: 100px;
background-color: red;
animation: 100s anim paused both;
animation-delay: 0s;
}
.manualAnim2 {
position: fixed;
display: block;
left: 120px;
width: 100px;
height: 100px;
background-color: red;
animation: 100s anim paused both;
animation-delay: 0s;
}
.manualAnim3 {
position: fixed;
display: block;
left: 240px;
width: 100px;
height: 100px;
background-color: red;
animation: 100s anim paused both;
animation-delay: 0s;
}
@keyframes anim{
0% {
background-color: red;
transform: scale(1);
}
30% {
background-color: green;
transform: scale(1.5);
}
60% {
background-color: blue;
transform: scale(0.5);
}
100% {
background-color: yellow;
transform: scale(1);
}
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="manualAnim"></div>
<div class="manualAnim2"></div>
<div class="manualAnim3"></div>Run Code Online (Sandbox Code Playgroud)
我现在用谷歌搜索了几个小时,但我不知道可能是什么问题.任何的想法?
经过大量实验后,这里有一个包含解决方法的版本,可以在Safari 11.1.2 和 Chrome 68(希望其他浏览器也能)中提供流畅、预期的行为。
正如问题所述,根本问题似乎是当暂停动画的动画属性发生更改时,元素不会重新绘制。该解决方案通过在每帧重新添加必要的动画相关 CSS(具有正确的延迟)来解决这个问题。这通常会导致闪烁(因为当动画被删除时,Safari 会尝试恢复为无动画样式),因此此解决方案每次修改动画时都会手动应用当前的动画样式。
$(document).ready(function() {
fluider([{
selector: '.manualAnim',
start: 100,
end: 500
},
{
selector: '.manualAnim2',
start: 500,
end: 1000
},
{
selector: '.manualAnim3',
start: 0,
end: 1500
}
])
})
function getAnimatedProperties(animName) {
// Get an array of all property names that
// are modified by the animation ${animName}
let properties = {};
let sheets = document.styleSheets;
let propertyRegex = /([a-z\-]+):/ig;
for (let sheet of sheets) {
let rules = sheet.rules || sheet.cssRules;
for (let r of rules) {
if (r.name === animName) {
let rText = r.cssText;
let match = propertyRegex.exec(rText);
while (match) {
properties[match[1]] = true;
match = propertyRegex.exec(rText);
}
}
}
}
return Object.keys(properties);
}
function fluider(o) {
const animationName = "anim";
const preservedProperties = getAnimatedProperties(animationName);
$(window).scroll(function() {
var h = $(window).scrollTop();
for (var i = 0; i < o.length; i++) {
let el = document.querySelector(o[i].selector);
let pct = 100 * (parseInt(h) - o[i].start) / o[i].end;
let delay = -Math.max(Math.min(pct, 100), 0) + 's';
let s = window.getComputedStyle(el);
// without setting these properties and overwriting .style,
// the animation will flicker
let preservedStyles = preservedProperties.map(p => `${p}: ${s[p]};`).join("");
el.style = `${preservedStyles} animation-delay: ${delay}; animation-duration: 100s; animation-play-state: paused;`;
// without scheduling this *using setTimeout*,
// the animation will not rerender
window.setTimeout(() => {
el.style.animationName = animationName;
}, 0);
}
});
}Run Code Online (Sandbox Code Playgroud)
body {
height: 1000vh;
}
.manualAnim {
position: fixed;
display: block;
width: 100px;
height: 100px;
background-color: red;
}
.manualAnim2 {
position: fixed;
display: block;
left: 120px;
width: 100px;
height: 100px;
background-color: red;
}
.manualAnim3 {
position: fixed;
display: block;
left: 240px;
width: 100px;
height: 100px;
background-color: red;
}
@keyframes anim {
0% {
background-color: red;
transform: scale(1);
}
30% {
background-color: green;
transform: scale(1.5);
}
60% {
background-color: blue;
transform: scale(0.5);
}
100% {
background-color: yellow;
transform: scale(1);
}
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="manualAnim"></div>
<div class="manualAnim2"></div>
<div class="manualAnim3"></div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
244 次 |
| 最近记录: |