Skip to content

Commit 5ea5a01

Browse files
committed
feat: partial rewrite
BREAKING CHANGE: Lot of things changed, mostly the public API - `Promise` support, most public methods returns a promise. - `shuffle` arguments. - `stop` arguments. - `run` has been deleted, this feature can be achieved using promises. - `constructor` options have been shrinked.
1 parent 63e2760 commit 5ea5a01

File tree

15 files changed

+813
-996
lines changed

15 files changed

+813
-996
lines changed

README.md

Lines changed: 31 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ const el = document.querySelector('#machine');
3434

3535
const machine = new SlotMachine(el, {
3636
active: 1,
37-
delay: 450,
38-
auto: 1500
37+
delay: 450
3938
});
39+
40+
machine.shuffle();
4041
```
4142

4243
> Lookup the sourcecode in the [examples page](http://josex2r.github.io/jQuery-SlotMachine/) to see more examples.
@@ -71,85 +72,70 @@ const machine = new SlotMachine(element, {
7172
});
7273
```
7374

74-
| Name | Type | Default | Description |
75-
|----------------|------------|---------------|-------------------------------------------------------------------------------------|
76-
| **active** | `Number` | `0` | The initial visible element (0 means the first one) |
77-
| **delay** | `Number` | `200` | Duration (in ms) of each spin |
78-
| **auto** | `Boolean` | `false` | Runs the carousel mode when creating the machine |
79-
| **spins** | `Number` | `5` | Number of spins after stop in carousel mode |
80-
| **randomize** | `Function` | `null` | Function (returns number) that is going to be called to set the next active element |
81-
| **onComplete** | `Function` | `null` | Callback after each spin in carousel mode |
82-
| **inViewport** | `Boolean` | `true` | Only spin when the machine is inside the viewport |
83-
| **direction** | `String` | `up` | The spin direction (possible values are `up` and `down`) |
84-
| **transition** | `String` | `ease-in-out` | The CSS transition |
75+
| Name | Type | Default | Description |
76+
|----------------|------------|----------------|------------------------------------------------------------------------------------------|
77+
| **active** | `Number` | `0` | The initial visible element (0 means the first one) |
78+
| **delay** | `Number` | `200` | Duration (in ms) of each spin |
79+
| **randomize** | `Function` | `() => number` | Function (returns number) that returns the next active element (random value as default) |
80+
| **direction** | `String` | `up` | The spin direction (possible values are `up` and `down`) |
8581

8682
### Properties
8783

8884
- `machine.nextActive`: Get the next active element (only while shuffling).
8985
- `machine.nextIndex`: Next element index according to the current direction.
9086
- `machine.prevIndex`: Prev element index according to the current direction.
91-
- `machine.random`: Get rando index between the machine bounds.
9287
- `machine.running`: Check if the machine is running.
9388
- `machine.stopping`: Check if the machine is stopping.
94-
- `machine.visible`: Check if the machine is visible.
95-
- `machine.visibleTile`: Get the current visible element in the machine viewport.
96-
- `machine.active`: Alias to the `active` setting.
97-
- `machine.randomize`: Alias to the `randomize` setting.
98-
- `machine.direction`: Alias to the `direction` setting.
99-
- `machine.transition`: Alias to the `transition` setting.
89+
- `machine.active`: The current `active` element.
10090

10191
### Methods
10292

103-
`machine.shuffle(spins, callback)`: Starts spining the machine.
104-
- spins (`Number`): Optionally set the number of spins.
105-
- callback(`Function`): Callback triggered when the machine stops.
93+
`machine.shuffle(spins: number): Promise<void>`: Starts spining the machine.
94+
95+
**Arguments**:
96+
- spins (`Number`): Optionally set the number of spins until stop.
10697

10798
```javascript
10899
// Do a single spin
109100
machine.shuffle();
110-
// Do a single spin and then shows an alert
111-
machine.shuffle(() => alert('Stop!'));
112101
// Do 5 spins before stop
113102
machine.shuffle(5);
114-
// Do 7 spins and then showing an alert
115-
machine.shuffle(7, () => alert('Stop!'));
116103
// "Infinite" spins
117-
machine.shuffle(9999999); // O_O
104+
machine.shuffle(Infinity);
118105
```
119106

