01.简单实例
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>流动箭头</title> |
| </head> |
| |
| <style> |
| |
| |
| .arrow-body { |
| position: relative; |
| margin: 0; |
| padding: 0; |
| |
| width: 500px; |
| |
| height: 24px; |
| overflow: hidden; |
| } |
| |
| .arrow-body::after { |
| content:""; |
| position:absolute; |
| |
| right: -12px; |
| top: 0; |
| width: 0; |
| height: 0; |
| |
| border: 12px solid transparent; |
| |
| border-left-width: 20px; |
| border-left-color: skyblue; |
| } |
| |
| .flow-body { |
| position: relative; |
| margin: 0; |
| padding: 0; |
| height: 100%; |
| width: calc(100% - 10px); |
| overflow: hidden; |
| } |
| |
| .flow-body::before { |
| content:""; |
| position: absolute; |
| width: 200%; |
| |
| height: 6px; |
| top: calc(50% - 3px); |
| |
| background: repeating-linear-gradient(90deg,skyblue 0,skyblue 15px,rgba(0,0,0,0) 15px,rgba(0,0,0,0) 20px); |
| transform: translateX(-100%); |
| animation: flow linear 8s infinite; |
| } |
| |
| |
| @keyframes flow { |
| from { |
| transform:translateX(-50%); |
| } |
| to { |
| transform:translateX(0); |
| } |
| } |
| |
| </style> |
| |
| <body> |
| |
| <div class="flow-arrow"> |
| <div class="arrow-body"> |
| <div class="flow-body"></div> |
| </div> |
| </div> |
| |
| </body> |
| </html> |
复制

02.DEH项目流动油管
01.需求分析
封装流动管道动画功能:
- 设置动画的起点和终点 宽度和高度暂时定死
- 有横版和竖版两种方式进行选择
- 可以选择流动方向
- 流动的速度可调
- 可以选择头部尾部是否添加弧形
- 油管分为静态白色油管和动态油管
02.css初步实现代码
01.油管横向向右滑动
html
| <div class="arrow-body"> |
| <div class="flow-body blcak-border"></div> |
| </div> |
复制
css
| |
| .arrow-body { |
| position: absolute; |
| margin: 0; |
| padding: 0; |
| |
| width: calc(409vw * 100 / 1920); |
| height: calc(10vh * 100 / 1080); |
| overflow: hidden; |
| } |
| |
| .flow-body { |
| position: relative; |
| margin: 0; |
| padding: 0; |
| height: 100%; |
| width: 100%; |
| overflow: hidden; |
| border: calc(2vh * 100 / 1080) solid #00eaf7; |
| } |
| |
| .flow-body::before { |
| content: ""; |
| position: absolute; |
| width: 200%; |
| |
| height: 30%; |
| top: 35%; |
| |
| background: repeating-linear-gradient( |
| 90deg, |
| skyblue 0, |
| skyblue calc(5vw * 100 / 1920), |
| #01155d calc(5vw * 100 / 1920), |
| #01155d calc(10vw * 100 / 1920) |
| ); |
| animation: flow linear 8s infinite; |
| } |
| |
| @keyframes flow { |
| from { |
| transform: translateX(-50%); |
| } |
| to { |
| transform: translateX(0); |
| } |
| } |
复制

02.油管横向向左滑动
直接改变动画函数帧即可,其他不做变动
| .arrow-body:nth-child(4) .flow-body::before { |
| animation: flowRight linear 2s 0; |
| } |
| @keyframes flowRight { |
| from { |
| transform: translateX(0%); |
| } |
| to { |
| transform: translateX(-50%); |
| } |
| } |
复制

