Skip to content

Commit 62161fb

Browse files
moQuezdanilowoz
andauthored
Add support for top-down gradient animation (#264)
* feat(svg.tsx): add support for top-down gradient animation add gradientDirection prop which translates into a rotate transformation applied to the linearGradient SVG element. Providing the option to animate either from left to right or top to bottom. fix #255 * test(gradient-direction): revert change Co-authored-by: Danilo Woznica <[email protected]>
1 parent dea7d7b commit 62161fb

File tree

5 files changed

+56
-17
lines changed

5 files changed

+56
-17
lines changed

README.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -108,22 +108,23 @@ const MyLoader = () => (
108108

109109
## Options
110110

111-
| <div style="width:250px">Prop name and type</div> | Environment | Description |
112-
| ------------------------------------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
113-
| **`animate?: boolean`** <br/> Defaults to `true` | React DOM<br/>React Native | Opt-out of animations with `false` |
114-
| **`title?: string`** <br/> Defaults to `Loading interface...` | React DOM only | It's used to describe what element it is. <br />Use `''` (empty string) to remove. |
115-
| **`baseUrl?: string`**<br /> Defaults to an empty string | React DOM only | Required if you're using `<base url="/" />` document `<head/>`. <br/>This prop is common used as: <br/>`<ContentLoader baseUrl={window.location.pathname} />` which will fill the SVG attribute with the relative path. Related [#93](https://github.com/danilowoz/react-content-loader/issues/93). |
116-
| **`speed?: number`** <br /> Defaults to `1.2` | React DOM<br/>React Native | Animation speed in seconds. |
117-
| **`interval?: number`** <br /> Defaults to `0.25` | React DOM<br/>React Native | Interval of time between runs of the animation, <br/>as a fraction of the animation speed. |
118-
| **`viewBox?: string`** <br /> Defaults to `undefined` | React DOM<br/>React Native | Use viewBox props to set a custom viewBox value, <br/>for more information about how to use it, <br/>read the article [How to Scale SVG](https://css-tricks.com/scale-svg/). |
119-
| **`gradientRatio?: number`** <br /> Defaults to `1.2` | React DOM only | Width of the animated gradient as a fraction of the view box width. |
120-
| **`rtl?: boolean`** <br /> Defaults to `false` | React DOM<br/>React Native | Content right-to-left. |
121-
| **`backgroundColor?: string`** <br /> Defaults to `#f5f6f7` | React DOM<br/>React Native | Used as background of animation. |
122-
| **`foregroundColor?: string`** <br /> Defaults to `#eee` | React DOM<br/>React Native | Used as the foreground of animation. |
123-
| **`backgroundOpacity?: number`** <br /> Defaults to `1` | React DOM only | Background opacity (0 = transparent, 1 = opaque)<br/>used to solve an issue in [Safari](#safari--ios) |
124-
| **`foregroundOpacity?: number`** <br /> Defaults to `1` | React DOM only | Animation opacity (0 = transparent, 1 = opaque)<br/>used to solve an issue in [Safari](#safari--ios) |
125-
| **`style?: React.CSSProperties`** <br /> Defaults to `{}` | React DOM only | |
126-
| **`uniqueKey?: string`** <br /> Defaults to random unique id | React DOM only | Use the same value of prop key, <br/>that will solve inconsistency on the SSR, see more [here](https://github.com/danilowoz/react-content-loader/issues/78). |
111+
| <div style="width:250px">Prop name and type</div> | Environment | Description |
112+
| ---------------------------------------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
113+
| **`animate?: boolean`** <br/> Defaults to `true` | React DOM<br/>React Native | Opt-out of animations with `false` |
114+
| **`title?: string`** <br/> Defaults to `Loading interface...` | React DOM only | It's used to describe what element it is. <br />Use `''` (empty string) to remove. |
115+
| **`baseUrl?: string`**<br /> Defaults to an empty string | React DOM only | Required if you're using `<base url="/" />` document `<head/>`. <br/>This prop is common used as: <br/>`<ContentLoader baseUrl={window.location.pathname} />` which will fill the SVG attribute with the relative path. Related [#93](https://github.com/danilowoz/react-content-loader/issues/93). |
116+
| **`speed?: number`** <br /> Defaults to `1.2` | React DOM<br/>React Native | Animation speed in seconds. |
117+
| **`interval?: number`** <br /> Defaults to `0.25` | React DOM<br/>React Native | Interval of time between runs of the animation, <br/>as a fraction of the animation speed. |
118+
| **`viewBox?: string`** <br /> Defaults to `undefined` | React DOM<br/>React Native | Use viewBox props to set a custom viewBox value, <br/>for more information about how to use it, <br/>read the article [How to Scale SVG](https://css-tricks.com/scale-svg/). |
119+
| **`gradientRatio?: number`** <br /> Defaults to `1.2` | React DOM only | Width of the animated gradient as a fraction of the view box width. |
120+
| **`gradientDirection?: string`** <br /> Defaults to `left-right` | React DOM only | Direction in which the gradient is animated. Useful to implement top-down animations |
121+
| **`rtl?: boolean`** <br /> Defaults to `false` | React DOM<br/>React Native | Content right-to-left. |
122+
| **`backgroundColor?: string`** <br /> Defaults to `#f5f6f7` | React DOM<br/>React Native | Used as background of animation. |
123+
| **`foregroundColor?: string`** <br /> Defaults to `#eee` | React DOM<br/>React Native | Used as the foreground of animation. |
124+
| **`backgroundOpacity?: number`** <br /> Defaults to `1` | React DOM only | Background opacity (0 = transparent, 1 = opaque)<br/>used to solve an issue in [Safari](#safari--ios) |
125+
| **`foregroundOpacity?: number`** <br /> Defaults to `1` | React DOM only | Animation opacity (0 = transparent, 1 = opaque)<br/>used to solve an issue in [Safari](#safari--ios) |
126+
| **`style?: React.CSSProperties`** <br /> Defaults to `{}` | React DOM only | |
127+
| **`uniqueKey?: string`** <br /> Defaults to random unique id | React DOM only | Use the same value of prop key, <br/>that will solve inconsistency on the SSR, see more [here](https://github.com/danilowoz/react-content-loader/issues/78). |
127128

128129
See all options [live](https://danilowoz.com/react-content-loader/)
129130

docs/index.stories.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,29 @@ gradientRatio.story = {
212212
},
213213
}
214214

215+
/**
216+
* Gradient Direction
217+
*/
218+
export const gradientDirection = () => {
219+
return (
220+
<>
221+
<SyntaxCode>{`<BulletList gradientDirection="left-right" />`}</SyntaxCode>
222+
<BulletList gradientDirection="left-right" />
223+
224+
<SyntaxCode>{`<BulletList gradientDirection="top-bottom" />`}</SyntaxCode>
225+
<BulletList gradientDirection="top-bottom" />
226+
</>
227+
)
228+
}
229+
230+
gradientDirection.story = {
231+
parameters: {
232+
notes: `## \`gradientDirection?: 'left-right' | 'top-bottom' \`
233+
234+
Defaults to \`left-right\`. Direction in which the gradient is animated. Useful to implement top-down animations`,
235+
},
236+
}
237+
215238
/**
216239
* Speed
217240
*/

src/web/Svg.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const SVG: React.FC<IContentLoaderProps> = ({
1212
foregroundColor,
1313
foregroundOpacity,
1414
gradientRatio,
15+
gradientDirection,
1516
uniqueKey,
1617
interval,
1718
rtl,
@@ -28,6 +29,8 @@ const SVG: React.FC<IContentLoaderProps> = ({
2829
const rtlStyle = rtl ? { transform: 'scaleX(-1)' } : null
2930
const keyTimes = `0; ${interval}; 1`
3031
const dur = `${speed}s`
32+
const gradientTransform =
33+
gradientDirection === 'top-bottom' ? 'rotate(90)' : undefined
3134

3235
return (
3336
<svg
@@ -50,7 +53,7 @@ const SVG: React.FC<IContentLoaderProps> = ({
5053
<defs>
5154
<clipPath id={idClip}>{children}</clipPath>
5255

53-
<linearGradient id={idGradient}>
56+
<linearGradient id={idGradient} gradientTransform={gradientTransform}>
5457
<stop
5558
offset="0%"
5659
stopColor={backgroundColor}
@@ -113,6 +116,7 @@ SVG.defaultProps = {
113116
foregroundColor: '#eee',
114117
foregroundOpacity: 1,
115118
gradientRatio: 2,
119+
gradientDirection: 'left-right',
116120
id: null,
117121
interval: 0.25,
118122
rtl: false,

src/web/__tests__/ContentLoader.test.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ describe('ContentLoader', () => {
4141
foregroundColor="#fff"
4242
foregroundOpacity={0.12}
4343
gradientRatio={0.5}
44+
gradientDirection="top-bottom"
4445
height={200}
4546
interval={0.5}
4647
preserveAspectRatio="xMaxYMax meet"
@@ -97,6 +98,15 @@ describe('ContentLoader', () => {
9798
expect(propsFromFullfield.gradientRatio).toBe(0.5)
9899
})
99100

101+
it("`gradientDirection` is a string and it's used", () => {
102+
// defaultProps
103+
expect(typeof propsFromEmpty.gradientDirection).toBe('string')
104+
expect(propsFromEmpty.gradientDirection).toBe('left-right')
105+
// custom props
106+
expect(typeof propsFromFullfield.gradientDirection).toBe('string')
107+
expect(propsFromFullfield.gradientDirection).toBe('top-bottom')
108+
})
109+
100110
it("`animate` is a boolean and it's used", () => {
101111
// defaultProps
102112
expect(typeof propsFromEmpty.animate).toBe('boolean')

src/web/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export interface IContentLoaderProps extends SVGAttributes<SVGElement> {
1010
foregroundColor?: string
1111
foregroundOpacity?: number
1212
gradientRatio?: number
13+
gradientDirection?: 'left-right' | 'top-bottom'
1314
interval?: number
1415
rtl?: boolean
1516
speed?: number

0 commit comments

Comments
 (0)