├── .gitignore
├── .npmignore
├── doc
├── image
│ ├── sierra.jpg
│ └── screen.svg
├── font
│ ├── Lato-Light.eot
│ ├── Lato-Light.ttf
│ ├── Lato-Light.woff
│ ├── Lato-Light.woff2
│ ├── Lato-Regular.eot
│ ├── Lato-Regular.ttf
│ ├── Lato-Regular.woff
│ └── Lato-Regular.woff2
├── index.html
└── css
│ └── style.css
├── bower.json
├── LICENSE
├── package.json
├── README.md
├── src
├── jsx
│ ├── test.jsx
│ └── react-screen.jsx
└── sass
│ └── react-screen.scss
├── gulpfile.js
└── dist
├── react-screen.css
└── react-screen.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | doc/
2 | src/jsx/test.jsx
--------------------------------------------------------------------------------
/doc/image/sierra.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gao-sun/react-screen/HEAD/doc/image/sierra.jpg
--------------------------------------------------------------------------------
/doc/font/Lato-Light.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gao-sun/react-screen/HEAD/doc/font/Lato-Light.eot
--------------------------------------------------------------------------------
/doc/font/Lato-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gao-sun/react-screen/HEAD/doc/font/Lato-Light.ttf
--------------------------------------------------------------------------------
/doc/font/Lato-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gao-sun/react-screen/HEAD/doc/font/Lato-Light.woff
--------------------------------------------------------------------------------
/doc/font/Lato-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gao-sun/react-screen/HEAD/doc/font/Lato-Light.woff2
--------------------------------------------------------------------------------
/doc/font/Lato-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gao-sun/react-screen/HEAD/doc/font/Lato-Regular.eot
--------------------------------------------------------------------------------
/doc/font/Lato-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gao-sun/react-screen/HEAD/doc/font/Lato-Regular.ttf
--------------------------------------------------------------------------------
/doc/font/Lato-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gao-sun/react-screen/HEAD/doc/font/Lato-Regular.woff
--------------------------------------------------------------------------------
/doc/font/Lato-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gao-sun/react-screen/HEAD/doc/font/Lato-Regular.woff2
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-screen",
3 | "description": "A different React carousel component.",
4 | "main": "dist/react-screen.js",
5 | "authors": [
6 | "Gao Sun"
7 | ],
8 | "license": "MIT",
9 | "keywords": [
10 | "carousel",
11 | "react"
12 | ],
13 | "homepage": "https://github.com/gao-sun/react-screen"
14 | }
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016
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 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-screen",
3 | "version": "0.1.7",
4 | "description": "A different React carousel component.",
5 | "main": "dist/react-screen.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/gao-sun/react-screen.git"
12 | },
13 | "keywords": [
14 | "carousel",
15 | "react"
16 | ],
17 | "author": "Gao Sun",
18 | "license": "MIT",
19 | "bugs": {
20 | "url": "https://github.com/gao-sun/react-screen/issues"
21 | },
22 | "homepage": "https://github.com/gao-sun/react-screen#readme",
23 | "devDependencies": {
24 | "babel-plugin-transform-class-properties": "^6.16.0",
25 | "babel-preset-es2015": "^6.16.0",
26 | "babel-preset-react": "^6.16.0",
27 | "babelify": "^7.3.0",
28 | "browserify": "^13.1.0",
29 | "gulp": "^3.9.1",
30 | "gulp-autoprefixer": "^3.1.1",
31 | "gulp-babel": "^6.1.2",
32 | "gulp-clean": "^0.3.2",
33 | "gulp-clean-css": "^2.0.13",
34 | "gulp-sass": "^2.3.2",
35 | "gulp-uglify": "^2.0.0",
36 | "react": "^15.3.2",
37 | "react-dom": "^15.3.2",
38 | "vinyl-buffer": "^1.0.0",
39 | "vinyl-source-stream": "^1.1.0"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-screen
2 |
3 | A lot of boring carousels? Let's try something else!
4 |
5 | 
6 |
7 | Full documentation @[react-screen](http://gao-sun.github.io/react-screen).
8 |
9 | ### Get Started
10 |
11 | 1.Install react-screen.
12 | ```baseh
13 | # Via npm
14 | npm install react-screen
15 |
16 | # Via Bower
17 | bower install react-screen
18 | ```
19 |
20 | 2.Import react & react-screen.
21 | ```javascript
22 | import React, { Component } from 'react';
23 | import ReactDOM from 'react-dom';
24 | import { Screen, ScreenSlice } from 'react-screen';
25 | ```
26 |
27 | 3.Import stylesheet.
28 | ```javascript
29 | // In jsx
30 | import styles from 'node_modules/react-screen/dist/css/react-screen.css';
31 | ```
32 |
33 | Or
34 | ```html
35 |
36 |
37 | ```
38 |
39 | 4.Render it!
40 | ```javascript
41 | ReactDOM.render((
42 |
43 |
44 | First Screen
45 |
46 |
47 | Second Screen
48 |
49 |
50 | Third Screen
51 |
52 |
53 | ), document.getElementById('react-screen'));
54 | ```
--------------------------------------------------------------------------------
/src/jsx/test.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { Screen, ScreenSlice } from './react-screen.jsx';
4 |
5 | ReactDOM.render((
6 |
7 |
8 |
9 |
Immersive
10 |
Full screen. Full experience.
11 |
12 |
13 |
14 |
15 |
16 |
React Screen
17 |
18 |
19 |
20 |
21 |
22 |
23 |
Customizable
24 |
Put whatever you want.
25 |
26 |
27 |
React Screen
28 |
Button
29 |
30 |
31 |
32 |
33 |
34 |
35 | Modularized
36 |
37 |
38 | Clear. Clean. Clever.
39 |
40 |
41 |
45 |
49 |
50 |
51 |
52 | ), document.getElementById('react-screen'));
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp');
2 | const minifyCss = require('gulp-clean-css');
3 | const browserify = require('browserify');
4 | const babelify = require('babelify');
5 | const source = require("vinyl-source-stream");
6 | const buffer = require('vinyl-buffer');
7 | const sass = require('gulp-sass');
8 | const autoprefixer = require('gulp-autoprefixer');
9 | const clean = require('gulp-clean');
10 | const uglify = require('gulp-uglify');
11 | const babel = require('gulp-babel');
12 |
13 | const paths = {
14 | jsx: 'src/jsx/*.jsx',
15 | component: 'src/jsx/react-screen.jsx',
16 | test: 'src/jsx/test.jsx',
17 | sass: 'src/sass/*.scss',
18 | };
19 |
20 | const debug = false;
21 |
22 | gulp.task('clean', function() {
23 | return gulp.src('dist/', { read: false })
24 | .pipe(clean());
25 | });
26 |
27 | gulp.task('sass', ['clean'], function() {
28 | return gulp.src(paths.sass)
29 | .pipe(sass())
30 | .pipe(autoprefixer({
31 | browsers: ['last 10 versions'],
32 | cascade: false
33 | }))
34 | .pipe(minifyCss())
35 | .pipe(gulp.dest('dist/'))
36 | });
37 |
38 | gulp.task('generation', ['sass'], function() {
39 | let babelConfig = { presets: ['es2015', 'react'], plugins: ['transform-class-properties'] };
40 |
41 | if(!debug) {
42 | return gulp.src(paths.component)
43 | .pipe(babel(babelConfig))
44 | .pipe(uglify())
45 | .pipe(gulp.dest('dist/'));
46 | }
47 |
48 | gulp.src(paths.component)
49 | .pipe(gulp.dest('dist/'));
50 |
51 | let b = browserify({
52 | entries: paths.test,
53 | debug: debug,
54 | });
55 |
56 | return b
57 | .transform('babelify', babelConfig)
58 | .bundle()
59 | .pipe(source('react-screen.js'))
60 | .pipe(buffer())
61 | .pipe(gulp.dest('dist/'));
62 | });
63 |
64 | // Whole build
65 | gulp.task('build', ['clean', 'sass', 'generation']);
66 |
67 | gulp.task('watch', function() {
68 | gulp.watch([paths.sass, paths.jsx], ['build']);
69 | });
70 |
71 | gulp.task('default', ['build', 'watch']);
--------------------------------------------------------------------------------
/doc/image/screen.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
11 |
12 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/src/sass/react-screen.scss:
--------------------------------------------------------------------------------
1 | .react-screen-test {
2 | position: relative;
3 | width: 100%;
4 | height: 100vh;
5 | background: #888;
6 | }
7 |
8 | .react-screen-wrapper {
9 | &.out {
10 | & .react-screen-background,
11 | & .react-screen {
12 | z-index: -1;
13 | }
14 | }
15 |
16 | .hide {
17 | display: none;
18 | }
19 | }
20 |
21 | .react-screen-skip {
22 | position: fixed;
23 | z-index: 99999;
24 | bottom: 20px;
25 | right: 10px;
26 | transform: translateX(-50%);
27 | text-align: center;
28 | font-size: 1rem;
29 | color: #999;
30 | padding: .5rem 2rem;
31 | background-color: #f5f5f5;
32 | letter-spacing: 1px;
33 | border-radius: 5px;
34 | user-select: none;
35 | transition: all .2s ease;
36 | text-decoration: none;
37 |
38 | &:hover {
39 | cursor: pointer;
40 | background-color: #eee;
41 | color: #666;
42 | text-decoration: none;
43 | }
44 | }
45 |
46 | .react-screen {
47 | // display: none;
48 | position: fixed;
49 | left: 0;
50 | top: 0;
51 | width: 100%;
52 | height: 100%;
53 | background-color: #fafafa;
54 | z-index: 99998;
55 |
56 | /* In & Out */
57 | &.in {
58 | animation-name: react-screen-in;
59 | animation-duration: .5s;
60 | animation-timing-function: ease-out;
61 | animation-fill-mode: forwards;
62 | z-index: 99999;
63 |
64 | .image-main,
65 | .description {
66 | opacity: 0;
67 |
68 | animation-name: react-screen-item-in;
69 | animation-duration: .5s;
70 | animation-timing-function: ease-out;
71 | animation-fill-mode: forwards;
72 | animation-delay: .2s;
73 | }
74 | }
75 |
76 | &.out {
77 | animation-name: react-screen-out;
78 | animation-duration: .5s;
79 | animation-timing-function: ease-out;
80 | animation-fill-mode: forwards;
81 |
82 | .image-main,
83 | .description {
84 | opacity: 1;
85 |
86 | animation-name: react-screen-item-out;
87 | animation-duration: .5s;
88 | animation-timing-function: ease-out;
89 | animation-fill-mode: forwards;
90 | animation-delay: 0s;
91 | }
92 | }
93 | }
94 |
95 | .react-screen-progress {
96 | position: fixed;
97 | right: 30px;
98 | top: 50%;
99 | width: 2px;
100 | transform: translateY(-50%);
101 | z-index: 99999;
102 |
103 | .item {
104 | position: relative;
105 | width: 2px;
106 | height: 40px;
107 | background: #ddd;
108 |
109 | .number {
110 | position: absolute;
111 | right: 15px;
112 | line-height: 40px;
113 | color: #ddd;
114 |
115 | &.active {
116 | color: #777;
117 | }
118 |
119 | &:hover {
120 | cursor: pointer;
121 | }
122 | }
123 | }
124 |
125 | .bar {
126 | position: absolute;
127 | top: 0;
128 | left: 0;
129 | width: 2px;
130 | height: 50%;
131 | background: #777;
132 | }
133 | }
134 |
135 | .react-screen-gap {
136 | position: relative;
137 | width: 100%;
138 | }
139 |
140 | .react-screen-background {
141 | position: fixed;
142 | z-index: 99998;
143 | background: #f5f5f5;
144 | top: 0;
145 | left: 0;
146 | width: 100%;
147 | height: 100%;
148 |
149 | &.in {
150 | animation-name: react-screen-in;
151 | animation-duration: .5s;
152 | animation-timing-function: ease-out;
153 | animation-fill-mode: forwards;
154 | }
155 |
156 | &.out {
157 | animation-name: react-screen-out;
158 | animation-duration: .5s;
159 | animation-timing-function: ease-out;
160 | animation-fill-mode: forwards;
161 | }
162 | }
163 |
164 | @keyframes react-screen-in {
165 | from {
166 | opacity: 0;
167 | }
168 |
169 | to {
170 | opacity: 1;
171 | }
172 | }
173 |
174 | @keyframes react-screen-out {
175 | from {
176 | opacity: 1;
177 | }
178 |
179 | to {
180 | opacity: 0;
181 | }
182 | }
183 |
184 | @keyframes react-screen-item-in {
185 | from {
186 | opacity: .2;
187 | transform: translateY(80%);
188 | }
189 |
190 | to {
191 | opacity: 1;
192 | transform: translateY(0);
193 | }
194 | }
195 |
196 | @keyframes react-screen-item-out {
197 | from {
198 | opacity: 1;
199 | transform: translateY(0);
200 | }
201 |
202 | to {
203 | opacity: .2;
204 | transform: translateY(80%);
205 | }
206 | }
--------------------------------------------------------------------------------
/dist/react-screen.css:
--------------------------------------------------------------------------------
1 | .react-screen-test{position:relative;width:100%;height:100vh;background:#888}.react-screen-wrapper.out .react-screen,.react-screen-wrapper.out .react-screen-background{z-index:-1}.react-screen-wrapper .hide{display:none}.react-screen-skip{position:fixed;z-index:99999;bottom:20px;right:10px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);text-align:center;font-size:1rem;color:#999;padding:.5rem 2rem;background-color:#f5f5f5;letter-spacing:1px;border-radius:5px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .2s ease;transition:all .2s ease;text-decoration:none}.react-screen-skip:hover{cursor:pointer;background-color:#eee;color:#666;text-decoration:none}.react-screen{position:fixed;left:0;top:0;width:100%;height:100%;background-color:#fafafa;z-index:99998}.react-screen.in{-webkit-animation-name:react-screen-in;animation-name:react-screen-in;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;z-index:99999}.react-screen.in .description,.react-screen.in .image-main,.react-screen.out{-webkit-animation-duration:.5s;-webkit-animation-timing-function:ease-out;-webkit-animation-fill-mode:forwards}.react-screen.in .description,.react-screen.in .image-main{opacity:0;-webkit-animation-name:react-screen-item-in;animation-name:react-screen-item-in;animation-duration:.5s;animation-timing-function:ease-out;animation-fill-mode:forwards;-webkit-animation-delay:.2s;animation-delay:.2s}.react-screen.out{-webkit-animation-name:react-screen-out;animation-name:react-screen-out;animation-duration:.5s;animation-timing-function:ease-out;animation-fill-mode:forwards}.react-screen-background.in,.react-screen.out .description,.react-screen.out .image-main{-webkit-animation-duration:.5s;-webkit-animation-timing-function:ease-out;-webkit-animation-fill-mode:forwards}.react-screen.out .description,.react-screen.out .image-main{opacity:1;-webkit-animation-name:react-screen-item-out;animation-name:react-screen-item-out;animation-duration:.5s;animation-timing-function:ease-out;animation-fill-mode:forwards;-webkit-animation-delay:0s;animation-delay:0s}.react-screen-progress{position:fixed;right:30px;top:50%;width:2px;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);z-index:99999}.react-screen-progress .item{position:relative;width:2px;height:40px;background:#ddd}.react-screen-progress .item .number{position:absolute;right:15px;line-height:40px;color:#ddd}.react-screen-progress .item .number.active{color:#777}.react-screen-progress .item .number:hover{cursor:pointer}.react-screen-progress .bar{position:absolute;top:0;left:0;width:2px;height:50%;background:#777}.react-screen-gap{position:relative;width:100%}.react-screen-background{position:fixed;z-index:99998;background:#f5f5f5;top:0;left:0;width:100%;height:100%}.react-screen-background.in{-webkit-animation-name:react-screen-in;animation-name:react-screen-in;animation-duration:.5s;animation-timing-function:ease-out;animation-fill-mode:forwards}.react-screen-background.out{-webkit-animation-name:react-screen-out;animation-name:react-screen-out;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@-webkit-keyframes react-screen-in{from{opacity:0}to{opacity:1}}@keyframes react-screen-in{from{opacity:0}to{opacity:1}}@-webkit-keyframes react-screen-out{from{opacity:1}to{opacity:0}}@keyframes react-screen-out{from{opacity:1}to{opacity:0}}@-webkit-keyframes react-screen-item-in{from{opacity:.2;-webkit-transform:translateY(80%);transform:translateY(80%)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes react-screen-item-in{from{opacity:.2;-webkit-transform:translateY(80%);transform:translateY(80%)}to{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes react-screen-item-out{from{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}to{opacity:.2;-webkit-transform:translateY(80%);transform:translateY(80%)}}@keyframes react-screen-item-out{from{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}to{opacity:.2;-webkit-transform:translateY(80%);transform:translateY(80%)}}
--------------------------------------------------------------------------------
/doc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | React Screen
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | React Screen
15 |
A different React carousel component.
16 |
20 |
21 |
22 |
23 |
Too many boring carousel?
24 |
Need a fancy way to show banners?
25 |
JUST SCROLL DOWN
26 |
27 |
28 |
29 |
30 |
31 |
32 |
Document
33 |
Get Started
34 |
1. Install react-screen.
35 |
# Via npm
36 | npm install react-screen
37 |
38 | # Via Bower
39 | bower install react-screen
40 |
2. Import react & react-screen.
41 |
import React, { Component } from 'react';
42 | import ReactDOM from 'react-dom';
43 | import { Screen, ScreenSlice } from 'react-screen';
44 |
3. Import stylesheet.
45 |
// In jsx
46 | import styles from 'path/to/css/react-screen.css';
47 |
Or
48 |
<!-- In HTML -->
49 | <link rel="stylesheet" href="path/to/css/react-screen.css">
50 |
4. Render it!
51 |
ReactDOM.render((
52 | <Screen>
53 | <ScreenSlice>
54 | <h1>First Screen</h1>
55 | </ScreenSlice>
56 | <ScreenSlice>
57 | <h1>Second Screen</h1>
58 | </ScreenSlice>
59 | <ScreenSlice>
60 | <h1>Third Screen</h1>
61 | </ScreenSlice>
62 | </Screen>
63 | ), document.getElementById('react-screen'));
64 |
Properties
65 |
// Values show below are default.
66 | <Screen style={} sliceHeight={ 60 } delay={ 500 } showSkip={ true }>
67 |
68 | // Descriptions
69 | {
70 | style: "A React style object. It will apply to every screen."
71 | sliceHeight: "Unit: vh. Implies each screen's scroll height.",
72 | delay:
73 | "Unit: ms. When scroll to a new screen, it will disables scroll for a while.
74 | Useful for playing animation.",
75 | showSkip: "Boolean. Determines whether show a skip button on screen."
76 | }
77 |
78 |
Styling
79 |
You can easily overwrite styles, just use inspect tool to check class names.
80 |
Animation
81 |
react-screen will add class "in" to the screen just entered in, and class "out" to other screens. So you can write your own animation like this:
82 |
.react-screen.in .your-element-class {
83 | /* In animation */
84 | }
85 |
86 | .react-screen.out .your-element-class {
87 | /* Out animation */
88 | }
89 |
90 |
Issues and Contributing
91 |
If you find any bugs or have any advices, please leave an
issue . Feel free to make a pull request and wait for accpetance!
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/dist/react-screen.js:
--------------------------------------------------------------------------------
1 | "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function preventDefault(e){e=e||window.event,e.preventDefault&&e.preventDefault(),e.returnValue=!1}function preventDefaultForScrollKeys(e){if(scrollKeys[e.keyCode])return preventDefault(e),!1}function disableScroll(){window.addEventListener&&window.addEventListener("DOMMouseScroll",preventDefault,!1),window.onwheel=preventDefault,window.onmousewheel=document.onmousewheel=preventDefault,window.ontouchmove=preventDefault,document.onkeydown=preventDefaultForScrollKeys}function enableScroll(){window.removeEventListener&&window.removeEventListener("DOMMouseScroll",preventDefault,!1),window.onmousewheel=document.onmousewheel=null,window.onwheel=null,window.ontouchmove=null,document.onkeydown=null}Object.defineProperty(exports,"__esModule",{value:!0}),exports.ScreenSlice=exports.Screen=void 0;var _createClass=function(){function e(e,t){for(var r=0;r=0&&l=0&&l=0&&l0&&this.prevIndex!=l&&this.blockScrollForAnimation(),this.blockAt(a).animateIn(),this.refs["number-"+a].classList.add("active")):(this.blockAt(a).animateOut(),this.refs["number-"+a].classList.remove("active"));this.prevIndex=l}},{key:"jumpTo",value:function(e){var t=this.length,r=window.innerHeight,n=this.getPosition(this.refs.gap).y,s=n-.5*r,o=this.refs.gap.offsetHeight;window.scrollTo(0,e*(o/t)+s+1)}}]),_createClass(t,[{key:"componentDidMount",value:function(){window.addEventListener("scroll",this.scrollListener),this.handleScroll()}},{key:"componentWillUnmount",value:function(){window.removeEventListener("scroll",this.scrollListener)}},{key:"render",value:function(){for(var e=this,t=[],r=0;r {
69 | method.bind(this)();
70 | }, delay);
71 | }
72 |
73 | blockScrollForAnimation() {
74 | disableScroll();
75 | setTimeout(function() {
76 | enableScroll();
77 | }, this.delay);
78 | }
79 |
80 | skip() {
81 | window.scrollTo(0, this.getPosition(this.refs.gap).y + this.refs.gap.offsetHeight);
82 | }
83 |
84 | handleScroll() {
85 | let length = this.length;
86 | let innerHeight = window.innerHeight;
87 | let bodyScrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
88 | let screenTop = this.getPosition(this.refs.gap).y;
89 | let screenStartTop = screenTop - 0.5 * innerHeight;
90 | let screenHeight = this.refs.gap.offsetHeight;
91 | let screenIndex = Math.floor((bodyScrollTop - screenStartTop) / (screenHeight / length));
92 |
93 | // Background
94 | if(screenIndex >= 0 && screenIndex < length) {
95 | this.refs.background.classList.remove('out');
96 |
97 | // Move slider to top, need a fancier way
98 | clearTimeout(this.removeWrapperTimeoutId);
99 | this.refs.wrapper.classList.remove('out');
100 | this.removeWrapperTimeoutId = null;
101 | } else {
102 | this.refs.background.classList.add('out');
103 |
104 | // Move slider to bottom, need a fancier way
105 | if(this.removeWrapperTimeoutId == null) {
106 | this.removeWrapperTimeoutId = window.setTimeout(() => {
107 | this.refs.wrapper.classList.add('out');
108 | }, 500);
109 | }
110 | }
111 | // Progress
112 | if(screenIndex >= 0 && screenIndex < length) {
113 | this.refs.progress.classList.remove('hide');
114 | this.refs['progress-bar'].style.height = (((bodyScrollTop - screenStartTop) / screenHeight) * 100) + '%';
115 | } else {
116 | this.refs.progress.classList.add('hide');
117 | }
118 |
119 | // Skip
120 | if(this.showSkip && screenIndex >= 0 && screenIndex < length) {
121 | this.refs.skip.classList.remove('hide');
122 | } else {
123 | this.refs.skip.classList.add('hide');
124 | }
125 |
126 | // Screen
127 | for(let i = 0; i < length; ++ i) {
128 | if(i == screenIndex) {
129 | if(this.delay > 0 && this.prevIndex != screenIndex) {
130 | this.blockScrollForAnimation();
131 | }
132 |
133 | this.blockAt(i).animateIn();
134 | this.refs['number-' + i].classList.add('active');
135 | } else {
136 | this.blockAt(i).animateOut();
137 | this.refs['number-' + i].classList.remove('active');
138 | }
139 | }
140 |
141 | this.prevIndex = screenIndex;
142 | }
143 |
144 | jumpTo(index) {
145 | let length = this.length;
146 | let innerHeight = window.innerHeight;
147 | let screenTop = this.getPosition(this.refs.gap).y;
148 | let screenStartTop = screenTop - 0.5 * innerHeight;
149 | let screenHeight = this.refs.gap.offsetHeight;
150 |
151 | window.scrollTo(0, index * (screenHeight / length) + screenStartTop + 1);
152 | }
153 |
154 | // Original Event Handlers
155 | constructor(props) {
156 | super(props);
157 | this.length = Array.isArray(props.children) ? props.children.length : 1;
158 | (props.delay != undefined) && (this.delay = props.delay);
159 | (props.sliceHeight != undefined) && (this.sliceHeight = props.sliceHeight);
160 | (props.showSkip != undefined) && (this.showSkip = props.showSkip);
161 | }
162 | componentDidMount() {
163 | window.addEventListener('scroll', this.scrollListener);
164 | this.handleScroll();
165 | }
166 |
167 | componentWillUnmount() {
168 | window.removeEventListener('scroll', this.scrollListener);
169 | }
170 |
171 | render() {
172 | let numbers = [];
173 |
174 | for(let i = 0; i < this.length; ++ i) {
175 | numbers.push(
176 |
179 | );
180 | }
181 |
182 | let index = 0;
183 | let slices = React.Children.map(this.props.children,
184 | (child) => React.cloneElement(child, {
185 | ref: 'slice-' + (index++),
186 | style: this.props.style
187 | })
188 | );
189 |
190 | return (
191 |
192 |
193 |
194 |
195 | { slices }
196 |
197 | { numbers }
198 |
199 |
200 |
SKIP
201 |
202 |
203 | );
204 | }
205 | }
206 |
207 | export class ScreenSlice extends Component {
208 | cleanUp() {
209 | this.refs.screen.classList.remove('in');
210 | this.refs.screen.classList.remove('out');
211 | }
212 | animateIn() {
213 | this.cleanUp();
214 | this.refs.screen.classList.add('in');
215 | }
216 | animateOut() {
217 | this.cleanUp();
218 | this.refs.screen.classList.add('out');
219 | }
220 | render() {
221 | return (
222 | { this.props.children }
223 | );
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/doc/css/style.css:
--------------------------------------------------------------------------------
1 | /* Webfont: Lato-Light */@font-face {
2 | font-family: 'LatoWebLight';
3 | src: url('../font/Lato-Light.eot'); /* IE9 Compat Modes */
4 | src: url('../font/Lato-Light.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
5 | url('../font/Lato-Light.woff2') format('woff2'), /* Modern Browsers */
6 | url('../font/Lato-Light.woff') format('woff'), /* Modern Browsers */
7 | url('../font/Lato-Light.ttf') format('truetype');
8 | font-style: normal;
9 | font-weight: normal;
10 | text-rendering: optimizeLegibility;
11 | }
12 |
13 | /* Webfont: Lato-Regular */@font-face {
14 | font-family: 'LatoWeb';
15 | src: url('../font/Lato-Regular.eot'); /* IE9 Compat Modes */
16 | src: url('../font/Lato-Regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
17 | url('../font/Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
18 | url('../font/Lato-Regular.woff') format('woff'), /* Modern Browsers */
19 | url('../font/Lato-Regular.ttf') format('truetype');
20 | font-style: normal;
21 | font-weight: normal;
22 | text-rendering: optimizeLegibility;
23 | }
24 |
25 | html, body {
26 | margin: 0;
27 | padding: 0;
28 | font-family: 'Lato', 'LatoWebLight', 'Myriad Pro', 'Helvetica';
29 | font-weight: 300;
30 | font-size: 12px;
31 | color: #333;
32 | }
33 |
34 | .font-light {
35 | font-family: 'Lato', 'LatoWebLight', 'Myriad Pro', 'Helvetica';
36 | font-weight: 300;
37 | }
38 |
39 | .font-regular {
40 | font-family: 'Lato', 'LatoWeb', 'Myriad Pro', 'Helvetica';
41 | font-weight: 400;
42 | }
43 |
44 | .block {
45 | width: 90%;
46 | margin: 0 auto;
47 | max-width: 1000px;
48 | font-size: 1.3rem;
49 | }
50 |
51 |
52 | /* Repo */
53 |
54 | .repo {
55 | position: relative;
56 | padding: 0;
57 | text-align: center;
58 | min-height: 100vh;
59 | background: #fafafa;
60 | }
61 |
62 | .repo .title {
63 | font-size: 4rem;
64 | padding: 20vh 0;
65 | background-color: #1d1d1d;
66 | color: #2852fd;
67 | }
68 |
69 | .repo .subtitle {
70 | padding: 1.2rem;
71 | font-size: 1.3rem;
72 | color: #c5c5c5;
73 | }
74 |
75 | .repo .intro {
76 | padding: 6rem 0;
77 | }
78 |
79 | .repo .button-group .button {
80 | display: inline-block;
81 | width: 120px;
82 | font-size: 1.2rem;
83 | padding: .6rem 0;
84 | color: #333;
85 | background-color: #eee;
86 | border-radius: 3px;
87 | text-decoration: none;
88 | transition: all ease .2s;
89 | }
90 |
91 | .repo .button-group .button:hover {
92 | cursor: pointer;
93 | background-color: #ccc;
94 | }
95 |
96 | .repo .block .item {
97 | font-size: 1.8rem;
98 | padding: 1.3rem;
99 | color: #555;
100 | }
101 |
102 | /* Document */
103 |
104 | .document {
105 | min-height: 100vh;
106 | background: #fafafa;
107 | padding: 2rem 0;
108 | }
109 |
110 | .document .bigtitle {
111 | padding: 1rem 0;
112 | font-size: 3rem;
113 | }
114 |
115 | .document .title {
116 | padding: 1rem 0;
117 | font-size: 2rem;
118 | color: rgb(7,120,215);
119 | }
120 |
121 | .document .text {
122 | padding: 1rem 0;
123 | font-size: 1.5rem;
124 | }
125 |
126 | /* Screen */
127 |
128 | .screen {
129 | position: absolute;
130 | width: 100%;
131 | height: 100%;
132 | top: 0;
133 | left: 0;
134 | perspective: 150vw;
135 | }
136 |
137 | .screen > .title {
138 | position: absolute;
139 | left: 10%;
140 | top: 10%;
141 | font-size: 3rem;
142 | color: #333;
143 | }
144 |
145 | .screen > .text {
146 | position: absolute;
147 | left: 10%;
148 | top: calc(10% + 4rem);
149 | font-size: 1.5rem;
150 | color: #888;
151 | }
152 |
153 | /* Screen 1 */
154 |
155 | .screen-1-base,
156 | .screen-2-base {
157 | position: absolute;
158 | width: 60%;
159 | height: 50%;
160 | left: 50%;
161 | top: 50%;
162 | background: #ddd;
163 | border-radius: 3px;
164 | overflow: hidden;
165 | box-shadow: 5px 5px 5px rgba(233,233,233,.8);
166 | }
167 |
168 | .screen-1-base {
169 | transform: translateX(-50%) translateY(-50%);
170 | }
171 |
172 | .screen-1-base .block {
173 | position: absolute;
174 | height: 80%;
175 | border-radius: 3px;
176 | }
177 |
178 | .screen-1-base .block .image {
179 | position: absolute;
180 | width: 20%;
181 | height: 20%;
182 | left: 30%;
183 | top: 50%;
184 |
185 | transform: translateX(-50%) translateY(-50%);
186 | background-image: url(../image/screen.svg);
187 | background-position: center;
188 | background-repeat: no-repeat;
189 | background-size: contain;
190 | }
191 |
192 | .screen-1-base .block .text {
193 | position: absolute;
194 | width: 35%;
195 | height: 20%;
196 | left: 65%;
197 | top: 55%;
198 | font-size: 2vw;
199 | color: rgba(0,57,179,1);
200 | overflow: hidden;
201 | text-overflow: ellipsis;
202 | white-space: nowrap;
203 |
204 | transform: translateX(-50%) translateY(-50%);
205 | }
206 |
207 | .screen-1-base .block.block-1 {
208 | background: rgba(79, 127, 232, .9);
209 | top: 10%;
210 | left: 10%;
211 | width: 50%;
212 | }
213 |
214 | .screen-1-base .block.block-2 {
215 | background: rgba(151,183,242,.9);
216 | top: 10%;
217 | left: 65%;
218 | width: 25%;
219 | }
220 |
221 | .screen-1-base .block.block-3 {
222 | background: #f5f5f5;
223 | top: 100%;
224 | left: 0;
225 | width: 100%;
226 | height: 100%;
227 | transform: scaleX(0.8) scaleY(0.8);
228 | overflow: hidden;
229 | }
230 |
231 | .react-screen.in .screen-1-base .block.block-1,
232 | .react-screen.in .screen-1-base .block.block-2 {
233 | animation-delay: .3s;
234 | animation-duration: 1s;
235 | animation-timing-function: ease;
236 | animation-fill-mode: forwards;
237 | animation-name: ReactScreen-1-Scroll;
238 | }
239 |
240 | .react-screen.in .screen-1-base .block.block-3 {
241 | animation-delay: .3s, 1.3s;
242 | animation-duration: 1s, .8s;
243 | animation-timing-function: ease;
244 | animation-fill-mode: forwards;
245 | animation-name: ReactScreen-1-Screen-Scroll, ReactScreen-1-Resize;
246 | }
247 |
248 | .react-screen.out .screen-1-base .block.block-1,
249 | .react-screen.out .screen-1-base .block.block-2 {
250 | animation: none;
251 | transform: translateY(-113%);
252 | }
253 |
254 | .react-screen.out .screen-1-base .block.block-3 {
255 | animation: none;
256 | transform: translateY(-100%) scaleX(1) scaleY(1);
257 | }
258 |
259 | @keyframes ReactScreen-1-Scroll {
260 | to {
261 | transform: translateY(-113%);
262 | }
263 | }
264 |
265 | @keyframes ReactScreen-1-Screen-Scroll {
266 | from {
267 | transform: scaleX(0.8) scaleY(0.8);
268 | }
269 | to {
270 | transform: translateY(-100%) scaleX(0.8) scaleY(0.8);;
271 | }
272 | }
273 |
274 | @keyframes ReactScreen-1-Resize {
275 | from {
276 | transform: translateY(-100%) scaleX(0.8) scaleY(0.8);
277 | }
278 | to {
279 | transform: translateY(-100%) scaleX(1) scaleY(1);
280 | }
281 | }
282 |
283 | /* Screen 2 */
284 | .screen-2-base {
285 | transform: translateX(-50%) translateY(-50%);
286 | }
287 |
288 | .screen-2-base .image {
289 | position: absolute;
290 | top: 0;
291 | left: 0;
292 | width: 100%;
293 | height: 100%;
294 | transform: translateY(100%);
295 |
296 | background-image: url(../image/sierra.jpg);
297 | background-position: center;
298 | background-size: cover;
299 | background-repeat: no-repeat;
300 | }
301 |
302 | .screen-2-base .text {
303 | position: absolute;
304 | top: 15%;
305 | left: 0;
306 | width: 100%;
307 | text-align: center;
308 | color: white;
309 | font-size: 3vw;
310 | font-family: 'Lato', 'LatoWeb';
311 | font-weight: 400;
312 | opacity: 0;
313 | }
314 |
315 | .screen-2-base .button {
316 | position: absolute;
317 | top: 50%;
318 | left: 50%;
319 | width: 70px;
320 | font-size: 1vw;
321 | padding: .3vw 1.3vw;
322 | border-radius: 3px;
323 | background: rgba(39, 87, 232, .9);
324 | text-align: center;
325 | color: white;
326 | opacity: 0;
327 | }
328 |
329 | .react-screen.in .screen-2-base .image {
330 | animation-delay: .2s;
331 | animation-duration: 1s;
332 | animation-timing-function: ease;
333 | animation-fill-mode: forwards;
334 | animation-name: ReactScreen-2-Image;
335 | }
336 |
337 | .react-screen.in .screen-2-base .text {
338 | animation-delay: 1.2s;
339 | animation-duration: .6s;
340 | animation-timing-function: ease;
341 | animation-fill-mode: forwards;
342 | animation-name: ReactScreen-2-Text;
343 | }
344 |
345 | .react-screen.in .screen-2-base .button {
346 | animation-delay: 1.8s;
347 | animation-duration: .6s;
348 | animation-timing-function: ease;
349 | animation-fill-mode: forwards;
350 | animation-name: ReactScreen-2-Button;
351 | }
352 |
353 | .react-screen.out .screen-2-base .image,
354 | .react-screen.out .screen-2-base .text,
355 | .react-screen.out .screen-2-base .button {
356 | animation: none;
357 | }
358 |
359 | .react-screen.out .screen-2-base .image {
360 | transform: none;
361 | }
362 |
363 | .react-screen.out .screen-2-base .text {
364 | opacity: 1;
365 | transform: none;
366 | }
367 |
368 | .react-screen.out .screen-2-base .button {
369 | opacity: 1;
370 | transform: translateX(-50%) translateY(-100%);
371 | }
372 |
373 | @keyframes ReactScreen-2-Image {
374 | from {
375 | transform: translateY(100%);
376 | }
377 |
378 | to {
379 | transform: none;
380 | }
381 | }
382 |
383 | @keyframes ReactScreen-2-Text {
384 | from {
385 | opacity: 0;
386 | transform: translateY(-100%);
387 | }
388 |
389 | to {
390 | opacity: 1;
391 | transform: translateY(0);
392 | }
393 | }
394 |
395 | @keyframes ReactScreen-2-Button {
396 | from {
397 | opacity: 0;
398 | transform: translateX(-50%) translateY(0);
399 | }
400 |
401 | to {
402 | opacity: 1;
403 | transform: translateX(-50%) translateY(-100%);
404 | }
405 | }
406 |
407 | /* Screen 3 */
408 |
409 | .rec {
410 | /*transform: translateX(-50%) translateY(-50%);*/
411 | transform: translateX(-50%) translateY(-50%) rotateX(60deg) rotateZ(50deg);
412 |
413 | border-radius: 3px;
414 | }
415 |
416 | .rec-base-1 {
417 | position: absolute;
418 | width: 40%;
419 | height: 40%;
420 | left: 50%;
421 | top: 50%;
422 | background: rgba(0, 57, 179, .9);
423 | box-shadow: 10px 10px 5px rgba(233,233,233,.8);
424 | }
425 |
426 | .rec-base-2 {
427 | position: absolute;
428 | width: 40%;
429 | height: 40%;
430 | left: 50%;
431 | top: 45%;
432 | opacity: 0;
433 | }
434 |
435 | .rec-base-3 {
436 | position: absolute;
437 | width: 40%;
438 | height: 40%;
439 | left: 50%;
440 | top: 40%;
441 | opacity: 0;
442 | }
443 |
444 | .rec-block-1 {
445 | position: absolute;
446 | width: 85%;
447 | height: 100%;
448 | left: 1%;
449 | top: 1%;
450 | background: rgba(79, 127, 232, .9);
451 | border-radius: 3px;
452 | }
453 |
454 | .rec-block-2 {
455 | position: absolute;
456 | width: 12%;
457 | height: 100%;
458 | left: 87%;
459 | top: 1%;
460 | background: rgba(104,146,237,.9);
461 | border-radius: 3px;
462 | }
463 |
464 | .rec-block-3 {
465 | position: absolute;
466 | width: 30%;
467 | height: 50%;
468 | left: 2%;
469 | top: 1%;
470 | background: rgba(151,183,242,.9);
471 | border-radius: 3px;
472 | }
473 |
474 | .rec-block-4 {
475 | position: absolute;
476 | width: 50%;
477 | height: 100%;
478 | left: 33%;
479 | top: 1%;
480 | background: rgba(190,208,247,.9);
481 | border-radius: 3px;
482 | }
483 |
484 | .react-screen.in .rec {
485 | animation-duration: .7s;
486 | animation-timing-function: ease;
487 | animation-fill-mode: forwards;
488 | }
489 |
490 | .react-screen.in .rec-base-1 {
491 | animation-name: ReactScreenFlyInBase;
492 | }
493 |
494 | .react-screen.in .rec-base-2 {
495 | animation-name: ReactScreenFlyInElements;
496 | animation-delay: .2s;
497 | }
498 |
499 | .react-screen.in .rec-base-3 {
500 | animation-name: ReactScreenFlyInElements2;
501 | animation-delay: .4s;
502 | }
503 |
504 | .react-screen.out .rec {
505 | animation: none;
506 | opacity: 1;
507 | }
508 |
509 | .react-screen.in .rec-base-1 {
510 | top: 50%;
511 | }
512 |
513 | .react-screen.in .rec-base-2 {
514 | top: 45%;
515 | }
516 |
517 | .react-screen.in .rec-base-3 {
518 | top: 40%;
519 | }
520 |
521 | @keyframes ReactScreenFlyInBase {
522 | from {
523 | top: 65%;
524 | opacity: .2;
525 | }
526 |
527 | to {
528 | top: 50%;
529 | opacity: 1;
530 | }
531 | }
532 |
533 | @keyframes ReactScreenFlyInElements {
534 | from {
535 | top: 55%;
536 | opacity: 0;
537 | }
538 |
539 | to {
540 | top: 45%;
541 | opacity: 1;
542 | }
543 | }
544 |
545 | @keyframes ReactScreenFlyInElements2 {
546 | from {
547 | top: 50%;
548 | opacity: 0;
549 | }
550 |
551 | to {
552 | top: 40%;
553 | opacity: 1;
554 | }
555 | }
--------------------------------------------------------------------------------