@thinkpixellab-public/px-vue 3.0.43 → 3.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,24 +25,43 @@
25
25
  </div>
26
26
  </px-slide-transition>
27
27
  </div>
28
+
29
+ <slot name="scrollpreview" :direction="scrollPreview">
30
+ <div :class="bem('scroll-preview', { prev: true, visible: scrollPreview == -1 })">
31
+ <px-icon :src="require('../assets/feather/arrow-left.svg')" :size="2" />
32
+ </div>
33
+
34
+ <div :class="bem('scroll-preview', { next: true, visible: scrollPreview == 1 })">
35
+ <px-icon :src="require('../assets/feather/arrow-right.svg')" :size="2" />
36
+ </div>
37
+ </slot>
28
38
  </div>
29
39
  </template>
30
40
 
31
41
  <script>
32
42
  import PxBaseItemsSelect from './PxBaseItemsSelect.vue';
33
43
  import PxSlideTransition from './PxSlideTransition.vue';
44
+ import PxIcon from './PxIcon.vue';
45
+
34
46
  import gsap from 'gsap';
35
47
  import Drag from '../utils/drag.js';
48
+ import Lethargy from '../utils/lethargy.js';
36
49
 
37
50
  export default {
38
51
  name: 'px-slides',
39
52
  mixins: [PxBaseItemsSelect],
40
- components: { PxSlideTransition },
53
+ components: { PxSlideTransition, PxIcon },
41
54
 
42
55
  props: {
43
56
  // whether drag interaction is enabled
44
57
  dragEnabled: { type: Boolean, default: true },
45
58
 
59
+ // whether scroll interaction is enabled
60
+ scrollEnabled: { type: Boolean, default: false },
61
+
62
+ // whether to show an icon or other indicator that scrolling has started
63
+ scrollPreviewEnabled: { type: Boolean, default: false },
64
+
46
65
  // if true, slides loop to the first slide once last slide is reached
47
66
  loop: { type: Boolean, default: true },
48
67
 
@@ -60,6 +79,7 @@ export default {
60
79
  return {
61
80
  direction: 1,
62
81
  activeTransitions: 0,
82
+ scrollPreview: 0,
63
83
  };
64
84
  },
65
85
  computed: {},
@@ -100,11 +120,17 @@ export default {
100
120
  excludeSelector: this.dragExcludeSelector,
101
121
  disabled: !this.dragEnabled,
102
122
  });
123
+
124
+ if (this.scrollEnabled) {
125
+ this.$el.addEventListener('wheel', this.onWheel);
126
+ }
103
127
  },
104
128
  beforeDestroy() {
105
129
  if (this.drag) {
106
130
  this.drag.destroy();
107
131
  }
132
+
133
+ this.$el.removeEventListener('wheel', this.onWheel);
108
134
  },
109
135
  methods: {
110
136
  transitionStart() {
@@ -153,6 +179,39 @@ export default {
153
179
  }
154
180
  },
155
181
 
182
+ onWheel(e) {
183
+ if (typeof this.lethargy == 'undefined') {
184
+ this.lethargy = new Lethargy();
185
+ this.lethargyPrevCheck = false;
186
+ }
187
+
188
+ if (this.scrollPreviewEnabled) {
189
+ const delta = (e.deltaY + e.deltaX) / 2;
190
+ if (Math.abs(delta) > 5) {
191
+ this.scrollPreview = Math.max(Math.min(delta, 1), -1);
192
+ }
193
+
194
+ clearTimeout(this.scrollPreviewTimeout);
195
+ this.scrollPreviewTimeout = setTimeout(() => {
196
+ this.scrollPreview = 0;
197
+ }, 200);
198
+ }
199
+
200
+ const check = this.lethargy.check(e);
201
+
202
+ if (check !== this.lethargyPrevCheck) {
203
+ if (check) {
204
+ if (check > 0) {
205
+ this.previous();
206
+ } else {
207
+ this.next();
208
+ }
209
+ }
210
+ }
211
+
212
+ this.lethargyPrevCheck = check;
213
+ },
214
+
156
215
  next() {
157
216
  this.selectOffsetSafe(1, this.loop);
158
217
  },
@@ -213,5 +272,40 @@ export default {
213
272
  width: 100%;
214
273
  height: 100%;
215
274
  }
275
+
276
+ &__scroll-preview {
277
+ position: absolute;
278
+ top: 50%;
279
+ width: 5em;
280
+ height: 5em;
281
+ border-radius: 50%;
282
+ background-color: rgba(black, 0.07);
283
+ background-color: #f2f2f2;
284
+ backdrop-filter: blur(6px);
285
+ z-index: 100;
286
+ pointer-events: none;
287
+ opacity: 0;
288
+ transform: translate(0, -50%);
289
+
290
+ @include transition(opacity transform, $dur: 500ms);
291
+ @include depth-shadow(55, 0.05);
292
+
293
+ svg {
294
+ @include center();
295
+ color: currentColor;
296
+ }
297
+
298
+ &--prev {
299
+ left: 2.5em;
300
+ }
301
+
302
+ &--next {
303
+ right: 2.5em;
304
+ }
305
+
306
+ &--visible {
307
+ opacity: 1;
308
+ }
309
+ }
216
310
  }