120-
`machine.stop(callback)`: Manually stops the machine.
121-
- callback(`Function`): Callback triggered when the machine stops.
107+
`machine.stop(spins: number): Promise<void>`: Manually stops the machine.
122108

123-
For example, start spinning the machine and stop it after pressing a button:
109+
**Arguments**:
110+
- spins (`Number`): Set the number of spins until stop. Use `0` to inmediate stop.
124111

125112
```javascript
126-
machine.shuffle(99999);
127-
// Add the button listener
128-
myButton.addEventListener('click', () => {
129-
// Stop spinning
130-
machine.stop();
131-
});
113+
// Start spinning the machine
114+
machine.shuffle(Infinity);
115+
// Do 4 spins an then stop
116+
machine.stop(4);
132117
```
133118

134-
`machine.next()`/`machine.prev()`: Spin to the next/previous element.
119+
`machine.next(): Promise<void>`/`machine.prev(): Promise<void>`: Spins to the **next/previous** element.
135120

136121
```javascript
137122
// Spin to the previous element
138123
machine.prev();
124+
139125
// Spin to the next element
140126
machine.next();
141127
```
142128

143-
`machine.run()`: Starts the preview mode, it will spin/stop given a delay (more info in options).
144-
145-
```javascript
146-
machine.run();
147-
```
129+
### Usefull recipes
148130

149-
`machine.run()`: Destroys the machine. It will be useful when you want to reuse DOM.
131+
To create an inifite carousel effect (as the previous versions `run` method) use a recursive function:
150132

151133
```javascript
152-
machine.destroy();
134+
(async function run() {
135+
await machine.shuffle(5)
136+
await timeout(1000);
137+
run();
138+
})();
153139
```
154140

155141
## Authors

