├── .eslintignore ├── .eslintrc.json ├── .github ├── FUNDING.yml └── workflows │ ├── lint.yml │ ├── npm-install.yml │ └── npm-publish.yml ├── .gitignore ├── .npmignore ├── .prettierrc ├── .storybook └── main.js ├── LICENSE ├── README.md ├── jestconfig.json ├── package-lock.json ├── package.json ├── src ├── __tests__ │ └── rellaxWrapper.test.tsx ├── index.ts └── rellaxWrapper.tsx ├── stories ├── 1-rellaxWrapper.stories.js ├── 2-horizontal.stories.js ├── 3-centered.stories.js ├── 4-callback.stories.js ├── Introduction.stories.mdx └── index.css └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | lib -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": [ 4 | "plugin:cypress/recommended" 5 | ], 6 | "plugins": ["@typescript-eslint", "import", "cypress"], 7 | "parserOptions": { 8 | "ecmaVersion": 6, 9 | "sourceType": "module", 10 | "ecmaFeatures": { 11 | "modules": true 12 | } 13 | }, 14 | "rules": { 15 | "semi": ["error", "always"], 16 | "quotes": [2, "single"], 17 | "import/order": [ 18 | "error", 19 | { 20 | "newlines-between": "always-and-inside-groups", 21 | "groups": [ 22 | "builtin", 23 | "external", 24 | ["internal", "parent"], 25 | "sibling", 26 | "index" 27 | ] 28 | } 29 | ], 30 | "no-magic-numbers": [ 31 | 2, 32 | { 33 | "ignore": [-1, 0, 1, 2], 34 | "enforceConst": true, 35 | "detectObjects": true 36 | } 37 | ], 38 | "@typescript-eslint/no-non-null-assertion": 0, 39 | "@typescript-eslint/no-var-requires": 0, 40 | "@typescript-eslint/no-unused-vars": 1, 41 | "@typescript-eslint/no-empty-function": 0, 42 | "@typescript-eslint/prefer-interface": 0, 43 | "@typescript-eslint/explicit-function-return-type": 0, 44 | "@typescript-eslint/indent": [ 45 | 2, 46 | 2, 47 | { 48 | "SwitchCase": 0 49 | } 50 | ], 51 | "@typescript-eslint/no-use-before-define": [ 52 | 2, 53 | { 54 | "classes": false, 55 | "functions": false, 56 | "variables": false 57 | } 58 | ], 59 | "key-spacing": [ 60 | 2, 61 | { 62 | "beforeColon": false, 63 | "afterColon": true, 64 | "mode": "strict" 65 | } 66 | ], 67 | "keyword-spacing": [ 68 | 2, 69 | { 70 | "before": true, 71 | "after": true, 72 | "overrides": {} 73 | } 74 | ], 75 | "line-comment-position": 0, 76 | "linebreak-style": 2, 77 | "lines-around-comment": [ 78 | 2, 79 | { 80 | "beforeBlockComment": true, 81 | "beforeLineComment": true, 82 | "allowBlockStart": true, 83 | "allowBlockEnd": true 84 | } 85 | ], 86 | "max-lines": [ 87 | 1, 88 | { 89 | "max": 450, 90 | "skipBlankLines": true, 91 | "skipComments": false 92 | } 93 | ], 94 | "max-nested-callbacks": [ 95 | 2, 96 | { 97 | "max": 2 98 | } 99 | ], 100 | "max-statements-per-line": [ 101 | 2, 102 | { 103 | "max": 1 104 | } 105 | ], 106 | "no-mixed-spaces-and-tabs": 2, 107 | "no-return-await": 2, 108 | "no-trailing-spaces": [ 109 | 2, 110 | { 111 | "skipBlankLines": false 112 | } 113 | ], 114 | "array-bracket-spacing": [ 115 | 2, 116 | "never" 117 | ], 118 | "arrow-spacing": [ 119 | 2, 120 | { 121 | "before": true, 122 | "after": true 123 | } 124 | ], 125 | "no-unused-expressions": 2, 126 | "class-methods-use-this": 0, 127 | "comma-dangle": [ 128 | 2, 129 | "always-multiline" 130 | ], 131 | "comma-spacing": [ 132 | 2, 133 | { 134 | "before": false, 135 | "after": true 136 | } 137 | ], 138 | "comma-style": [ 139 | 2, 140 | "last" 141 | ] 142 | } 143 | } -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [scottjr632] 2 | custom: ["https://www.buymeacoffee.com/scottrichardson"] 3 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | on: [push, pull_request] 3 | jobs: 4 | eslint: 5 | name: eslint 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v1 9 | - uses: actions/setup-node@v1 10 | with: 11 | node-version: 10 12 | - run: npm i 13 | - run: npm run style:check -------------------------------------------------------------------------------- /.github/workflows/npm-install.yml: -------------------------------------------------------------------------------- 1 | name: npm-install 2 | on: 3 | push: 4 | branches: 5 | - '*' 6 | - '!master' 7 | pull_request: 8 | branches: 9 | - '*' 10 | - '!master' 11 | jobs: 12 | npm-install: 13 | name: npm-install 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v1 17 | - uses: actions/setup-node@v1 18 | with: 19 | node-version: 10 20 | - run: npm install 21 | - run: npm test 22 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: npm-publish 2 | on: 3 | push: 4 | branches: 5 | - master # Change this to your default branch 6 | jobs: 7 | npm-publish: 8 | name: npm-publish 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v1 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 10 15 | - run: npm install 16 | - run: npm test 17 | - uses: JS-DevTools/npm-publish@v1 18 | with: 19 | token: ${{ secrets.NPM_AUTH_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib/ 3 | .vscode 4 | .eslintcache -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | tsconfig.json 3 | tslint.json 4 | .prettierrc 5 | .storybook 6 | stories -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "trailingComma": "all", 4 | "singleQuote": true 5 | } 6 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "stories": [ 3 | "../stories/**/*.stories.mdx", 4 | "../src/**/*.stories.@(js|jsx|ts|tsx)", 5 | "../stories/**/*.stories.js" 6 | ], 7 | "addons": [ 8 | "@storybook/addon-links", 9 | "@storybook/addon-essentials", 10 | "@storybook/addon-storysource" 11 | ] 12 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Scott Richardson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [React Rellax Wrapper 🎁](https://github.com/scottjr632/react-rellax-wrapper) 2 | 3 | [![NPM version](http://img.shields.io/npm/v/react-rellax-wrapper.svg)](https://www.npmjs.com/package/react-rellax-wrapper) 4 | [![NPM downloads](http://img.shields.io/npm/dm/react-rellax-wrapper.svg)](https://www.npmjs.com/package/react-rellax-wrapper) 5 | [![Storybook](https://cdn.jsdelivr.net/gh/storybookjs/brand@master/badge/badge-storybook.svg)](https://scottjr632.github.io/react-rellax-wrapper/) 6 | 7 | [![Buy Me a Coffee](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/scottrichardson) 8 | 9 | ## About 10 | 11 | react-rellax-wrapper provides a react wrapper around the Rellax js library. This allows for a more idomatic React way of handling parallax with the Rellax library. 12 | 13 | Rellax Library https://dixonandmoe.com/rellax/ 14 | 15 | ## Examples 16 | 17 | [Check out the Storybook](https://scottjr632.github.io/react-rellax-wrapper/) 18 | 19 | __Or run your own__ 20 | ```sh 21 | $ git clone https://github.com/scottjr632/react-rellax-wrapper.git && cd react-rellax-wrapper 22 | $ npm install 23 | $ npm run storybook 24 | ``` 25 | 26 | ## Installing 27 | 28 | ### npm 29 | ```sh 30 | $ npm install react-rellax-wrapper 31 | ``` 32 | ### yarn 33 | ```sh 34 | $ yarn add react-rellax-wrapper 35 | ``` 36 | 37 | ## Getting started 38 | 39 | Import RellaxWrapper and wrap the component that you want to add the parralex feature to with RellaxWrapper. 40 | 41 | ```js 42 | import RellaxWrapper from 'react-rellax-wrapper' 43 | // or 44 | import { RellaxWrapper } from 'react-rellax-wrapper' 45 | ``` 46 | 47 | ```js 48 | 49 | const App = () => ( 50 |
51 | 52 |