217
311
  </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinkpixellab-public/px-vue",
3
- "version": "3.0.43",
3
+ "version": "3.0.44",
4
4
  "description": "General purpose Vue components and helpers that can be used across projects.",
5
5
  "author": "Pixel Lab",
6
6
  "license": "MIT",
@@ -0,0 +1,111 @@
1
+ // Adapted from here: https://github.com/d4nyll/lethargy
2
+ // MIT License
3
+
4
+ function Lethargy(stability, sensitivity, tolerance, delay) {
5
+ this.stability = stability != null ? Math.abs(stability) : 8;
6
+ this.sensitivity = sensitivity != null ? 1 + Math.abs(sensitivity) : 100;
7
+ this.tolerance = tolerance != null ? 1 + Math.abs(tolerance) : 1.1;
8
+ this.delay = delay != null ? delay : 150;
9
+ this.lastUpDeltas = function () {
10
+ var i, ref, results;
11
+ results = [];
12
+ for (
13
+ i = 1, ref = this.stability * 2;
14
+ 1 <= ref ? i <= ref : i >= ref;
15
+ 1 <= ref ? i++ : i--
16
+ ) {
17
+ results.push(null);
18
+ }
19
+ return results;
20
+ }.call(this);
21
+ this.lastDownDeltas = function () {
22
+ var i, ref, results;
23
+ results = [];
24
+ for (
25
+ i = 1, ref = this.stability * 2;
26
+ 1 <= ref ? i <= ref : i >= ref;
27
+ 1 <= ref ? i++ : i--
28
+ ) {
29
+ results.push(null);
30
+ }
31
+ return results;
32
+ }.call(this);
33
+ this.deltasTimestamp = function () {
34
+ var i, ref, results;
35
+ results = [];
36
+ for (
37
+ i = 1, ref = this.stability * 2;
38
+ 1 <= ref ? i <= ref : i >= ref;
39
+ 1 <= ref ? i++ : i--
40
+ ) {
41
+ results.push(null);
42
+ }
43
+ return results;
44
+ }.call(this);
45
+ }
46
+
47
+ Lethargy.prototype.check = function (e) {
48
+ var lastDelta;
49
+ e = e.originalEvent || e;
50
+ if (e.wheelDelta != null) {
51
+ lastDelta = e.wheelDelta;
52
+ } else if (e.deltaY != null) {
53
+ lastDelta = e.deltaY * -40;
54
+ } else if (e.detail != null || e.detail === 0) {
55
+ lastDelta = e.detail * -40;
56
+ }
57
+ this.deltasTimestamp.push(Date.now());
58
+ this.deltasTimestamp.shift();
59
+ if (lastDelta > 0) {
60
+ this.lastUpDeltas.push(lastDelta);
61
+ this.lastUpDeltas.shift();
62
+ return this.isInertia(1);
63
+ } else {
64
+ this.lastDownDeltas.push(lastDelta);
65
+ this.lastDownDeltas.shift();
66
+ return this.isInertia(-1);
67
+ }
68
+ return false;
69
+ };
70
+
71
+ Lethargy.prototype.isInertia = function (direction) {
72
+ var lastDeltas, lastDeltasNew, lastDeltasOld, newAverage, newSum, oldAverage, oldSum;
73
+ lastDeltas = direction === -1 ? this.lastDownDeltas : this.lastUpDeltas;
74
+ if (lastDeltas[0] === null) {
75
+ return direction;
76
+ }
77
+ if (
78
+ this.deltasTimestamp[this.stability * 2 - 2] + this.delay > Date.now() &&
79
+ lastDeltas[0] === lastDeltas[this.stability * 2 - 1]
80
+ ) {
81
+ return false;
82
+ }
83
+ lastDeltasOld = lastDeltas.slice(0, this.stability);
84
+ lastDeltasNew = lastDeltas.slice(this.stability, this.stability * 2);
85
+ oldSum = lastDeltasOld.reduce(function (t, s) {
86
+ return t + s;
87
+ });
88
+ newSum = lastDeltasNew.reduce(function (t, s) {
89
+ return t + s;
90
+ });
91
+ oldAverage = oldSum / lastDeltasOld.length;
92
+ newAverage = newSum / lastDeltasNew.length;
93
+ if (
94
+ Math.abs(oldAverage) < Math.abs(newAverage * this.tolerance) &&
95
+ this.sensitivity < Math.abs(newAverage)
96
+ ) {
97
+ return direction;
98
+ } else {
99
+ return false;
100
+ }
101
+ };
102
+
103
+ Lethargy.prototype.showLastUpDeltas = function () {
104
+ return this.lastUpDeltas;
105
+ };
106
+
107
+ Lethargy.prototype.showLastDownDeltas = function () {
108
+ return this.lastDownDeltas;
109
+ };
110
+
111
+ export default Lethargy;