CSS分层动画可以让元素沿弧形路径运动_html/css_WEB-ITnose
原文: Moving along a curved path in CSS with layered animation
翻译:涂鸦码龙
译者注:部分代码示例在原文中可以看效果(作者写在博文里面了…),我偷懒把它做成Gif图了。
CSS 的 animations (动画) 和 transitions(变换)擅于实现从点 A 到点 B 的直线运动,运动轨迹是直线路径。给一个元素添加了 animation 或者 transition 以后,无论你如何调整 贝塞尔曲线 ,都无法让它沿着弧形路径运动。你可以通过自定义 timing function 属性,做出弹动的效果,但是它沿着 X 和 Y 轴相对移动的值永远是相同的。
与其使用 JavaScript 实现外观自然的运动,不如尝试用这种简单的方式:分层动画,绕过已有的限制。通过使用两个或多个元素实现动画效果,我们可以更加细粒度地控制某个元素的路径,沿着 X 轴运动使用一种 timing function ,沿着 Y 轴运动使用另一种 timing function 。
问题所在
当我们深入探讨解决方案之前,看看到底问题在哪。CSS animations 和 transitions 限制我们只能沿直线路径运动。元素总是沿着点 A 到点 B 的最短路径运动,如果我们另辟蹊径,告诉 CSS 沿着“更好的路径”,而不是“最短路径”运动呢?
用 CSS (开启硬件加速)实现两点之间的运动,最直截了当的方式是使用 transform 的 translate 在一定时间内移动某个元素。这就产生了直线运动。在 @keyframes 中,我们打算在 (0,0) 和 (100,-100) 间来回运动,见上图例子:
@keyframes straightLine { 50% { transform: translate3D(100px, -100px, 0); }}.dot { animation: straightLine 2.5s infinite linear;}
这些看起来并不难懂,但我们稍等片刻,思考一下我们需要的解决方案,拆分开来的动画,视觉上长什么样子呢。
0% 时,元素从 (0,0) 出发, 50% 时,我们用了 translate3D(100px, -100px, 0) 把它移动到 (100,-100),然后原路返回。换句话说,我们把元素向右移动了 100px ,向上移动了 100px ,两个方向联合作用使元素沿着一个角度运动。
解决方案:每个轴执行自己的动画函数
那么,原先展示的例子中我们如何实现的弧形路径呢?为了让创建的路径不是直线, 我们想让元素沿 X 轴和 Y 轴的运动速度不同步 。
先前例子中都用到了 linear 线性运动函数,如果我们给运动的元素包裹一个容器,我们可以为 X 轴应用一种动画函数,Y 轴应用另一种动画函数。以下例子,我们在 X 轴使用 ease-in ,Y 轴使用 ease-out 。
每个轴元素的具体实现
不幸的是,我们不能只把 transform 动画简单叠加:因为只有最后声明的动画会执行。那么我们如何把两个动画效果联合起来呢?可以把一个元素放入另一个元素内部,给容器元素加一种动画,给里面的子元素添加另一种动画。
在以上例子中,你已经看到一个点沿着弧形路径运动,看到两个独立的元素一起做动画,只不过容器元素是完全透明的。为了清晰地看到两个元素沿着弧形路径是如何相互作用的,我们给容器元素加个边框看看呗:
那个点藏在带边框的盒子内部,跟随盒子一起沿 X 轴远动,同时它自己又在 Y 轴方向上下运动。去掉容器盒子的边框,我们就得到了弧形路径。与其在 HTML 中用两个元素,还不如用伪元素实现嘞。如果 HTML 是这样:
<div class="dot"></div>
我们可以添加伪元素:
.dot { /* 容器:沿 X 轴运动 */}.dot::after { /* 黑点儿,沿 Y 轴运动 */}
然后,我们需要两块独立的动画代码:X 轴,Y 轴各一块。注意一处用了 ease-in ,另一处用了 ease-out :
.dot { /*省略 一些布局代码...*/ animation: xAxis 2.5s infinite ease-in;}.dot::after { /* 渲染小黑点儿*/ animation: yAxis 2.5s infinite ease-out;}@keyframes xAxis { 50% { animation-timing-function: ease-in; transform: translateX(100px); }}@keyframes yAxis { 50% { animation-timing-function: ease-out; transform: translateY(-100px); }}
加上 WebKit 前缀,用一些自定义的贝塞尔曲线代替 ease-in 和 ease-out ,我们就可以实现文章最开头展示的效果:
.demo-dot { -webkit-animation: xAxis 2.5s infinite cubic-bezier(0.02, 0.01, 0.21, 1); animation: xAxis 2.5s infinite cubic-bezier(0.02, 0.01, 0.21, 1);}.demo-dot::after { content: ''; display: block; width: 20px; height: 20px; border-radius: 20px; background-color: #fff; -webkit-animation: yAxis 2.5s infinite cubic-bezier(0.3, 0.27, 0.07, 1.64); animation: yAxis 2.5s infinite cubic-bezier(0.3, 0.27, 0.07, 1.64);}@-webkit-keyframes yAxis { 50% { -webkit-animation-timing-function: cubic-bezier(0.02, 0.01, 0.21, 1); animation-timing-function: cubic-bezier(0.02, 0.01, 0.21, 1); -webkit-transform: translateY(-100px); transform: translateY(-100px); }}@keyframes yAxis { 50% { -webkit-animation-timing-function: cubic-bezier(0.02, 0.01, 0.21, 1); animation-timing-function: cubic-bezier(0.02, 0.01, 0.21, 1); -webkit-transform: translateY(-100px); transform: translateY(-100px); }}@-webkit-keyframes xAxis { 50% { -webkit-animation-timing-function: cubic-bezier(0.3, 0.27, 0.07, 1.64); animation-timing-function: cubic-bezier(0.3, 0.27, 0.07, 1.64); -webkit-transform: translateX(100px); transform: translateX(100px); }}@keyframes xAxis { 50% { -webkit-animation-timing-function: cubic-bezier(0.3, 0.27, 0.07, 1.64); animation-timing-function: cubic-bezier(0.3, 0.27, 0.07, 1.64); -webkit-transform: translateX(100px); transform: translateX(100px); }}
以下是文章起始处的例子:
JS Bin on jsbin.com
你可能注意到我们在所有例子中都用了 @keyframes ,这纯粹是因为我们想展示黑点儿往返的两种状态。如果只想实现点 A 至点 B 的运动,使用 transition 属性做分层动画同样好用。
如果有个绝对定位的元素,通过给 left 和 bottom 属性加特效,就可以实现弧形路径运动,单个元素就可以,不需要容器元素。为什么不这么做呢:它性能稍差一些,动画的每一帧都会引起重绘。使用带伪元素的分层动画, translate 属性又开了硬件加速,动画效果更好,性能也更高。
译者自己搞了个绝对定位的例子:
JS Bin on jsbin.com

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











이 기사는 HTML & lt; Progress & Gt에 대해 설명합니다. 요소, 그 목적, 스타일 및 & lt; meter & gt의 차이; 요소. 주요 초점은 & lt; progress & gt; 작업 완료 및 & lt; meter & gt; Stati의 경우

이 기사는 HTML & LT; Datalist & GT에 대해 논의합니다. 자동 완성 제안을 제공하고, 사용자 경험을 향상시키고, 오류를 줄임으로써 양식을 향상시키는 요소. 문자 수 : 159

기사는 HTML5 크로스 브라우저 호환성을 보장하기위한 모범 사례에 대해 논의하고 기능 감지, 점진적 향상 및 테스트 방법에 중점을 둡니다.

이 기사는 HTML & lt; meter & gt에 대해 설명합니다. 범위 내에 스칼라 또는 분수 값을 표시하는 데 사용되는 요소 및 웹 개발의 일반적인 응용 프로그램. & lt; meter & gt; & lt; Progress & Gt; 그리고 Ex

이 기사는 html5 & lt; time & gt; 시맨틱 날짜/시간 표현 요소. 인간이 읽을 수있는 텍스트와 함께 기계 가독성 (ISO 8601 형식)에 대한 DateTime 속성의 중요성을 강조하여 Accessibilit를 향상시킵니다.

이 기사에서는 브라우저에서 직접 사용자 입력을 검증하기 위해 필요한, Pattern, Min, Max 및 Length 한계와 같은 HTML5 양식 검증 속성을 사용하는 것에 대해 설명합니다.

이 기사는 모바일 장치의 반응 형 웹 디자인에 필수적인 Viewport Meta Tag에 대해 설명합니다. 적절한 사용이 최적의 컨텐츠 스케일링 및 사용자 상호 작용을 보장하는 방법을 설명하는 반면, 오용은 설계 및 접근성 문제로 이어질 수 있습니다.

이 기사는 & lt; iframe & gt; 외부 컨텐츠를 웹 페이지, 공통 용도, 보안 위험 및 객체 태그 및 API와 같은 대안을 포함시키는 태그의 목적.