03.纵向油管向下滑动
| .arrow-body{ |
| position: absolute; |
| margin: 0; |
| padding: 0; |
| |
| left: calc(793vw * 100 / 1920); |
| top: calc(44vh * 100 / 1080); |
| |
| width: calc(10vw * 100 / 1920); |
| height: calc(82vh * 100 / 1080); |
| overflow: hidden; |
| } |
| .arrow-body .flow-body { |
| border-radius: 0 20px 0 0; |
| } |
| .arrow-body .flow-body::before { |
| content: ""; |
| |
| |
| position: absolute; |
| border-radius: 0 50% 0 0; |
| top: 0; |
| width: 30%; |
| |
| height: 200%; |
| right: 35%; |
| |
| background: repeating-linear-gradient( |
| 180deg, |
| skyblue 0, |
| skyblue calc(5vw * 100 / 1920), |
| #01155d calc(5vw * 100 / 1920), |
| #01155d calc(10vw * 100 / 1920) |
| ); |
| animation: flowDown linear 8s 0; |
| } |
复制
04.纵向油管向上滑动
| |
| @keyframes flowUp { |
| from { |
| transform: translateY(0%); |
| } |
| to { |
| transform: translateY(-50%); |
| } |
| } |
复制
05.油管添加圆角
直接修改放款圆角即可
| .arrow-body:nth-child(5) .flow-body { |
| border-radius: 0 20px 0 0; |
| } |
复制
03.scss封装
| |
| @mixin framFlow($direction, $startPosition, $endPosition) { |
| from { |
| transform: if |
| ($direction, translateX($startPosition), translateY($startPosition)); |
| } |
| to { |
| transform: if |
| ($direction, translateX($endPosition), translateY($endPosition)); |
| } |
| } |
| @keyframes flowRight { |
| @include framFlow(1, -50%, 0); |
| } |
| |
| @keyframes flowLeft { |
| @include framFlow(1, 0%, -50%); |
| } |
| |
| @keyframes flowDown { |
| @include framFlow(0, -50%, 0%); |
| } |
| |
| @keyframes flowUp { |
| @include framFlow(0, 0%, -50%); |
| } |
复制
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| @mixin flow-animation( |
| $shape, |
| $direction, |
| $distence, |
| $startPosition, |
| $endPosition, |
| $speed, |
| $radiusPosition: "none", |
| $style: #00eaf7 |
| ) { |
| position: absolute; |
| |
| @if $shape == 0 { |
| left: $startPosition; |
| top: $distence; |
| } @else { |
| left: $distence; |
| top: $startPosition; |
| } |
| margin: 0; |
| padding: 0; |
| |
| @if $shape == 0 { |
| |
| width: $endPosition - $startPosition; |
| |
| height: calc(10 * var(--flexHeight)); |
| } @else { |
| |
| width: 1rem; |
| |
| height: $endPosition - $startPosition; |
| } |
| overflow: hidden; |
| |
| .flow-body { |
| position: relative; |
| margin: 0; |
| padding: 0; |
| height: 100%; |
| width: 100%; |
| overflow: hidden; |
| border: calc(2 * var(--flexHeight)) solid $style; |
| |
| @if $radiusPosition == "top-left" { |
| border-radius: 20px 0 0 0; |
| } @else if $radiusPosition == "top-right" { |
| border-radius: 0 20px 0 0; |
| } @else if $radiusPosition == "bottom-left" { |
| border-radius: 0 0 0 20px; |
| } @else if $radiusPosition == "bottom-right" { |
| border-radius: 0 0 20px 0; |
| } @else { |
| border-radius: 0; |
| } |
| &::before { |
| content: ""; |
| position: absolute; |
| |
| @if $shape == 0 { |
| width: 200%; |
| |
| height: 30%; |
| top: 35%; |
| left: 0; |
| |
| background: repeating-linear-gradient( |
| 90deg, |
| skyblue 0, |
| skyblue calc(5vw * 100 / 1920), |
| #01155d calc(5vw * 100 / 1920), |
| #01155d calc(10vw * 100 / 1920) |
| ); |
| } @else { |
| top: 0; |
| width: 30%; |
| |
| height: 200%; |
| right: 35%; |
| |
| background: repeating-linear-gradient( |
| 180deg, |
| skyblue 0, |
| skyblue calc(5vw * 100 / 1920), |
| #01155d calc(5vw * 100 / 1920), |
| #01155d calc(10vw * 100 / 1920) |
| ); |
| } |
| @if $direction == "right" { |
| animation: flowRight linear $speed infinite; |
| } @else if $direction == "left" { |
| animation: flowLeft linear $speed infinite; |
| } @else if $direction == "up" { |
| animation: flowUp linear $speed infinite; |
| } @else { |
| animation: flowDown linear $speed infinite; |
| } |
| } |
| } |
| } |
| |
| |
| |
| @keyframes flowRight { |
| from { |
| transform: translateX(-50%); |
| } |
| to { |
| transform: translateX(0); |
| } |
| } |
| |
| @keyframes flowLeft { |
| from { |
| transform: translateX(0); |
| } |
| to { |
| transform: translateX(-50%); |
| } |
| } |
| |
| @keyframes flowDown { |
| from { |
| transform: translateY(-50%); |
| } |
| to { |
| transform: translateY(0%); |
| } |
| } |
| |
| @keyframes flowUp { |
| from { |
| transform: translateY(0%); |
| } |
| to { |
| transform: translateY(-50%); |
| } |
| } |
| |
| .arrow-body { |
| @include flow-animation( |
| 1, |
| "down", |
| 30px, |
| 30px, |
| 200px, |
| 0s, |
| "bottom-right", |
| #cecece |
| ); |
| } |
| .arrow-body:nth-child(1) { |
| @include flow-animation(1, "up", 300px, 30px, 200px, 8s, "top-right"); |
| } |
| .arrow-body:nth-child(2) { |
| @include flow-animation(0, "left", 400px, 30px, 200px, 8s, "top-right"); |
| } |
复制
最终的展示效果
