복잡한 CSS 애니메이션을 다룰 때 많은 선언이있는 광범위한 @keyframes를 만드는 경향이 있습니다. 바닐라 CSS에 머무르는 동안 일을 더 쉽게 만드는 데 도움이 될 수있는 몇 가지 트릭이 있습니다.
첫 번째는 더 널리 사용되고 친숙하지만 두 번째는 덜 일반적입니다. 그에 대한 충분한 이유가있을 수 있습니다. 쉼표로 애니메이션을 체인하는 것은 우리가 사용할 수있는 다양한 타이밍 기능과 그들이하는 일을 조정하는 것보다 상대적으로 쉽습니다. 맞춤 타이밍 기능을 만들기 위해 완전히 제어 할 수있는 특히 깔끔한 타이밍 기능이 하나 있습니다. 그것은 Cubic-Bezier () 일 것입니다.이 게시물에서는 그것의 힘과 너무 복잡하지 않고 멋진 애니메이션을 만드는 데 어떻게 사용될 수 있는지 보여줄 것입니다.
무한대 (∞) 모양과 같은 흥미로운 방향으로 공을 움직일 수있는 방법을 보여주는 기본 예에서 시작합시다.
보시다시피, 복잡한 코드 (두 개의 키 프레임과 Cubic-Bezier) 기능 만 없습니다. 그럼에도 불구하고, 매우 복잡한 최종 인피니티 형 모양의 애니메이션은 우리가 얻는 것입니다.
멋져요? 이것을 파헤쳐 봅시다!
공식 정의부터 시작하겠습니다.
입방 베지어 완화 함수는 엔드 포인트 P0 및 P3이 각각 (0, 0) 및 (1, 1)에 고정 된 입방 베지어 곡선의 2 개의 제어점 P1 및 P2를 지정하는 4 개의 실수로 정의 된 유형의 유형입니다. P1 및 P2의 X 좌표는 범위 [0, 1]로 제한됩니다.
위의 곡선은 시간 (x 축)에 따라 출력 (y 축)이 어떻게 작동하는지 정의합니다. 각 축에는 [0, 1] (또는 [0% 100%])의 범위가 있습니다. 2 초 (2) 지속되는 애니메이션이 있다면 :
0 (0%) = 0s 1 (100%) = 2s
우리가 5px에서 20px에서 남은 애니메이션을 원한다면 :
0 (0%) = 5px 1 (100%) = 20px
시간은 항상 [0 1]으로 제한됩니다. 그러나 출력 인 y는 [0 1]를 넘어갈 수 있습니다.
내 목표는 다음 곡선을 만들기 위해 P1과 P2를 조정하는 것입니다.
정의에 명시된 바와 같이 P0과 P3은 (0,0)과 (1,1)이 동일한 축에있을 수 없기 때문에이를 달성하기가 불가능하다고 생각할 수 있습니다. 그것은 사실이며, 우리는 몇 가지 수학 트릭을 사용하여“근사”할 것입니다.
다음 정의부터 시작하겠습니다 : Cubic-Bezier (0,1.5,1,1.5). 그것은 우리에게 다음과 같은 곡선을줍니다.
우리의 목표는 (1,1)를 움직여서 기술적으로 불가능한 (0,1)로 만드는 것입니다. 그래서 우리는 그것을 가짜하려고 노력할 것입니다.
우리는 이전에 우리의 범위가 [0 1] (또는 [0% 100%])라고 말했기 때문에 0%가 100%에 매우 가까운 경우를 상상해 봅시다. 예를 들어, 우리는 20px (0%)에서 20.1px (100%)에서 상단을 애니메이션하려면 초기 및 최종 상태가 모두 같다고 말할 수 있습니다.
흠, 그러나 우리의 요소는 전혀 움직이지 않을 것입니다.
y 값이 20.1px (100%)를 초과하기 때문에 조금 움직입니다. 그러나 그것은 우리에게 지각 가능한 움직임을주기에 충분하지 않습니다.
곡선을 업데이트하고 대신 입방 베 지어 (0,4,1,4)를 사용해 봅시다. 우리의 곡선이 이전보다 얼마나 키가 큰지 주목하십시오.
그러나 최고 가치가 3 (또는 300%)을 가로 지르더라도 여전히 움직임이 없습니다. 입방 -Bezier (0,20,1,20)를 시도해 봅시다.
예! 조금 움직이기 시작했습니다. 우리가 값을 증가시킬 때마다 곡선의 진화를 알았습니까? 그것은 우리가 전체 곡선을보기 위해 확대 할 때 (0,1)“시각적으로”(1,1)에 더 가깝게 만듭니다. 이것이 트릭입니다.
v가 매우 큰 값이고 초기 및 최종 상태가 모두 매우 가깝거나 거의 동일합니다. 포물선 곡선을 시뮬레이션 할 수 있습니다.
예는 천 단어의 가치가 있습니다.
나는 "매직"입방-베 지어 함수를 최상위 애니메이션에 적용하고 왼쪽에 적용되는 선형을 적용했습니다. 이것은 우리가 원하는 곡선을 제공합니다.
수학을 생각하는 사람들을 위해, 우리는 그 설명을 더 이상 나눌 수 있습니다. 입방 베 지어는 다음 공식을 사용하여 정의 할 수 있습니다.
p = (1 -t) ³p0 3 (1 -t) ²tp1 3 (1 -t) t²p2 t³p3
각 점은 다음과 같이 정의됩니다 : P0 = (0,0), p1 = (0, v), p2 = (1, v) 및 p3 = (1,1).
이것은 우리에게 x와 y 좌표에 대한 두 가지 함수를 제공합니다.
v는 우리의 큰 가치이고 t는 범위 내에 있습니다 [0 1]. 이전 예제를 고려하면 y (t)는 우리에게 상단의 값을 제공하고 x (t)는 시간 진행입니다. 포인트 (x (t), y (t))는 곡선을 정의합니다.
y (t)의 최대 값을 찾아 봅시다. 이를 위해서는 y '(t) = 0을 줄 t의 값을 찾아야합니다 (미분이 0과 같을 때) :
y '(t) = 3T² -6VT 3V
y '(t) = 0은 2 차 방정식입니다. 나는 지루한 부분을 건너 뛰고 당신에게 t = v -sqrt (v² -V) 인 결과를 줄 것입니다.
v가 큰 값이면 t는 0.5입니다. 따라서 y (0.5) = max 및 x (0.5)는 0.5와 같습니다. 즉, 우리는 애니메이션의 중간 지점에서 최대 값에 도달하는 것을 의미합니다. 이는 우리가 원하는 포물선 곡선을 준수합니다.
또한 Y (0.5)는 (1 6V)/8을 제공하며 V에 따라 최대 값을 찾을 수 있습니다. 그리고 우리는 항상 v에 큰 값을 사용할 것이므로 6V/8 = 0.75V로 단순화 할 수 있습니다.
마지막 예제에서 v = 500을 사용 했으므로 최대 값은 375 (또는 37500%)로 나옵니다.
0과 1 사이에는 -0.5px의 차이가 있습니다.이를 증분 이라고합시다. 375 (또는 37500%)의 경우 375*-0.5px = -187.5px의 방정식이 있습니다. 우리의 애니메이션 요소는 상단에 도달합니다 : 12.5px (200px -187.5px)와 다음과 같은 애니메이션을 제공합니다.
상단 : 200px (시간의 0%) → 상단 : 12.5px (시간의 50%) → 상단 : 199.5px (시간의 100%)
또는 다른 방법으로 표현했습니다.
상단 : 200px (0%) → 상단 : 12.5px (50%) → 상단 : 200px (100%)
반대 논리를 해보자. 우리의 요소가 상단에 도달하기 위해 V의 값은 어떤 값을 사용해야합니까 : 0px? 애니메이션은 200px → 0px → 199.5px이므로 0px에 도달하려면 -200px가 필요합니다. 우리의 증분은 항상 -0.5px와 같습니다. 최대 값은 200/0.5 = 400이므로 0.75V = 400이면 V = 533.33을 의미합니다.
우리의 요소는 상단에 닿는다!
다음은 우리가 방금 한 수학을 요약 한 그림입니다.
우리는 정현파 곡선을 만들기 위해 거의 동일한 트릭을 사용하지만 다른 공식을 사용합니다. 이번에는 입방 베 지어 (0.5, v, 0.5, -v)를 사용할 것입니다.
우리가 이전과 마찬가지로, 우리가 값을 높일 때 곡선이 어떻게 발전 할 것인지 봅시다.
나는 당신이 아마 지금까지 아이디어를 얻는 것 같아요. V에 큰 값을 사용하면 정현파 곡선에 가까워집니다.
다음은 지속적인 애니메이션이있는 또 다른 것입니다 - 실제 정현파 애니메이션!
이것에 대한 수학에 참여합시다! 이전과 동일한 공식을 Follling하면 다음 기능을 얻을 수 있습니다.
이번에는 y (t)의 최소 및 최대 값을 찾아야합니다. y '(t) = 0은 우리에게 두 가지 솔루션을 제공합니다. 이것을 해결 한 후 :
y '(t) = 3 (6V 1) T² -18VT 3V = 0
… 우리는 얻는다 :
v의 큰 값의 경우, 우리는 t '= 0.211 및 t "= 0.789입니다. 즉, y (0.211) = max 및 y (0.789) = min. 이는 또한 x (0.211) = 0.26 및 x (0.789) = 0.74를 의미한다는 것을 의미합니다. 다른 말로, 우리는 시간의 26%에서 최대에 도달합니다.
y (0.211)는 0.289V, Y (0.789) ~ -0.289V와 같습니다. 우리는 V가 매우 크다는 것을 고려할 때 반올림으로 그 값을 얻었습니다.
우리의 정현파 곡선은 또한 절반의 시간 (또는 x (t) = 0.5)에 x 축 (또는 y (t) = 0)를 가로 질러야합니다. 이것을 증명하기 위해, 우리는 y (t)의 두 번째 파생물을 사용합니다.
y ''(t) = 6 (6V 1) t -18V = 0
솔루션은 3V/(6V 1)이고, 큰 V 값의 경우 솔루션은 0.5입니다. 그것은 우리에게 y (0.5) = 0 및 x (0.5) = 0.5를 제공하여 곡선이 (0.5,0) 지점을 가로 지르는 것을 확인합니다.
이제 이전 예제를 고려하고 우리를 맨 위로 다시 얻는 V의 값을 찾으십시오 : 0%. 우리는 다음과 같습니다.
상단에 도달하려면 -50%가 필요합니다 : 0%, 0.289V*-0.1% = -50%로 V = 1730.10을 제공합니다.
보시다시피, 우리의 요소는 다음과 같은 애니메이션을 가지고 있기 때문에 상단에 닿아 아래에서 사라지고 있습니다.
상단 : 50% → 상단 : 0% → 상단 : 50% → 상단 : 100% → 상단 : 50% → 등 ...
계산을 요약하는 그림 :
그리고 모든 곡선을 함께 설명하는 예 :
예, 4 개의 곡선이 보입니다! 자세히 살펴보면 두 개의 다른 애니메이션을 사용하고 있는데, 하나는 49.9% (-0.01% 증가)로, 다른 하나는 50.1% (0.01% 증가)로갑니다. 증분의 부호를 변경함으로써 곡선의 방향을 제어합니다. 또한 동일한 곡선에서 더 많은 변형을 생성하기 위해 입방 베 지어 (큰 값으로 남아있는 V가 아님)의 다른 매개 변수를 제어 할 수 있습니다.
그리고 아래에서 대화식 데모 :
무한대 기호 모양으로 움직이는 공의 초기 예로 돌아가 봅시다. 나는 단순히 두 개의 정현파 애니메이션을 결합하여 작동하게합니다.
이전에 한 일을 여러 애니메이션의 개념과 결합하면 놀라운 결과를 얻을 수 있습니다. 이번에는 대화 형 데모로서 다시 초기 예입니다. 값을 바꾸고 마법을보십시오.
더 나아가서 CSS Houdini를 믹스에 추가합시다. @property 덕분에 복잡한 변환 선언을 애니메이션 할 수 있습니다 (그러나 CSS Houdini는 현재 Chrome 및 Edge 지원으로 제한됩니다).
그것으로 어떤 종류의 그림을 만들 수 있습니까? 다음은 내가 만들 수 있었던 몇 가지가 있습니다.
그리고 여기에 spirograph 애니메이션이 있습니다.
그리고 CSS Houdini가없는 버전 :
이 예에서 빼앗아 갈 몇 가지 사항이 있습니다.
타이밍 기능과 관련하여 동일한 논리를 따르기 때문에 동일한 기술을 CSS 전환 속성과 함께 사용할 수도 있습니다. 복잡한 호버 효과를 만들 때 키 프레임을 피할 수 있기 때문에 이것은 훌륭합니다.
키 프레임없이 내가 만든 것은 다음과 같습니다.
마리오는 포물선 곡선 덕분에 점프하고 있습니다. 호버에 쉐이크 애니메이션을 만들기 위해 키 프레임이 전혀 필요하지 않았습니다. 정현파 곡선은 모든 작업을 수행 할 수 있습니다.
다음은 CSS Houdini를 사용하는 Mario의 또 다른 버전입니다. 그리고, 그는 포물선 곡선 덕분에 여전히 점프하고 있습니다.
좋은 측정을 위해 키 프레임이없는 더 멋진 호버 효과가 있습니다 (다시, Chrome 및 Edge 만 해당).
이제 당신은 마법의 입방체-베 지어 () 곡선과 그 뒤에 수학이 있습니다. 물론 이점은 이와 같은 커스텀 타이밍 기능을 통해 우리가 일반적으로 도달하는 복잡한 키 프레임없이 멋진 애니메이션을 할 수 있다는 것입니다.
나는 모든 사람이 수학을 생각하는 것이 아니라 괜찮다는 것을 이해합니다. Matthew Lein의 Ceaser와 같이 도움이되는 도구가 있습니다. 곡선 지점을 드래그하여 필요한 것을 얻을 수 있습니다. 그리고 아직 북마크를 가지고 있지 않다면 Cubic-bezier.com은 또 다른 것입니다. CSS 세계 밖에서 입방 베 지어와 놀고 싶다면 수학 공식을 볼 수있는 Desmos를 추천합니다.
당신이 당신의 입방-베 지어 () 값을 얻는 방법에 관계없이, 이제 당신은 그들의 힘에 대한 감각과 프로세스에서 더 좋은 코드를 만드는 데 어떻게 도움이 될 수 있기를 바랍니다.
위 내용은 Cubic-Bezier ()를 사용한 고급 CSS 애니메이션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!