I am really fast!

53 |
54 | 55 |
56 |

I am really slow

57 |
58 |
59 |
60 | ) 61 | 62 | ``` 63 | 64 | ## Props 65 | 66 | __All props are optional__ 67 | 68 | If a prop is ommited it will default to the rellax's generic default. For example if speed is omited default speed is -2. 69 | All traditional options for Rellax can also be used such as callback, center, and relativeToWrapper. 70 | 71 | ```ts 72 | interface RellaxWrapperProps { 73 | style?: React.CSSProperties; 74 | className?: string; 75 | zIndex?: number; 76 | 77 | /** 78 | * Centered parallax elements in your viewport. 0.5 is centered. 79 | */ 80 | percentage?: number; 81 | 82 | /** 83 | * Specify different speeds for xs devices 84 | */ 85 | xs?: number; 86 | 87 | /** 88 | * Specify different speeds for mobile devices. Default breakpoint is 576. 89 | */ 90 | mobile?: number; 91 | 92 | /** 93 | * Specify different speeds for tablets. Default breakpoint is 768. 94 | */ 95 | tablet?: number; 96 | 97 | /** 98 | * Specify different speeds for desktop devices. Default breakpoint is 1201. 99 | */ 100 | desktop?: number; 101 | 102 | /** 103 | * Will run on every animation event 104 | * @param positions Object with x and y positions of the rellax element 105 | */ 106 | callback?(positions: { x: number; y: number }): void; 107 | 108 | /** 109 | * Enable the ability to center parallax elements in your viewport 110 | */ 111 | center?: boolean; 112 | 113 | /** 114 | * Enable horizontal parallax. This feature is intended for panoramic style websites, where users scroll horizontally instead of vertically 115 | */ 116 | horizontal?: boolean; 117 | 118 | /** 119 | * Allow decimal pixel values 120 | */ 121 | round?: boolean; 122 | 123 | /** 124 | * A negative value will make it move slower than regular scrolling, and a positive value will make it move faster 125 | */ 126 | speed?: number; 127 | 128 | /** 129 | * Enable vertical parallax 130 | */ 131 | vertical?: boolean; 132 | 133 | /** 134 | * By default, the position of parallax elements is determined via the scroll position of the body. Passing in the wrapper property will tell Rellax to watch that element instead 135 | */ 136 | wrapper?: string | HTMLElement; 137 | 138 | /** 139 | * Do we want rellax element to be relative to the mentioned wrapper. 140 | */ 141 | relativeToWrapper?: boolean; 142 | 143 | /** 144 | * Each breakpoint value represents the resolution for mobile, tablet, desktop respectively. 145 | */ 146 | breakpoints?: [number, number, number]; 147 | } 148 | ``` 149 | -------------------------------------------------------------------------------- /jestconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.(t|j)sx?$": "ts-jest" 4 | }, 5 | "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", 6 | "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"] 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-rellax-wrapper", 3 | "version": "1.0.6", 4 | "description": "A react wrapper around the Rellax javascript library. Rellax -> https://dixonandmoe.com/rellax/", 5 | "main": "lib/index.js", 6 | "types": "lib/index.d.ts", 7 | "scripts": { 8 | "test": "jest --config jestconfig.json", 9 | "build": "tsc", 10 | "style:check": "eslint --ext .js --ext .jsx --ext tsx --ext ts . --quiet --cache", 11 | "style:fix": "eslint --ext .js --ext .jsx --ext tsx --ext ts . --quiet --fix --cache", 12 | "lint": "npm run style:check", 13 | "prepare": "npm run build", 14 | "prepublishOnly": "npm run lint", 15 | "preversion": "npm run lint", 16 | "version": "npm run format && git add -A src", 17 | "postversion": "git push && git push --tags", 18 | "storybook": "start-storybook -p 6006", 19 | "build-storybook": "build-storybook", 20 | "deploy-storybook": "storybook-to-ghpages" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/scottjr632/react-rellax-wrapper.git" 25 | }, 26 | "keywords": [ 27 | "ReactJS", 28 | "React", 29 | "Providers", 30 | "Context", 31 | "Wrapper" 32 | ], 33 | "author": "Scott Richardson ", 34 | "license": "MIT", 35 | "bugs": { 36 | "url": "https://github.com/scottjr632/react-rellax-wrapper/issues" 37 | }, 38 | "homepage": "https://github.com/scottjr632/react-rellax-wrapper#readme", 39 | "devDependencies": { 40 | "@babel/core": "^7.8.7", 41 | "@storybook/addon-actions": "^6.1.10", 42 | "@storybook/addon-essentials": "^6.1.10", 43 | "@storybook/addon-links": "^6.1.10", 44 | "@storybook/addon-storysource": "^6.1.10", 45 | "@storybook/addons": "^6.1.10", 46 | "@storybook/cli": "^6.1.10", 47 | "@storybook/preset-typescript": "^3.0.0", 48 | "@storybook/react": "^6.1.10", 49 | "@storybook/storybook-deployer": "^2.8.7", 50 | "@types/jest": "^25.1.3", 51 | "@types/react": "^16.9.23", 52 | "@types/react-dom": "^16.9.5", 53 | "@types/rellax": "^1.7.2", 54 | "@typescript-eslint/eslint-plugin": "^3.6.1", 55 | "@typescript-eslint/parser": "^3.6.1", 56 | "babel-loader": "^8.0.6", 57 | "eslint": "^7.4.0", 58 | "eslint-plugin-cypress": "^2.11.1", 59 | "eslint-plugin-import": "^2.22.0", 60 | "jest": "^25.1.0", 61 | "prettier": "^1.19.1", 62 | "react-dom": "^16.8.0", 63 | "ts-jest": "^25.4.0", 64 | "ts-loader": "^6.2.1", 65 | "tslint-config-prettier": "^1.18.0", 66 | "typescript": "^3.8.3", 67 | "react": "^16.8.0" 68 | }, 69 | "files": [ 70 | "lib/**/*", 71 | "README.md" 72 | ], 73 | "dependencies": { 74 | "rellax": "^1.12.1" 75 | }, 76 | "peerDependencies": { 77 | "react": "^16.8.0", 78 | "react-dom": "^16.8.0" 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/__tests__/rellaxWrapper.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | describe('React wrapper provider', () => { 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(
, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | }); -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import RellaxWrapper from './rellaxWrapper'; 2 | export { default as RellaxWrapper } from './rellaxWrapper'; 3 | export default RellaxWrapper; 4 | -------------------------------------------------------------------------------- /src/rellaxWrapper.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC, useState, useRef, useEffect } from 'react'; 2 | import Rellax from 'rellax'; 3 | 4 | interface RellaxWrapperProps { 5 | style?: React.CSSProperties; 6 | className?: string; 7 | zIndex?: number; 8 | 9 | /** 10 | * Centered parallax elements in your viewport. 0.5 is centered. 11 | */ 12 | percentage?: number; 13 | 14 | /** 15 | * Specify different speeds for xs devices 16 | */ 17 | xs?: number; 18 | 19 | /** 20 | * Specify different speeds for mobile devices. Default breakpoint is 576. 21 | */ 22 | mobile?: number; 23 | 24 | /** 25 | * Specify different speeds for tablets. Default breakpoint is 768. 26 | */ 27 | tablet?: number; 28 | 29 | /** 30 | * Specify different speeds for desktop devices. Default breakpoint is 1201. 31 | */ 32 | desktop?: number; 33 | 34 | /** 35 | * Will run on every animation event 36 | * @param positions Object with x and y positions of the rellax element 37 | */ 38 | callback?(positions: { x: number; y: number }): void; 39 | 40 | /** 41 | * Enable the ability to center parallax elements in your viewport 42 | */ 43 | center?: boolean; 44 | 45 | /** 46 | * Enable horizontal parallax. This feature is intended for panoramic style websites, where users scroll horizontally instead of vertically 47 | */ 48 | horizontal?: boolean; 49 | 50 | /** 51 | * Allow decimal pixel values 52 | */ 53 | round?: boolean; 54 | 55 | /** 56 | * A negative value will make it move slower than regular scrolling, and a positive value will make it move faster 57 | */ 58 | speed?: number; 59 | 60 | /** 61 | * Enable vertical parallax 62 | */ 63 | vertical?: boolean; 64 | 65 | /** 66 | * By default, the position of parallax elements is determined via the scroll position of the body. Passing in the wrapper property will tell Rellax to watch that element instead 67 | */ 68 | wrapper?: string | HTMLElement; 69 | 70 | /** 71 | * Do we want rellax element to be relative to the mentioned wrapper. 72 | */ 73 | relativeToWrapper?: boolean; 74 | 75 | /** 76 | * Each breakpoint value represents the resolution for mobile, tablet, desktop respectively. 77 | */ 78 | breakpoints?: [number, number, number]; 79 | } 80 | 81 | const RellaxWrapper: FC = ({ 82 | children, 83 | className, 84 | zIndex, 85 | speed, 86 | mobile, 87 | tablet, 88 | desktop, 89 | percentage, 90 | xs, 91 | style, 92 | ...options 93 | }) => { 94 | const [rellax, setRellax] = useState(null); 95 | const rellaxElement = useRef(null); 96 | 97 | useEffect(() => { 98 | if (rellaxElement.current) { 99 | setRellax(new Rellax(rellaxElement.current, options)); 100 | } 101 | return () => { 102 | if (rellax) { 103 | rellax.destroy(); 104 | } 105 | }; 106 | }, [rellaxElement]); 107 | return ( 108 |
120 | {children} 121 |
122 | ); 123 | }; 124 | 125 | export default RellaxWrapper; 126 | -------------------------------------------------------------------------------- /stories/1-rellaxWrapper.stories.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import RellaxWrapper from '../src'; 4 | 5 | import './index.css'; 6 | 7 | export default { 8 | title: 'Example/Default', 9 | component: Default, 10 | }; 11 | 12 | export const Default = () => ( 13 |
14 |
15 | 16 |
17 | 🐌 18 |
19 |
20 | 21 |
22 | 🚀 23 |
24 |
25 |
26 |

Vertical Parallex

27 |
28 | ); 29 | -------------------------------------------------------------------------------- /stories/2-horizontal.stories.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | 3 | import RellaxWrapper from '../src'; 4 | 5 | import './index.css'; 6 | 7 | export default { 8 | title: 'Example/Horizontal', 9 | component: Horizontal, 10 | }; 11 | 12 | export const Horizontal = () => ( 13 |
14 |

Horizontal Scrolling

15 | 16 |
17 | 🐌 18 |
19 |
20 | 21 |
22 | 🚀 23 |
24 |
25 |
26 | ); 27 | -------------------------------------------------------------------------------- /stories/3-centered.stories.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | 3 | import RellaxWrapper from '../src'; 4 | 5 | import './index.css'; 6 | 7 | export default { 8 | title: 'Example/Centered', 9 | component: Centered, 10 | }; 11 | 12 | export const Centered = () => ( 13 |
14 |
15 | 16 |
17 | 🐌 18 |
19 |
20 | 21 |
22 | 🚀 23 |
24 |
25 |
26 |

Centered Parallex

27 |
28 | ); 29 | -------------------------------------------------------------------------------- /stories/4-callback.stories.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | 3 | import RellaxWrapper from '../src'; 4 | 5 | import './index.css'; 6 | 7 | export default { 8 | title: 'Example/Callback', 9 | component: Callback, 10 | }; 11 | 12 | export const Callback = () => { 13 | const [slowValues, setSlowValues] = useState({x: 0, y: 0}); 14 | const [fastValues, setFastValues] = useState({x: 0, y: 0}); 15 | return ( 16 |
17 |
18 | setSlowValues({...pos})}> 19 |
20 | 🐌 21 |
{`X: ${slowValues.x} Y: ${slowValues.y}`}
22 |
23 |
24 | setFastValues({...pos})}> 25 |
26 | 🚀 27 |
{`X: ${fastValues.x} Y: ${fastValues.y}`}
28 |
29 |
30 |
31 |

Using Callback

32 |
33 | ); 34 | }; -------------------------------------------------------------------------------- /stories/Introduction.stories.mdx: -------------------------------------------------------------------------------- 1 | import { Meta } from '@storybook/addon-docs/blocks'; 2 | 3 | 4 | 5 | 6 | 109 | 110 | # [React Rellax Wrapper 🎁](https://github.com/scottjr632/react-rellax-wrapper) 111 | 112 | [![NPM version](http://img.shields.io/npm/v/react-rellax-wrapper.svg)](https://www.npmjs.com/package/react-rellax-wrapper) 113 | [![NPM downloads](http://img.shields.io/npm/dm/react-rellax-wrapper.svg)](https://www.npmjs.com/package/react-rellax-wrapper) 114 | [![Storybook](https://cdn.jsdelivr.net/gh/storybookjs/brand@master/badge/badge-storybook.svg)](https://scottjr632.github.io/react-rellax-wrapper/) 115 | 116 | ## About 117 | 118 | react-rellax-wrapper provides a react wrapper around the Rellax js library. This allows for a more idomatic React way of handling parallax with the Rellax library. 119 | 120 | Rellax Library https://dixonandmoe.com/rellax/ 121 | 122 | ## Examples 123 | 124 | [Check out the Storybook](https://scottjr632.github.io/react-rellax-wrapper/) 125 | 126 | __Or run your own__ 127 | ```sh 128 | $ git clone https://github.com/scottjr632/react-rellax-wrapper.git && cd react-rellax-wrapper 129 | $ npm install 130 | $ npm run storybook 131 | ``` 132 | 133 | ## Installing 134 | 135 | ### npm 136 | ```sh 137 | $ npm install react-rellax-wrapper 138 | ``` 139 | ### yarn 140 | ```sh 141 | $ yarn add react-rellax-wrapper 142 | ``` 143 | 144 | ## Getting started 145 | 146 | Import RellaxWrapper and wrap the component that you want to add the parralex feature to with RellaxWrapper. 147 | 148 | ```js 149 | import RellaxWrapper from 'react-rellax-wrapper' 150 | # or 151 | import { RellaxWrapper } from 'react-rellax-wrapper' 152 | ``` 153 | 154 | ```js 155 | 156 | const App = () => ( 157 |
158 | 159 |

