https://skeletonreact.com
在线 skeleton svg动画 https://skeletonreact.com/#gallery
Github https://github.com/danilowoz/react-content-loader
- 用于内容加载之前的占位动画相比与loading动画
- Skeleton Screen的效果要更生动
- skeleton移动端效果 https://www.jianshu.com/p/5e8de42483f4
page-skeleton-webpack-plugin https://blog.csdn.net/weixin_33795093/article/details/91428233
yarn add react-content-loader
骨架屏实现思路
- 通过伪元素实现骨架样式
- 骨架结构很简单,只是随意的放几个你喜欢的块级元素就ok
- css制作布局组件,添加骨架样式
- 用 css3 的 background-image设置背景颜色动画
- 通过拉伸背景图片,动态设置背景定位百分比,改变背景定位,
- 从而计算得到图片相对容器的不同偏移值
css样式
background-position
属性设置了两个值,第一个值代表水平位置相对容器的偏移,第二个代表垂直位置相对容器的偏移- 用百分比设置
background-position
值时,它会执行一个计算实际定位值公式(container width - image width) * (position x%) = (x offset value)
,即容器和图片的宽度差乘上设置的百分比定位值,得到的结果就是实际的偏移值, - 将
**background-size**
的宽度设置为400%的其中一个目的就是,这样就会和容器产生宽度差 - 如果将
background-size
值设为50%,也可以和容器产生宽度差。是的,但是这样,背景图片会平铺整个容器,你会惊喜的发现,绿点变成了double - 扩展:试着给background-size设置不同的值,观察它的表现,并想一下为什么会这样
动画计算
- 假设容器的宽度是
100px
,那么背景图片的宽度就是400px
,利用上边的公式,- 第一帧的动画中,背景图相对容器偏移的真实值是
(100px-400px)*100% = -300px
- 最后一帧实际偏移
(``100px``-400px``)*``0%
= ``0
- 动画的过程实际就是一个3倍容器宽的线性背景图片相对于容器的偏移从
-300px
到0
的变化的过程 ```css li{ background-image: linear-gradient(90deg, #ff0000 25%, #41de6a 37%, #ff0000 63%); width: 100%; height: 32px; list-style: none; background-size: 400% 100%; background-position: 100% 50%; animation: loading 1.4s ease infinite; }
@keyframes loading { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
<a name="kCsKh"></a>
## Lazy & Suspense
Suspense组件,帮助我们“等待”目标代码加载,<br />用户等待的时候显示,并且可以直接指定一个加载的界面,像是个 spinner
```jsx
<Suspense fallback={null}>
<div>加载的内容</div>
</Suspense>
- 仅处理界面的交互,与接口数据加载快慢无关
- 使用 Suspense 必须搭配 fallback, 需要指定 fallback 以哪种形式展示-等待加载页面
- Suspense文档 https://zh-hans.reactjs.org/docs/concurrent-mode-suspense.html
svg-skeleton
- svg-skeleton文档 https://github.com/yyued/SVG-Skeleton
- 英文文档 https://svg-skeleton.js.org/
npm i svg-skeleton --save
组件中使用
import SVGSkeleton from 'svg-skeleton';
const { h, render } = SVGSkeleton;
// inside #shining animation
const Item = (
<svg width="750" height="191">
<circle cx="95" cy="102" r="63" fill="#edeff0" mask="url(#shining)" />
<rect width="160" height="35" x="190" y="45" fill="#edeff0" mask="url(#shining)" />
<rect width="400" height="35" x="190" y="90" fill="#edeff0" mask="url(#shining)" />
<line x1="0" y1="190" x2="750" y2="190" stroke="#edeff0"></line>
</svg>
);
const Page = ( ( ) => {
let List = [ ];
for ( let i = 0; i < 6; i++ ) {
List.push( ( <Item y={ i == 0 ? 0 : i * 191 } /> ) );
}
return (
<svg width="750" height="1334" fill="#fafafa">
{ List }
</svg>
);
} )( );
render( Page, document.body );