dist/slotmachine.css

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
1-
.slotMachineNoTransition {
2-
transition: none !important;
1+
.slot-machine__tile--no-transition {
2+
transition: none !important;
33
}
44

5-
.slotMachineBlurFast {
6-
filter: blur(5px);
5+
.slot-machine__tile--blur-fast {
6+
filter: blur(5px);
77
}
88

9-
.slotMachineBlurMedium {
10-
filter: blur(3px);
9+
.slot-machine__tile--blur-medium {
10+
filter: blur(3px);
1111
}
1212

13-
.slotMachineBlurSlow {
14-
filter: blur(2px);
13+
.slot-machine__tile--blur-slow {
14+
filter: blur(2px);
1515
}
1616

17-
.slotMachineBlurTurtle {
18-
filter: blur(1px);
17+
.slot-machine__tile--blur-turtle {
18+
filter: blur(1px);
1919
}
2020

21-
.slotMachineGradient {
22-
-webkit-mask-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(0,0,0,0)), color-stop(25%, rgba(0,0,0,1)), color-stop(75%, rgba(0,0,0,1)), color-stop(100%, rgba(0,0,0,0)) );
23-
mask: url('data:image/svg+xml;utf8,<svg version="1.1" xmlns="http:// www.w3.org/2000/svg" width="0" height="0"><mask id="slotMachineFadeMask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox"><linearGradient id="slotMachineFadeGradient" gradientUnits="objectBoundingBox" x="0" y="0"><stop stop-color="white" stop-opacity="0" offset="0"></stop><stop stop-color="white" stop-opacity="1" offset="0.25"></stop><stop stop-color="white" stop-opacity="1" offset="0.75"></stop><stop stop-color="white" stop-opacity="0" offset="1"></stop></linearGradient><rect x="0" y="-1" width="1" height="1" transform="rotate(90)" fill="url(#slotMachineFadeMask)"></rect></mask></svg>#slotMachineFadeMask');
21+
.slot-machine__container--gradient, .slot-machine__tile--gradient {
22+
-webkit-mask-image: -webkit-gradient(
23+
linear,
24+
left top,
25+
left bottom,
26+
color-stop(0%, rgba(0, 0, 0, 0)),
27+
color-stop(25%, rgba(0, 0, 0, 1)),
28+
color-stop(75%, rgba(0, 0, 0, 1)),
29+
color-stop(100%, rgba(0, 0, 0, 0))
30+
);
31+
mask: url('data:image/svg+xml;utf8,<svg version="1.1" xmlns="http:// www.w3.org/2000/svg" width="0" height="0"><mask id="slotMachineFadeMask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox"><linearGradient id="slotMachineFadeGradient" gradientUnits="objectBoundingBox" x="0" y="0"><stop stop-color="white" stop-opacity="0" offset="0"></stop><stop stop-color="white" stop-opacity="1" offset="0.25"></stop><stop stop-color="white" stop-opacity="1" offset="0.75"></stop><stop stop-color="white" stop-opacity="0" offset="1"></stop></linearGradient><rect x="0" y="-1" width="1" height="1" transform="rotate(90)" fill="url(#slotMachineFadeMask)"></rect></mask></svg>#slotMachineFadeMask');
2432
}

lib/constants.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Options } from './types';
2+
3+
function randomInteger(min: number, max: number) {
4+
return Math.floor(Math.random() * (max - min + 1)) + min;
5+
}
6+
7+
export const DEFAULTS: Required<Options> = {
8+
active: 0, // Active element [Number]
9+
delay: 200, // Animation time [Number]
10+
randomize: (_, max) => randomInteger(0, max), // Randomize function, must return a number with the selected position
11+
direction: 'up', // Animation direction ['up'||'down']
12+
};
13+
14+
export enum CONTAINER_FX {
15+
GRADIENT = 'slot-machine__container--gradient',
16+
}
17+
18+
export enum TILE_FX {
19+
NO_TRANSITION = 'slot-machine__tile--no-transition',
20+
FAST = 'slot-machine__tile--blur-fast',
21+
NORMAL = 'slot-machine__tile--blur-medium',
22+
SLOW = 'slot-machine__tile--blur-slow',
23+
TURTLE = 'slot-machine__tile--blur-turtle',
24+
STOP = 'slot-machine__tile--gradient',
25+
}

lib/dom.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
export class Container {
2+
element: HTMLElement;
3+
tiles: Tile[] = [];
4+
tileNodes: Tile[] = [];
5+
6+
constructor(public container: HTMLElement) {
7+
const tileElements = [].slice.call(this.container.children) as HTMLElement[];
8+
9+
this.container.style.overflow = 'hidden';
10+
this.element = document.createElement('div');
11+
this.element.classList.add('slot-machine__container');
12+
this.element.style.transition = '1s ease-in-out';
13+
this.container.appendChild(this.element);
14+
this.tiles = [...tileElements].map((element) => new Tile(element));
15+
this.tileNodes = [
16+
this.tiles[this.tiles.length - 1].clone(),
17+
...this.tiles,
18+
this.tiles[0].clone(),
19+
];
20+
this.wrapTiles();
21+
}
22+
23+
private wrapTiles() {
24+
this.tileNodes.forEach((tile) => {
25+
this.element.appendChild(tile.element);
26+
});
27+
}
28+
29+
private get lastTileOffset() {
30+
return this.tiles[0].offset;
31+
}
32+
33+
getTileOffset(index: number) {
34+
let offset = 0;
35+
36+
for (let i = 0; i < index; i++) {
37+
offset += this.tiles[i].offset;
38+
}
39+
40+
return -this.lastTileOffset - offset;
41+
}
42+
43+
get maxTopOffset() {
44+
return -1 * (this.tiles.reduce((acc, { offset }) => acc + offset, 0) + this.lastTileOffset);
45+
}
46+
}
47+
48+
export class Tile {
49+
constructor(public element: HTMLElement) {
50+
this.element.classList.add('slot-machine__tile');
51+
}
52+
53+
clone() {
54+
const element = this.element.cloneNode(true) as HTMLElement;
55+
56+
return new Tile(element);
57+
}
58+
59+
get offset() {
60+
return this.element.offsetHeight;
61+
}
62+
}

0 commit comments

Comments
 (0)