I am really fast!

160 |
161 | 162 |
163 |

I am really slow

164 |
165 |
166 |
167 | ) 168 | 169 | ``` 170 | 171 | ## Props 172 | 173 | __All props are optional__ 174 | 175 | If a prop is ommited it will default to the rellax's generic default. For example if speed is omited default speed is -2. 176 | All traditional options for Rellax can also be used such as callback, center, and relativeToWrapper. 177 | 178 | ```ts 179 | interface RellaxWrapperProps extends Rellax.RellaxOptions { 180 | zIndex?: number 181 | percentage?: number 182 | speed?: number 183 | xs?: number 184 | mobile?: number 185 | tablet?: number 186 | desktop?: number 187 | } 188 | interface RellaxOptions { 189 | /** 190 | * Will run on every animation event 191 | * @param positions Object with x and y positions of the rellax element 192 | */ 193 | callback?(positions: { x: number; y: number }): void; 194 | /** 195 | * Enable the ability to center parallax elements in your viewport 196 | */ 197 | center?: boolean; 198 | /** 199 | * Enable horizontal parallax. This feature is intended for panoramic style websites, where users scroll horizontally instead of vertically 200 | */ 201 | horizontal?: boolean; 202 | /** 203 | * Allow decimal pixel values 204 | */ 205 | round?: boolean; 206 | /** 207 | * A negative value will make it move slower than regular scrolling, and a positive value will make it move faster 208 | */ 209 | speed?: number; 210 | /** 211 | * Enable vertical parallax 212 | */ 213 | vertical?: boolean; 214 | /** 215 | * By default, the position of parallax elements is determined via the scroll position of the body. Passing in the wrapper property will tell Rellax to watch that element instead 216 | */ 217 | wrapper?: string | HTMLElement; 218 | /** 219 | * Do we want rellax element to be relative to the mentioned wrapper. 220 | */ 221 | relativeToWrapper?: boolean; 222 | } 223 | 224 | ``` 225 | 226 | 318 | -------------------------------------------------------------------------------- /stories/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";; 3 | } 4 | 5 | html { 6 | font-size: 15px 7 | } 8 | 9 | .black { 10 | background-color: black; 11 | } 12 | 13 | .default__container { 14 | position: relative; 15 | display: flex; 16 | justify-content: center; 17 | flex-direction: column; 18 | align-items: center; 19 | height: 100vh; 20 | width: 100%; 21 | } 22 | 23 | .default__wrapper { 24 | display: flex; 25 | position: absolute; 26 | height: 100vh; 27 | margin-top: 50vh; 28 | } 29 | 30 | .default__wrapper > div { 31 | padding: 0 10rem; 32 | } 33 | 34 | .text { 35 | font-size: 2rem; 36 | } 37 | 38 | .icon { 39 | font-size: 5rem; 40 | } 41 | 42 | .horizontal__container { 43 | position: relative; 44 | display: flex; 45 | align-items: center; 46 | height: 100vh; 47 | width: 100%; 48 | overflow-y: hidden; 49 | overflow-x: scroll; 50 | padding-left: 10rem; 51 | } 52 | 53 | .horizontal__container .icon { 54 | width: 65vw; 55 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "declaration": true, 6 | "outDir": "./lib", 7 | "strict": false, 8 | "jsx": "react", 9 | "esModuleInterop": true, 10 | }, 11 | "include": ["src"], 12 | "exclude": ["node_modules", "**/__tests__/*", "**/__mocks__/*"] 13 | } --------------------------------------------------------------------------------