2017-11-20 4 views
0

시간이 지남에 따라 background-position 요소를 변경하여 배경과 함께 스크롤 효과를 생성하는 CSS로 애니메이션을 만들었습니다.재설정하지 않고 배경 위치 애니메이션을 뒤집습니다.

@keyframes stars-animate { 
    0% { 
     background-position: 0 -500px; 
    } 
    100% { 
     background-position: 2000px -500px; 
    } 
} 

이것은 완벽하게 작동합니다. 그러나 애니메이션을 되감기 시작하고 역방향 스크롤 이벤트를 생성하기를 원합니다. 이 작업은 무의미한 작업에 의해 유발됩니다. 나는 animation-direction에 반대을 설정할 때

function triggerReverse(element) { 
    element.style.animationDirection = 'reverse'; 
} 

그러나,이 작업을 수행하지만, 전체 배경을 화나게하지 전에.

내가 잘못하고있는 것입니까, 아니면 잘못된 방법입니까? 그렇다면 올바른 방법은 무엇입니까?

편집 :이 재생되는 동안 나는 애니메이션을 반전 할 수 있어야합니다

답변

0

UPDATE

갱신 된 샘플 코드는 아래의 애니메이션을 일시 정지/중단하는 것을 가능 효과를 제공 (첫 번째 반복 과정에서) 즉시 애니메이션을 뒤집기 시작합니다.

여기서 제어를 위해 시간을 사용하고 있습니다. 애니메이션 시작부터 경과 된 시간을 기록하고 역방향 애니메이션을 시작하는 방법을 계산합니다. 전체 루프를 만들기 위해 반복이 css에 정의되어 있습니다. 사용자 개입없이 애니메이션은 첫 번째 반복 후에 일시 중지/중지됩니다. 그러나있을 경우 반복을 일시 중지하고 즉시 animation-delay 시간으로 다시 시작하십시오. 이것은 즉각적인 역전처럼 보일 것입니다. 그러나 실제로 그것은 새로운 시작입니다.

애니메이션을 다시 시작하는 방법에 대한 트릭이 있습니다. 코드 주석을 참조하십시오.

나는 주위를 수색했지만 아무도 유사한 시나리오 나 비슷한 해결책을 언급하지 않았다. 통제하는 데 시간을 사용하는 대신, 나는 다른 더 나은 접근법을보고 싶다.

내 테스트는 또한 다른 실행 환경이 약간 다른 부드러움을 렌더링 함을 증명합니다. 다행히도, 여기에 그래서 최고입니다.

솔루션을 사용하여 자신의 시나리오에서 제대로 작동하는지 확인하십시오.


const span = document.querySelector('span'), 
 
    button = document.querySelector('button'), 
 
    duration = 10; // animation-during 
 

 
let startTime; 
 

 
span.addEventListener('animationstart',() => { 
 
    startTime = Date.now(); 
 
    button.style.visibility = 'visible'; 
 
}); 
 

 
span.addEventListener('animationiteration',() => span.style.animationPlayState = 'paused'); 
 

 
span.addEventListener('animationend',() => { 
 
    button.style.visibility = 'hidden'; 
 
}); 
 

 
button.addEventListener('click',() => { 
 
    span.classList.remove('my_anim'); 
 
    void span.offsetWidth; // safely apply changes 
 
    span.classList.add('my_anim'); 
 
    const elapsed = Date.now() - startTime; 
 
    const delay = (elapsed < duration * 1000) ? (elapsed/1000 - duration * 2) : -duration; 
 
    span.style.animationDelay = `${delay}s`; 
 
    span.style.animationPlayState = 'running'; 
 
});
span.my_anim { 
 
    animation: 10s 2 alternate my_move; 
 
} 
 

 
@keyframes my_move { 
 
    from { 
 
    margin-left: 0; 
 
    } 
 
    to { 
 
    margin-left: 50%; 
 
    } 
 
} 
 

 
button { 
 
    visibility: hidden; 
 
}
<div> 
 
    <span class="my_anim">@</span> 
 
</div> 
 
<button>reverse</button>
이 예제는 애니메이션이지만 일반 문자 background-position를 사용하지 않습니다.

const span = document.querySelector("span"), 
 
    button = document.querySelector("button"); 
 

 
span.addEventListener(
 
    "animationiteration", 
 
    function() { 
 
    this.classList.add("paused"); 
 
    button.style.visibility = "visible"; 
 
    } 
 
); 
 

 
button.addEventListener(
 
    "click", 
 
    function() { 
 
    this.style.visibility = "hidden"; 
 
    span.classList.remove("paused"); 
 
    } 
 
);
span { 
 
    animation: 3s 2 alternate my_move; 
 
} 
 

 
span.paused { 
 
    animation-play-state: paused; 
 
} 
 

 
@keyframes my_move { 
 
    from { 
 
    margin-left: 0; 
 
    } 
 
    to { 
 
    margin-left: 50%; 
 
    } 
 
} 
 

 
button { 
 
    visibility: hidden; 
 
}
<div> 
 
    <span>@</span> 
 
</div> 
 
<button>reverse</button>

NB : CSS 애니메이션을 사용 -webkit- 접두사 필요합니다.

+0

이것은 최적화되어 있지만 문제는 해결되지 않습니다. –

+0

@AceInteract 업데이트로 작동하는 예제입니다. – themefield

+0

이것은 작동하지 않습니다. –