├── .editorconfig
├── .gitignore
├── .npmignore
├── FUNDING.yml
├── LICENSE.md
├── README.md
├── bower.json
├── build
├── mojs-player.js
└── mojs-player.min.js
├── css
├── assets
│ ├── colors.postcss.css
│ └── globals.postcss.css
├── blocks
│ ├── button-switch.postcss.css
│ ├── button-switch.postcss.css.json
│ ├── button.postcss.css
│ ├── button.postcss.css.json
│ ├── handle.postcss.css
│ ├── handle.postcss.css.json
│ ├── hide-button.postcss.css
│ ├── hide-button.postcss.css.json
│ ├── icon-button.postcss.css
│ ├── icon-button.postcss.css.json
│ ├── icon-fork.postcss.css
│ ├── icon-fork.postcss.css.json
│ ├── icon.postcss.css
│ ├── icon.postcss.css.json
│ ├── label-button.postcss.css
│ ├── label-button.postcss.css.json
│ ├── mojs-player.postcss.css
│ ├── mojs-player.postcss.css.json
│ ├── opacity-switch.postcss.css
│ ├── opacity-switch.postcss.css.json
│ ├── play-button.postcss.css
│ ├── play-button.postcss.css.json
│ ├── player-slider.postcss.css
│ ├── player-slider.postcss.css.json
│ ├── player.postcss.css
│ ├── repeat-button.postcss.css
│ ├── repeat-button.postcss.css.json
│ ├── slider.postcss.css
│ ├── slider.postcss.css.json
│ ├── speed-control.postcss.css
│ ├── speed-control.postcss.css.json
│ ├── stop-button.postcss.css
│ ├── stop-button.postcss.css.json
│ ├── track.postcss.css
│ └── track.postcss.css.json
├── main.postcss.css
└── main.postcss.css.json
├── gulpfile.js
├── index.html
├── js
├── components
│ ├── bounds-button.babel.js
│ ├── button-switch.babel.js
│ ├── button.babel.js
│ ├── handle.babel.js
│ ├── hide-button.babel.js
│ ├── icon-button.babel.js
│ ├── icon-fork.babel.js
│ ├── icon.babel.js
│ ├── icons.babel.js
│ ├── label-button.babel.js
│ ├── module.babel.js
│ ├── opacity-switch.babel.js
│ ├── play-button.babel.js
│ ├── player-slider.babel.js
│ ├── repeat-button.babel.js
│ ├── ripple.babel.js
│ ├── slider.babel.js
│ ├── speed-control.babel.js
│ ├── stop-button.babel.js
│ └── track.babel.js
└── mojs-player.babel.js
├── lib
├── components
│ ├── bounds-button.js
│ ├── button-switch.js
│ ├── button.js
│ ├── handle.js
│ ├── hide-button.js
│ ├── icon-button.js
│ ├── icon-fork.js
│ ├── icon.js
│ ├── icons.js
│ ├── label-button.js
│ ├── module.js
│ ├── opacity-switch.js
│ ├── play-button.js
│ ├── player-slider.js
│ ├── repeat-button.js
│ ├── ripple.js
│ ├── slider.js
│ ├── speed-control.js
│ ├── stop-button.js
│ └── track.js
└── mojs-player.js
├── logo.png
├── mockups
├── mojs-player.sketch
└── mojs-player@x4.png
├── package-lock.json
├── package.json
└── webpack.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # top-most editorconfig file
2 | root = true
3 |
4 | # editor configuration
5 | [*]
6 | charset = utf-8
7 | end_of_line = lf
8 | indent_style = space
9 | indent_size = 2
10 | trim_trailing_whitespace = true
11 | insert_final_newline = true
12 |
13 | # preserve markdown line break
14 | [*.md]
15 | trim_trailing_whitespace = false
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | mockups/
2 | css/
3 | lib/
4 | js/
5 | .editorconfig
6 | index.html
7 | bower.json
8 | gulpfile.js
9 | webpack.config.js
10 |
--------------------------------------------------------------------------------
/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: xavierfoucrier
4 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Oleg Solomka, Xavier Foucrier, Jonas Sandstedt
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 | # @mojs/player – [](https://www.npmjs.com/package/@mojs/player)
2 |
3 | GUI player to control your animations.
4 |
5 | 
6 |
7 | Player controls for [mojs](https://github.com/mojs/mojs). Intended to help you to craft `mojs` animation sequences. To be clear, this player is not needed to play `mojs` animations. It is just a debug tool that gives you the ability to:
8 | - control your sequences with `GUI` while working on them
9 | - it saves the current progress of your animation thus you don't loose the `focus`
10 | - it gives you `bounds` to constrain `focus point` of your animation
11 | - it gives you the control over the speed of animation
12 | - it gives you the ability to seek animations freely
13 | - it saves player's state and settings thus they not get lost when page reloaded
14 |
15 | ## Installation
16 |
17 | The `MojsPlayer` depends on `mojs >= 0.225.2` so make sure you link it first.
18 |
19 | ```console
20 | # cdn
21 |
22 |
23 | # npm
24 | npm i @mojs/player
25 | ```
26 |
27 | Import `MojsPlayer` constructor to your code, depending on your environment:
28 |
29 | ```javascript
30 | const MojsPlayer = require('mojs-player').default;
31 |
32 | // or
33 | import MojsPlayer from '@mojs/player';
34 | ```
35 |
36 | > If you installed it with script link — you should have `MojsPlayer` global
37 |
38 | ## Usage
39 |
40 | Construct `MojsPlayer` and pass your main `Tween/Timeline` to the `add` option:
41 |
42 | ```javascript
43 | // create the timeline
44 | const mainTimeline = new mojs.Timeline({});
45 |
46 | // add the timeline to the player
47 | const mojsPlayer = new MojsPlayer({
48 | add: mainTimeline
49 | });
50 | ```
51 |
52 | > The `add` option is the **only required option** to launch: player's controls should appear at the bottom of the page when ready
53 |
54 | You can also set other player initial state:
55 |
56 | ```javascript
57 | const mojsPlayer = new MojsPlayer({
58 |
59 | // required
60 | add: mainTimeline,
61 |
62 | // optionally
63 | className: '', // class name to add to main HTMLElement
64 | isSaveState: true, // determines if should preserve state on page reload
65 | isPlaying: false, // playback state
66 | progress: 0, // initial progress
67 | isRepeat: false, // determines if it should repeat after completion
68 | isBounds: false, // determines if it should have bounds
69 | leftBound: 0, // left bound position [0...1]
70 | rightBound: 1, // right bound position [0...1]
71 | isSpeed: false, // determines if speed control should be open
72 | speed: 1, // `speed` value
73 | isHidden: false, // determines if the player should be hidden
74 | precision: 0.1, // step size for player handle - for instance, after page reload - player should restore timeline progress - the whole timeline will be updated incrementally with the `precision` step size until the progress will be met.
75 | name: 'mojs-player', // name for the player - mainly used for localstorage identifier, use to distinguish between multiple local players
76 | onToggleHide(isHidden) { // should be called after user taps on the hide-button (isHidden is a boolean, indicating the visibility state of the player)
77 | if (isHidden) {
78 | // do something when player is invisible
79 | } else {
80 | // do something when player is visible
81 | }
82 | }
83 | });
84 | ```
85 |
86 | ## Shortcuts
87 |
88 | - `alt + p` - toggle `play`/`pause` playback state
89 | - `alt + - ` - decrease progress by `1/100`
90 | - `alt + +` - increase progress by `1/100`
91 | - `shift + alt + -` - decrease progress by `1/10`
92 | - `shift + alt + +` - increase progress by `1/10`
93 | - `alt + s` - `stop` playback
94 | - `alt + r` - toggle `repeat` state
95 | - `alt + b` - toggle `bounds` state
96 | - `alt + h` - toggle `show`/`hide` player state
97 | - `alt + q` - reset `speed` to `1x`
98 | - `alt + 2` - decrease `speed` by `1/50`
99 | - `alt + 3` - increase `speed` by `1/50`
100 | - `shift + alt + 2` - decrease `speed` by `1/10`
101 | - `shift + alt + 3` - increase `speed` by `1/10`
102 |
103 |
104 | ## Development
105 |
106 | Install [webpack](https://webpack.github.io/) globally:
107 |
108 | ```console
109 | [sudo] npm install webpack -g
110 | ```
111 |
112 | Install dependencies with [npm](https://www.npmjs.com/):
113 |
114 | ```console
115 | [sudo] npm install
116 | ```
117 |
118 | Run [webpack](https://webpack.github.io/):
119 |
120 | ```console
121 | webpack
122 | ```
123 |
124 | Please make sure you are on the `dev` branch before making changes.
125 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mojs-player",
3 | "version": "1.3.0",
4 | "description": "Player controls for [mojs](mojs.github.io). Intended to help you to craft `mojs` animation sequences.",
5 | "main": "build/mojs-player.min.js",
6 | "authors": ["Oleg Solomka"],
7 | "license": "MIT",
8 | "keywords": ["motion", "effects", "animation", "motion", "graphics", "player"],
9 | "homepage": "https://github.com/mojs/mojs-player",
10 | "moduleType": ["amd", "node", "es6", "globals"],
11 | "ignore": ["**/.*", "node_modules", "bower_components", "test", "tests"]
12 | }
--------------------------------------------------------------------------------
/css/assets/colors.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | $c-purple: #3A0839;
3 | $c-orange: #FF512F;
4 | $c-white : #FFFFFF;
5 |
--------------------------------------------------------------------------------
/css/assets/globals.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import './colors.postcss.css';
3 |
4 | /*$PX: 1/16rem;*/
5 | $PX: 1px;
6 | $GS: calc( 10 * $PX );
7 | $BRADIUS: calc( 3 * $PX );
8 |
--------------------------------------------------------------------------------
/css/blocks/button-switch.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .button-switch {
5 | position: relative;
6 | display: inline-block;
7 |
8 | & > .icon {
9 | position: absolute;
10 | }
11 |
12 | &:after {
13 | content: "";
14 | position: absolute;
15 | left: 0;
16 | top: 0;
17 | right: 0;
18 | bottom: 0;
19 | z-index: 1;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/css/blocks/button-switch.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"button-switch":"_button-switch_1putg_4","icon":"_icon_1putg_8"}
--------------------------------------------------------------------------------
/css/blocks/button.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .button {
5 | position: relative;
6 | width: calc( 35 * $PX );
7 | height: calc( 40 * $PX );
8 | cursor: pointer;
9 | fill: #FFF;
10 | display: inline-block;
11 | &__ripple {
12 | position: absolute;
13 | left: 0;
14 | right: 0;
15 | top: 0;
16 | bottom: 0;
17 | z-index: 5;
18 | overflow: hidden;
19 | &:after {
20 | content: "";
21 | position: absolute;
22 | left: 0;
23 | right: 0;
24 | top: 0;
25 | bottom: 0;
26 | z-index: 1;
27 | cursor: pointer;
28 | }
29 | }
30 | &:hover {
31 | opacity: .85;
32 | }
33 |
34 | &:active {
35 | opacity: 1;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/css/blocks/button.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"button":"_button_wb9ek_4","button__ripple":"_button__ripple_wb9ek_1"}
--------------------------------------------------------------------------------
/css/blocks/handle.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | $handleHeight: 13;
5 | .handle {
6 | width: calc( $handleHeight * $PX );
7 | height: calc( $handleHeight * $PX );
8 |
9 | cursor: pointer;
10 | transform: translateX(0);
11 | backface-visibility: hidden;
12 |
13 | &__inner,
14 | &__shadow {
15 | position: absolute;
16 | left: 0;
17 | top: 0;
18 | z-index: 1;
19 |
20 | width: 100%;
21 | height: 100%;
22 | border-radius: 50%;
23 | cursor: pointer;
24 | /*transform: translateZ(0);*/
25 | /*backface-visibility: hidden;*/
26 | }
27 |
28 | &__inner {
29 | background: #FFF;
30 | }
31 |
32 | &__shadow {
33 | box-shadow: calc( $PX ) calc( $PX ) calc( 2*$PX ) black;
34 | opacity: .35;
35 | z-index: 0;
36 | }
37 |
38 | &:hover &__inner,
39 | &:hover &__shadow {
40 | transform: scale(1.1);
41 | }
42 |
43 | &:active &__inner {
44 | transform: scale(1.2);
45 | /*box-shadow: calc( $PX ) calc( $PX ) calc( 1*$PX ) rgba(0,0,0,.35);*/
46 | }
47 | &:active &__shadow {
48 | opacity: .85;
49 | transform: scale(1);
50 | }
51 |
52 | $width: 9;
53 | $height: 20;
54 | &.is-bound {
55 | width: calc( $width * $PX );
56 | height: calc( $height * $PX );
57 | margin-left: calc( - $width * $PX );
58 | margin-top: calc( - $height/2 * $PX );
59 | }
60 | &.is-bound &__inner {
61 | background: $c-orange;
62 | $lineHeight: 40;
63 | &:after {
64 | content: '';
65 | position: absolute;
66 | right: 0;
67 | top: 50%;
68 | margin-top: calc( - $lineHeight/2 * $PX );
69 | width: calc( $PX );
70 | height: calc( $lineHeight * $PX );
71 | background: $c-orange;
72 | }
73 | }
74 | &.is-bound &__inner,
75 | &.is-bound &__shadow {
76 | border-top-left-radius: $BRADIUS;
77 | border-bottom-left-radius: $BRADIUS;
78 | border-top-right-radius: 0;
79 | border-bottom-right-radius: 0;
80 | }
81 |
82 | &.is-inversed {
83 | margin-left: 0;
84 | }
85 | &.is-inversed &__shadow {
86 | box-shadow: calc( - $PX ) calc( $PX ) calc( 2*$PX ) black;
87 | }
88 | &.is-inversed &__inner {
89 | border-top-left-radius: 0;
90 | border-bottom-left-radius: 0;
91 | border-top-right-radius: $BRADIUS;
92 | border-bottom-right-radius: $BRADIUS;
93 | &:after {
94 | right: auto;
95 | left: 0;
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/css/blocks/handle.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"handle":"_handle_8vrrs_5","handle__inner":"_handle__inner_8vrrs_1","handle__shadow":"_handle__shadow_8vrrs_1","is-bound":"_is-bound_8vrrs_54","is-inversed":"_is-inversed_8vrrs_82"}
--------------------------------------------------------------------------------
/css/blocks/hide-button.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .hide-button {
5 |
6 | width: calc( 22 * $PX );
7 | height: calc( 16 * $PX );
8 |
9 | background: $c-purple;
10 |
11 | border-top-left-radius: $BRADIUS;
12 | border-top-right-radius: $BRADIUS;
13 |
14 | &__icon {
15 | position: absolute;
16 | left: 50%;
17 | top: 50%;
18 | width: calc( 8 * $PX );
19 | height: calc( 8 * $PX );
20 | margin-top: calc( 1 * $PX );
21 | transform: translate( -50%, -50% );
22 | }
23 |
24 | &.is-hidden &__icon {
25 | transform: translate( -50%, -65% ) rotate( 180deg );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/css/blocks/hide-button.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"hide-button":"_hide-button_aiv1o_4","hide-button__icon":"_hide-button__icon_aiv1o_1","is-hidden":"_is-hidden_aiv1o_24"}
--------------------------------------------------------------------------------
/css/blocks/icon-button.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .icon-button {
5 | /* styles */
6 | & .icon {
7 | position: absolute;
8 | left: 50%;
9 | top: 50%;
10 | transform: translate( -50%, -50% );
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/css/blocks/icon-button.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"icon-button":"_icon-button_qglug_4","icon":"_icon_qglug_4"}
--------------------------------------------------------------------------------
/css/blocks/icon-fork.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .icon-fork {
5 | & > .icon {
6 | /*position: absolute;*/
7 | opacity: 0;
8 | position: absolute;
9 | top: 50%;
10 | left: 50%;
11 | transform: translate( -50%, -50% );
12 | }
13 | & > .icon:nth-of-type(3) {
14 | position: absolute;
15 | opacity: 1;
16 | }
17 |
18 | &.is-on > .icon:nth-of-type(2) {
19 | opacity: 1;
20 | }
21 | &.is-on > .icon:nth-of-type(3) {
22 | opacity: 0;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/css/blocks/icon-fork.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"icon-fork":"_icon-fork_1n6j9_4","icon":"_icon_1n6j9_4","is-on":"_is-on_1n6j9_18"}
--------------------------------------------------------------------------------
/css/blocks/icon.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | $size: 12;
5 | .icon {
6 | position: relative;
7 | width: calc( 12 * $PX );
8 | height: calc( 12 * $PX );
9 | cursor: pointer;
10 |
11 | & > svg {
12 | position: absolute;
13 | left: 0;
14 | top: 0;
15 | width: 100%;
16 | height: 100%;
17 | fill: inherit;
18 | & > use {
19 | fill: inherit;
20 | }
21 | }
22 |
23 | &:after {
24 | content: '';
25 | position: absolute;
26 | left: 0;
27 | top: 0;
28 | right: 0;
29 | bottom: 0;
30 | z-index: 1;
31 | }
32 |
33 | &.is-x2 {
34 | width: calc( 16*$PX );
35 | height: calc( 16*$PX );
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/css/blocks/icon.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"icon":"_icon_if24v_5","is-x2":"_is-x2_if24v_33"}
--------------------------------------------------------------------------------
/css/blocks/label-button.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .label-button {
5 | font-family: Arial, sans-serif;
6 | font-size: calc( 9 * $PX );
7 | letter-spacing: calc( .5* $PX );
8 | color: white;
9 | &__label {
10 | position: absolute;
11 | left: 50%;
12 | top: 50%;
13 | transform: translate( -50%, -50% );
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/css/blocks/label-button.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"label-button":"_label-button_1cxps_4","label-button__label":"_label-button__label_1cxps_1"}
--------------------------------------------------------------------------------
/css/blocks/mojs-player.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .mojs-player {
5 | position: fixed;
6 | left: 0;
7 | bottom: 0;
8 | width: 100%;
9 | height: calc( 40 * $PX );
10 | background: rgba( 58, 8, 57, .85 );
11 | z-index: 100;
12 |
13 | * {
14 | box-sizing: border-box;
15 | }
16 |
17 | $btnWidth: 35;
18 | $btnCount: 5;
19 | $leftWidth: calc( $btnCount * $btnWidth * $PX );
20 | &__left {
21 | position: absolute;
22 | left: 0;
23 | width: $leftWidth;
24 | }
25 |
26 | &__mid {
27 | position: absolute;
28 | left: $leftWidth;
29 | right: calc( $btnWidth/2 * $PX );
30 | overflow: hidden;
31 | padding: 0 calc( 20 * $PX );
32 | }
33 |
34 | &__right {
35 | position: absolute;
36 | right: 0;
37 | }
38 |
39 | &__hide-button {
40 | position: absolute;
41 | right: calc( 6 * $PX );
42 | bottom: 100%;
43 | }
44 |
45 | &__mojs-logo {
46 | [data-component="icon"] {
47 | fill: $c-orange;
48 | }
49 | }
50 |
51 | &.is-hidden {
52 | transform: translateY(100%);
53 | }
54 | &.is-transition {
55 | transition: all .15s ease-out;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/css/blocks/mojs-player.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"mojs-player":"_mojs-player_12g93_4","mojs-player__left":"_mojs-player__left_12g93_1","mojs-player__mid":"_mojs-player__mid_12g93_1","mojs-player__right":"_mojs-player__right_12g93_1","mojs-player__hide-button":"_mojs-player__hide-button_12g93_1","mojs-player__mojs-logo":"_mojs-player__mojs-logo_12g93_1","is-hidden":"_is-hidden_12g93_51","is-transition":"_is-transition_12g93_54"}
--------------------------------------------------------------------------------
/css/blocks/opacity-switch.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .opacity-switch {
5 | opacity: .5;
6 | .icon {
7 | position: absolute;
8 | left: 50%;
9 | top: 50%;
10 | transform: translate(-50%, -50%);
11 | }
12 | &:hover {
13 | opacity: .4;
14 | }
15 | &.is-on {
16 | opacity: 1;
17 | &:hover {
18 | opacity: .85;
19 | }
20 | }
21 |
22 |
23 |
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/css/blocks/opacity-switch.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"opacity-switch":"_opacity-switch_17z5s_4","icon":"_icon_17z5s_6","is-on":"_is-on_17z5s_15"}
--------------------------------------------------------------------------------
/css/blocks/play-button.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .play-button {
5 | /* styles */
6 | }
7 |
--------------------------------------------------------------------------------
/css/blocks/play-button.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"play-button":"_play-button_16uj5_4"}
--------------------------------------------------------------------------------
/css/blocks/player-slider.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 | /*@import './handle.postcss.css';*/
4 |
5 | $height: 40;
6 | .player-slider {
7 | /*overflow: hidden;*/
8 | height: calc( $height * $PX );
9 | & > div {
10 | position: absolute;
11 | left: 0;
12 | top: 0;
13 | z-index: 2;
14 | }
15 | & .slider {
16 | z-index: 1;
17 | height: 100%;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/css/blocks/player-slider.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"player-slider":"_player-slider_1h9vh_6","slider":"_slider_1h9vh_15"}
--------------------------------------------------------------------------------
/css/blocks/player.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | .mojs-player {
3 | background-color: color(#3A0839 alpha(85%));
4 | height: calc( 40 * $PX );
5 | width: calc( 100 * $PX );
6 | display: inline-block;
7 |
8 | position: fixed;
9 | bottom: calc( 1.5 * $GS );
10 | left: 50%;
11 | transform: translateX( -50% );
12 | border-radius: $BRADIUS;
13 |
14 | box-shadow: calc($PX) calc($PX) calc( 1*$PX ) rgba(0,0,0,.25)
15 | }
16 |
--------------------------------------------------------------------------------
/css/blocks/repeat-button.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .repeat-button {
5 | /* styles */
6 | }
7 |
--------------------------------------------------------------------------------
/css/blocks/repeat-button.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"repeat-button":"_repeat-button_xhfpi_4"}
--------------------------------------------------------------------------------
/css/blocks/slider.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 | /*@import './handle.postcss.css';*/
4 |
5 | $height: 30;
6 | .slider {
7 | position: relative;
8 | width: 100%;
9 | height: calc( $height * $PX );
10 |
11 | &__inner {
12 | width: 100%;
13 | height: 100%;
14 | position: relative;
15 | }
16 |
17 | & .handle,
18 | & .progress-handle {
19 | z-index: 3;
20 | position: absolute;
21 | top: 50%;
22 | }
23 | $handleHeight: 13;
24 | & .progress-handle {
25 | left: 0;
26 | margin-left: calc( - $handleHeight/2 * $PX );
27 | margin-top: calc( - $handleHeight/2 * $PX );
28 | }
29 |
30 | & .track {
31 | z-index: 2;
32 | }
33 |
34 | &.is-y {
35 | width: calc( $height * $PX );
36 | height: 100%;
37 |
38 | .handle {
39 | left: 50%;
40 | top: auto;
41 | bottom: 0;
42 | margin-top: 0;
43 | margin-bottom: calc( -$handleHeight/2 * $PX );
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/css/blocks/slider.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"slider":"_slider_1e5my_6","slider__inner":"_slider__inner_1e5my_1","handle":"_handle_1e5my_17","progress-handle":"_progress-handle_1e5my_18","track":"_track_1e5my_30","is-y":"_is-y_1e5my_34"}
--------------------------------------------------------------------------------
/css/blocks/speed-control.postcss.css:
--------------------------------------------------------------------------------
1 | @import '../assets/globals.postcss.css';
2 |
3 | .speed-control {
4 | position: relative;
5 | display: inline-block;
6 | height: calc( 40 * $PX );
7 |
8 | $pad: 20;
9 | &__slider {
10 | position: absolute;
11 | bottom: 100%;
12 | left: calc( 3 * $PX );
13 | width: calc( 30 * $PX );
14 | height: calc( (80 + 2*$pad) * $PX );
15 | padding-top: calc( $pad * $PX );
16 | padding-bottom: calc( $pad * $PX );
17 |
18 | border-top-right-radius: $BRADIUS;
19 | border-top-left-radius: $BRADIUS;
20 |
21 | background: $c-purple;
22 |
23 | $translateSize: calc( -99999999 * $PX );
24 | transform: translate($translateSize, $translateSize);
25 | backface-visibility: hidden;
26 |
27 | &:before,
28 | &:after {
29 | content: '';
30 | position: absolute;
31 | top: 50%;
32 | width: calc( 3*$PX );
33 | height: calc( $PX );
34 | background: #FFF;
35 | }
36 | $shift: calc( 5*$PX );
37 | &:before {
38 | left: $shift;
39 | }
40 | &:after {
41 | right: $shift;
42 | }
43 | }
44 | &__button {
45 | border: 1px solid cyan;
46 | }
47 |
48 | &.is-on &__slider {
49 | transform: translate(0, 0);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/css/blocks/speed-control.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"speed-control":"_speed-control_1jd3z_3","speed-control__slider":"_speed-control__slider_1jd3z_1","speed-control__button":"_speed-control__button_1jd3z_1","is-on":"_is-on_1jd3z_48"}
--------------------------------------------------------------------------------
/css/blocks/stop-button.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | .stop-button {
5 | /* styles */
6 | }
7 |
--------------------------------------------------------------------------------
/css/blocks/stop-button.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"stop-button":"_stop-button_lpa7l_4"}
--------------------------------------------------------------------------------
/css/blocks/track.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import '../assets/globals.postcss.css';
3 |
4 | $height: 40;
5 | .track {
6 | position: relative;
7 | height: 100%;
8 |
9 | &__track {
10 | position: absolute;
11 | top: 50%;
12 | left: 0;
13 |
14 | width: 100%;
15 | height: calc( $PX );
16 |
17 | background: #FFF;
18 | box-shadow: calc( $PX ) calc( $PX ) calc( $PX ) rgba(0,0,0,.5);
19 |
20 | &:after {
21 | content: '';
22 | position: absolute;
23 | left: 0;
24 | top: calc( - $height/2 * $PX );
25 | width: 100%;
26 | height: calc( $height * $PX );
27 | cursor: pointer;
28 | /*background-color: yellow;*/
29 | }
30 | }
31 |
32 | &__track-progress {
33 | position: absolute;
34 | left: 0;
35 | top: 50%;
36 | margin-top: calc( -1 * $PX );
37 | height: calc( 3*$PX );
38 | width: 0.0625em;
39 | /*background: $c-orange;*/
40 | background: $c-white;
41 | z-index: 1;
42 | transform-origin: left center;
43 | &:after {
44 | /*content: '';*/
45 | position: absolute;
46 | left: 0;
47 | top: calc( - $height/2 * $PX );
48 | width: 100%;
49 | height: calc( $height * $PX );
50 | cursor: pointer;
51 | backface-visibility: hidden;
52 | }
53 | }
54 |
55 | &__ripple {
56 | position: absolute;
57 | left: 0;
58 | top: 0;
59 | right: 0;
60 | bottom: 0;
61 | overflow: hidden;
62 | /*background: black;*/
63 | /*z-index: 1;*/
64 | }
65 |
66 | &.is-inversed {
67 | left: auto;
68 | right: 0;
69 | }
70 |
71 | &.is-inversed &__track-progress {
72 | transform-origin: right center;
73 | }
74 |
75 | &.is-bound &__track-progress {
76 | background: $c-orange;
77 | }
78 |
79 | &.is-y &__track {
80 | top: 0;
81 | left: 50%;
82 |
83 | height: 100%;
84 | width: calc( $PX );
85 |
86 | /*box-shadow: calc( $PX ) calc( $PX ) calc( $PX ) rgba(0,0,0,.5); */
87 | }
88 |
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/css/blocks/track.postcss.css.json:
--------------------------------------------------------------------------------
1 | {"track":"_track_1dpwb_5","track__track":"_track__track_1dpwb_1","track__track-progress":"_track__track-progress_1dpwb_1","track__ripple":"_track__ripple_1dpwb_1","is-inversed":"_is-inversed_1dpwb_66","is-bound":"_is-bound_1dpwb_75","is-y":"_is-y_1dpwb_79"}
--------------------------------------------------------------------------------
/css/main.postcss.css:
--------------------------------------------------------------------------------
1 |
2 | @import 'assets/globals.postcss.css';
3 |
4 |
5 |
--------------------------------------------------------------------------------
/css/main.postcss.css.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var fs = require('fs');
3 | var livereload = require('gulp-livereload');
4 | var changed = require('gulp-changed');
5 |
6 | var plumber = require('gulp-plumber');
7 | var concat = require('gulp-concat');
8 | var rename = require('gulp-rename');
9 | var uglify = require('gulp-uglify');
10 | var sequence = require('run-sequence');
11 |
12 | var insert = require('gulp-insert');
13 | var jeditor = require("gulp-json-editor");
14 | var shell = require("gulp-shell");
15 | var babel = require("gulp-babel");
16 |
17 | var devFolder = '', distFolder = '', currentVersion = 0;
18 | var distMoFile = devFolder + 'build/mojs-player.js';
19 | var libMainFile = devFolder + 'lib/mojs-player.js';
20 |
21 | var paths = {
22 | src: {
23 | babel: devFolder + 'js/**/*.babel.js',
24 | index: devFolder + 'index.jade',
25 | css: devFolder + 'css/**/*.styl',
26 | tests: distFolder + 'spec/**/*.coffee'
27 | },
28 | dist:{
29 | js: distFolder + 'js/',
30 | index: distFolder,
31 | css: distFolder + 'css/',
32 | tests: distFolder + 'spec/'
33 | }
34 | }
35 |
36 | var credits = ''
37 |
38 | gulp.task('babel-lib', function(e){
39 | return gulp.src(paths.src.babel)
40 | .pipe(plumber())
41 | .pipe(babel({ presets: ['es2015-loose'], plugins: [ 'transform-runtime' ] }))
42 | .pipe(rename(function (path) {
43 | return path.basename = path.basename.replace('.babel', '');
44 | })
45 | ).pipe(gulp.dest('lib/'))
46 | });
47 |
48 | gulp.task('minify', function() {
49 | return gulp.src(distMoFile)
50 | .pipe(plumber())
51 | .pipe(livereload())
52 | .pipe(insert.transform(function(contents) {
53 | return credits + contents;
54 | }))
55 | .pipe(gulp.dest('./build'))
56 | .pipe(uglify())
57 | .pipe(insert.transform(function(contents) {
58 | return credits + contents;
59 | }))
60 | .pipe(rename('mojs-player.min.js'))
61 | .pipe(gulp.dest('./build'))
62 | });
63 |
64 | gulp.task('attribute-lib', function() {
65 | return gulp.src(libMainFile)
66 | .pipe(plumber())
67 | .pipe(insert.transform(function(contents) {
68 | return credits + contents;
69 | }))
70 | .pipe(gulp.dest('./lib'))
71 | });
72 |
73 | gulp.task('update-version', function() {
74 | sequence('get-current-version', 'update-bower-version', 'update-main-file-version');
75 | });
76 |
77 | gulp.task('get-current-version', function(e){
78 | return gulp.src('package.json')
79 | .pipe(plumber())
80 | .pipe(jeditor(function (json) {
81 | currentVersion = json.version;
82 | credits = '/*! \n\t:: MojsPlayer :: Player controls for [mojs](mojs.github.io). Intended to help you to craft `mojs` animation sequences.\n\tOleg Solomka @LegoMushroom 2021 MIT\n\t' + currentVersion + ' \n*/\n\n'
83 | return json;
84 | }))
85 | });
86 |
87 | gulp.task('update-bower-version', function(e){
88 | return gulp.src('bower.json')
89 | .pipe(plumber())
90 | .pipe(jeditor(function (json) {
91 | json.version = currentVersion;
92 | return json;
93 | }))
94 | .pipe(gulp.dest(''))
95 | });
96 |
97 | gulp.task('update-main-file-version', function(e){
98 | return gulp.src('js/mojs-player.babel.js')
99 | .pipe(plumber())
100 | .pipe(insert.transform(function(contents) {
101 | var newString = 'revision = \''+currentVersion+'\'';
102 | return contents
103 | .replace(/revision\s+?\=\s+?(\'|\")\d+\.\d+\.+\d+(\'|\")/i, newString);
104 | }))
105 | .pipe(gulp.dest('js/'))
106 | });
107 |
108 | gulp.task('default', function(){
109 | livereload.listen();
110 | gulp.run('get-current-version');
111 | gulp.watch(paths.src.babel, [ 'babel-lib' ]);
112 | gulp.watch(distMoFile, [ 'minify' ]);
113 | gulp.watch(libMainFile, [ 'attribute-lib' ]);
114 | gulp.watch('package.json', ['update-version']);
115 | });
116 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | mo · js player
6 |
7 |
8 |
9 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/js/components/bounds-button.babel.js:
--------------------------------------------------------------------------------
1 | import RepeatButton from './repeat-button';
2 |
3 | // require('css/blocks/repeat-button.postcss.css');
4 | // let CLASSES = require('css/blocks/repeat-button.postcss.css.json');
5 |
6 | class BoundsButton extends RepeatButton {
7 | /*
8 | Method to declare defaults.
9 | @private
10 | @overrides @ RepeatButton
11 | */
12 | _declareDefaults () {
13 | super._declareDefaults();
14 | this._defaults.icon = 'bounds';
15 | this._defaults.title = 'progress bounds (alt + b)';
16 | }
17 | }
18 |
19 | export default BoundsButton;
20 |
--------------------------------------------------------------------------------
/js/components/button-switch.babel.js:
--------------------------------------------------------------------------------
1 | import Button from './button';
2 |
3 | require('../../css/blocks/button-switch.postcss.css');
4 | let CLASSES = require('../../css/blocks/button-switch.postcss.css.json');
5 |
6 | class ButtonSwitch extends Button {
7 | /*
8 | Method to declare _defaults.
9 | @private
10 | @overrides @ Button
11 | */
12 | _declareDefaults () {
13 | super._declareDefaults();
14 | this._defaults.isOn = false;
15 | this._defaults.onStateChange = null;
16 | }
17 | /*
18 | Method to set the state to `true`.
19 | @public
20 | @param {Boolean} If should invoke callback.
21 | */
22 | on ( isCallback = true ) {
23 | // set to true because the next step is toggle
24 | this._props.isOn = true;
25 | this._reactOnStateChange( isCallback );
26 | }
27 | /*
28 | Method to set the state to `false`.
29 | @public
30 | @param {Boolean} If should invoke callback.
31 | */
32 | off ( isCallback = true ) {
33 | // set to true because the next step is toggle
34 | this._props.isOn = false;
35 | this._reactOnStateChange( isCallback );
36 | }
37 |
38 | // ---
39 |
40 | /*
41 | Initial render method.
42 | @private
43 | @overrides @ Button
44 | @returns this
45 | */
46 | _render () {
47 | super._render();
48 | this.el.classList.add( CLASSES[ 'button-switch' ] );
49 | this._setState();
50 | this._reactOnStateChange();
51 | }
52 | /*
53 | Method to invoke onPointerUp callback if excist.
54 | @private
55 | @overrides @ Button
56 | @param {Object} Original event object.
57 | */
58 | _pointerUp ( e ) {
59 | if ( !this.wasTouched ) {
60 | this.wasTouched = false;
61 | e.stopPropagation();
62 | return;
63 | }
64 | this._changeState();
65 | super._pointerUp( e );
66 | }
67 | /*
68 | Method to switch icons.
69 | @private
70 | */
71 | _changeState () {
72 | this._props.isOn = !this._props.isOn;
73 | this._reactOnStateChange();
74 | }
75 | /*
76 | Method to react on state change.
77 | @private
78 | @param {Boolean} If should invoke callback.
79 | */
80 | _reactOnStateChange ( isCallback = true ) {
81 | if ( isCallback ) {
82 | this._callIfFunction( this._props.onStateChange, this._props.isOn );
83 | }
84 | this._setState();
85 | }
86 | /*
87 | Method that have been called on switch state change.
88 | @private
89 | */
90 | _setState () {
91 | // console.log('change');
92 | }
93 |
94 | }
95 |
96 | export default ButtonSwitch;
97 |
--------------------------------------------------------------------------------
/js/components/button.babel.js:
--------------------------------------------------------------------------------
1 | import Module from './module';
2 | import HammerJS from 'hammerjs';
3 | import Ripple from './ripple';
4 |
5 | require('../../css/blocks/button.postcss.css');
6 | let CLASSES = require('../../css/blocks/button.postcss.css.json');
7 |
8 | class Button extends Module {
9 | /*
10 | Method to declare defaults for the module.
11 | @private
12 | @overrides @ Module
13 | */
14 | _declareDefaults () {
15 | super._declareDefaults()
16 | this._defaults.link = null;
17 | this._defaults.title = '';
18 | this._defaults.target = null;
19 | this._defaults.onPointerDown = null;
20 | this._defaults.onPointerUp = null;
21 | this._defaults.onDoubleTap = null;
22 | }
23 | /*
24 | Initial render method.
25 | @private
26 | @overrides @ Module
27 | */
28 | _render () {
29 | let p = this._props,
30 | className = 'button',
31 | tagName = ( p.link != null ) ? 'a' : 'div';
32 |
33 | this._addMainElement( tagName );
34 | this.el.classList.add( CLASSES[ className ] );
35 | this.el.setAttribute( 'title', p.title );
36 | p.link && this.el.setAttribute( 'href', p.link );
37 | p.link && p.target && this.el.setAttribute( 'target', p.target );
38 | this._addListeners();
39 |
40 | this._createRipple();
41 | }
42 | /*
43 | Method to create ripple.
44 | @private
45 | */
46 | _createRipple () {
47 | this.ripple = new Ripple({
48 | className: CLASSES[ `button__ripple` ],
49 | parent: this.el
50 | });
51 | }
52 | /*
53 | Method to add event listeners to the icon.
54 | @private
55 | */
56 | _addListeners () {
57 | this._addPointerDownEvent( this.el, this._pointerDown.bind( this ) );
58 | this._addPointerUpEvent( this.el, this._pointerUp.bind( this ) );
59 | this._addPointerUpEvent( document, this._pointerCancel.bind( this ) );
60 | HammerJS(this.el).on('doubletap', this._doubleTap.bind( this ) );
61 | }
62 | /*
63 | Method to invoke onPointerDown callback if exist.
64 | @private
65 | @param {Object} Original event object.
66 | */
67 | _pointerDown ( e ) {
68 | this.wasTouched = true;
69 | this._callIfFunction( this._props.onPointerDown );
70 | this.ripple._hold( e );
71 | }
72 | /*
73 | Method to invoke onPointerUp callback if exist.
74 | @private
75 | @param {Object} Original event object.
76 | */
77 | _pointerUp ( e ) {
78 | if ( !this.wasTouched ) { e.stopPropagation(); return; }
79 |
80 | this.wasTouched = false;
81 | this._callIfFunction( this._props.onPointerUp );
82 | this.ripple._release();
83 | e.preventDefault();
84 | return false;
85 | }
86 | /*
87 | Method to invoke onPointerCancel callback if exist.
88 | @private
89 | @param {Object} Original event object.
90 | */
91 | _pointerCancel ( e ) {
92 | if ( !this.wasTouched ) { return; };
93 | this.wasTouched = false;
94 | this.ripple._cancel();
95 | }
96 | /*
97 | Method to invoke onDoubleTap callback if exist.
98 | @private
99 | @param {Object} Original event object.
100 | */
101 | _doubleTap ( e ) {
102 | this._callIfFunction( this._props.onDoubleTap );
103 | }
104 | }
105 |
106 | export default Button;
107 |
--------------------------------------------------------------------------------
/js/components/handle.babel.js:
--------------------------------------------------------------------------------
1 | import Module from './module';
2 | import HammerJS from 'hammerjs';
3 |
4 | require('../../css/blocks/handle.postcss.css');
5 | let CLASSES = require('../../css/blocks/handle.postcss.css.json');
6 |
7 | class Handle extends Module {
8 | /*
9 | Method to declare _defaults.
10 | @private
11 | @overrides @ Module
12 | */
13 | _declareDefaults () {
14 | super._declareDefaults();
15 | this._defaults.minBound = 0;
16 | this._defaults.maxBound = 1;
17 | this._defaults.isBound = false;
18 | this._defaults.isInversed = false;
19 | this._defaults.direction = 'x';
20 | this._defaults.onSeekStart = null;
21 | this._defaults.onSeekEnd = null;
22 | this._defaults.onProgress = null;
23 | this._defaults.snapPoint = 0;
24 | this._defaults.snapStrength = 0;
25 | }
26 | /*
27 | Method to set handle progress.
28 | @public
29 | @param {Number} Progress [0...1].
30 | @param {Boolean} If should invoke onProgress callback.
31 | @returns this.
32 | */
33 | setProgress ( progress, isCallback = true ) {
34 | let shift = this._progressToShift( progress );
35 | this._setShift( shift, isCallback );
36 | // calc delta and save it
37 | this._delta = shift - this._shift;
38 | this._saveDelta();
39 | return this;
40 | }
41 | /*
42 | Method to set bounds of progress.
43 | @public
44 | @param {Number} Min bound to set [0...1].
45 | @param {Number} Max bound to set [0...1].
46 | @returns this.
47 | */
48 | setBounds ( min, max ) {
49 | this.setMinBound( min );
50 | this.setMaxBound( max );
51 | return this;
52 | }
53 | /*
54 | Method to set min bound of progress.
55 | @public
56 | @param {Number} Min bound to set [0...1].
57 | @returns this.
58 | */
59 | setMinBound ( min ) {
60 | this._props.minBound = Math.max( min, 0 );
61 | if ( this._progress < min ) { this.setProgress( min ); }
62 | return this;
63 | }
64 | /*
65 | Method to set max bound of progress.
66 | @public
67 | @param {Number} Max bound to set [0...1].
68 | @returns this.
69 | */
70 | setMaxBound ( max ) {
71 | this._props.maxBound = Math.min( max, 1 );
72 | if ( this._progress > max ) { this.setProgress( max ); }
73 | return this;
74 | }
75 | /*
76 | Method to declare properties.
77 | @private
78 | @overrides @ Module.
79 | */
80 | _vars () {
81 | // `progress` of the handle [0..1]
82 | this._progress = 0;
83 | // `shift` of the handle ( position in `px` )
84 | this._shift = 0;
85 | // `delta` deviation from the current `shift`
86 | this._delta = 0;
87 | }
88 | /*
89 | Method to set handle shift.
90 | @private
91 | @param {Number} Shift in `px`.
92 | @param {Boolean} If should invoke onProgress callback.
93 | @returns {Number}.
94 | */
95 | _setShift(shift, isCallback = true) {
96 | let p = this._props,
97 | minBound = p.minBound*this._maxWidth,
98 | maxBound = p.maxBound*this._maxWidth;
99 |
100 | shift = this.clamp(shift, minBound, maxBound );
101 | this._applyShift( shift );
102 | if (isCallback) { this._onProgress( shift ); }
103 | else { this._progress = this._shiftToProgress( shift ); }
104 | return shift;
105 | }
106 |
107 | /**
108 | * clamp - functiboundson to clamp a `value` between `min` and `max`
109 | *
110 | * @param {Number} value Value to clamp.
111 | * @param {Number} min Min bound
112 | * @param {Number} max Max bound
113 | * @return {Number} Clamped value.
114 | */
115 | clamp(value, min, max) {
116 | return Math.min(Math.max(value, min), max);
117 | }
118 |
119 | /*
120 | Method to apply shift to the DOMElement.
121 | @private
122 | @param {Number} Shift in pixels.
123 | */
124 | _applyShift ( shift ) {
125 | let p = this._props;
126 | // translateZ(0)
127 | this.el.style.transform = ( p.direction === 'x' )
128 | ? `translateX( ${ shift }px )`
129 | : `translateY( ${ -shift }px )`;
130 | }
131 | /*
132 | Method to get max width of the parent.
133 | @private
134 | */
135 | _getMaxWidth () {
136 | let p = this._props,
137 | parent = p.parent;
138 |
139 | this._maxWidth = ( p.direction === 'x' )
140 | ? parent.clientWidth : parent.clientHeight;
141 | }
142 | /*
143 | Method to render the component.
144 | @private
145 | @overrides @ Module
146 | */
147 | _render () {
148 | super._render();
149 | this._addElements();
150 | this._getMaxWidth();
151 | this._hammerTime();
152 | }
153 | /*
154 | Method to classes on `this.el`.
155 | @private
156 | @overrides @ Module
157 | */
158 | _addMainClasses () {
159 | super._addMainClasses();
160 |
161 | let p = this._props,
162 | classList = this.el.classList;
163 |
164 | classList.add( CLASSES.handle );
165 | if ( p.isBound ) { classList.add( CLASSES['is-bound'] ); }
166 | if ( p.isInversed ) { classList.add( CLASSES['is-inversed'] ); }
167 | }
168 | /*
169 | Method to add DOM elements on render.
170 | @private
171 | */
172 | _addElements () {
173 | var inner = this._createElement('div'),
174 | shadow = this._createElement('div');
175 |
176 | inner.classList.add( `${ CLASSES.handle__inner }` );
177 | shadow.classList.add( `${ CLASSES.handle__shadow }` );
178 | this.el.appendChild( shadow );
179 | this.el.appendChild( inner );
180 | }
181 | /*
182 | Method to initialize HammerJS an set up all even listeners.
183 | @private
184 | */
185 | _hammerTime () {
186 | let p = this._props,
187 | direction = ( p.direction === 'x' ) ? 'HORIZONTAL' : 'VERTICAL',
188 | hm = new HammerJS.Manager(this.el, {
189 | recognizers: [
190 | [HammerJS.Pan, { direction: HammerJS[ `DIRECTION_${direction}` ] }]
191 | ]
192 | });
193 |
194 | hm.on( 'pan', this._pan.bind( this ) );
195 | hm.on( 'panend', this._panEnd.bind( this ) );
196 | this._addPointerDownEvent( this.el, this._pointerDown.bind(this) );
197 | this._addPointerUpEvent( this.el, this._pointerUp.bind( this ) );
198 | // add listener on document to cover edge cases
199 | // like when you press -> leave the element -> release
200 | this._addPointerUpEvent( document, this._pointerUpDoc.bind( this ) );
201 |
202 | window.addEventListener( 'resize', this._onWindowResize.bind( this ) );
203 | }
204 | /*
205 | Callback for pan end on main el.
206 | @private
207 | @param {Object} Original event object.
208 | */
209 | _pan ( e ) {
210 | let p = this._props;
211 | this._delta = ( p.direction === 'x' ) ? e.deltaX : -e.deltaY;
212 | // get progress from the shift to undestand how far is the snapPoint
213 | let shift = this._shift + this._delta,
214 | proc = this._shiftToProgress( shift );
215 | // if progress is around snapPoint set it to the snap point
216 | proc = ( Math.abs( proc - p.snapPoint ) < p.snapStrength )
217 | ? p.snapPoint : proc;
218 | // recalculate the progress to shift and set it
219 | this._setShift( this._progressToShift( proc ) );
220 | }
221 | /*
222 | Callback for pan end on main el.
223 | @private
224 | @param {Object} Original event object.
225 | */
226 | _panEnd ( e ) {
227 | this._saveDelta();
228 | this._callIfFunction( this._props.onSeekEnd, e );
229 | }
230 | /*
231 | Callback for pointer down on main el.
232 | @private
233 | @param {Object} Original event object.
234 | */
235 | _pointerDown ( e ) {
236 | let p = this._props;
237 | this._isPointerDown = true;
238 | this._callIfFunction( p.onSeekStart, e );
239 | }
240 | /*
241 | Callback for pointer up on main el.
242 | @private
243 | @param {Object} Original event object.
244 | */
245 | _pointerUp ( e ) {
246 | this._callIfFunction( this._props.onSeekEnd, e );
247 | e.preventDefault();
248 | return false;
249 | }
250 | /*
251 | Callback for pointer up on document.
252 | @private
253 | @param {Object} Original event object.
254 | */
255 | _pointerUpDoc ( e ) {
256 | if ( !this._isPointerDown ) { return }
257 | this._callIfFunction( this._props.onSeekEnd, e );
258 | this._isPointerDown = false;
259 | }
260 | /*
261 | Method to add _delta to _shift.
262 | @private
263 | */
264 | _saveDelta () { this._shift += this._delta; }
265 | /*
266 | Method to call onProgress callback.
267 | @private
268 | @param {Number} Shift in `px`.
269 | */
270 | _onProgress ( shift ) {
271 | let p = this._props,
272 | progress = this._shiftToProgress( shift );
273 |
274 | if ( this._progress !== progress ) {
275 | this._progress = progress;
276 | if ( this._isFunction( p.onProgress ) ) {
277 | p.onProgress.call( this, progress );
278 | }
279 | }
280 | }
281 | /*
282 | Method to recalc shift to progress.
283 | @private
284 | @param {Number} Shift in `px`.
285 | @returns {Number} Progress [0...1].
286 | */
287 | _shiftToProgress ( shift ) {
288 | return shift / this._maxWidth;
289 | }
290 | /*
291 | Method to progress shift to shift.
292 | @private
293 | @param {Number} Progress [0...1].
294 | @returns {Number} Shift in `px`.
295 |
296 | */
297 | _progressToShift ( progress ) {
298 | return progress*this._maxWidth;
299 | }
300 | /*
301 | Callback for window resize event.
302 | @private
303 | @param {Object} Original event object.
304 | */
305 | _onWindowResize ( e ) {
306 | this._getMaxWidth();
307 | this.setProgress( this._progress );
308 | }
309 | }
310 |
311 | export default Handle;
312 |
--------------------------------------------------------------------------------
/js/components/hide-button.babel.js:
--------------------------------------------------------------------------------
1 |
2 | import ButtonSwitch from './button-switch';
3 | import Icon from './icon';
4 |
5 | require('../../css/blocks/hide-button.postcss.css');
6 | let CLASSES = require('../../css/blocks/hide-button.postcss.css.json'),
7 | className = 'hide-button';
8 |
9 | class HideButton extends ButtonSwitch {
10 | _declareDefaults () {
11 | super._declareDefaults();
12 | this._defaults.title = 'hide (alt + h)'
13 | }
14 | /*
15 | Initial render method.
16 | @private
17 | @overrides @ Button
18 | @returns this
19 | */
20 | _render () {
21 | super._render();
22 | this.el.classList.add( CLASSES[ className ] );
23 | this._addIcon();
24 | }
25 | /*
26 | Method to add icon.
27 | @private
28 | */
29 | _addIcon () {
30 | this.icon = new Icon({
31 | parent: this.el,
32 | className: CLASSES[ `${ className }__icon` ],
33 | shape: 'hide',
34 | prefix: this._props.prefix
35 | });
36 | }
37 | /*
38 | Method that have been called on switch state change.
39 | @private
40 | @override @ ButtonSwitch
41 | */
42 | _setState () {
43 | let method = ( this._props.isOn ) ? 'add' : 'remove' ;
44 | this.el.classList[ method ]( CLASSES[ `is-hidden` ] );
45 | }
46 | }
47 |
48 | export default HideButton;
49 |
--------------------------------------------------------------------------------
/js/components/icon-button.babel.js:
--------------------------------------------------------------------------------
1 | import Icon from './icon';
2 | import Button from './button';
3 |
4 | require('../../css/blocks/icon-button.postcss.css');
5 | let CLASSES = require('../../css/blocks/icon-button.postcss.css.json');
6 |
7 | class IconButton extends Button {
8 | /*
9 | Method to declare _defaults.
10 | @private
11 | @overrides @ Button
12 | */
13 | _declareDefaults () {
14 | super._declareDefaults();
15 | this._defaults.icon = '';
16 | this._defaults.iconClass = '';
17 | }
18 | /*
19 | Initial render method.
20 | @private
21 | @overrides @ Button
22 | @returns this
23 | */
24 | _render () {
25 | super._render();
26 | let p = this._props,
27 | className = 'icon-button';
28 | this.el.classList.add( CLASSES[ className ] );
29 |
30 | let icon = new Icon({
31 | shape: p.icon,
32 | parent: this.el,
33 | className: [ CLASSES[ `icon` ], p.iconClass ],
34 | prefix: p.prefix
35 | });
36 | }
37 | }
38 |
39 | export default IconButton;
40 |
--------------------------------------------------------------------------------
/js/components/icon-fork.babel.js:
--------------------------------------------------------------------------------
1 | import ButtonSwitch from './button-switch';
2 | import Icon from './icon';
3 | // import HammerJS from 'hammerjs'
4 |
5 | require('../../css/blocks/icon-fork.postcss.css');
6 | let CLASSES = require('../../css/blocks/icon-fork.postcss.css.json');
7 |
8 | class IconFork extends ButtonSwitch {
9 | /*
10 | Initial render method.
11 | @private
12 | @overrides @ Icon
13 | @returns this
14 | */
15 | _render () {
16 | super._render();
17 | this.el.classList.add( CLASSES[ 'icon-fork' ] );
18 | let p = this._props,
19 | prefix = p.prefix,
20 | parent = this.el,
21 | className = CLASSES.icon;
22 |
23 | this.icon1 = new Icon({ shape: p.icon1, prefix, parent, className });
24 | this.icon2 = new Icon({ shape: p.icon2, prefix, parent, className });
25 | }
26 | /*
27 | Method that should be called on state change.
28 | @private
29 | @override @ IconSwitch
30 | */
31 | _setState () {
32 | let p = this._props,
33 | classList = this.el.classList,
34 | method = ( p.isOn ) ? 'add' : 'remove';
35 |
36 | classList[ method ]( CLASSES[ 'is-on' ] )
37 | }
38 | }
39 |
40 | export default IconFork;
41 |
--------------------------------------------------------------------------------
/js/components/icon.babel.js:
--------------------------------------------------------------------------------
1 | import Module from './module';
2 | import HammerJS from 'hammerjs'
3 |
4 | require('../../css/blocks/icon.postcss.css');
5 | let CLASSES = require('../../css/blocks/icon.postcss.css.json');
6 |
7 | class Icon extends Module {
8 | /*
9 | Method to declare _defaults.
10 | @private
11 | @overrides @ Module
12 | */
13 | _declareDefaults () {
14 | super._declareDefaults();
15 | this._defaults.shape = '';
16 | this._defaults.size = 'x1';
17 | this.NS = 'http://www.w3.org/2000/svg';
18 | }
19 | /*
20 | Initial render method.
21 | @private
22 | @overrides @ Module
23 | @returns this
24 | */
25 | _render () {
26 | this._addMainElement();
27 | this.el.classList.add( CLASSES.icon );
28 | this.el.classList.add( CLASSES[ `is-${ this._props.size }` ] );
29 | this.el.setAttribute('data-component', 'icon');
30 | this._renderIcon();
31 | }
32 | /*
33 | Method to render svg icon into the el.
34 | @private
35 | */
36 | _renderIcon () {
37 | let p = this._props,
38 | svg = document.createElementNS( this.NS, 'svg' ),
39 | content = ``;
40 | svg.setAttribute( 'viewBox', '0 0 32 32' );
41 | this._addSVGHtml( svg, content );
42 | this.el.appendChild( svg );
43 | }
44 | /*
45 | Add HTML to SVG element.
46 | @private
47 | @param {Object} SVG node.
48 | @param {String} SVG content to add.
49 | */
50 | _addSVGHtml ( svg, content ) {
51 | let receptacle = this._createElement( 'div' ),
52 | svgfragment = ``;
53 | receptacle.innerHTML = svgfragment;
54 | let nodes = Array.prototype.slice.call(receptacle.childNodes[0].childNodes);
55 | for (let i = 0; i < nodes.length; i++) {
56 | svg.appendChild( nodes[i] );
57 | }
58 | }
59 | }
60 |
61 | export default Icon;
62 |
--------------------------------------------------------------------------------
/js/components/icons.babel.js:
--------------------------------------------------------------------------------
1 | import Module from './module';
2 |
3 | class Icons extends Module {
4 | /*
5 | Initial render method.
6 | @private
7 | @overrides @ Module
8 | */
9 | _render () {
10 | this.el = this._createElement( 'div' );
11 | this.el.innerHTML = this.getIcons();
12 | this.el.setAttribute( 'id', `${ this._props.prefix }icons` );
13 | this._prependChild( document.body, this.el );
14 | }
15 | /*
16 | Method to get icons shapes.
17 | @private
18 | */
19 | getIcons () {
20 | let prefix = this._props.prefix;
21 | return ``;
33 | }
34 |
35 | }
36 |
37 | export default Icons;
38 |
--------------------------------------------------------------------------------
/js/components/label-button.babel.js:
--------------------------------------------------------------------------------
1 | import ButtonSwitch from './button-switch';
2 |
3 | require('../../css/blocks/label-button.postcss.css');
4 | let CLASSES = require('../../css/blocks/label-button.postcss.css.json');
5 |
6 | class LabelButton extends ButtonSwitch {
7 | /*
8 | Method to declare defaults.
9 | @private
10 | @overrides @ OpacitySwitch
11 | */
12 | _declareDefaults () {
13 | super._declareDefaults();
14 | this._defaults.title = 'speed (reset: alt + 1)';
15 | }
16 | /*
17 | Method to populate the label with progress text.
18 | @public
19 | @param {String} Text to set.
20 | */
21 | setLabelText ( text ) {
22 | this.label.innerHTML = text;
23 | }
24 |
25 | /*
26 | ^ PUBLIC ^
27 | v PPRIVATE v
28 | */
29 |
30 | /*
31 | Initial render method.
32 | @private
33 | @overrides @ Button
34 | @returns this
35 | */
36 | _render () {
37 | super._render();
38 | this._addClass( this.el, CLASSES[ 'label-button' ] );
39 | this._addLabel();
40 | // this.setLabelText( this._props.progress );
41 | }
42 | /*
43 | Method to add label to the `el`.
44 | @private
45 | */
46 | _addLabel () {
47 | this.label = this._createElement('div');
48 | this.label.classList.add( CLASSES[ `label-button__label` ] );
49 | this.el.appendChild( this.label );
50 | }
51 | }
52 |
53 | export default LabelButton;
54 |
--------------------------------------------------------------------------------
/js/components/module.babel.js:
--------------------------------------------------------------------------------
1 | /*
2 | Base class for all modules.
3 | Extends _defaults to _props
4 | */
5 | class Module {
6 | /*
7 | constructor method calls scaffolding methods.
8 | */
9 | constructor ( o = {} ) {
10 | this._o = o;
11 | this._index = this._o.index || 0;
12 | this._declareDefaults();
13 | this._extendDefaults();
14 | this._vars()
15 | this._render();
16 | }
17 | /*
18 | Method to declare defaults.
19 | @private
20 | */
21 | _declareDefaults () {
22 | this._defaults = {
23 | className: '',
24 | parent: document.body,
25 | isPrepend: false,
26 | isRipple: false,
27 | prefix: ''
28 | };
29 | }
30 | /*
31 | Method to add pointer down even listener to el.
32 | @param {Object} HTMLElement to add event listener on.
33 | @param {Function} Event listener callback.
34 | */
35 | _addPointerDownEvent (el, fn) {
36 | if (window.navigator.msPointerEnabled) {
37 | el.addEventListener('MSPointerDown', fn);
38 | } else if ( window.ontouchstart !== undefined ) {
39 | el.addEventListener('touchstart', fn);
40 | el.addEventListener('mousedown', fn);
41 | } else {
42 | el.addEventListener('mousedown', fn);
43 | }
44 | }
45 | /*
46 | Method to add pointer up even listener to el.
47 | @param {Object} HTMLElement to add event listener on.
48 | @param {Function} Event listener callback.
49 | */
50 | _addPointerUpEvent (el, fn) {
51 | if (window.navigator.msPointerEnabled) {
52 | el.addEventListener('MSPointerUp', fn);
53 | } else if ( window.ontouchstart !== undefined ) {
54 | el.addEventListener('touchend', fn);
55 | el.addEventListener('mouseup', fn);
56 | } else {
57 | el.addEventListener('mouseup', fn);
58 | }
59 | }
60 | /*
61 | Method to check if variable holds link to a function.
62 | @param {Function?} A variable to check.
63 | @returns {Boolean} If passed variable is a function.
64 | */
65 | _isFunction ( fn ) { return ( typeof fn === 'function' ); }
66 | /*
67 | Method to a function or silently fail.
68 | @param {Function?} A variable to check.
69 | @param {Array like} Arguments.
70 | */
71 | _callIfFunction ( fn ) {
72 | Array.prototype.shift.call( arguments );
73 | this._isFunction( fn ) && fn.apply( this, arguments );
74 | }
75 | /*
76 | Method to declare module's variables.
77 | @private
78 | */
79 | _vars () { }
80 | /*
81 | Method to render on initialization.
82 | @private
83 | */
84 | _render () { this._addMainElement(); }
85 | /*
86 | Method to add `this.el` on the module.
87 | @private
88 | @param {String} Tag name of the element.
89 | */
90 | _addMainElement ( tagName = 'div' ) {
91 | let p = this._props;
92 |
93 | this.el = this._createElement( tagName );
94 | this._addMainClasses();
95 |
96 | let method = ( p.isPrepend ) ? 'prepend' : 'append' ;
97 | this[ `_${ method }Child` ]( p.parent, this.el );
98 | }
99 | /*
100 | Method to classes on `this.el`.
101 | @private
102 | */
103 | _addMainClasses () {
104 | let p = this._props;
105 | if ( p.className instanceof Array ) {
106 | for (var i = 0; i < p.className.length; i++) {
107 | this._addClass( this.el, p.className[i] );
108 | }
109 | } else { this._addClass( this.el, p.className ); }
110 | }
111 | /*
112 | Method to add a class on el.
113 | @private
114 | @param {Object} HTML element to add the class on.
115 | @param {String} Class name to add.
116 | */
117 | _addClass ( el, className ) { className && el.classList.add( className ); }
118 | /*
119 | Method to set property on the module.
120 | @private
121 | @param {String, Object} Name of the property to set
122 | or object with properties to set.
123 | @param {Any} Value for the property to set. Could be
124 | undefined if the first param is object.
125 | */
126 | _setProp ( attr, value ) {
127 | if ( typeof attr === 'object' ) {
128 | for ( var key in attr ) { this._assignProp( key, attr[key] ); }
129 | } else { this._assignProp( attr, value ); }
130 | }
131 | /*
132 | Method to assign single property's value.
133 | @private
134 | @param {String} Property name.
135 | @param {Any} Property value.
136 | */
137 | _assignProp ( key, value ) {
138 | this._props[key] = value;
139 | }
140 | /*
141 | Method to copy `_o` options to `_props` object
142 | with fallback to `_defaults`.
143 | @private
144 | */
145 | _extendDefaults ( ) {
146 | this._props = {};
147 | // this._deltas = {};
148 | for (var key in this._defaults) {
149 | let value = this._o[key];
150 | this.isIt && console.log(key)
151 | // copy the properties to the _o object
152 | this._assignProp( key, ( value != null ) ? value : this._defaults[key] );
153 | }
154 | }
155 | /*
156 | Method to create HTMLElement from tag name.
157 | @private
158 | @param {String} Name of the tag to create `HTML` element.
159 | @returns {Object} HtmlElement.
160 | */
161 | _createElement ( tagName ) { return document.createElement( tagName ); }
162 | /*
163 | Method to create HTMLElement and append it to the `el` with a className.
164 | @private
165 | @param {String} The tagname for the HTMLElement.
166 | @param {String} Optional class name to add to the new child.
167 | @returns {Object} The newely created HTMLElement.
168 | */
169 | _createChild ( tagName, className ) {
170 | let child = this._createElement( 'div' );
171 | className && child.classList.add( className );
172 | this.el.appendChild( child );
173 | return child;
174 | }
175 | /*
176 | Method to prepend child to the el.
177 | @private
178 | @param {Object} Parent HTMLElement.
179 | @param {Object} Child HTMLElement.
180 | */
181 | _appendChild ( el, childEl ) { el.appendChild( childEl ); }
182 | /*
183 | Method to prepend child to the el.
184 | @private
185 | @param {Object} Parent HTMLElement.
186 | @param {Object} Child HTMLElement.
187 | */
188 | _prependChild ( el, childEl ) { el.insertBefore(childEl, el.firstChild); }
189 | }
190 |
191 | export default Module;
192 |
--------------------------------------------------------------------------------
/js/components/opacity-switch.babel.js:
--------------------------------------------------------------------------------
1 | import Icon from './icon';
2 | import ButtonSwitch from './button-switch';
3 |
4 | require('../../css/blocks/opacity-switch.postcss.css');
5 | let CLASSES = require('../../css/blocks/opacity-switch.postcss.css.json');
6 |
7 | class OpacitySwitch extends ButtonSwitch {
8 | /*
9 | Method to decalre defaults.
10 | @private
11 | @overrides @ ButtonSwitch
12 | */
13 | _declareDefaults () {
14 | super._declareDefaults();
15 | this._defaults.icon = '';
16 | this._defaults.iconSize = '';
17 | }
18 | /*
19 | Method to render the module.
20 | @private
21 | @overrides @ ButtonSwitch
22 | */
23 | _render () {
24 | super._render();
25 | this.el.classList.add( CLASSES[ 'opacity-switch' ] );
26 |
27 | let p = this._props,
28 | icon = new Icon({
29 | parent: this.el,
30 | shape: p.icon,
31 | size: p.iconSize,
32 | className: CLASSES[ 'icon' ],
33 | prefix: p.prefix
34 | });
35 | this.el.appendChild( icon.el );
36 | }
37 | /*
38 | Method to react to switch state change.
39 | @private
40 | @overrides @ ButtonSwitch
41 | */
42 | _setState () {
43 | let method = ( this._props.isOn ) ? 'add' : 'remove';
44 | this.el.classList[ method ]( CLASSES[ 'is-on' ] );
45 | }
46 | }
47 |
48 | export default OpacitySwitch;
49 |
--------------------------------------------------------------------------------
/js/components/play-button.babel.js:
--------------------------------------------------------------------------------
1 |
2 | import IconFork from './icon-fork';
3 |
4 | require('../../css/blocks/play-button.postcss.css');
5 | let CLASSES = require('../../css/blocks/play-button.postcss.css.json');
6 | // PLAYER_BTN_CLASSES = require('css/blocks/player-button.postcss.css.json');
7 |
8 | class PlayButton extends IconFork {
9 | /*
10 | Method to declare defaults on the module.
11 | @private
12 | @overrides @ ButtonSwitch
13 | */
14 | _declareDefaults () {
15 | super._declareDefaults();
16 | this._defaults.icon1 = 'pause';
17 | this._defaults.icon2 = 'play';
18 | this._defaults.title = 'play/pause (alt + p)';
19 | }
20 | /*
21 | Method to render the module.
22 | @private
23 | */
24 | _render () {
25 | super._render();
26 | this._addClass( this.el, CLASSES[ 'play-button' ] );
27 | }
28 | }
29 |
30 | export default PlayButton;
31 |
--------------------------------------------------------------------------------
/js/components/player-slider.babel.js:
--------------------------------------------------------------------------------
1 | import Slider from './slider';
2 | import Module from './module';
3 |
4 | require('../../css/blocks/player-slider.postcss.css');
5 | let CLASSES = require('../../css/blocks/player-slider.postcss.css.json');
6 | let SLIDER_CLASSES = require('../../css/blocks/slider.postcss.css.json');
7 |
8 | class PlayerSlider extends Module {
9 | /*
10 | Method to declare _defaults.
11 | @private
12 | @overrides @ Module
13 | */
14 | _declareDefaults () {
15 | this._defaults = {
16 | className: CLASSES['player-slider'],
17 | parent: document.body,
18 | progress: 0,
19 | leftProgress: 0,
20 | rightProgress: 1,
21 | isBounds: false,
22 | onLeftProgress: null,
23 | onProgress: null,
24 | onRightProgress: null,
25 | onSeekStart: null,
26 | onSeekEnd: null
27 | }
28 | }
29 | /*
30 | Method to disable bounds.
31 | @public
32 | @returns this.
33 | */
34 | disableBounds () {
35 | this.track.setBounds( 0, 1 );
36 | this.rightBound.hide();
37 | this.leftBound.hide();
38 | return this;
39 | }
40 | /*
41 | Method to enable bounds.
42 | @public
43 | @returns this.
44 | */
45 | enableBounds () {
46 | let p = this._props;
47 | this.track.setBounds( p.leftProgress, p.rightProgress );
48 | this.rightBound.show();
49 | this.leftBound.show();
50 | return this;
51 | }
52 | /*
53 | Method to set progress of the track.
54 | @public
55 | @param {Number} Progress to set [0...1].
56 | @returns this.
57 | */
58 | setTrackProgress ( p ) {
59 | this.track.setProgress( p );
60 | return this;
61 | }
62 | /*
63 | Method to decrease progress value.
64 | @public
65 | @param {Number} Value that the slider should be decreased by.
66 | @returns this.
67 | */
68 | decreaseProgress ( amount = 0.01 ) {
69 | let progress = this.track._progress;
70 | progress -= amount;
71 | progress = ( progress < 0 ) ? 0 : progress;
72 | this.setTrackProgress( progress );
73 | return this;
74 | }
75 | /*
76 | Method to inclease progress value.
77 | @public
78 | @param {Number} Value that the slider should be increased by.
79 | @returns this.
80 | */
81 | increaseProgress ( amount = 0.01 ) {
82 | let progress = this.track._progress;
83 | progress += amount;
84 | progress = ( progress > 1 ) ? 1 : progress;
85 | this.setTrackProgress( progress );
86 | return this;
87 | }
88 | /*
89 | Initial render method.
90 | @private
91 | @overrides @ Module
92 | @returns this
93 | */
94 | _render () {
95 | let p = this._props;
96 |
97 | this._addMainElement();
98 | this.el.classList.add( SLIDER_CLASSES.slider );
99 |
100 | this.leftBound = new Slider({
101 | isBound: true,
102 | parent: this.el,
103 | isRipple: false,
104 | onProgress: this._onLeftBoundProgress.bind(this),
105 | onSeekStart: p.onSeekStart,
106 | onSeekEnd: p.onSeekEnd
107 | });
108 |
109 | this.track = new Slider({
110 | parent: this.el,
111 | className: CLASSES.slider,
112 | onProgress: this._onTrackProgress.bind(this),
113 | onSeekStart: p.onSeekStart,
114 | onSeekEnd: p.onSeekEnd
115 | });
116 | this.rightBound = new Slider({
117 | isBound: true,
118 | parent: this.el,
119 | isRipple: false,
120 | isInversed: true,
121 | onProgress: this._onRightBoundProgress.bind(this),
122 | onSeekStart: p.onSeekStart,
123 | onSeekEnd: p.onSeekEnd
124 | });
125 |
126 | this.rightBound.setProgress( p.rightProgress );
127 | this.track.setProgress( p.progress );
128 | this.leftBound.setProgress( p.leftProgress );
129 |
130 | p.parent.appendChild( this.el );
131 |
132 | }
133 | /*
134 | Method that should be called on track update.
135 | @private
136 | @param {Number} Track progress value [0...1].
137 | */
138 | _onTrackProgress ( p ) {
139 | this._callIfFunction( this._props.onProgress, p );
140 | }
141 | /*
142 | Method that should be called on left bound update.
143 | @private
144 | @param {Number} Track progress value [0...1].
145 | */
146 | _onLeftBoundProgress ( p ) {
147 | if ( !this._props.isBounds ) { return; }
148 | this._props.leftProgress = p;
149 | this.track.setMinBound( p );
150 | this.rightBound.setMinBound( p );
151 | this._callIfFunction( this._props.onLeftProgress, p );
152 | }
153 | /*
154 | Method that should be called on right bound update.
155 | @private
156 | @param {Number} Track progress value [0...1].
157 | */
158 | _onRightBoundProgress ( p ) {
159 | if ( !this._props.isBounds ) { return; }
160 | this._props.rightProgress = p;
161 | this.track.setMaxBound( p );
162 | this.leftBound.setMaxBound( p );
163 | this._callIfFunction( this._props.onRightProgress, p );
164 | }
165 | }
166 |
167 | export default PlayerSlider;
168 |
--------------------------------------------------------------------------------
/js/components/repeat-button.babel.js:
--------------------------------------------------------------------------------
1 | import OpacitySwitch from './opacity-switch';
2 |
3 | require('../../css/blocks/repeat-button.postcss.css');
4 | let CLASSES = require('../../css/blocks/repeat-button.postcss.css.json');
5 |
6 | class RepeatButton extends OpacitySwitch {
7 | /*
8 | Method to declare defaults.
9 | @private
10 | @overrides @ OpacitySwitch
11 | */
12 | _declareDefaults () {
13 | super._declareDefaults();
14 | this._defaults.icon = 'repeat';
15 | this._defaults.iconSize = 'x2';
16 | this._defaults.title = 'repeat (alt + r)';
17 | }
18 | /*
19 | Initial render method.
20 | @private
21 | @overrides @ Button
22 | @returns this
23 | */
24 | _render () {
25 | super._render();
26 | this._addClass( this.el, CLASSES[ 'repeat-button' ] );
27 | }
28 | }
29 |
30 | export default RepeatButton;
31 |
--------------------------------------------------------------------------------
/js/components/ripple.babel.js:
--------------------------------------------------------------------------------
1 | import Module from './module';
2 |
3 | class Ripple extends Module {
4 | /*
5 | Method to declare defaults.
6 | @private
7 | @overrides @ Module.
8 | */
9 | _declareDefaults () {
10 | super._declareDefaults();
11 | this._defaults.withHold = true;
12 | }
13 | /*
14 | Method to render the component.
15 | @private
16 | @overrides @ Module
17 | */
18 | _render () {
19 | super._render();
20 | this.curtain = document.createElement('div');
21 | // this.curtain.style.background = 'rgba(255,255,255,.15)';
22 | // this.curtain.style.background = 'yellow';
23 | this.curtain.style.position = 'absolute';
24 | this.curtain.style.width = '100%';
25 | this.curtain.style.height = '100%';
26 | this.curtain.style.left = 0;
27 | this.curtain.style.top = 0;
28 | this.curtain.style.zIndex = 1;
29 |
30 | this.el.appendChild(this.curtain);
31 |
32 | if (mojs.Shape) {
33 | this._addRipple();
34 | }
35 | }
36 | /*
37 | Method to construct ripple object.
38 | @private
39 | */
40 | _addRipple () {
41 | this.shape = new mojs.Shape({
42 | parent: this.el,
43 | left: 0, top: this._o.top || 0,
44 | // strokeWidth: 10,
45 | strokeWidth: { 10 : 0 },
46 | fill: 'none',
47 | stroke: 'hotpink',
48 | fill: 'hotpink',
49 | fillOpacity: .75,
50 | opacity: { .85: 0 },
51 | radius: 40,
52 | scale: { 0: 1 },
53 | isShowEnd: false,
54 | // duration: 15000,
55 | // isForce3d: true,
56 | onStart: () => { this.isStart = true; },
57 | onUpdate: this._onUpdate.bind(this),
58 | onComplete: () => { this.isStart = false; }
59 | });
60 | }
61 | /*
62 | Method that is invoked on ripple update.
63 | @private
64 | @param {Number} Curret progress [0...1].
65 | */
66 | _onUpdate(p) {
67 | if (!this._props.withHold) { return; }
68 | if (p >= .15 && this.isStart && !this.isRelease) {
69 | this.isStart = false;
70 |
71 | if (mojs.Shape) {
72 | this.shape.setSpeed(.02);
73 | }
74 | }
75 | }
76 | /*
77 | Method that should be run on touch serface release.
78 | @private
79 | */
80 | _release () {
81 | if ( !this._props.withHold ) { return; }
82 | this.isRelease = true;
83 |
84 | if (mojs.Shape) {
85 | this.shape.setSpeed( 1 ).play();
86 | }
87 | }
88 | /*
89 | Method that should be run on touch serface hold.
90 | @private
91 | @param {Object} Origin event object.
92 | */
93 | _hold ( e ) {
94 | let x = ( e.offsetX != null ) ? e.offsetX : e.layerX,
95 | y = ( e.offsetY != null ) ? e.offsetY : e.layerY;
96 |
97 | this.isRelease = false;
98 | if (mojs.Shape) {
99 | this.shape.tune({ x: x, y: y }).replay();
100 | }
101 | }
102 | /*
103 | Method that should be run on touch serface cancel.
104 | @private
105 | */
106 | _cancel () {
107 | if ( !this._props.withHold ) { return; }
108 | this.isRelease = true;
109 |
110 | if (mojs.Shape) {
111 | this.shape
112 | .pause()
113 | .setSpeed( 1 )
114 | .playBackward();
115 | }
116 | }
117 | }
118 |
119 | export default Ripple;
120 |
--------------------------------------------------------------------------------
/js/components/slider.babel.js:
--------------------------------------------------------------------------------
1 | import Module from './module';
2 | import Handle from './handle';
3 | import Track from './track';
4 |
5 | require('../../css/blocks/slider.postcss.css');
6 | let CLASSES = require('../../css/blocks/slider.postcss.css.json');
7 |
8 | class Slider extends Module {
9 | /*
10 | Method to declare _defaults.
11 | @private
12 | @overrides @ Module
13 | */
14 | _declareDefaults () {
15 | this._defaults = {
16 | className: '',
17 | parent: document.body,
18 | isBound: false,
19 | isInversed: false,
20 | isRipple: true,
21 | isProgress: true,
22 | onProgress: null,
23 | onSeekStart: null,
24 | onSeekEnd: null,
25 | direction: 'x',
26 | snapPoint: 0,
27 | snapStrength: 0
28 | }
29 | }
30 | /*
31 | Method to set slider progress.
32 | @public
33 | @param {Number} Progress to set.
34 | @returns this.
35 | */
36 | setProgress ( progress ) {
37 | this.handle.setProgress( progress );
38 | this.track.setProgress( progress );
39 | return this;
40 | }
41 | /*
42 | Method to set bounds of progress.
43 | @public
44 | @param {Number} Min bound to set [0...1].
45 | @param {Number} Max bound to set [0...1].
46 | @returns this.
47 | */
48 | setBounds ( min, max ) {
49 | this.handle.setBounds( min, max );
50 | this.track.setBounds( min, max );
51 | return this;
52 | }
53 | /*
54 | Method to set min bound of progress.
55 | @public
56 | @param {Number} Min bound to set [0...1].
57 | @returns this.
58 | */
59 | setMinBound ( min ) {
60 | this.handle.setMinBound( min );
61 | this.track.setMinBound( min );
62 | return this;
63 | }
64 | /*
65 | Method to set max bound of progress.
66 | @public
67 | @param {Number} Max bound to set [0...1].
68 | @returns this.
69 | */
70 | setMaxBound ( max ) {
71 | this.handle.setMaxBound( max );
72 | this.track.setMaxBound( max );
73 | return this;
74 | }
75 | /*
76 | Method to hide elements.
77 | @public
78 | */
79 | show () {
80 | this.track.el.style.display = 'block';
81 | this.handle.el.style.display = 'block';
82 | }
83 | /*
84 | Method to hide elements.
85 | @public
86 | */
87 | hide () {
88 | this.track.el.style.display = 'none';
89 | this.handle.el.style.display = 'none';
90 | }
91 | /*
92 | Method to render the component.
93 | @private
94 | @overrides @ Module
95 | */
96 | _render () {
97 | var p = this._props;
98 |
99 | if ( !p.isBound ) {
100 | let el = this._createElement( 'div' ),
101 | classList = el.classList;
102 | this.el = el;
103 |
104 | this.inner = this._createElement( 'div' );
105 | this.inner.classList.add( CLASSES[ 'slider__inner' ] )
106 | this.el.appendChild( this.inner );
107 |
108 |
109 | classList.add( CLASSES.slider );
110 | ( p.direction === 'y' ) && classList.add( CLASSES[ 'is-y' ] );
111 | p.className && classList.add( p.className );
112 | p.parent.appendChild( el );
113 | }
114 |
115 | let rootEl = ( !p.isBound ) ? this.inner : p.parent;
116 |
117 | this.track = new Track({
118 | className: CLASSES.track,
119 | onProgress: this._onTrackProgress.bind(this),
120 | onSeekStart: p.onSeekStart,
121 | onSeekEnd: p.onSeekEnd,
122 | isBound: p.isBound,
123 | isInversed: p.isInversed,
124 | isRipple: p.isRipple,
125 | isProgress: p.isProgress,
126 | parent: rootEl,
127 | direction: p.direction,
128 | snapPoint: p.snapPoint,
129 | snapStrength: p.snapStrength
130 | });
131 | rootEl.appendChild( this.track.el );
132 |
133 | let handleClass = [ CLASSES.handle ];
134 | if ( !p.isBound ) { handleClass.push( CLASSES[ 'progress-handle' ] ) }
135 |
136 | this.handle = new Handle({
137 | className: handleClass,
138 | onProgress: this._onHandleProgress.bind(this),
139 | onSeekStart: p.onSeekStart,
140 | onSeekEnd: p.onSeekEnd,
141 | isBound: p.isBound,
142 | isInversed: p.isInversed,
143 | parent: rootEl,
144 | direction: p.direction,
145 | snapPoint: p.snapPoint,
146 | snapStrength: p.snapStrength
147 | });
148 | rootEl.appendChild( this.handle.el );
149 | }
150 | /*
151 | Method that is invoked on handle progress change.
152 | @private
153 | @param {Number} Progress [0...1].
154 | */
155 | _onHandleProgress ( p ) {
156 | this.track.setProgress( p, false );
157 | this._onProgress( p );
158 | }
159 | /*
160 | Method that is invoked on track progress change.
161 | @private
162 | @param {Number} Progress [0...1].
163 | */
164 | _onTrackProgress ( p ) {
165 | this.handle.setProgress( p, false );
166 | this._onProgress( p );
167 | }
168 | /*
169 | Method to call onProgress callback.
170 | @private
171 | @param {Number} Progress value [0...1].
172 | */
173 | _onProgress ( progress ) {
174 | let p = this._props;
175 | if ( typeof p.onProgress === 'function' && this._progress !== progress) {
176 | this._progress = progress;
177 | p.onProgress.call( this, progress );
178 | }
179 | }
180 | }
181 |
182 | export default Slider;
183 |
--------------------------------------------------------------------------------
/js/components/speed-control.babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Module from './module'
3 | import LabelButton from './label-button';
4 | import Slider from './slider';
5 |
6 | require('../../css/blocks/speed-control.postcss.css');
7 | let CLASSES = require('../../css/blocks/speed-control.postcss.css.json');
8 |
9 | class SpeedControl extends Module {
10 | /*
11 | Method to declare defaults for the module.
12 | @private
13 | @overrides @ Module
14 | */
15 | _declareDefaults () {
16 | super._declareDefaults();
17 | this._defaults.isOn = false;
18 | this._defaults.speed = 1;
19 | this._defaults.progress = .5;
20 | this._defaults.onSpeedChange = null;
21 | this._defaults.onIsSpeed = null
22 | }
23 | /*
24 | Method to reset speed to 1x.
25 | @public
26 | @returns this
27 | */
28 | reset () { this._onDoubleTap(); }
29 | /*
30 | Method to decrease speed value.
31 | @public
32 | @param {Number} Value that the slider should be decreased by.
33 | @returns this.
34 | */
35 | decreaseSpeed ( amount = 0.01 ) {
36 | let p = this._props;
37 | p.progress -= amount;
38 | p.progress = ( p.progress < 0 ) ? 0 : p.progress;
39 | this.slider.setProgress( p.progress );
40 | return this;
41 | }
42 | /*
43 | Method to inclease speed value.
44 | @public
45 | @param {Number} Value that the slider should be increased by.
46 | @returns this.
47 | */
48 | increaseSpeed ( amount = 0.01 ) {
49 | let p = this._props;
50 | p.progress += amount;
51 | p.progress = ( p.progress > 1 ) ? 1 : p.progress;
52 | this.slider.setProgress( p.progress );
53 | return this;
54 | }
55 | /*
56 | Initial render method.
57 | @private
58 | @overrides @ Module
59 | */
60 | _render () {
61 | let p = this._props,
62 | className = 'speed-control',
63 | slider = this._createElement( 'div' ),
64 | sliderIn = this._createElement( 'div' ),
65 | icon = this._createElement( 'div' );
66 |
67 | this._addMainElement();
68 | this.el.classList.add( CLASSES[ className ] );
69 | // places for child components
70 | slider.classList.add( CLASSES[ `${ className }__slider` ] );
71 | // sliderIn.classList.add( CLASSES[ `${ className }__slider-inner` ] );
72 | // slider.appendChild( sliderIn );
73 | this.el.appendChild( slider );
74 | // child components
75 | this.labelButton = new LabelButton({
76 | parent: this.el,
77 | isOn: p.isOn,
78 | className: CLASSES[ `${ className }__icon` ],
79 | onStateChange: this._onButtonStateChange.bind( this ),
80 | onDoubleTap: this._onDoubleTap.bind( this )
81 | });
82 | this.slider = new Slider({
83 | parent: slider,
84 | isProgress: false,
85 | direction: 'y',
86 | onProgress: this._onSliderProgress.bind( this ),
87 | snapPoint: .5,
88 | snapStrength: .05
89 | });
90 |
91 | this.slider.setProgress( this._speedToProgress( this._props.speed ) );
92 | }
93 | /*
94 | Method that is invoked on slider progress.
95 | @private
96 | @param {Number} Progress of the slider.
97 | */
98 | _onSliderProgress ( p ) {
99 | // progress should be at least 0.01
100 | p = Math.max( p, 0.0001 );
101 |
102 | let props = this._props,
103 | args = [ ];
104 |
105 | this._callIfFunction( props.onSpeedChange, this._progressToSpeed(p), p );
106 | this.labelButton.setLabelText( this._progressToLabel( props.progress = p ) );
107 | }
108 | /*
109 | Method that is invoked on button state change.
110 | @private
111 | @param {Boolean} State of the button switch.
112 | */
113 | _onButtonStateChange ( isOn ) {
114 | let method = ( isOn ) ? 'add' : 'remove' ;
115 | this.el.classList[ method ]( CLASSES[ 'is-on' ] );
116 | this._callIfFunction( this._props.onIsSpeed, isOn );
117 | }
118 | /*
119 | Method to recalc progress to label string.
120 | @private
121 | @param {Number} Progress [0...1].
122 | @returns {String} String for a label to set.
123 | */
124 | _progressToLabel ( progress ) {
125 | let text = this._progressToSpeed(progress).toFixed( 2 ),
126 | zeros = /\.+00$/;
127 |
128 | if ( text.match( zeros ) ) { text = text.replace( zeros, '' ); }
129 |
130 | return `${ text }x`;
131 | }
132 | /*
133 | Method to recalc progress to speed.
134 | @private
135 | @param {Number} Progress [0...1].
136 | @returns {Number} Speed [0...10].
137 | */
138 | _progressToSpeed ( progress ) {
139 | let speed = progress;
140 | if ( progress < .5 ) {
141 | speed = 2*progress;
142 | }
143 | if ( progress === .5 ) { speed = 1; }
144 | if ( progress > .5 ) {
145 | progress -= .5;
146 | speed = 1 + progress*18;
147 | // console.log( speed/10, mojs.easing.cubic.out( speed/10 ) );
148 | // console.log( .5 + ( speed - 1 ) / 18 );
149 | }
150 | return speed;
151 | }
152 | /*
153 | Method to recalc progress to speed.
154 | @private
155 | @param {Number} Progress [0...1].
156 | @returns {Number} Speed [0...10].
157 | */
158 | _speedToProgress ( speed ) {
159 | let progress = speed;
160 | if ( speed < 1 ) { progress = speed/2; }
161 | if ( speed === 1 ) { progress = .5; }
162 | if ( speed > 1 ) {
163 | progress = .5 + ( ( speed - 1 ) / 18 );
164 | }
165 | return progress;
166 | }
167 | /*
168 | Method that is invoked on double button tap.
169 | @private
170 | */
171 | _onDoubleTap () {
172 | this.slider.setProgress( .5 );
173 | this.labelButton.off();
174 | }
175 | }
176 |
177 | export default SpeedControl;
178 |
--------------------------------------------------------------------------------
/js/components/stop-button.babel.js:
--------------------------------------------------------------------------------
1 | import IconButton from './icon-button';
2 |
3 | require('../../css/blocks/stop-button.postcss.css');
4 | let CLASSES = require('../../css/blocks/stop-button.postcss.css.json');
5 |
6 | class StopButton extends IconButton {
7 | _declareDefaults () {
8 | super._declareDefaults();
9 | this._defaults.icon = 'stop';
10 | this._defaults.title = 'stop (alt + s)';
11 | }
12 | /*
13 | Initial render method.
14 | @private
15 | @overrides @ Button
16 | @returns this
17 | */
18 | _render () {
19 | super._render();
20 | this._addClass( this.el, CLASSES[ 'stop-button' ] );
21 | }
22 | }
23 |
24 | export default StopButton;
25 |
--------------------------------------------------------------------------------
/js/components/track.babel.js:
--------------------------------------------------------------------------------
1 | import Handle from './handle';
2 | import HamerJS from 'hammerjs';
3 | import Ripple from './ripple';
4 |
5 | require('../../css/blocks/track.postcss.css');
6 | let CLASSES = require('../../css/blocks/track.postcss.css.json');
7 |
8 | class Track extends Handle {
9 | /*
10 | Method to declare _defaults.
11 | @private
12 | @overrides @ Handle
13 | */
14 | _declareDefaults () {
15 | super._declareDefaults();
16 | this._defaults.isProgress = true;
17 | this._defaults.isRipple = true;
18 | }
19 | /*
20 | Method to render the component.
21 | @private
22 | @overrides @ Handle
23 | */
24 | _render () {
25 | super._render();
26 | if ( !this._props.isRipple ) { return; }
27 | this.ripple = new Ripple({
28 | withHold: false,
29 | className: CLASSES[ `track__ripple` ],
30 | // top: '50%',
31 | parent: this.el
32 | });
33 | }
34 | /*
35 | Method to apply shift to the DOMElement.
36 | @private
37 | @overrides @ Handle.
38 | @param {Number} Shift in pixels.x
39 | */
40 | _applyShift ( shift ) {
41 | if ( !this._props.isProgress ) { return; }
42 | if ( this._props.isInversed ) { shift = this._maxWidth - shift; }
43 | let transform = `scaleX( ${shift} ) translateZ(0)`;
44 | this.trackProgressEl.style.transform = transform;
45 | // this.trackProgressEl.style.width = `${shift}px`;
46 | }
47 | /*
48 | Method to add classes on `this.el`.
49 | @private
50 | @overrides @ Handle.
51 | */
52 | _addMainClasses () {
53 | let p = this._props,
54 | classList = this.el.classList;
55 |
56 | classList.add( CLASSES.track );
57 | if ( p.isInversed ) { classList.add( CLASSES[ 'is-inversed' ] ); }
58 | if ( p.isBound ) { classList.add( CLASSES[ 'is-bound' ] ); }
59 | if ( p.direction === 'y' ) { classList.add( CLASSES[ 'is-y' ] ); }
60 | }
61 | /*
62 | Method to add DOM elements on render.
63 | @private
64 | */
65 | _addElements () {
66 | let p = this._props;
67 |
68 | if ( p.isProgress ) {
69 | // progress track
70 | const trackP = document.createElement('div');
71 | trackP.classList.add(`${ CLASSES['track__track-progress'] }`);
72 | this.trackProgressEl = trackP;
73 | this.el.appendChild( trackP );
74 | }
75 | // track
76 | if ( !p.isBound ) {
77 | let track = document.createElement('div');
78 | track.classList.add(`${ CLASSES.track__track }`);
79 | this.el.appendChild( track );
80 | }
81 |
82 | }
83 | /*
84 | Callback for pointer down on main el.
85 | @private
86 | @param {Object} Original event object.
87 | @overrides @ Handle
88 | */
89 | _pointerDown ( e ) {
90 | let p = this._props,
91 | x = (p.direction === 'x' ) ? e.layerX : e.layerY;
92 | this._isPointerDown = true;
93 |
94 | if ( p.direction === 'y' ) { x = this._maxWidth - e.layerY; }
95 | x = ( this._props.isInversed && x < 0 ) ? this._maxWidth + x : x;
96 |
97 | // if near the snap point - set it to the snap point
98 | let progress = this._shiftToProgress( x );
99 | progress = ( Math.abs( p.snapPoint - progress ) < p.snapStrength )
100 | ? p.snapPoint : progress;
101 | this.setProgress( progress );
102 |
103 | p.isRipple && this.ripple._hold( e );
104 | this._callIfFunction( p.onSeekStart, e );
105 | }
106 | }
107 |
108 | export default Track;
109 |
--------------------------------------------------------------------------------
/js/mojs-player.babel.js:
--------------------------------------------------------------------------------
1 | import Polyfill from 'classlist-polyfill';
2 | import Icons from './components/icons';
3 | import Module from './components/module';
4 | import PlayerSlider from './components/player-slider';
5 | import IconButton from './components/icon-button';
6 | import SpeedControl from './components/speed-control';
7 | import PlayButton from './components/play-button';
8 | import StopButton from './components/stop-button';
9 | import RepeatButton from './components/repeat-button';
10 | import BoundsButton from './components/bounds-button';
11 | import HideButton from './components/hide-button';
12 |
13 | // TODO
14 |
15 | require('../css/blocks/mojs-player.postcss.css');
16 | let CLASSES = require('../css/blocks/mojs-player.postcss.css.json');
17 |
18 | class MojsPlayer extends Module {
19 | constructor ( o ) {
20 | if ( typeof mojs === 'undefined' ) {
21 | throw new Error(`MojsPlayer relies on mojs^0.225.2, please include it before player initialization. [ https://github.com/mojs/mojs ] `);
22 | }
23 | super( o );
24 | }
25 | /*
26 | Method to declare defaults.
27 | @private
28 | @overrides @ Module
29 | */
30 | _declareDefaults () {
31 | super._declareDefaults();
32 |
33 | this._defaults.isSaveState = true;
34 | this._defaults.isPlaying = false;
35 | this._defaults.progress = 0;
36 | this._defaults.isRepeat = false;
37 | this._defaults.isBounds = false;
38 | this._defaults.leftBound = 0;
39 | this._defaults.rightBound = 1;
40 | this._defaults.isSpeed = false;
41 | this._defaults.speed = 1;
42 | this._defaults.isHidden = false;
43 | this._defaults.precision = 0.1;
44 | this._defaults.name = 'mojs-player';
45 | this._defaults.onToggleHide = null;
46 | this._defaults.onPlayStateChange = null;
47 | this._defaults.onSeekStart = null;
48 | this._defaults.onSeekEnd = null;
49 | this._defaults.onProgress = null;
50 |
51 | this._play = this._play.bind(this);
52 |
53 | this.revision = '1.3.0';
54 |
55 | let str = this._fallbackTo( this._o.name, this._defaults.name );
56 | str += ( str === this._defaults.name ) ? '' : `__${this._defaults.name}`;
57 | this._localStorage = `${str}__${ this._hashCode( str ) }`;
58 | }
59 | /*
60 | Method to copy `_o` options to `_props` object
61 | with fallback to `localStorage` and `_defaults`.
62 | @private
63 | */
64 | _extendDefaults () {
65 | this._props = {};
66 | let p = this._props,
67 | o = this._o,
68 | defs = this._defaults;
69 |
70 | // get localstorage regarding isSaveState option
71 | p.isSaveState = this._fallbackTo( o.isSaveState, defs.isSaveState );
72 | let m = ( p.isSaveState )
73 | ? JSON.parse( localStorage.getItem(this._localStorage) ) || {}
74 | : {};
75 |
76 | for (let key in defs) {
77 | let value = this._fallbackTo( m[ key ], o[ key ] );
78 | this._assignProp( key, this._fallbackTo( value, defs[ key ] ) );
79 | }
80 | // get raw-speed option
81 | this._props[ 'raw-speed' ] = this._fallbackTo( m[ 'raw-speed' ], .5 );
82 | }
83 | /*
84 | Callback for keyup on document.
85 | @private
86 | @param {Object} Original event object.
87 | */
88 | _keyUp ( e ) {
89 | if ( e.altKey ) {
90 | switch ( e.keyCode ) {
91 | case 80: // alt + P => PLAY/PAUSE TOGGLE
92 | this._props.isPlaying = !this._props.isPlaying;
93 | this._onPlayStateChange( this._props.isPlaying );
94 | break;
95 | case 189: // alt + - => DECREASE PROGRESS
96 | this.playButton.off();
97 | this.playerSlider.decreaseProgress( ( e.shiftKey ) ? .1 : .01 );
98 | break;
99 | case 187: // alt + + => INCREASE PROGRESS
100 | this.playButton.off();
101 | this.playerSlider.increaseProgress( ( e.shiftKey ) ? .1 : .01 );
102 | break;
103 | case 83: // alt + S => STOP
104 | this._onStop();
105 | break;
106 | case 82: // alt + R => REPEAT TOGGLE
107 | this._props.isRepeat = !this._props.isRepeat;
108 | var method = ( this._props.isRepeat ) ? 'on' : 'off';
109 | this.repeatButton[ method ]();
110 | break;
111 | case 66: // alt + B => BOUNDS TOGGLE
112 | this._props.isBounds = !this._props.isBounds;
113 | var method = ( this._props.isBounds ) ? 'on' : 'off';
114 | this.boundsButton[ method ]();
115 | break;
116 | case 72: // alt + H => HIDE PLAYER TOGGLE
117 | this._props.isHidden = !this._props.isHidden;
118 | this._onHideStateChange( this._props.isHidden );
119 | var method = ( this._props.isHidden ) ? 'on' : 'off';
120 | this.hideButton[ method ]();
121 | break;
122 | // case 49: // alt + 1 => RESET SPEED TO 1x
123 | case 81: // alt + q => RESET SPEED TO 1x
124 | this.speedControl.reset();
125 | break;
126 | case 50: // alt + 2 => DECREASE SPEEED by .05
127 | this.speedControl.decreaseSpeed( ( e.shiftKey ) ? .05 : .01 );
128 | break;
129 | case 51: // alt + 3 => INCREASE SPEED by .05
130 | this.speedControl.increaseSpeed( ( e.shiftKey ) ? .05 : .01 );
131 | break;
132 | }
133 | }
134 | }
135 | /*
136 | Method to declare properties.
137 | @private
138 | @overrides @ Module
139 | */
140 | _vars () {
141 | this._hideCount = 0;
142 | }
143 | /*
144 | Method to render the module.
145 | @private
146 | @overrides @ Module
147 | */
148 | _render () {
149 | this._initTimeline();
150 | let p = this._props,
151 | className = 'mojs-player',
152 | icons = new Icons({ prefix: this._props.prefix });
153 | super._render();
154 | // this.el.classList.add(p.classNAme );
155 | this.el.classList.add( CLASSES[ className ] );
156 | this.el.setAttribute( 'id', 'js-mojs-player' );
157 |
158 | let left = this._createChild( 'div', CLASSES[ `${ className }__left` ] ),
159 | mid = this._createChild( 'div', CLASSES[ `${ className }__mid` ] ),
160 | right = this._createChild( 'div', CLASSES[ `${ className }__right` ] );
161 |
162 | this.repeatButton = new RepeatButton({
163 | parent: left,
164 | isOn: p.isRepeat,
165 | onStateChange: this._onRepeatStateChange.bind( this ),
166 | prefix: this._props.prefix
167 | });
168 |
169 | this.playerSlider = new PlayerSlider({
170 | parent: mid,
171 | isBounds: p.isBounds,
172 | leftProgress: p.leftBound,
173 | rightProgress: p.rightBound,
174 | progress: p.progress,
175 | onLeftProgress: this._onLeftProgress.bind( this ),
176 | onProgress: this._onProgress.bind( this ),
177 | onRightProgress: this._onRightProgress.bind( this ),
178 | onSeekStart: this._onSeekStart.bind( this ),
179 | onSeekEnd: this._onSeekEnd.bind( this )
180 | });
181 |
182 | this.boundsButton = new BoundsButton({
183 | isOn: p.isBounds,
184 | parent: left,
185 | onStateChange: this._boundsStateChange.bind( this ),
186 | prefix: this._props.prefix
187 | });
188 |
189 | this.speedControl = new SpeedControl({
190 | parent: left,
191 | // progress: p.speed,
192 | speed: p.speed,
193 | isOn: p.isSpeed,
194 | onSpeedChange: this._onSpeedChange.bind( this ),
195 | onIsSpeed: this._onIsSpeed.bind( this ),
196 | prefix: this._props.prefix
197 | });
198 |
199 | let proc = 0,
200 | progress = [],
201 | procToSpeed = [],
202 | speedToProc = [];
203 |
204 | this.stopButton = new StopButton({
205 | parent: left,
206 | isPrepend: true,
207 | onPointerUp: this._onStop.bind( this ),
208 | prefix: this._props.prefix
209 | });
210 |
211 | this.playButton = new PlayButton({
212 | parent: left,
213 | isOn: p.isPlaying,
214 | isPrepend: true,
215 | onStateChange: this._onPlayStateChange.bind( this ),
216 | prefix: this._props.prefix
217 | });
218 |
219 | this.mojsButton = new IconButton({
220 | parent: right,
221 | className: CLASSES[ `${ className }__mojs-logo` ],
222 | icon: 'mojs',
223 | target: '_blank',
224 | link: 'https://github.com/mojs/mojs-player',
225 | title: 'mo • js',
226 | prefix: this._props.prefix
227 | });
228 |
229 | this.hideButton = new HideButton({
230 | parent: this.el,
231 | className: CLASSES[ `${ className }__hide-button` ],
232 | isOn: p.isHidden,
233 | onStateChange: this._onHideStateChange.bind( this ),
234 | prefix: this._props.prefix
235 | });
236 |
237 | this._listen();
238 | }
239 | /*
240 | Method to initialize event listeners.
241 | @private
242 | */
243 | _listen () {
244 | const unloadEvent = ('onpagehide' in window) ? 'pagehide' : 'beforeunload';
245 | window.addEventListener( unloadEvent, this._onUnload.bind(this) );
246 | document.addEventListener( 'keyup' , this._keyUp.bind(this) );
247 | }
248 | /*
249 | Method that is invoked when user touches the track.
250 | @private
251 | @param {Object} Original event object.
252 | */
253 | _onSeekStart ( e ) {
254 | this._sysTween.pause();
255 |
256 | const { onSeekStart } = this._props;
257 | if (this._isFunction(onSeekStart)) {
258 | onSeekStart(e);
259 | }
260 | }
261 | /*
262 | Method that is invoked when user touches the track.
263 | @private
264 | @param {Object} Original event object.
265 | */
266 | _onSeekEnd ( e ) {
267 | clearTimeout( this._endTimer );
268 | this._endTimer = setTimeout( () => {
269 | this._props.isPlaying && this._play();
270 | }, 20 );
271 | }
272 | /*
273 | Method to init timeline.
274 | @private
275 | */
276 | _initTimeline () {
277 | this.timeline = new mojs.Timeline({});
278 |
279 | let add = this._o.add;
280 | // check whether the `add` option meets the next criterias:
281 | let isUndefined = typeof add === 'undefined';
282 |
283 | if ( !isUndefined ) { add = add.timeline || add.tween || add; }
284 |
285 | let isAdd = !!add.setProgress;
286 |
287 | if ( isUndefined || !isAdd ) {
288 | throw new Error('MojsPlayer expects Tween/Timeline/Module as `add` option in constructor call. [ new MojsPlayer({ add: new mojs.Tween }); ]');
289 | return;
290 | }
291 |
292 | this.timeline.add(this._o.add);
293 |
294 | const { _props } = this.timeline;
295 | const duration = (_props.repeatTime !== void 0) ? _props : _props.delay + _props.duration;
296 |
297 | this._sysTween = new mojs.Tween({
298 | easing: 'linear.none',
299 | duration,
300 | onUpdate: this._onSysProgress.bind( this ),
301 | onComplete: this._onSysTweenComplete.bind( this ),
302 | onPlaybackStop: () => { this._setPlayState( 'off' ); },
303 | onPlaybackPause: () => { this._setPlayState( 'off' ); },
304 | onPlaybackStart: () => { this._setPlayState( 'on' ); }
305 | });
306 | }
307 | /*
308 | Method that is invoked on system tween progress.
309 | @private
310 | @param {Number} Progress value [0...1].
311 | */
312 | _onSysProgress(p) {
313 | this.playerSlider.setTrackProgress(p);
314 |
315 | let rightBound = ( this._props.isBounds ) ? this._props.rightBound : 1,
316 | leftBound = ( this._props.isBounds ) ? this._props.leftBound : -1;
317 |
318 | // since js is really bed in numbers precision,
319 | // if we set a progress in the `_play` method it returns slighly
320 | // different when piped thru tween, so add `0.01` gap to soften that
321 | if ( p < leftBound - 0.01 && p !== 0 ) {
322 | this._reset();
323 | requestAnimationFrame(this._play);
324 | }
325 |
326 | if ( p >= rightBound ) {
327 | this._reset( rightBound === 1 );
328 |
329 | if (this._props.isRepeat) {
330 | requestAnimationFrame(this._play);
331 | } else { this._props.isPlaying = false; }
332 | }
333 | }
334 | /*
335 | Method to play system tween from progress.
336 | @private
337 | */
338 | _play() {
339 | const p = this._props;
340 | let leftBound = (p.isBounds) ? p.leftBound : p.progress;
341 | let progress = (p.progress >= this._getBound('right'))
342 | ? leftBound : p.progress;
343 |
344 | if (progress === 1) { progress = (p.isBounds) ? p.leftBound : 0 };
345 | if (progress !== 0) { this._sysTween.setProgress(progress); };
346 |
347 | this._sysTween.play();
348 | }
349 | /*
350 | Method to reset sysTween and timeline.
351 | @param {Boolean} If should not set progress to 0.
352 | @private
353 | */
354 | _reset(isPause) {
355 | this._sysTween.reset();
356 |
357 | // if ( !isPause ) {
358 | // const p = this._props,
359 | // progress = p.progress;
360 | //
361 | // let start = progress,
362 | // leftBound = (p.isBounds) ? p.leftBound : 0;
363 | //
364 | // // while ( (start - p.precision) >= leftBound ) {
365 | // // start -= p.precision;
366 | // // this.timeline.setProgress( start );
367 | // // }
368 | // }
369 |
370 | this.timeline.reset();
371 | }
372 | /*
373 | Method to set play button state.
374 | @private
375 | @param {String} Method name to call it on playButton.
376 | */
377 | _setPlayState ( method ) {
378 | clearTimeout( this._playTimeout );
379 | this._playTimeout = setTimeout( () => {
380 | this.playButton && this.playButton[ method ]( false );
381 | }, 20);
382 | }
383 | /*
384 | Method that is invoked on system tween completion.
385 | @private
386 | @param {Boolean} If forward direction.
387 | */
388 | _onSysTweenComplete ( isForward ) {
389 | // console.log(' complete ', this._props.isPlaying, isForward, this._props.isRepeat);
390 | // if ( this._props.isPlaying && isForward ) {
391 | // if ( this._props.isRepeat ) {
392 | // console.log('reset 2')
393 | // // this._sysTween.reset();
394 | // // this._play();
395 | // }
396 | // }
397 | }
398 | /*
399 | Method that is invoked play button state change.
400 | @private
401 | @param {Boolean} Repeat button state.
402 | */
403 | _onPlayStateChange ( isPlay ) {
404 | this._props.isPlaying = isPlay;
405 | if ( isPlay ) { this._play(); } else { this._sysTween.pause(); }
406 |
407 | const { onPlayStateChange } = this._props;
408 | if (this._isFunction(onPlayStateChange)) {
409 | onPlayStateChange(isPlay);
410 | }
411 | }
412 | /*
413 | Callback for hide button change state.
414 | @private
415 | @param {Boolean}
416 | */
417 | _onHideStateChange ( isHidden ) {
418 | this._props.isHidden = isHidden;
419 | const { onToggleHide } = this._props;
420 | if (this._isFunction(onToggleHide)) {
421 | onToggleHide(isHidden);
422 | }
423 |
424 | let method = ( isHidden ) ? 'add' : 'remove';
425 | this.el.classList[ method ]( CLASSES[ 'is-hidden' ] );
426 | // enable CSS transition on subsequent calls
427 | if ( this._hideCount++ === 1 ) {
428 | this.el.classList.add( CLASSES[ 'is-transition' ] );
429 | }
430 | }
431 | /*
432 | Method that is invoked on stop button tap.
433 | @private
434 | */
435 | _onStop() {
436 | const p = this._props;
437 | p.isPlaying = false;
438 |
439 | const leftBound = ( p.isBounds ) ? p.leftBound : 0;
440 | // set sysTween progress twice because it could be _reset already
441 | this._sysTween.setProgress(leftBound + 0.01);
442 | this._sysTween.setProgress(leftBound);
443 |
444 | this._reset();
445 | }
446 | /*
447 | Method that is invoked on repeat switch state change.
448 | @private
449 | @param {Boolean} Repeat button state.
450 | */
451 | _onRepeatStateChange ( isOn ) { this._props.isRepeat = isOn; }
452 | /*
453 | Method that is invoked on bounds switch state change.
454 | @private
455 | @param {Boolean} Bounds state.
456 | */
457 | _boundsStateChange ( isOn ) {
458 | this.playerSlider._props.isBounds = isOn;
459 | this.playerSlider[ `${ ( isOn ) ? 'enable' : 'disable' }Bounds` ]();
460 | this._props.isBounds = isOn;
461 | }
462 | /*
463 | Method that is invoked on speed value change.
464 | @private
465 | @param {Number} Speed value.
466 | @param {Number} Slider progress.
467 | */
468 | _onSpeedChange(speed, progress) {
469 | this._props[ 'raw-speed' ] = progress;
470 | this._props.speed = speed;
471 | this._sysTween.setSpeed(speed);
472 | }
473 | /*
474 | Method that is invoked on speed state change.
475 | @private
476 | @param {Boolean} Speed control state.
477 | */
478 | _onIsSpeed(isOn) { this._props.isSpeed = isOn; }
479 | /*
480 | Method that is invoked on timeline's left bound progress.
481 | @private
482 | @param {Number} Progress value [0...1].
483 | */
484 | _onLeftProgress(progress) { this._props.leftBound = progress; }
485 | /*
486 | Method that is invoked on timeline progress.
487 | @private
488 | @param {Number} Progress value [0...1].
489 | */
490 | _onProgress(progress) {
491 | this._props.progress = progress;
492 | // if timeline was reset - refresh it's state
493 | // by incremental updates until progress (0 always)
494 | // if ( !this.timeline._prevTime && progress > 0 ) {
495 | // let start = 0;
496 | // do {
497 | // this.timeline.setProgress( start );
498 | // start += this._props.precision;
499 | // } while ( start + this._props.precision < progress );
500 | // }
501 | // console.log(`timeline.setProgress: ${progress}`);
502 | this.timeline.setProgress(progress);
503 | }
504 | /*
505 | Method that is invoked on timeline's right bound progress.
506 | @private
507 | @param {Number} Progress value [0...1].
508 | */
509 | _onRightProgress ( progress ) { this._props.rightBound = progress; }
510 | /*
511 | Method that is invoked on window unload.
512 | @private
513 | @param {Object} Original even object.
514 | */
515 | _onUnload ( e ) {
516 | if ( !this._props.isSaveState ) {
517 | return localStorage.removeItem( this._localStorage );
518 | }
519 |
520 | const props = { ...this._props };
521 | delete props.parent;
522 | delete props.className;
523 | delete props.isSaveState;
524 | delete props.precision;
525 |
526 | localStorage.setItem(this._localStorage, JSON.stringify( props ) );
527 | }
528 | /*
529 | Method that returns the second argument if the first one isn't set.
530 | @private
531 | @param {Any} Property to set.
532 | @param {Any} Property to return as fallback.
533 | @returns {Any} If set - the first property, if not - the second.
534 | */
535 | _fallbackTo ( prop, fallback ) { return ( prop != null ) ? prop : fallback; }
536 | /*
537 | Method to get bound regarding isBound option.
538 | @private
539 | @param {String} Bound name.
540 | */
541 | _getBound ( boundName ) {
542 | let p = this._props,
543 | fallback = ( boundName === 'left' ) ? 0 : 1;
544 |
545 | return ( p.isBounds ) ? p[ `${ boundName }Bound` ] : fallback;
546 | }
547 | /*
548 | Method to defer a method.
549 | @private
550 | @param {Function} Function that should be defered.
551 | */
552 | _defer (fn) { setTimeout( fn.bind(this), 1 ); }
553 | /*
554 | Method to generate hash code.
555 | @private
556 | @return {String} Hash code.
557 | */
558 | _hashCode ( str ) {
559 | var hash = 0, i, chr, len;
560 | if (str.length === 0) return hash;
561 | for (i = 0, len = str.length; i < len; i++) {
562 | chr = str.charCodeAt(i);
563 | hash = ((hash << 5) - hash) + chr;
564 | hash |= 0; // Convert to 32bit integer
565 | }
566 | return Math.abs( hash );
567 | }
568 |
569 | /*
570 | Method to determine if variable is a function
571 | @private
572 | @param {Function} Function to be guarenteed.
573 | @return {Boolean} true/false whether variable reference was a function
574 | */
575 | _isFunction (fn) { return typeof fn === 'function'; }
576 | }
577 |
578 | if ( (typeof define === "function") && define.amd ) {
579 | define(function () { return MojsPlayer; });
580 | }
581 | if ( (typeof module === "object") && (typeof module.exports === "object") ) {
582 | module.exports = MojsPlayer;
583 | }
584 |
585 | let _global = ( typeof global !== 'undefined' ) ? global : window;
586 | _global.MojsPlayer = MojsPlayer;
587 |
588 | export default MojsPlayer;
589 |
--------------------------------------------------------------------------------
/lib/components/bounds-button.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _repeatButton = require('./repeat-button');
18 |
19 | var _repeatButton2 = _interopRequireDefault(_repeatButton);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | // require('css/blocks/repeat-button.postcss.css');
24 | // let CLASSES = require('css/blocks/repeat-button.postcss.css.json');
25 |
26 | var BoundsButton = function (_RepeatButton) {
27 | (0, _inherits3.default)(BoundsButton, _RepeatButton);
28 |
29 | function BoundsButton() {
30 | (0, _classCallCheck3.default)(this, BoundsButton);
31 | return (0, _possibleConstructorReturn3.default)(this, _RepeatButton.apply(this, arguments));
32 | }
33 |
34 | /*
35 | Method to declare defaults.
36 | @private
37 | @overrides @ RepeatButton
38 | */
39 | BoundsButton.prototype._declareDefaults = function _declareDefaults() {
40 | _RepeatButton.prototype._declareDefaults.call(this);
41 | this._defaults.icon = 'bounds';
42 | this._defaults.title = 'progress bounds (alt + b)';
43 | };
44 |
45 | return BoundsButton;
46 | }(_repeatButton2.default);
47 |
48 | exports.default = BoundsButton;
--------------------------------------------------------------------------------
/lib/components/button-switch.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _button = require('./button');
18 |
19 | var _button2 = _interopRequireDefault(_button);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | require('../../css/blocks/button-switch.postcss.css');
24 | var CLASSES = require('../../css/blocks/button-switch.postcss.css.json');
25 |
26 | var ButtonSwitch = function (_Button) {
27 | (0, _inherits3.default)(ButtonSwitch, _Button);
28 |
29 | function ButtonSwitch() {
30 | (0, _classCallCheck3.default)(this, ButtonSwitch);
31 | return (0, _possibleConstructorReturn3.default)(this, _Button.apply(this, arguments));
32 | }
33 |
34 | /*
35 | Method to declare _defaults.
36 | @private
37 | @overrides @ Button
38 | */
39 | ButtonSwitch.prototype._declareDefaults = function _declareDefaults() {
40 | _Button.prototype._declareDefaults.call(this);
41 | this._defaults.isOn = false;
42 | this._defaults.onStateChange = null;
43 | };
44 | /*
45 | Method to set the state to `true`.
46 | @public
47 | @param {Boolean} If should invoke callback.
48 | */
49 |
50 |
51 | ButtonSwitch.prototype.on = function on() {
52 | var isCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
53 |
54 | // set to true because the next step is toggle
55 | this._props.isOn = true;
56 | this._reactOnStateChange(isCallback);
57 | };
58 | /*
59 | Method to set the state to `false`.
60 | @public
61 | @param {Boolean} If should invoke callback.
62 | */
63 |
64 |
65 | ButtonSwitch.prototype.off = function off() {
66 | var isCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
67 |
68 | // set to true because the next step is toggle
69 | this._props.isOn = false;
70 | this._reactOnStateChange(isCallback);
71 | };
72 |
73 | // ---
74 |
75 | /*
76 | Initial render method.
77 | @private
78 | @overrides @ Button
79 | @returns this
80 | */
81 |
82 |
83 | ButtonSwitch.prototype._render = function _render() {
84 | _Button.prototype._render.call(this);
85 | this.el.classList.add(CLASSES['button-switch']);
86 | this._setState();
87 | this._reactOnStateChange();
88 | };
89 | /*
90 | Method to invoke onPointerUp callback if excist.
91 | @private
92 | @overrides @ Button
93 | @param {Object} Original event object.
94 | */
95 |
96 |
97 | ButtonSwitch.prototype._pointerUp = function _pointerUp(e) {
98 | if (!this.wasTouched) {
99 | this.wasTouched = false;
100 | e.stopPropagation();
101 | return;
102 | }
103 | this._changeState();
104 | _Button.prototype._pointerUp.call(this, e);
105 | };
106 | /*
107 | Method to switch icons.
108 | @private
109 | */
110 |
111 |
112 | ButtonSwitch.prototype._changeState = function _changeState() {
113 | this._props.isOn = !this._props.isOn;
114 | this._reactOnStateChange();
115 | };
116 | /*
117 | Method to react on state change.
118 | @private
119 | @param {Boolean} If should invoke callback.
120 | */
121 |
122 |
123 | ButtonSwitch.prototype._reactOnStateChange = function _reactOnStateChange() {
124 | var isCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
125 |
126 | if (isCallback) {
127 | this._callIfFunction(this._props.onStateChange, this._props.isOn);
128 | }
129 | this._setState();
130 | };
131 | /*
132 | Method that have been called on switch state change.
133 | @private
134 | */
135 |
136 |
137 | ButtonSwitch.prototype._setState = function _setState() {
138 | // console.log('change');
139 | };
140 |
141 | return ButtonSwitch;
142 | }(_button2.default);
143 |
144 | exports.default = ButtonSwitch;
--------------------------------------------------------------------------------
/lib/components/button.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _module = require('./module');
18 |
19 | var _module2 = _interopRequireDefault(_module);
20 |
21 | var _hammerjs = require('hammerjs');
22 |
23 | var _hammerjs2 = _interopRequireDefault(_hammerjs);
24 |
25 | var _ripple = require('./ripple');
26 |
27 | var _ripple2 = _interopRequireDefault(_ripple);
28 |
29 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30 |
31 | require('../../css/blocks/button.postcss.css');
32 | var CLASSES = require('../../css/blocks/button.postcss.css.json');
33 |
34 | var Button = function (_Module) {
35 | (0, _inherits3.default)(Button, _Module);
36 |
37 | function Button() {
38 | (0, _classCallCheck3.default)(this, Button);
39 | return (0, _possibleConstructorReturn3.default)(this, _Module.apply(this, arguments));
40 | }
41 |
42 | /*
43 | Method to declare defaults for the module.
44 | @private
45 | @overrides @ Module
46 | */
47 | Button.prototype._declareDefaults = function _declareDefaults() {
48 | _Module.prototype._declareDefaults.call(this);
49 | this._defaults.link = null;
50 | this._defaults.title = '';
51 | this._defaults.target = null;
52 | this._defaults.onPointerDown = null;
53 | this._defaults.onPointerUp = null;
54 | this._defaults.onDoubleTap = null;
55 | };
56 | /*
57 | Initial render method.
58 | @private
59 | @overrides @ Module
60 | */
61 |
62 |
63 | Button.prototype._render = function _render() {
64 | var p = this._props,
65 | className = 'button',
66 | tagName = p.link != null ? 'a' : 'div';
67 |
68 | this._addMainElement(tagName);
69 | this.el.classList.add(CLASSES[className]);
70 | this.el.setAttribute('title', p.title);
71 | p.link && this.el.setAttribute('href', p.link);
72 | p.link && p.target && this.el.setAttribute('target', p.target);
73 | this._addListeners();
74 |
75 | this._createRipple();
76 | };
77 | /*
78 | Method to create ripple.
79 | @private
80 | */
81 |
82 |
83 | Button.prototype._createRipple = function _createRipple() {
84 | this.ripple = new _ripple2.default({
85 | className: CLASSES['button__ripple'],
86 | parent: this.el
87 | });
88 | };
89 | /*
90 | Method to add event listeners to the icon.
91 | @private
92 | */
93 |
94 |
95 | Button.prototype._addListeners = function _addListeners() {
96 | this._addPointerDownEvent(this.el, this._pointerDown.bind(this));
97 | this._addPointerUpEvent(this.el, this._pointerUp.bind(this));
98 | this._addPointerUpEvent(document, this._pointerCancel.bind(this));
99 | (0, _hammerjs2.default)(this.el).on('doubletap', this._doubleTap.bind(this));
100 | };
101 | /*
102 | Method to invoke onPointerDown callback if exist.
103 | @private
104 | @param {Object} Original event object.
105 | */
106 |
107 |
108 | Button.prototype._pointerDown = function _pointerDown(e) {
109 | this.wasTouched = true;
110 | this._callIfFunction(this._props.onPointerDown);
111 | this.ripple._hold(e);
112 | };
113 | /*
114 | Method to invoke onPointerUp callback if exist.
115 | @private
116 | @param {Object} Original event object.
117 | */
118 |
119 |
120 | Button.prototype._pointerUp = function _pointerUp(e) {
121 | if (!this.wasTouched) {
122 | e.stopPropagation();return;
123 | }
124 |
125 | this.wasTouched = false;
126 | this._callIfFunction(this._props.onPointerUp);
127 | this.ripple._release();
128 | e.preventDefault();
129 | return false;
130 | };
131 | /*
132 | Method to invoke onPointerCancel callback if exist.
133 | @private
134 | @param {Object} Original event object.
135 | */
136 |
137 |
138 | Button.prototype._pointerCancel = function _pointerCancel(e) {
139 | if (!this.wasTouched) {
140 | return;
141 | };
142 | this.wasTouched = false;
143 | this.ripple._cancel();
144 | };
145 | /*
146 | Method to invoke onDoubleTap callback if exist.
147 | @private
148 | @param {Object} Original event object.
149 | */
150 |
151 |
152 | Button.prototype._doubleTap = function _doubleTap(e) {
153 | this._callIfFunction(this._props.onDoubleTap);
154 | };
155 |
156 | return Button;
157 | }(_module2.default);
158 |
159 | exports.default = Button;
--------------------------------------------------------------------------------
/lib/components/handle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _module = require('./module');
18 |
19 | var _module2 = _interopRequireDefault(_module);
20 |
21 | var _hammerjs = require('hammerjs');
22 |
23 | var _hammerjs2 = _interopRequireDefault(_hammerjs);
24 |
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26 |
27 | require('../../css/blocks/handle.postcss.css');
28 | var CLASSES = require('../../css/blocks/handle.postcss.css.json');
29 |
30 | var Handle = function (_Module) {
31 | (0, _inherits3.default)(Handle, _Module);
32 |
33 | function Handle() {
34 | (0, _classCallCheck3.default)(this, Handle);
35 | return (0, _possibleConstructorReturn3.default)(this, _Module.apply(this, arguments));
36 | }
37 |
38 | /*
39 | Method to declare _defaults.
40 | @private
41 | @overrides @ Module
42 | */
43 | Handle.prototype._declareDefaults = function _declareDefaults() {
44 | _Module.prototype._declareDefaults.call(this);
45 | this._defaults.minBound = 0;
46 | this._defaults.maxBound = 1;
47 | this._defaults.isBound = false;
48 | this._defaults.isInversed = false;
49 | this._defaults.direction = 'x';
50 | this._defaults.onSeekStart = null;
51 | this._defaults.onSeekEnd = null;
52 | this._defaults.onProgress = null;
53 | this._defaults.snapPoint = 0;
54 | this._defaults.snapStrength = 0;
55 | };
56 | /*
57 | Method to set handle progress.
58 | @public
59 | @param {Number} Progress [0...1].
60 | @param {Boolean} If should invoke onProgress callback.
61 | @returns this.
62 | */
63 |
64 |
65 | Handle.prototype.setProgress = function setProgress(progress) {
66 | var isCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
67 |
68 | var shift = this._progressToShift(progress);
69 | this._setShift(shift, isCallback);
70 | // calc delta and save it
71 | this._delta = shift - this._shift;
72 | this._saveDelta();
73 | return this;
74 | };
75 | /*
76 | Method to set bounds of progress.
77 | @public
78 | @param {Number} Min bound to set [0...1].
79 | @param {Number} Max bound to set [0...1].
80 | @returns this.
81 | */
82 |
83 |
84 | Handle.prototype.setBounds = function setBounds(min, max) {
85 | this.setMinBound(min);
86 | this.setMaxBound(max);
87 | return this;
88 | };
89 | /*
90 | Method to set min bound of progress.
91 | @public
92 | @param {Number} Min bound to set [0...1].
93 | @returns this.
94 | */
95 |
96 |
97 | Handle.prototype.setMinBound = function setMinBound(min) {
98 | this._props.minBound = Math.max(min, 0);
99 | if (this._progress < min) {
100 | this.setProgress(min);
101 | }
102 | return this;
103 | };
104 | /*
105 | Method to set max bound of progress.
106 | @public
107 | @param {Number} Max bound to set [0...1].
108 | @returns this.
109 | */
110 |
111 |
112 | Handle.prototype.setMaxBound = function setMaxBound(max) {
113 | this._props.maxBound = Math.min(max, 1);
114 | if (this._progress > max) {
115 | this.setProgress(max);
116 | }
117 | return this;
118 | };
119 | /*
120 | Method to declare properties.
121 | @private
122 | @overrides @ Module.
123 | */
124 |
125 |
126 | Handle.prototype._vars = function _vars() {
127 | // `progress` of the handle [0..1]
128 | this._progress = 0;
129 | // `shift` of the handle ( position in `px` )
130 | this._shift = 0;
131 | // `delta` deviation from the current `shift`
132 | this._delta = 0;
133 | };
134 | /*
135 | Method to set handle shift.
136 | @private
137 | @param {Number} Shift in `px`.
138 | @param {Boolean} If should invoke onProgress callback.
139 | @returns {Number}.
140 | */
141 |
142 |
143 | Handle.prototype._setShift = function _setShift(shift) {
144 | var isCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
145 |
146 | var p = this._props,
147 | minBound = p.minBound * this._maxWidth,
148 | maxBound = p.maxBound * this._maxWidth;
149 |
150 | shift = this.clamp(shift, minBound, maxBound);
151 | this._applyShift(shift);
152 | if (isCallback) {
153 | this._onProgress(shift);
154 | } else {
155 | this._progress = this._shiftToProgress(shift);
156 | }
157 | return shift;
158 | };
159 |
160 | /**
161 | * clamp - functiboundson to clamp a `value` between `min` and `max`
162 | *
163 | * @param {Number} value Value to clamp.
164 | * @param {Number} min Min bound
165 | * @param {Number} max Max bound
166 | * @return {Number} Clamped value.
167 | */
168 |
169 |
170 | Handle.prototype.clamp = function clamp(value, min, max) {
171 | return Math.min(Math.max(value, min), max);
172 | };
173 |
174 | /*
175 | Method to apply shift to the DOMElement.
176 | @private
177 | @param {Number} Shift in pixels.
178 | */
179 |
180 |
181 | Handle.prototype._applyShift = function _applyShift(shift) {
182 | var p = this._props;
183 | // translateZ(0)
184 | this.el.style.transform = p.direction === 'x' ? 'translateX( ' + shift + 'px )' : 'translateY( ' + -shift + 'px )';
185 | };
186 | /*
187 | Method to get max width of the parent.
188 | @private
189 | */
190 |
191 |
192 | Handle.prototype._getMaxWidth = function _getMaxWidth() {
193 | var p = this._props,
194 | parent = p.parent;
195 |
196 | this._maxWidth = p.direction === 'x' ? parent.clientWidth : parent.clientHeight;
197 | };
198 | /*
199 | Method to render the component.
200 | @private
201 | @overrides @ Module
202 | */
203 |
204 |
205 | Handle.prototype._render = function _render() {
206 | _Module.prototype._render.call(this);
207 | this._addElements();
208 | this._getMaxWidth();
209 | this._hammerTime();
210 | };
211 | /*
212 | Method to classes on `this.el`.
213 | @private
214 | @overrides @ Module
215 | */
216 |
217 |
218 | Handle.prototype._addMainClasses = function _addMainClasses() {
219 | _Module.prototype._addMainClasses.call(this);
220 |
221 | var p = this._props,
222 | classList = this.el.classList;
223 |
224 | classList.add(CLASSES.handle);
225 | if (p.isBound) {
226 | classList.add(CLASSES['is-bound']);
227 | }
228 | if (p.isInversed) {
229 | classList.add(CLASSES['is-inversed']);
230 | }
231 | };
232 | /*
233 | Method to add DOM elements on render.
234 | @private
235 | */
236 |
237 |
238 | Handle.prototype._addElements = function _addElements() {
239 | var inner = this._createElement('div'),
240 | shadow = this._createElement('div');
241 |
242 | inner.classList.add('' + CLASSES.handle__inner);
243 | shadow.classList.add('' + CLASSES.handle__shadow);
244 | this.el.appendChild(shadow);
245 | this.el.appendChild(inner);
246 | };
247 | /*
248 | Method to initialize HammerJS an set up all even listeners.
249 | @private
250 | */
251 |
252 |
253 | Handle.prototype._hammerTime = function _hammerTime() {
254 | var p = this._props,
255 | direction = p.direction === 'x' ? 'HORIZONTAL' : 'VERTICAL',
256 | hm = new _hammerjs2.default.Manager(this.el, {
257 | recognizers: [[_hammerjs2.default.Pan, { direction: _hammerjs2.default['DIRECTION_' + direction] }]]
258 | });
259 |
260 | hm.on('pan', this._pan.bind(this));
261 | hm.on('panend', this._panEnd.bind(this));
262 | this._addPointerDownEvent(this.el, this._pointerDown.bind(this));
263 | this._addPointerUpEvent(this.el, this._pointerUp.bind(this));
264 | // add listener on document to cover edge cases
265 | // like when you press -> leave the element -> release
266 | this._addPointerUpEvent(document, this._pointerUpDoc.bind(this));
267 |
268 | window.addEventListener('resize', this._onWindowResize.bind(this));
269 | };
270 | /*
271 | Callback for pan end on main el.
272 | @private
273 | @param {Object} Original event object.
274 | */
275 |
276 |
277 | Handle.prototype._pan = function _pan(e) {
278 | var p = this._props;
279 | this._delta = p.direction === 'x' ? e.deltaX : -e.deltaY;
280 | // get progress from the shift to undestand how far is the snapPoint
281 | var shift = this._shift + this._delta,
282 | proc = this._shiftToProgress(shift);
283 | // if progress is around snapPoint set it to the snap point
284 | proc = Math.abs(proc - p.snapPoint) < p.snapStrength ? p.snapPoint : proc;
285 | // recalculate the progress to shift and set it
286 | this._setShift(this._progressToShift(proc));
287 | };
288 | /*
289 | Callback for pan end on main el.
290 | @private
291 | @param {Object} Original event object.
292 | */
293 |
294 |
295 | Handle.prototype._panEnd = function _panEnd(e) {
296 | this._saveDelta();
297 | this._callIfFunction(this._props.onSeekEnd, e);
298 | };
299 | /*
300 | Callback for pointer down on main el.
301 | @private
302 | @param {Object} Original event object.
303 | */
304 |
305 |
306 | Handle.prototype._pointerDown = function _pointerDown(e) {
307 | var p = this._props;
308 | this._isPointerDown = true;
309 | this._callIfFunction(p.onSeekStart, e);
310 | };
311 | /*
312 | Callback for pointer up on main el.
313 | @private
314 | @param {Object} Original event object.
315 | */
316 |
317 |
318 | Handle.prototype._pointerUp = function _pointerUp(e) {
319 | this._callIfFunction(this._props.onSeekEnd, e);
320 | e.preventDefault();
321 | return false;
322 | };
323 | /*
324 | Callback for pointer up on document.
325 | @private
326 | @param {Object} Original event object.
327 | */
328 |
329 |
330 | Handle.prototype._pointerUpDoc = function _pointerUpDoc(e) {
331 | if (!this._isPointerDown) {
332 | return;
333 | }
334 | this._callIfFunction(this._props.onSeekEnd, e);
335 | this._isPointerDown = false;
336 | };
337 | /*
338 | Method to add _delta to _shift.
339 | @private
340 | */
341 |
342 |
343 | Handle.prototype._saveDelta = function _saveDelta() {
344 | this._shift += this._delta;
345 | };
346 | /*
347 | Method to call onProgress callback.
348 | @private
349 | @param {Number} Shift in `px`.
350 | */
351 |
352 |
353 | Handle.prototype._onProgress = function _onProgress(shift) {
354 | var p = this._props,
355 | progress = this._shiftToProgress(shift);
356 |
357 | if (this._progress !== progress) {
358 | this._progress = progress;
359 | if (this._isFunction(p.onProgress)) {
360 | p.onProgress.call(this, progress);
361 | }
362 | }
363 | };
364 | /*
365 | Method to recalc shift to progress.
366 | @private
367 | @param {Number} Shift in `px`.
368 | @returns {Number} Progress [0...1].
369 | */
370 |
371 |
372 | Handle.prototype._shiftToProgress = function _shiftToProgress(shift) {
373 | return shift / this._maxWidth;
374 | };
375 | /*
376 | Method to progress shift to shift.
377 | @private
378 | @param {Number} Progress [0...1].
379 | @returns {Number} Shift in `px`.
380 | */
381 |
382 |
383 | Handle.prototype._progressToShift = function _progressToShift(progress) {
384 | return progress * this._maxWidth;
385 | };
386 | /*
387 | Callback for window resize event.
388 | @private
389 | @param {Object} Original event object.
390 | */
391 |
392 |
393 | Handle.prototype._onWindowResize = function _onWindowResize(e) {
394 | this._getMaxWidth();
395 | this.setProgress(this._progress);
396 | };
397 |
398 | return Handle;
399 | }(_module2.default);
400 |
401 | exports.default = Handle;
--------------------------------------------------------------------------------
/lib/components/hide-button.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _buttonSwitch = require('./button-switch');
18 |
19 | var _buttonSwitch2 = _interopRequireDefault(_buttonSwitch);
20 |
21 | var _icon = require('./icon');
22 |
23 | var _icon2 = _interopRequireDefault(_icon);
24 |
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26 |
27 | require('../../css/blocks/hide-button.postcss.css');
28 | var CLASSES = require('../../css/blocks/hide-button.postcss.css.json'),
29 | className = 'hide-button';
30 |
31 | var HideButton = function (_ButtonSwitch) {
32 | (0, _inherits3.default)(HideButton, _ButtonSwitch);
33 |
34 | function HideButton() {
35 | (0, _classCallCheck3.default)(this, HideButton);
36 | return (0, _possibleConstructorReturn3.default)(this, _ButtonSwitch.apply(this, arguments));
37 | }
38 |
39 | HideButton.prototype._declareDefaults = function _declareDefaults() {
40 | _ButtonSwitch.prototype._declareDefaults.call(this);
41 | this._defaults.title = 'hide (alt + h)';
42 | };
43 | /*
44 | Initial render method.
45 | @private
46 | @overrides @ Button
47 | @returns this
48 | */
49 |
50 |
51 | HideButton.prototype._render = function _render() {
52 | _ButtonSwitch.prototype._render.call(this);
53 | this.el.classList.add(CLASSES[className]);
54 | this._addIcon();
55 | };
56 | /*
57 | Method to add icon.
58 | @private
59 | */
60 |
61 |
62 | HideButton.prototype._addIcon = function _addIcon() {
63 | this.icon = new _icon2.default({
64 | parent: this.el,
65 | className: CLASSES[className + '__icon'],
66 | shape: 'hide',
67 | prefix: this._props.prefix
68 | });
69 | };
70 | /*
71 | Method that have been called on switch state change.
72 | @private
73 | @override @ ButtonSwitch
74 | */
75 |
76 |
77 | HideButton.prototype._setState = function _setState() {
78 | var method = this._props.isOn ? 'add' : 'remove';
79 | this.el.classList[method](CLASSES['is-hidden']);
80 | };
81 |
82 | return HideButton;
83 | }(_buttonSwitch2.default);
84 |
85 | exports.default = HideButton;
--------------------------------------------------------------------------------
/lib/components/icon-button.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _icon = require('./icon');
18 |
19 | var _icon2 = _interopRequireDefault(_icon);
20 |
21 | var _button = require('./button');
22 |
23 | var _button2 = _interopRequireDefault(_button);
24 |
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26 |
27 | require('../../css/blocks/icon-button.postcss.css');
28 | var CLASSES = require('../../css/blocks/icon-button.postcss.css.json');
29 |
30 | var IconButton = function (_Button) {
31 | (0, _inherits3.default)(IconButton, _Button);
32 |
33 | function IconButton() {
34 | (0, _classCallCheck3.default)(this, IconButton);
35 | return (0, _possibleConstructorReturn3.default)(this, _Button.apply(this, arguments));
36 | }
37 |
38 | /*
39 | Method to declare _defaults.
40 | @private
41 | @overrides @ Button
42 | */
43 | IconButton.prototype._declareDefaults = function _declareDefaults() {
44 | _Button.prototype._declareDefaults.call(this);
45 | this._defaults.icon = '';
46 | this._defaults.iconClass = '';
47 | };
48 | /*
49 | Initial render method.
50 | @private
51 | @overrides @ Button
52 | @returns this
53 | */
54 |
55 |
56 | IconButton.prototype._render = function _render() {
57 | _Button.prototype._render.call(this);
58 | var p = this._props,
59 | className = 'icon-button';
60 | this.el.classList.add(CLASSES[className]);
61 |
62 | var icon = new _icon2.default({
63 | shape: p.icon,
64 | parent: this.el,
65 | className: [CLASSES['icon'], p.iconClass],
66 | prefix: p.prefix
67 | });
68 | };
69 |
70 | return IconButton;
71 | }(_button2.default);
72 |
73 | exports.default = IconButton;
--------------------------------------------------------------------------------
/lib/components/icon-fork.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _buttonSwitch = require('./button-switch');
18 |
19 | var _buttonSwitch2 = _interopRequireDefault(_buttonSwitch);
20 |
21 | var _icon = require('./icon');
22 |
23 | var _icon2 = _interopRequireDefault(_icon);
24 |
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26 |
27 | // import HammerJS from 'hammerjs'
28 |
29 | require('../../css/blocks/icon-fork.postcss.css');
30 | var CLASSES = require('../../css/blocks/icon-fork.postcss.css.json');
31 |
32 | var IconFork = function (_ButtonSwitch) {
33 | (0, _inherits3.default)(IconFork, _ButtonSwitch);
34 |
35 | function IconFork() {
36 | (0, _classCallCheck3.default)(this, IconFork);
37 | return (0, _possibleConstructorReturn3.default)(this, _ButtonSwitch.apply(this, arguments));
38 | }
39 |
40 | /*
41 | Initial render method.
42 | @private
43 | @overrides @ Icon
44 | @returns this
45 | */
46 | IconFork.prototype._render = function _render() {
47 | _ButtonSwitch.prototype._render.call(this);
48 | this.el.classList.add(CLASSES['icon-fork']);
49 | var p = this._props,
50 | prefix = p.prefix,
51 | parent = this.el,
52 | className = CLASSES.icon;
53 |
54 | this.icon1 = new _icon2.default({ shape: p.icon1, prefix: prefix, parent: parent, className: className });
55 | this.icon2 = new _icon2.default({ shape: p.icon2, prefix: prefix, parent: parent, className: className });
56 | };
57 | /*
58 | Method that should be called on state change.
59 | @private
60 | @override @ IconSwitch
61 | */
62 |
63 |
64 | IconFork.prototype._setState = function _setState() {
65 | var p = this._props,
66 | classList = this.el.classList,
67 | method = p.isOn ? 'add' : 'remove';
68 |
69 | classList[method](CLASSES['is-on']);
70 | };
71 |
72 | return IconFork;
73 | }(_buttonSwitch2.default);
74 |
75 | exports.default = IconFork;
--------------------------------------------------------------------------------
/lib/components/icon.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _module = require('./module');
18 |
19 | var _module2 = _interopRequireDefault(_module);
20 |
21 | var _hammerjs = require('hammerjs');
22 |
23 | var _hammerjs2 = _interopRequireDefault(_hammerjs);
24 |
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26 |
27 | require('../../css/blocks/icon.postcss.css');
28 | var CLASSES = require('../../css/blocks/icon.postcss.css.json');
29 |
30 | var Icon = function (_Module) {
31 | (0, _inherits3.default)(Icon, _Module);
32 |
33 | function Icon() {
34 | (0, _classCallCheck3.default)(this, Icon);
35 | return (0, _possibleConstructorReturn3.default)(this, _Module.apply(this, arguments));
36 | }
37 |
38 | /*
39 | Method to declare _defaults.
40 | @private
41 | @overrides @ Module
42 | */
43 | Icon.prototype._declareDefaults = function _declareDefaults() {
44 | _Module.prototype._declareDefaults.call(this);
45 | this._defaults.shape = '';
46 | this._defaults.size = 'x1';
47 | this.NS = 'http://www.w3.org/2000/svg';
48 | };
49 | /*
50 | Initial render method.
51 | @private
52 | @overrides @ Module
53 | @returns this
54 | */
55 |
56 |
57 | Icon.prototype._render = function _render() {
58 | this._addMainElement();
59 | this.el.classList.add(CLASSES.icon);
60 | this.el.classList.add(CLASSES['is-' + this._props.size]);
61 | this.el.setAttribute('data-component', 'icon');
62 | this._renderIcon();
63 | };
64 | /*
65 | Method to render svg icon into the el.
66 | @private
67 | */
68 |
69 |
70 | Icon.prototype._renderIcon = function _renderIcon() {
71 | var p = this._props,
72 | svg = document.createElementNS(this.NS, 'svg'),
73 | content = '';
74 | svg.setAttribute('viewBox', '0 0 32 32');
75 | this._addSVGHtml(svg, content);
76 | this.el.appendChild(svg);
77 | };
78 | /*
79 | Add HTML to SVG element.
80 | @private
81 | @param {Object} SVG node.
82 | @param {String} SVG content to add.
83 | */
84 |
85 |
86 | Icon.prototype._addSVGHtml = function _addSVGHtml(svg, content) {
87 | var receptacle = this._createElement('div'),
88 | svgfragment = '';
89 | receptacle.innerHTML = svgfragment;
90 | var nodes = Array.prototype.slice.call(receptacle.childNodes[0].childNodes);
91 | for (var i = 0; i < nodes.length; i++) {
92 | svg.appendChild(nodes[i]);
93 | }
94 | };
95 |
96 | return Icon;
97 | }(_module2.default);
98 |
99 | exports.default = Icon;
--------------------------------------------------------------------------------
/lib/components/icons.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _module = require('./module');
18 |
19 | var _module2 = _interopRequireDefault(_module);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | var Icons = function (_Module) {
24 | (0, _inherits3.default)(Icons, _Module);
25 |
26 | function Icons() {
27 | (0, _classCallCheck3.default)(this, Icons);
28 | return (0, _possibleConstructorReturn3.default)(this, _Module.apply(this, arguments));
29 | }
30 |
31 | /*
32 | Initial render method.
33 | @private
34 | @overrides @ Module
35 | */
36 | Icons.prototype._render = function _render() {
37 | this.el = this._createElement('div');
38 | this.el.innerHTML = this.getIcons();
39 | this.el.setAttribute('id', this._props.prefix + 'icons');
40 | this._prependChild(document.body, this.el);
41 | };
42 | /*
43 | Method to get icons shapes.
44 | @private
45 | */
46 |
47 |
48 | Icons.prototype.getIcons = function getIcons() {
49 | var prefix = this._props.prefix;
50 | return '';
51 | };
52 |
53 | return Icons;
54 | }(_module2.default);
55 |
56 | exports.default = Icons;
--------------------------------------------------------------------------------
/lib/components/label-button.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _buttonSwitch = require('./button-switch');
18 |
19 | var _buttonSwitch2 = _interopRequireDefault(_buttonSwitch);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | require('../../css/blocks/label-button.postcss.css');
24 | var CLASSES = require('../../css/blocks/label-button.postcss.css.json');
25 |
26 | var LabelButton = function (_ButtonSwitch) {
27 | (0, _inherits3.default)(LabelButton, _ButtonSwitch);
28 |
29 | function LabelButton() {
30 | (0, _classCallCheck3.default)(this, LabelButton);
31 | return (0, _possibleConstructorReturn3.default)(this, _ButtonSwitch.apply(this, arguments));
32 | }
33 |
34 | /*
35 | Method to declare defaults.
36 | @private
37 | @overrides @ OpacitySwitch
38 | */
39 | LabelButton.prototype._declareDefaults = function _declareDefaults() {
40 | _ButtonSwitch.prototype._declareDefaults.call(this);
41 | this._defaults.title = 'speed (reset: alt + 1)';
42 | };
43 | /*
44 | Method to populate the label with progress text.
45 | @public
46 | @param {String} Text to set.
47 | */
48 |
49 |
50 | LabelButton.prototype.setLabelText = function setLabelText(text) {
51 | this.label.innerHTML = text;
52 | };
53 |
54 | /*
55 | ^ PUBLIC ^
56 | v PPRIVATE v
57 | */
58 |
59 | /*
60 | Initial render method.
61 | @private
62 | @overrides @ Button
63 | @returns this
64 | */
65 |
66 |
67 | LabelButton.prototype._render = function _render() {
68 | _ButtonSwitch.prototype._render.call(this);
69 | this._addClass(this.el, CLASSES['label-button']);
70 | this._addLabel();
71 | // this.setLabelText( this._props.progress );
72 | };
73 | /*
74 | Method to add label to the `el`.
75 | @private
76 | */
77 |
78 |
79 | LabelButton.prototype._addLabel = function _addLabel() {
80 | this.label = this._createElement('div');
81 | this.label.classList.add(CLASSES['label-button__label']);
82 | this.el.appendChild(this.label);
83 | };
84 |
85 | return LabelButton;
86 | }(_buttonSwitch2.default);
87 |
88 | exports.default = LabelButton;
--------------------------------------------------------------------------------
/lib/components/module.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _typeof2 = require('babel-runtime/helpers/typeof');
6 |
7 | var _typeof3 = _interopRequireDefault(_typeof2);
8 |
9 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
10 |
11 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | /*
16 | Base class for all modules.
17 | Extends _defaults to _props
18 | */
19 | var Module = function () {
20 | /*
21 | constructor method calls scaffolding methods.
22 | */
23 | function Module() {
24 | var o = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
25 | (0, _classCallCheck3.default)(this, Module);
26 |
27 | this._o = o;
28 | this._index = this._o.index || 0;
29 | this._declareDefaults();
30 | this._extendDefaults();
31 | this._vars();
32 | this._render();
33 | }
34 | /*
35 | Method to declare defaults.
36 | @private
37 | */
38 |
39 |
40 | Module.prototype._declareDefaults = function _declareDefaults() {
41 | this._defaults = {
42 | className: '',
43 | parent: document.body,
44 | isPrepend: false,
45 | isRipple: false,
46 | prefix: ''
47 | };
48 | };
49 | /*
50 | Method to add pointer down even listener to el.
51 | @param {Object} HTMLElement to add event listener on.
52 | @param {Function} Event listener callback.
53 | */
54 |
55 |
56 | Module.prototype._addPointerDownEvent = function _addPointerDownEvent(el, fn) {
57 | if (window.navigator.msPointerEnabled) {
58 | el.addEventListener('MSPointerDown', fn);
59 | } else if (window.ontouchstart !== undefined) {
60 | el.addEventListener('touchstart', fn);
61 | el.addEventListener('mousedown', fn);
62 | } else {
63 | el.addEventListener('mousedown', fn);
64 | }
65 | };
66 | /*
67 | Method to add pointer up even listener to el.
68 | @param {Object} HTMLElement to add event listener on.
69 | @param {Function} Event listener callback.
70 | */
71 |
72 |
73 | Module.prototype._addPointerUpEvent = function _addPointerUpEvent(el, fn) {
74 | if (window.navigator.msPointerEnabled) {
75 | el.addEventListener('MSPointerUp', fn);
76 | } else if (window.ontouchstart !== undefined) {
77 | el.addEventListener('touchend', fn);
78 | el.addEventListener('mouseup', fn);
79 | } else {
80 | el.addEventListener('mouseup', fn);
81 | }
82 | };
83 | /*
84 | Method to check if variable holds link to a function.
85 | @param {Function?} A variable to check.
86 | @returns {Boolean} If passed variable is a function.
87 | */
88 |
89 |
90 | Module.prototype._isFunction = function _isFunction(fn) {
91 | return typeof fn === 'function';
92 | };
93 | /*
94 | Method to a function or silently fail.
95 | @param {Function?} A variable to check.
96 | @param {Array like} Arguments.
97 | */
98 |
99 |
100 | Module.prototype._callIfFunction = function _callIfFunction(fn) {
101 | Array.prototype.shift.call(arguments);
102 | this._isFunction(fn) && fn.apply(this, arguments);
103 | };
104 | /*
105 | Method to declare module's variables.
106 | @private
107 | */
108 |
109 |
110 | Module.prototype._vars = function _vars() {};
111 | /*
112 | Method to render on initialization.
113 | @private
114 | */
115 |
116 |
117 | Module.prototype._render = function _render() {
118 | this._addMainElement();
119 | };
120 | /*
121 | Method to add `this.el` on the module.
122 | @private
123 | @param {String} Tag name of the element.
124 | */
125 |
126 |
127 | Module.prototype._addMainElement = function _addMainElement() {
128 | var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
129 |
130 | var p = this._props;
131 |
132 | this.el = this._createElement(tagName);
133 | this._addMainClasses();
134 |
135 | var method = p.isPrepend ? 'prepend' : 'append';
136 | this['_' + method + 'Child'](p.parent, this.el);
137 | };
138 | /*
139 | Method to classes on `this.el`.
140 | @private
141 | */
142 |
143 |
144 | Module.prototype._addMainClasses = function _addMainClasses() {
145 | var p = this._props;
146 | if (p.className instanceof Array) {
147 | for (var i = 0; i < p.className.length; i++) {
148 | this._addClass(this.el, p.className[i]);
149 | }
150 | } else {
151 | this._addClass(this.el, p.className);
152 | }
153 | };
154 | /*
155 | Method to add a class on el.
156 | @private
157 | @param {Object} HTML element to add the class on.
158 | @param {String} Class name to add.
159 | */
160 |
161 |
162 | Module.prototype._addClass = function _addClass(el, className) {
163 | className && el.classList.add(className);
164 | };
165 | /*
166 | Method to set property on the module.
167 | @private
168 | @param {String, Object} Name of the property to set
169 | or object with properties to set.
170 | @param {Any} Value for the property to set. Could be
171 | undefined if the first param is object.
172 | */
173 |
174 |
175 | Module.prototype._setProp = function _setProp(attr, value) {
176 | if ((typeof attr === 'undefined' ? 'undefined' : (0, _typeof3.default)(attr)) === 'object') {
177 | for (var key in attr) {
178 | this._assignProp(key, attr[key]);
179 | }
180 | } else {
181 | this._assignProp(attr, value);
182 | }
183 | };
184 | /*
185 | Method to assign single property's value.
186 | @private
187 | @param {String} Property name.
188 | @param {Any} Property value.
189 | */
190 |
191 |
192 | Module.prototype._assignProp = function _assignProp(key, value) {
193 | this._props[key] = value;
194 | };
195 | /*
196 | Method to copy `_o` options to `_props` object
197 | with fallback to `_defaults`.
198 | @private
199 | */
200 |
201 |
202 | Module.prototype._extendDefaults = function _extendDefaults() {
203 | this._props = {};
204 | // this._deltas = {};
205 | for (var key in this._defaults) {
206 | var value = this._o[key];
207 | this.isIt && console.log(key);
208 | // copy the properties to the _o object
209 | this._assignProp(key, value != null ? value : this._defaults[key]);
210 | }
211 | };
212 | /*
213 | Method to create HTMLElement from tag name.
214 | @private
215 | @param {String} Name of the tag to create `HTML` element.
216 | @returns {Object} HtmlElement.
217 | */
218 |
219 |
220 | Module.prototype._createElement = function _createElement(tagName) {
221 | return document.createElement(tagName);
222 | };
223 | /*
224 | Method to create HTMLElement and append it to the `el` with a className.
225 | @private
226 | @param {String} The tagname for the HTMLElement.
227 | @param {String} Optional class name to add to the new child.
228 | @returns {Object} The newely created HTMLElement.
229 | */
230 |
231 |
232 | Module.prototype._createChild = function _createChild(tagName, className) {
233 | var child = this._createElement('div');
234 | className && child.classList.add(className);
235 | this.el.appendChild(child);
236 | return child;
237 | };
238 | /*
239 | Method to prepend child to the el.
240 | @private
241 | @param {Object} Parent HTMLElement.
242 | @param {Object} Child HTMLElement.
243 | */
244 |
245 |
246 | Module.prototype._appendChild = function _appendChild(el, childEl) {
247 | el.appendChild(childEl);
248 | };
249 | /*
250 | Method to prepend child to the el.
251 | @private
252 | @param {Object} Parent HTMLElement.
253 | @param {Object} Child HTMLElement.
254 | */
255 |
256 |
257 | Module.prototype._prependChild = function _prependChild(el, childEl) {
258 | el.insertBefore(childEl, el.firstChild);
259 | };
260 |
261 | return Module;
262 | }();
263 |
264 | exports.default = Module;
--------------------------------------------------------------------------------
/lib/components/opacity-switch.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _icon = require('./icon');
18 |
19 | var _icon2 = _interopRequireDefault(_icon);
20 |
21 | var _buttonSwitch = require('./button-switch');
22 |
23 | var _buttonSwitch2 = _interopRequireDefault(_buttonSwitch);
24 |
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26 |
27 | require('../../css/blocks/opacity-switch.postcss.css');
28 | var CLASSES = require('../../css/blocks/opacity-switch.postcss.css.json');
29 |
30 | var OpacitySwitch = function (_ButtonSwitch) {
31 | (0, _inherits3.default)(OpacitySwitch, _ButtonSwitch);
32 |
33 | function OpacitySwitch() {
34 | (0, _classCallCheck3.default)(this, OpacitySwitch);
35 | return (0, _possibleConstructorReturn3.default)(this, _ButtonSwitch.apply(this, arguments));
36 | }
37 |
38 | /*
39 | Method to decalre defaults.
40 | @private
41 | @overrides @ ButtonSwitch
42 | */
43 | OpacitySwitch.prototype._declareDefaults = function _declareDefaults() {
44 | _ButtonSwitch.prototype._declareDefaults.call(this);
45 | this._defaults.icon = '';
46 | this._defaults.iconSize = '';
47 | };
48 | /*
49 | Method to render the module.
50 | @private
51 | @overrides @ ButtonSwitch
52 | */
53 |
54 |
55 | OpacitySwitch.prototype._render = function _render() {
56 | _ButtonSwitch.prototype._render.call(this);
57 | this.el.classList.add(CLASSES['opacity-switch']);
58 |
59 | var p = this._props,
60 | icon = new _icon2.default({
61 | parent: this.el,
62 | shape: p.icon,
63 | size: p.iconSize,
64 | className: CLASSES['icon'],
65 | prefix: p.prefix
66 | });
67 | this.el.appendChild(icon.el);
68 | };
69 | /*
70 | Method to react to switch state change.
71 | @private
72 | @overrides @ ButtonSwitch
73 | */
74 |
75 |
76 | OpacitySwitch.prototype._setState = function _setState() {
77 | var method = this._props.isOn ? 'add' : 'remove';
78 | this.el.classList[method](CLASSES['is-on']);
79 | };
80 |
81 | return OpacitySwitch;
82 | }(_buttonSwitch2.default);
83 |
84 | exports.default = OpacitySwitch;
--------------------------------------------------------------------------------
/lib/components/play-button.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _iconFork = require('./icon-fork');
18 |
19 | var _iconFork2 = _interopRequireDefault(_iconFork);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | require('../../css/blocks/play-button.postcss.css');
24 | var CLASSES = require('../../css/blocks/play-button.postcss.css.json');
25 | // PLAYER_BTN_CLASSES = require('css/blocks/player-button.postcss.css.json');
26 |
27 | var PlayButton = function (_IconFork) {
28 | (0, _inherits3.default)(PlayButton, _IconFork);
29 |
30 | function PlayButton() {
31 | (0, _classCallCheck3.default)(this, PlayButton);
32 | return (0, _possibleConstructorReturn3.default)(this, _IconFork.apply(this, arguments));
33 | }
34 |
35 | /*
36 | Method to declare defaults on the module.
37 | @private
38 | @overrides @ ButtonSwitch
39 | */
40 | PlayButton.prototype._declareDefaults = function _declareDefaults() {
41 | _IconFork.prototype._declareDefaults.call(this);
42 | this._defaults.icon1 = 'pause';
43 | this._defaults.icon2 = 'play';
44 | this._defaults.title = 'play/pause (alt + p)';
45 | };
46 | /*
47 | Method to render the module.
48 | @private
49 | */
50 |
51 |
52 | PlayButton.prototype._render = function _render() {
53 | _IconFork.prototype._render.call(this);
54 | this._addClass(this.el, CLASSES['play-button']);
55 | };
56 |
57 | return PlayButton;
58 | }(_iconFork2.default);
59 |
60 | exports.default = PlayButton;
--------------------------------------------------------------------------------
/lib/components/player-slider.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _slider = require('./slider');
18 |
19 | var _slider2 = _interopRequireDefault(_slider);
20 |
21 | var _module = require('./module');
22 |
23 | var _module2 = _interopRequireDefault(_module);
24 |
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26 |
27 | require('../../css/blocks/player-slider.postcss.css');
28 | var CLASSES = require('../../css/blocks/player-slider.postcss.css.json');
29 | var SLIDER_CLASSES = require('../../css/blocks/slider.postcss.css.json');
30 |
31 | var PlayerSlider = function (_Module) {
32 | (0, _inherits3.default)(PlayerSlider, _Module);
33 |
34 | function PlayerSlider() {
35 | (0, _classCallCheck3.default)(this, PlayerSlider);
36 | return (0, _possibleConstructorReturn3.default)(this, _Module.apply(this, arguments));
37 | }
38 |
39 | /*
40 | Method to declare _defaults.
41 | @private
42 | @overrides @ Module
43 | */
44 | PlayerSlider.prototype._declareDefaults = function _declareDefaults() {
45 | this._defaults = {
46 | className: CLASSES['player-slider'],
47 | parent: document.body,
48 | progress: 0,
49 | leftProgress: 0,
50 | rightProgress: 1,
51 | isBounds: false,
52 | onLeftProgress: null,
53 | onProgress: null,
54 | onRightProgress: null,
55 | onSeekStart: null,
56 | onSeekEnd: null
57 | };
58 | };
59 | /*
60 | Method to disable bounds.
61 | @public
62 | @returns this.
63 | */
64 |
65 |
66 | PlayerSlider.prototype.disableBounds = function disableBounds() {
67 | this.track.setBounds(0, 1);
68 | this.rightBound.hide();
69 | this.leftBound.hide();
70 | return this;
71 | };
72 | /*
73 | Method to enable bounds.
74 | @public
75 | @returns this.
76 | */
77 |
78 |
79 | PlayerSlider.prototype.enableBounds = function enableBounds() {
80 | var p = this._props;
81 | this.track.setBounds(p.leftProgress, p.rightProgress);
82 | this.rightBound.show();
83 | this.leftBound.show();
84 | return this;
85 | };
86 | /*
87 | Method to set progress of the track.
88 | @public
89 | @param {Number} Progress to set [0...1].
90 | @returns this.
91 | */
92 |
93 |
94 | PlayerSlider.prototype.setTrackProgress = function setTrackProgress(p) {
95 | this.track.setProgress(p);
96 | return this;
97 | };
98 | /*
99 | Method to decrease progress value.
100 | @public
101 | @param {Number} Value that the slider should be decreased by.
102 | @returns this.
103 | */
104 |
105 |
106 | PlayerSlider.prototype.decreaseProgress = function decreaseProgress() {
107 | var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0.01;
108 |
109 | var progress = this.track._progress;
110 | progress -= amount;
111 | progress = progress < 0 ? 0 : progress;
112 | this.setTrackProgress(progress);
113 | return this;
114 | };
115 | /*
116 | Method to inclease progress value.
117 | @public
118 | @param {Number} Value that the slider should be increased by.
119 | @returns this.
120 | */
121 |
122 |
123 | PlayerSlider.prototype.increaseProgress = function increaseProgress() {
124 | var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0.01;
125 |
126 | var progress = this.track._progress;
127 | progress += amount;
128 | progress = progress > 1 ? 1 : progress;
129 | this.setTrackProgress(progress);
130 | return this;
131 | };
132 | /*
133 | Initial render method.
134 | @private
135 | @overrides @ Module
136 | @returns this
137 | */
138 |
139 |
140 | PlayerSlider.prototype._render = function _render() {
141 | var p = this._props;
142 |
143 | this._addMainElement();
144 | this.el.classList.add(SLIDER_CLASSES.slider);
145 |
146 | this.leftBound = new _slider2.default({
147 | isBound: true,
148 | parent: this.el,
149 | isRipple: false,
150 | onProgress: this._onLeftBoundProgress.bind(this),
151 | onSeekStart: p.onSeekStart,
152 | onSeekEnd: p.onSeekEnd
153 | });
154 |
155 | this.track = new _slider2.default({
156 | parent: this.el,
157 | className: CLASSES.slider,
158 | onProgress: this._onTrackProgress.bind(this),
159 | onSeekStart: p.onSeekStart,
160 | onSeekEnd: p.onSeekEnd
161 | });
162 | this.rightBound = new _slider2.default({
163 | isBound: true,
164 | parent: this.el,
165 | isRipple: false,
166 | isInversed: true,
167 | onProgress: this._onRightBoundProgress.bind(this),
168 | onSeekStart: p.onSeekStart,
169 | onSeekEnd: p.onSeekEnd
170 | });
171 |
172 | this.rightBound.setProgress(p.rightProgress);
173 | this.track.setProgress(p.progress);
174 | this.leftBound.setProgress(p.leftProgress);
175 |
176 | p.parent.appendChild(this.el);
177 | };
178 | /*
179 | Method that should be called on track update.
180 | @private
181 | @param {Number} Track progress value [0...1].
182 | */
183 |
184 |
185 | PlayerSlider.prototype._onTrackProgress = function _onTrackProgress(p) {
186 | this._callIfFunction(this._props.onProgress, p);
187 | };
188 | /*
189 | Method that should be called on left bound update.
190 | @private
191 | @param {Number} Track progress value [0...1].
192 | */
193 |
194 |
195 | PlayerSlider.prototype._onLeftBoundProgress = function _onLeftBoundProgress(p) {
196 | if (!this._props.isBounds) {
197 | return;
198 | }
199 | this._props.leftProgress = p;
200 | this.track.setMinBound(p);
201 | this.rightBound.setMinBound(p);
202 | this._callIfFunction(this._props.onLeftProgress, p);
203 | };
204 | /*
205 | Method that should be called on right bound update.
206 | @private
207 | @param {Number} Track progress value [0...1].
208 | */
209 |
210 |
211 | PlayerSlider.prototype._onRightBoundProgress = function _onRightBoundProgress(p) {
212 | if (!this._props.isBounds) {
213 | return;
214 | }
215 | this._props.rightProgress = p;
216 | this.track.setMaxBound(p);
217 | this.leftBound.setMaxBound(p);
218 | this._callIfFunction(this._props.onRightProgress, p);
219 | };
220 |
221 | return PlayerSlider;
222 | }(_module2.default);
223 |
224 | exports.default = PlayerSlider;
--------------------------------------------------------------------------------
/lib/components/repeat-button.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _opacitySwitch = require('./opacity-switch');
18 |
19 | var _opacitySwitch2 = _interopRequireDefault(_opacitySwitch);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | require('../../css/blocks/repeat-button.postcss.css');
24 | var CLASSES = require('../../css/blocks/repeat-button.postcss.css.json');
25 |
26 | var RepeatButton = function (_OpacitySwitch) {
27 | (0, _inherits3.default)(RepeatButton, _OpacitySwitch);
28 |
29 | function RepeatButton() {
30 | (0, _classCallCheck3.default)(this, RepeatButton);
31 | return (0, _possibleConstructorReturn3.default)(this, _OpacitySwitch.apply(this, arguments));
32 | }
33 |
34 | /*
35 | Method to declare defaults.
36 | @private
37 | @overrides @ OpacitySwitch
38 | */
39 | RepeatButton.prototype._declareDefaults = function _declareDefaults() {
40 | _OpacitySwitch.prototype._declareDefaults.call(this);
41 | this._defaults.icon = 'repeat';
42 | this._defaults.iconSize = 'x2';
43 | this._defaults.title = 'repeat (alt + r)';
44 | };
45 | /*
46 | Initial render method.
47 | @private
48 | @overrides @ Button
49 | @returns this
50 | */
51 |
52 |
53 | RepeatButton.prototype._render = function _render() {
54 | _OpacitySwitch.prototype._render.call(this);
55 | this._addClass(this.el, CLASSES['repeat-button']);
56 | };
57 |
58 | return RepeatButton;
59 | }(_opacitySwitch2.default);
60 |
61 | exports.default = RepeatButton;
--------------------------------------------------------------------------------
/lib/components/ripple.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _module = require('./module');
18 |
19 | var _module2 = _interopRequireDefault(_module);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | var Ripple = function (_Module) {
24 | (0, _inherits3.default)(Ripple, _Module);
25 |
26 | function Ripple() {
27 | (0, _classCallCheck3.default)(this, Ripple);
28 | return (0, _possibleConstructorReturn3.default)(this, _Module.apply(this, arguments));
29 | }
30 |
31 | /*
32 | Method to declare defaults.
33 | @private
34 | @overrides @ Module.
35 | */
36 | Ripple.prototype._declareDefaults = function _declareDefaults() {
37 | _Module.prototype._declareDefaults.call(this);
38 | this._defaults.withHold = true;
39 | };
40 | /*
41 | Method to render the component.
42 | @private
43 | @overrides @ Module
44 | */
45 |
46 |
47 | Ripple.prototype._render = function _render() {
48 | _Module.prototype._render.call(this);
49 | this.curtain = document.createElement('div');
50 | // this.curtain.style.background = 'rgba(255,255,255,.15)';
51 | // this.curtain.style.background = 'yellow';
52 | this.curtain.style.position = 'absolute';
53 | this.curtain.style.width = '100%';
54 | this.curtain.style.height = '100%';
55 | this.curtain.style.left = 0;
56 | this.curtain.style.top = 0;
57 | this.curtain.style.zIndex = 1;
58 |
59 | this.el.appendChild(this.curtain);
60 |
61 | if (mojs.Shape) {
62 | this._addRipple();
63 | }
64 | };
65 | /*
66 | Method to construct ripple object.
67 | @private
68 | */
69 |
70 |
71 | Ripple.prototype._addRipple = function _addRipple() {
72 | var _this2 = this,
73 | _ref;
74 |
75 | this.shape = new mojs.Shape((_ref = {
76 | parent: this.el,
77 | left: 0, top: this._o.top || 0,
78 | // strokeWidth: 10,
79 | strokeWidth: { 10: 0 },
80 | fill: 'none',
81 | stroke: 'hotpink'
82 | }, _ref['fill'] = 'hotpink', _ref.fillOpacity = .75, _ref.opacity = { .85: 0 }, _ref.radius = 40, _ref.scale = { 0: 1 }, _ref.isShowEnd = false, _ref.onStart = function onStart() {
83 | _this2.isStart = true;
84 | }, _ref.onUpdate = this._onUpdate.bind(this), _ref.onComplete = function onComplete() {
85 | _this2.isStart = false;
86 | }, _ref));
87 | };
88 | /*
89 | Method that is invoked on ripple update.
90 | @private
91 | @param {Number} Curret progress [0...1].
92 | */
93 |
94 |
95 | Ripple.prototype._onUpdate = function _onUpdate(p) {
96 | if (!this._props.withHold) {
97 | return;
98 | }
99 | if (p >= .15 && this.isStart && !this.isRelease) {
100 | this.isStart = false;
101 |
102 | if (mojs.Shape) {
103 | this.shape.setSpeed(.02);
104 | }
105 | }
106 | };
107 | /*
108 | Method that should be run on touch serface release.
109 | @private
110 | */
111 |
112 |
113 | Ripple.prototype._release = function _release() {
114 | if (!this._props.withHold) {
115 | return;
116 | }
117 | this.isRelease = true;
118 |
119 | if (mojs.Shape) {
120 | this.shape.setSpeed(1).play();
121 | }
122 | };
123 | /*
124 | Method that should be run on touch serface hold.
125 | @private
126 | @param {Object} Origin event object.
127 | */
128 |
129 |
130 | Ripple.prototype._hold = function _hold(e) {
131 | var x = e.offsetX != null ? e.offsetX : e.layerX,
132 | y = e.offsetY != null ? e.offsetY : e.layerY;
133 |
134 | this.isRelease = false;
135 | if (mojs.Shape) {
136 | this.shape.tune({ x: x, y: y }).replay();
137 | }
138 | };
139 | /*
140 | Method that should be run on touch serface cancel.
141 | @private
142 | */
143 |
144 |
145 | Ripple.prototype._cancel = function _cancel() {
146 | if (!this._props.withHold) {
147 | return;
148 | }
149 | this.isRelease = true;
150 |
151 | if (mojs.Shape) {
152 | this.shape.pause().setSpeed(1).playBackward();
153 | }
154 | };
155 |
156 | return Ripple;
157 | }(_module2.default);
158 |
159 | exports.default = Ripple;
--------------------------------------------------------------------------------
/lib/components/slider.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _module = require('./module');
18 |
19 | var _module2 = _interopRequireDefault(_module);
20 |
21 | var _handle = require('./handle');
22 |
23 | var _handle2 = _interopRequireDefault(_handle);
24 |
25 | var _track = require('./track');
26 |
27 | var _track2 = _interopRequireDefault(_track);
28 |
29 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30 |
31 | require('../../css/blocks/slider.postcss.css');
32 | var CLASSES = require('../../css/blocks/slider.postcss.css.json');
33 |
34 | var Slider = function (_Module) {
35 | (0, _inherits3.default)(Slider, _Module);
36 |
37 | function Slider() {
38 | (0, _classCallCheck3.default)(this, Slider);
39 | return (0, _possibleConstructorReturn3.default)(this, _Module.apply(this, arguments));
40 | }
41 |
42 | /*
43 | Method to declare _defaults.
44 | @private
45 | @overrides @ Module
46 | */
47 | Slider.prototype._declareDefaults = function _declareDefaults() {
48 | this._defaults = {
49 | className: '',
50 | parent: document.body,
51 | isBound: false,
52 | isInversed: false,
53 | isRipple: true,
54 | isProgress: true,
55 | onProgress: null,
56 | onSeekStart: null,
57 | onSeekEnd: null,
58 | direction: 'x',
59 | snapPoint: 0,
60 | snapStrength: 0
61 | };
62 | };
63 | /*
64 | Method to set slider progress.
65 | @public
66 | @param {Number} Progress to set.
67 | @returns this.
68 | */
69 |
70 |
71 | Slider.prototype.setProgress = function setProgress(progress) {
72 | this.handle.setProgress(progress);
73 | this.track.setProgress(progress);
74 | return this;
75 | };
76 | /*
77 | Method to set bounds of progress.
78 | @public
79 | @param {Number} Min bound to set [0...1].
80 | @param {Number} Max bound to set [0...1].
81 | @returns this.
82 | */
83 |
84 |
85 | Slider.prototype.setBounds = function setBounds(min, max) {
86 | this.handle.setBounds(min, max);
87 | this.track.setBounds(min, max);
88 | return this;
89 | };
90 | /*
91 | Method to set min bound of progress.
92 | @public
93 | @param {Number} Min bound to set [0...1].
94 | @returns this.
95 | */
96 |
97 |
98 | Slider.prototype.setMinBound = function setMinBound(min) {
99 | this.handle.setMinBound(min);
100 | this.track.setMinBound(min);
101 | return this;
102 | };
103 | /*
104 | Method to set max bound of progress.
105 | @public
106 | @param {Number} Max bound to set [0...1].
107 | @returns this.
108 | */
109 |
110 |
111 | Slider.prototype.setMaxBound = function setMaxBound(max) {
112 | this.handle.setMaxBound(max);
113 | this.track.setMaxBound(max);
114 | return this;
115 | };
116 | /*
117 | Method to hide elements.
118 | @public
119 | */
120 |
121 |
122 | Slider.prototype.show = function show() {
123 | this.track.el.style.display = 'block';
124 | this.handle.el.style.display = 'block';
125 | };
126 | /*
127 | Method to hide elements.
128 | @public
129 | */
130 |
131 |
132 | Slider.prototype.hide = function hide() {
133 | this.track.el.style.display = 'none';
134 | this.handle.el.style.display = 'none';
135 | };
136 | /*
137 | Method to render the component.
138 | @private
139 | @overrides @ Module
140 | */
141 |
142 |
143 | Slider.prototype._render = function _render() {
144 | var p = this._props;
145 |
146 | if (!p.isBound) {
147 | var el = this._createElement('div'),
148 | classList = el.classList;
149 | this.el = el;
150 |
151 | this.inner = this._createElement('div');
152 | this.inner.classList.add(CLASSES['slider__inner']);
153 | this.el.appendChild(this.inner);
154 |
155 | classList.add(CLASSES.slider);
156 | p.direction === 'y' && classList.add(CLASSES['is-y']);
157 | p.className && classList.add(p.className);
158 | p.parent.appendChild(el);
159 | }
160 |
161 | var rootEl = !p.isBound ? this.inner : p.parent;
162 |
163 | this.track = new _track2.default({
164 | className: CLASSES.track,
165 | onProgress: this._onTrackProgress.bind(this),
166 | onSeekStart: p.onSeekStart,
167 | onSeekEnd: p.onSeekEnd,
168 | isBound: p.isBound,
169 | isInversed: p.isInversed,
170 | isRipple: p.isRipple,
171 | isProgress: p.isProgress,
172 | parent: rootEl,
173 | direction: p.direction,
174 | snapPoint: p.snapPoint,
175 | snapStrength: p.snapStrength
176 | });
177 | rootEl.appendChild(this.track.el);
178 |
179 | var handleClass = [CLASSES.handle];
180 | if (!p.isBound) {
181 | handleClass.push(CLASSES['progress-handle']);
182 | }
183 |
184 | this.handle = new _handle2.default({
185 | className: handleClass,
186 | onProgress: this._onHandleProgress.bind(this),
187 | onSeekStart: p.onSeekStart,
188 | onSeekEnd: p.onSeekEnd,
189 | isBound: p.isBound,
190 | isInversed: p.isInversed,
191 | parent: rootEl,
192 | direction: p.direction,
193 | snapPoint: p.snapPoint,
194 | snapStrength: p.snapStrength
195 | });
196 | rootEl.appendChild(this.handle.el);
197 | };
198 | /*
199 | Method that is invoked on handle progress change.
200 | @private
201 | @param {Number} Progress [0...1].
202 | */
203 |
204 |
205 | Slider.prototype._onHandleProgress = function _onHandleProgress(p) {
206 | this.track.setProgress(p, false);
207 | this._onProgress(p);
208 | };
209 | /*
210 | Method that is invoked on track progress change.
211 | @private
212 | @param {Number} Progress [0...1].
213 | */
214 |
215 |
216 | Slider.prototype._onTrackProgress = function _onTrackProgress(p) {
217 | this.handle.setProgress(p, false);
218 | this._onProgress(p);
219 | };
220 | /*
221 | Method to call onProgress callback.
222 | @private
223 | @param {Number} Progress value [0...1].
224 | */
225 |
226 |
227 | Slider.prototype._onProgress = function _onProgress(progress) {
228 | var p = this._props;
229 | if (typeof p.onProgress === 'function' && this._progress !== progress) {
230 | this._progress = progress;
231 | p.onProgress.call(this, progress);
232 | }
233 | };
234 |
235 | return Slider;
236 | }(_module2.default);
237 |
238 | exports.default = Slider;
--------------------------------------------------------------------------------
/lib/components/speed-control.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _module = require('./module');
18 |
19 | var _module2 = _interopRequireDefault(_module);
20 |
21 | var _labelButton = require('./label-button');
22 |
23 | var _labelButton2 = _interopRequireDefault(_labelButton);
24 |
25 | var _slider = require('./slider');
26 |
27 | var _slider2 = _interopRequireDefault(_slider);
28 |
29 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30 |
31 | require('../../css/blocks/speed-control.postcss.css');
32 | var CLASSES = require('../../css/blocks/speed-control.postcss.css.json');
33 |
34 | var SpeedControl = function (_Module) {
35 | (0, _inherits3.default)(SpeedControl, _Module);
36 |
37 | function SpeedControl() {
38 | (0, _classCallCheck3.default)(this, SpeedControl);
39 | return (0, _possibleConstructorReturn3.default)(this, _Module.apply(this, arguments));
40 | }
41 |
42 | /*
43 | Method to declare defaults for the module.
44 | @private
45 | @overrides @ Module
46 | */
47 | SpeedControl.prototype._declareDefaults = function _declareDefaults() {
48 | _Module.prototype._declareDefaults.call(this);
49 | this._defaults.isOn = false;
50 | this._defaults.speed = 1;
51 | this._defaults.progress = .5;
52 | this._defaults.onSpeedChange = null;
53 | this._defaults.onIsSpeed = null;
54 | };
55 | /*
56 | Method to reset speed to 1x.
57 | @public
58 | @returns this
59 | */
60 |
61 |
62 | SpeedControl.prototype.reset = function reset() {
63 | this._onDoubleTap();
64 | };
65 | /*
66 | Method to decrease speed value.
67 | @public
68 | @param {Number} Value that the slider should be decreased by.
69 | @returns this.
70 | */
71 |
72 |
73 | SpeedControl.prototype.decreaseSpeed = function decreaseSpeed() {
74 | var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0.01;
75 |
76 | var p = this._props;
77 | p.progress -= amount;
78 | p.progress = p.progress < 0 ? 0 : p.progress;
79 | this.slider.setProgress(p.progress);
80 | return this;
81 | };
82 | /*
83 | Method to inclease speed value.
84 | @public
85 | @param {Number} Value that the slider should be increased by.
86 | @returns this.
87 | */
88 |
89 |
90 | SpeedControl.prototype.increaseSpeed = function increaseSpeed() {
91 | var amount = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0.01;
92 |
93 | var p = this._props;
94 | p.progress += amount;
95 | p.progress = p.progress > 1 ? 1 : p.progress;
96 | this.slider.setProgress(p.progress);
97 | return this;
98 | };
99 | /*
100 | Initial render method.
101 | @private
102 | @overrides @ Module
103 | */
104 |
105 |
106 | SpeedControl.prototype._render = function _render() {
107 | var p = this._props,
108 | className = 'speed-control',
109 | slider = this._createElement('div'),
110 | sliderIn = this._createElement('div'),
111 | icon = this._createElement('div');
112 |
113 | this._addMainElement();
114 | this.el.classList.add(CLASSES[className]);
115 | // places for child components
116 | slider.classList.add(CLASSES[className + '__slider']);
117 | // sliderIn.classList.add( CLASSES[ `${ className }__slider-inner` ] );
118 | // slider.appendChild( sliderIn );
119 | this.el.appendChild(slider);
120 | // child components
121 | this.labelButton = new _labelButton2.default({
122 | parent: this.el,
123 | isOn: p.isOn,
124 | className: CLASSES[className + '__icon'],
125 | onStateChange: this._onButtonStateChange.bind(this),
126 | onDoubleTap: this._onDoubleTap.bind(this)
127 | });
128 | this.slider = new _slider2.default({
129 | parent: slider,
130 | isProgress: false,
131 | direction: 'y',
132 | onProgress: this._onSliderProgress.bind(this),
133 | snapPoint: .5,
134 | snapStrength: .05
135 | });
136 |
137 | this.slider.setProgress(this._speedToProgress(this._props.speed));
138 | };
139 | /*
140 | Method that is invoked on slider progress.
141 | @private
142 | @param {Number} Progress of the slider.
143 | */
144 |
145 |
146 | SpeedControl.prototype._onSliderProgress = function _onSliderProgress(p) {
147 | // progress should be at least 0.01
148 | p = Math.max(p, 0.0001);
149 |
150 | var props = this._props,
151 | args = [];
152 |
153 | this._callIfFunction(props.onSpeedChange, this._progressToSpeed(p), p);
154 | this.labelButton.setLabelText(this._progressToLabel(props.progress = p));
155 | };
156 | /*
157 | Method that is invoked on button state change.
158 | @private
159 | @param {Boolean} State of the button switch.
160 | */
161 |
162 |
163 | SpeedControl.prototype._onButtonStateChange = function _onButtonStateChange(isOn) {
164 | var method = isOn ? 'add' : 'remove';
165 | this.el.classList[method](CLASSES['is-on']);
166 | this._callIfFunction(this._props.onIsSpeed, isOn);
167 | };
168 | /*
169 | Method to recalc progress to label string.
170 | @private
171 | @param {Number} Progress [0...1].
172 | @returns {String} String for a label to set.
173 | */
174 |
175 |
176 | SpeedControl.prototype._progressToLabel = function _progressToLabel(progress) {
177 | var text = this._progressToSpeed(progress).toFixed(2),
178 | zeros = /\.+00$/;
179 |
180 | if (text.match(zeros)) {
181 | text = text.replace(zeros, '');
182 | }
183 |
184 | return text + 'x';
185 | };
186 | /*
187 | Method to recalc progress to speed.
188 | @private
189 | @param {Number} Progress [0...1].
190 | @returns {Number} Speed [0...10].
191 | */
192 |
193 |
194 | SpeedControl.prototype._progressToSpeed = function _progressToSpeed(progress) {
195 | var speed = progress;
196 | if (progress < .5) {
197 | speed = 2 * progress;
198 | }
199 | if (progress === .5) {
200 | speed = 1;
201 | }
202 | if (progress > .5) {
203 | progress -= .5;
204 | speed = 1 + progress * 18;
205 | // console.log( speed/10, mojs.easing.cubic.out( speed/10 ) );
206 | // console.log( .5 + ( speed - 1 ) / 18 );
207 | }
208 | return speed;
209 | };
210 | /*
211 | Method to recalc progress to speed.
212 | @private
213 | @param {Number} Progress [0...1].
214 | @returns {Number} Speed [0...10].
215 | */
216 |
217 |
218 | SpeedControl.prototype._speedToProgress = function _speedToProgress(speed) {
219 | var progress = speed;
220 | if (speed < 1) {
221 | progress = speed / 2;
222 | }
223 | if (speed === 1) {
224 | progress = .5;
225 | }
226 | if (speed > 1) {
227 | progress = .5 + (speed - 1) / 18;
228 | }
229 | return progress;
230 | };
231 | /*
232 | Method that is invoked on double button tap.
233 | @private
234 | */
235 |
236 |
237 | SpeedControl.prototype._onDoubleTap = function _onDoubleTap() {
238 | this.slider.setProgress(.5);
239 | this.labelButton.off();
240 | };
241 |
242 | return SpeedControl;
243 | }(_module2.default);
244 |
245 | exports.default = SpeedControl;
--------------------------------------------------------------------------------
/lib/components/stop-button.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _iconButton = require('./icon-button');
18 |
19 | var _iconButton2 = _interopRequireDefault(_iconButton);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | require('../../css/blocks/stop-button.postcss.css');
24 | var CLASSES = require('../../css/blocks/stop-button.postcss.css.json');
25 |
26 | var StopButton = function (_IconButton) {
27 | (0, _inherits3.default)(StopButton, _IconButton);
28 |
29 | function StopButton() {
30 | (0, _classCallCheck3.default)(this, StopButton);
31 | return (0, _possibleConstructorReturn3.default)(this, _IconButton.apply(this, arguments));
32 | }
33 |
34 | StopButton.prototype._declareDefaults = function _declareDefaults() {
35 | _IconButton.prototype._declareDefaults.call(this);
36 | this._defaults.icon = 'stop';
37 | this._defaults.title = 'stop (alt + s)';
38 | };
39 | /*
40 | Initial render method.
41 | @private
42 | @overrides @ Button
43 | @returns this
44 | */
45 |
46 |
47 | StopButton.prototype._render = function _render() {
48 | _IconButton.prototype._render.call(this);
49 | this._addClass(this.el, CLASSES['stop-button']);
50 | };
51 |
52 | return StopButton;
53 | }(_iconButton2.default);
54 |
55 | exports.default = StopButton;
--------------------------------------------------------------------------------
/lib/components/track.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | exports.__esModule = true;
4 |
5 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
6 |
7 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
8 |
9 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
10 |
11 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
12 |
13 | var _inherits2 = require('babel-runtime/helpers/inherits');
14 |
15 | var _inherits3 = _interopRequireDefault(_inherits2);
16 |
17 | var _handle = require('./handle');
18 |
19 | var _handle2 = _interopRequireDefault(_handle);
20 |
21 | var _hammerjs = require('hammerjs');
22 |
23 | var _hammerjs2 = _interopRequireDefault(_hammerjs);
24 |
25 | var _ripple = require('./ripple');
26 |
27 | var _ripple2 = _interopRequireDefault(_ripple);
28 |
29 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30 |
31 | require('../../css/blocks/track.postcss.css');
32 | var CLASSES = require('../../css/blocks/track.postcss.css.json');
33 |
34 | var Track = function (_Handle) {
35 | (0, _inherits3.default)(Track, _Handle);
36 |
37 | function Track() {
38 | (0, _classCallCheck3.default)(this, Track);
39 | return (0, _possibleConstructorReturn3.default)(this, _Handle.apply(this, arguments));
40 | }
41 |
42 | /*
43 | Method to declare _defaults.
44 | @private
45 | @overrides @ Handle
46 | */
47 | Track.prototype._declareDefaults = function _declareDefaults() {
48 | _Handle.prototype._declareDefaults.call(this);
49 | this._defaults.isProgress = true;
50 | this._defaults.isRipple = true;
51 | };
52 | /*
53 | Method to render the component.
54 | @private
55 | @overrides @ Handle
56 | */
57 |
58 |
59 | Track.prototype._render = function _render() {
60 | _Handle.prototype._render.call(this);
61 | if (!this._props.isRipple) {
62 | return;
63 | }
64 | this.ripple = new _ripple2.default({
65 | withHold: false,
66 | className: CLASSES['track__ripple'],
67 | // top: '50%',
68 | parent: this.el
69 | });
70 | };
71 | /*
72 | Method to apply shift to the DOMElement.
73 | @private
74 | @overrides @ Handle.
75 | @param {Number} Shift in pixels.x
76 | */
77 |
78 |
79 | Track.prototype._applyShift = function _applyShift(shift) {
80 | if (!this._props.isProgress) {
81 | return;
82 | }
83 | if (this._props.isInversed) {
84 | shift = this._maxWidth - shift;
85 | }
86 | var transform = 'scaleX( ' + shift + ' ) translateZ(0)';
87 | this.trackProgressEl.style.transform = transform;
88 | // this.trackProgressEl.style.width = `${shift}px`;
89 | };
90 | /*
91 | Method to add classes on `this.el`.
92 | @private
93 | @overrides @ Handle.
94 | */
95 |
96 |
97 | Track.prototype._addMainClasses = function _addMainClasses() {
98 | var p = this._props,
99 | classList = this.el.classList;
100 |
101 | classList.add(CLASSES.track);
102 | if (p.isInversed) {
103 | classList.add(CLASSES['is-inversed']);
104 | }
105 | if (p.isBound) {
106 | classList.add(CLASSES['is-bound']);
107 | }
108 | if (p.direction === 'y') {
109 | classList.add(CLASSES['is-y']);
110 | }
111 | };
112 | /*
113 | Method to add DOM elements on render.
114 | @private
115 | */
116 |
117 |
118 | Track.prototype._addElements = function _addElements() {
119 | var p = this._props;
120 |
121 | if (p.isProgress) {
122 | // progress track
123 | var trackP = document.createElement('div');
124 | trackP.classList.add('' + CLASSES['track__track-progress']);
125 | this.trackProgressEl = trackP;
126 | this.el.appendChild(trackP);
127 | }
128 | // track
129 | if (!p.isBound) {
130 | var track = document.createElement('div');
131 | track.classList.add('' + CLASSES.track__track);
132 | this.el.appendChild(track);
133 | }
134 | };
135 | /*
136 | Callback for pointer down on main el.
137 | @private
138 | @param {Object} Original event object.
139 | @overrides @ Handle
140 | */
141 |
142 |
143 | Track.prototype._pointerDown = function _pointerDown(e) {
144 | var p = this._props,
145 | x = p.direction === 'x' ? e.layerX : e.layerY;
146 | this._isPointerDown = true;
147 |
148 | if (p.direction === 'y') {
149 | x = this._maxWidth - e.layerY;
150 | }
151 | x = this._props.isInversed && x < 0 ? this._maxWidth + x : x;
152 |
153 | // if near the snap point - set it to the snap point
154 | var progress = this._shiftToProgress(x);
155 | progress = Math.abs(p.snapPoint - progress) < p.snapStrength ? p.snapPoint : progress;
156 | this.setProgress(progress);
157 |
158 | p.isRipple && this.ripple._hold(e);
159 | this._callIfFunction(p.onSeekStart, e);
160 | };
161 |
162 | return Track;
163 | }(_handle2.default);
164 |
165 | exports.default = Track;
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mojs/mojs-player/1efc22e32ae2a4dec52609495e477a67b17371e5/logo.png
--------------------------------------------------------------------------------
/mockups/mojs-player.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mojs/mojs-player/1efc22e32ae2a4dec52609495e477a67b17371e5/mockups/mojs-player.sketch
--------------------------------------------------------------------------------
/mockups/mojs-player@x4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mojs/mojs-player/1efc22e32ae2a4dec52609495e477a67b17371e5/mockups/mojs-player@x4.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@mojs/player",
3 | "description": "GUI player to control your animations",
4 | "version": "1.3.0",
5 | "license": "MIT",
6 | "private": false,
7 | "scripts": {
8 | "start": "webpack"
9 | },
10 | "source": "js/mojs-player.babel.js",
11 | "main": "build/mojs-player.min.js",
12 | "browser": "build/mojs-player.min.js",
13 | "unpkg": "build/mojs-player.min.js",
14 | "keywords": [
15 | "motion",
16 | "graphics",
17 | "toolbelt",
18 | "effects",
19 | "animation",
20 | "mojs",
21 | "player"
22 | ],
23 | "author": {
24 | "name": "Oleg Solomka",
25 | "email": "legomushroom@gmail.com",
26 | "url": "https://twitter.com/legomushroom",
27 | "github": "@legomushroom"
28 | },
29 | "repository": {
30 | "type": "git",
31 | "url": "git+https://github.com/mojs/mojs-player.git"
32 | },
33 | "bugs": {
34 | "url": "https://github.com/mojs/mojs-player/issues"
35 | },
36 | "homepage": "https://github.com/mojs/mojs-player",
37 | "engines": {
38 | "node": "^20",
39 | "npm": "^10"
40 | },
41 | "dependencies": {
42 | "classlist-polyfill": "^1.0.2",
43 | "hammerjs": "^2.0.6"
44 | },
45 | "devDependencies": {
46 | "@mojs/core": "^0.288.2",
47 | "autoprefixer": "^6.3.5",
48 | "babel-core": "^6.7.6",
49 | "babel-loader": "^6.2.4",
50 | "babel-plugin-transform-runtime": "^6.7.5",
51 | "babel-preset-es2015": "^6.6.0",
52 | "babel-preset-es2015-loose": "^7.0.0",
53 | "babel-preset-stage-2": "^6.5.0",
54 | "babel-runtime": "^6.6.1",
55 | "css-loader": "^0.23.1",
56 | "gulp": "^3.9.1",
57 | "gulp-babel": "^6.1.2",
58 | "gulp-changed": "^1.3.0",
59 | "gulp-concat": "^2.6.0",
60 | "gulp-insert": "^0.5.0",
61 | "gulp-json-editor": "^2.5.7",
62 | "gulp-livereload": "^3.8.1",
63 | "gulp-plumber": "^1.1.0",
64 | "gulp-rename": "^1.2.2",
65 | "gulp-shell": "^0.8.0",
66 | "gulp-uglify": "^1.5.3",
67 | "json-loader": "^0.5.4",
68 | "postcss-cssnext": "^2.5.1",
69 | "postcss-loader": "^0.8.2",
70 | "postcss-modules": "^0.4.1",
71 | "precss": "^1.4.0",
72 | "run-sequence": "^1.1.5",
73 | "style-loader": "^0.13.1",
74 | "webpack": "^1.13.1"
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 |
4 | module.exports = {
5 | watch: true,
6 | context: __dirname + "/",
7 | entry: [
8 | __dirname + '/js/mojs-player.babel.js'
9 | ],
10 | module: {
11 | loaders: [
12 | { test: /\.(json)$/, exclude: /node_modules/, loaders: ['json-loader'] },
13 | { test: /\.(jsx|es6.js|babel.js|.js)$/,
14 | exclude: /node_modules/,
15 | loader: 'babel-loader',
16 | query: {
17 | presets: [ 'es2015-loose', 'babel-preset-stage-2' ],
18 | plugins: [ 'transform-runtime' ]
19 | }
20 | },
21 | { test: /\.jade$/, loaders: ['jade'] },
22 | { test: /\.(postcss.css)$/, loader: "style-loader!css-loader!postcss-loader" },
23 | { test: /\.html$/, loader: 'raw-loader' },
24 | {
25 | test: /\.(eot|woff|ttf|svg|png|jpg|wav|mp3)$/,
26 | loader: 'url-loader?limit=30000&name=[name]-[hash].[ext]',
27 | }
28 | ]
29 | },
30 | postcss: function () {
31 | return [ require('precss'), require('postcss-cssnext'), require('postcss-modules') ];
32 | },
33 | output: {
34 | path: __dirname + '/build',
35 | filename: 'mojs-player.js',
36 | publicPath: 'build/',
37 | library: 'mojs-player',
38 | libraryTarget: 'umd',
39 | umdNamedDefine: true
40 | },
41 | plugins: [],
42 | resolve: {
43 | root: [ path.resolve('./') ],
44 | moduleDirectories: ['node_modules'],
45 | target: 'node',
46 | extensions: [
47 | '', '.js', '.es6', '.babel.js', '.coffee',
48 | '.postcss.css', '.css', '.json'
49 | ]
50 | }
51 | };
52 |
--------------------------------------------------------------------------------