@projektemacher/storymapjs 0.10.5 → 0.10.7

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.
Files changed (148) hide show
  1. package/CHANGELOG +11 -0
  2. package/dist/assets/{demo-CVQ7kFek.js → demo-D6cTmzn6.js} +1 -1
  3. package/dist/assets/{harness-C-VZV-ou.js → harness-BPFlzutp.js} +1 -1
  4. package/dist/assets/main-Y-MYUSJ4.js +17 -0
  5. package/dist/css/fonts/font.oldstandard.css +14 -32
  6. package/dist/demo.html +2 -2
  7. package/dist/docs/migration.html +1 -1
  8. package/dist/embed/index.html +129 -4
  9. package/dist/harness.html +2 -2
  10. package/dist/index.html +17 -0
  11. package/dist/js/storymap.d.ts +126 -7
  12. package/dist/js/storymap.js +4518 -3613
  13. package/dist/js/storymap.js.map +1 -1
  14. package/docs/migration-from-knightlab.md +139 -0
  15. package/docs/storymap-as-iiif-manifest.md +510 -0
  16. package/package.json +6 -3
  17. package/src/animation/easings.ts +18 -0
  18. package/src/animation/morpheus.d.ts +41 -0
  19. package/src/core/Browser.ts +19 -0
  20. package/src/core/Load.ts +180 -0
  21. package/src/core/Util.ts +354 -0
  22. package/src/core/mixins.ts +171 -0
  23. package/src/dom/Dom.ts +31 -0
  24. package/src/dom/DomEvent.ts +61 -0
  25. package/src/globals.d.ts +16 -0
  26. package/src/language/Language.ts +107 -0
  27. package/src/language/locale/be.json +18 -0
  28. package/src/language/locale/bg.json +18 -0
  29. package/src/language/locale/cs.json +18 -0
  30. package/src/language/locale/de.json +20 -0
  31. package/src/language/locale/el.json +18 -0
  32. package/src/language/locale/en.json +28 -0
  33. package/src/language/locale/es.json +18 -0
  34. package/src/language/locale/et.json +18 -0
  35. package/src/language/locale/fr.json +18 -0
  36. package/src/language/locale/he.json +18 -0
  37. package/src/language/locale/hu.json +18 -0
  38. package/src/language/locale/is.json +18 -0
  39. package/src/language/locale/it.json +18 -0
  40. package/src/language/locale/jp.json +18 -0
  41. package/src/language/locale/ko.json +18 -0
  42. package/src/language/locale/nl.json +18 -0
  43. package/src/language/locale/nn.json +18 -0
  44. package/src/language/locale/no.json +18 -0
  45. package/src/language/locale/pl.json +18 -0
  46. package/src/language/locale/pt.json +18 -0
  47. package/src/language/locale/ru.json +18 -0
  48. package/src/language/locale/sk.json +18 -0
  49. package/src/language/locale/sr.json +17 -0
  50. package/src/language/locale/sv.json +18 -0
  51. package/src/language/locale/tr.json +18 -0
  52. package/src/language/locale/uk.json +18 -0
  53. package/src/language/locale/ur.json +18 -0
  54. package/src/language/locale/zh-cn.json +18 -0
  55. package/src/language/locale/zh-tw.json +18 -0
  56. package/src/main.ts +51 -0
  57. package/src/map/Map.ts +717 -0
  58. package/src/map/MapMarker.ts +149 -0
  59. package/src/map/openlayers/Map.OpenLayers.ts +1879 -0
  60. package/src/map/openlayers/MapMarker.OpenLayers.ts +176 -0
  61. package/src/map/openlayers/zoomifyTiles.ts +28 -0
  62. package/src/map/types.ts +17 -0
  63. package/src/media/EmbedUtil.ts +168 -0
  64. package/src/media/Media.ts +409 -0
  65. package/src/media/MediaType.ts +163 -0
  66. package/src/media/types/Audio.ts +87 -0
  67. package/src/media/types/Blockquote.ts +40 -0
  68. package/src/media/types/DailyMotion.ts +58 -0
  69. package/src/media/types/DocumentCloud.ts +41 -0
  70. package/src/media/types/Facebook.ts +41 -0
  71. package/src/media/types/Flickr.ts +115 -0
  72. package/src/media/types/GoogleDoc.ts +59 -0
  73. package/src/media/types/IFrame.ts +51 -0
  74. package/src/media/types/Image.ts +49 -0
  75. package/src/media/types/Juxtapose.ts +32 -0
  76. package/src/media/types/SoundCloud.ts +77 -0
  77. package/src/media/types/Text.ts +172 -0
  78. package/src/media/types/Twitter.ts +96 -0
  79. package/src/media/types/Video.ts +84 -0
  80. package/src/media/types/Vimeo.ts +65 -0
  81. package/src/media/types/Website.ts +36 -0
  82. package/src/media/types/Wikipedia.ts +124 -0
  83. package/src/media/types/YouTube.ts +192 -0
  84. package/src/scss/Typography.scss +237 -0
  85. package/src/scss/VCO.StoryMap.Dark.scss +138 -0
  86. package/src/scss/VCO.StoryMap.scss +164 -0
  87. package/src/scss/Variables.Dark.scss +56 -0
  88. package/src/scss/Variables.scss +47 -0
  89. package/src/scss/core/Mixins.scss +112 -0
  90. package/src/scss/core/Reset.scss +206 -0
  91. package/src/scss/fonts/_font.base.scss +113 -0
  92. package/src/scss/fonts/font.abril-droidsans.scss +75 -0
  93. package/src/scss/fonts/font.amatic-andika.scss +73 -0
  94. package/src/scss/fonts/font.bitter-raleway.scss +86 -0
  95. package/src/scss/fonts/font.clicker-garamond.scss +92 -0
  96. package/src/scss/fonts/font.dancing-ledger.scss +74 -0
  97. package/src/scss/fonts/font.default.scss +9 -0
  98. package/src/scss/fonts/font.fjalla-average.scss +80 -0
  99. package/src/scss/fonts/font.georgia-helvetica.scss +58 -0
  100. package/src/scss/fonts/font.knightlab.scss +97 -0
  101. package/src/scss/fonts/font.lustria-lato.scss +80 -0
  102. package/src/scss/fonts/font.medula-lato.scss +73 -0
  103. package/src/scss/fonts/font.oldstandard.scss +88 -0
  104. package/src/scss/fonts/font.opensans-gentiumbook.scss +80 -0
  105. package/src/scss/fonts/font.playfair-faunaone.scss +86 -0
  106. package/src/scss/fonts/font.playfair.scss +85 -0
  107. package/src/scss/fonts/font.pt.scss +90 -0
  108. package/src/scss/fonts/font.roboto-megrim.scss +73 -0
  109. package/src/scss/fonts/font.rufina-sintony.scss +73 -0
  110. package/src/scss/fonts/font.ubuntu.scss +78 -0
  111. package/src/scss/fonts/font.unicaone-vollkorn.scss +85 -0
  112. package/src/scss/icons/Icons.scss +239 -0
  113. package/src/scss/map/VCO.ImageMarker.scss +23 -0
  114. package/src/scss/map/VCO.Map.scss +21 -0
  115. package/src/scss/map/VCO.MapMarker.scss +147 -0
  116. package/src/scss/map/openlayers/VCO.Map.OpenLayers.scss +126 -0
  117. package/src/scss/media/VCO.Media.scss +222 -0
  118. package/src/scss/media/types/VCO.Media.Blockquote.scss +76 -0
  119. package/src/scss/media/types/VCO.Media.IFrame.scss +11 -0
  120. package/src/scss/media/types/VCO.Media.Image.scss +13 -0
  121. package/src/scss/media/types/VCO.Media.Instagram.scss +7 -0
  122. package/src/scss/media/types/VCO.Media.Profile.scss +5 -0
  123. package/src/scss/media/types/VCO.Media.Text.scss +90 -0
  124. package/src/scss/media/types/VCO.Media.Twitter.scss +87 -0
  125. package/src/scss/media/types/VCO.Media.Wikipedia.scss +64 -0
  126. package/src/scss/site/site.scss +748 -0
  127. package/src/scss/slider/VCO.Slide.scss +447 -0
  128. package/src/scss/slider/VCO.SlideNav.scss +338 -0
  129. package/src/scss/slider/VCO.StorySlider.scss +64 -0
  130. package/src/scss/snapmap/VCO.SnapMap.scss +103 -0
  131. package/src/scss/ui/VCO.Consent.scss +77 -0
  132. package/src/scss/ui/VCO.MenuBar.Button.scss +99 -0
  133. package/src/scss/ui/VCO.MenuBar.scss +20 -0
  134. package/src/scss/ui/VCO.Message.scss +104 -0
  135. package/src/site/site.ts +87 -0
  136. package/src/slider/Slide.ts +460 -0
  137. package/src/slider/SlideNav.ts +212 -0
  138. package/src/slider/StorySlider.ts +722 -0
  139. package/src/storymap/Consent.ts +146 -0
  140. package/src/storymap/StoryMap.ts +1108 -0
  141. package/src/storymap/iiif.ts +386 -0
  142. package/src/storymap/validate.ts +184 -0
  143. package/src/types.ts +297 -0
  144. package/src/ui/Draggable.ts +374 -0
  145. package/src/ui/MenuBar.ts +323 -0
  146. package/src/ui/Message.ts +118 -0
  147. package/src/ui/Swipable.ts +388 -0
  148. package/dist/assets/main-DwbXrrYn.js +0 -17
package/src/types.ts ADDED
@@ -0,0 +1,297 @@
1
+ // Shared types for the StoryMapJS codebase.
2
+
3
+ // ---------- Storymap data (exchange format) ----------
4
+
5
+ export interface StorymapSlideText {
6
+ headline?: string;
7
+ text?: string;
8
+ text_align?: string;
9
+ }
10
+
11
+ export interface StorymapSlideLocation {
12
+ lat?: number;
13
+ lon?: number;
14
+ zoom?: number;
15
+ line?: boolean;
16
+ icon?: string;
17
+ iconSize?: number[];
18
+ image?: string;
19
+ use_custom_marker?: boolean;
20
+ [key: string]: unknown;
21
+ }
22
+
23
+ export type MediaTypeMatch = {
24
+ type: string;
25
+ name: string;
26
+ match_str: string;
27
+ // media type class constructor
28
+ cls: new (data: StorymapSlideMedia, options: Record<string, unknown>) => unknown;
29
+ };
30
+
31
+ export interface StorymapSlideMedia {
32
+ url?: string | null;
33
+ caption?: string | null;
34
+ credit?: string | null;
35
+ thumb?: string | null;
36
+ mediatype?: MediaTypeMatch | null;
37
+ [key: string]: unknown;
38
+ }
39
+
40
+ export interface StorymapSlideBackground {
41
+ url?: string | null;
42
+ color?: string | null;
43
+ opacity?: number;
44
+ }
45
+
46
+ export interface StorymapSlide {
47
+ type?: string;
48
+ date?: string | Record<string, unknown> | null;
49
+ group?: string;
50
+ location?: StorymapSlideLocation;
51
+ media?: StorymapSlideMedia;
52
+ text?: StorymapSlideText;
53
+ background?: StorymapSlideBackground | string | null;
54
+ uniqueid?: string;
55
+ [key: string]: unknown;
56
+ }
57
+
58
+ export interface StorymapData {
59
+ uniqueid?: string;
60
+ slides: StorymapSlide[];
61
+ [key: string]: unknown;
62
+ }
63
+
64
+ export interface StorymapDataWrapper {
65
+ storymap: StorymapData;
66
+ }
67
+
68
+ // ---------- StoryMap / Map options ----------
69
+
70
+ export interface StorymapOptions {
71
+ width: number;
72
+ height: number;
73
+ layout: string;
74
+ base_class: string;
75
+ default_bg_color: { r: number; g: number; b: number };
76
+ map_size_sticky: number;
77
+ map_center_offset: { left: number; top: number } | null;
78
+ less_bounce: boolean;
79
+ start_at_slide: number;
80
+ call_to_action: boolean;
81
+ call_to_action_text: string;
82
+ menubar_height: number;
83
+ /** Show a fullscreen toggle button in the menubar (default: true) */
84
+ fullscreen: boolean;
85
+ /** Show the map overview button in the menubar (default: true) */
86
+ show_overview: boolean;
87
+ /** Show the back-to-the-beginning button in the menubar (default: true) */
88
+ show_back_to_start: boolean;
89
+ skinny_size: number;
90
+ duration: number;
91
+ ease: unknown;
92
+ dragging: boolean;
93
+ trackResize: boolean;
94
+ /**
95
+ * Navigate slides with arrow keys anywhere on the page (default false:
96
+ * arrows only work when the slide panel has focus). Form elements and
97
+ * the map itself (which pans) are always skipped. Read at construction.
98
+ */
99
+ keyboard: boolean;
100
+ /** Re-fetch the source file on every load, bypassing caches (issue #417) */
101
+ nocache: boolean;
102
+ /** Advance slides automatically every N milliseconds; 0 disables (issue #380) */
103
+ autoplay: number;
104
+ /** Show a progress bar in the menubar (issue #247) */
105
+ show_progress: boolean;
106
+ /** Show the slide headline as a label on the active map marker (issue #243) */
107
+ marker_labels: boolean;
108
+ /** Default text alignment for slide text: left, center or right (issue #244) */
109
+ text_align: "left" | "center" | "right";
110
+ /** Override the overview fit center (issues #107, #271) */
111
+ map_overview_center: { lat: number; lon: number } | null;
112
+ map_type: string;
113
+ attribution: string;
114
+ /**
115
+ * Stacked raster overlays above the base map, below the route lines.
116
+ * Each entry accepts any `map_type` value (XYZ template, `osm:style`,
117
+ * …) plus per-layer presentation; see StorymapOverlayLayer. Empty
118
+ * (default) means base map only.
119
+ */
120
+ overlays: StorymapOverlayLayer[];
121
+ map_mini: boolean;
122
+ map_subdomains: string;
123
+ map_as_image: boolean;
124
+ map_access_token: string;
125
+ map_background_color: string;
126
+ /**
127
+ * Landscape map layout: `"full"` (default) spans the whole width with the
128
+ * slide panel fading in over it (the map view is offset so markers clear
129
+ * the panel); `"left"` limits the map to the left, visible half with an
130
+ * opaque slide panel — no offset needed, fits and constraints align with
131
+ * the visible area directly. Portrait layouts are unaffected.
132
+ */
133
+ map_area: "full" | "left";
134
+ /**
135
+ * Limit the map to a bounding box `[west, south, east, north]` (lon/lat;
136
+ * raw image pixel coordinates for image-space maps). The view center is
137
+ * constrained to the box; `null` (default) leaves the map unconstrained.
138
+ */
139
+ map_bbox: number[] | null;
140
+ /**
141
+ * Constrain the minimap overview to a bounding box `[west, south, east,
142
+ * north]` in lon/lat (mercator maps only); `null` (default) leaves the
143
+ * overview unconstrained.
144
+ */
145
+ overview_extent: [number, number, number, number] | null;
146
+ /**
147
+ * Legacy zoomify image pyramid (map_type: "zoomify"): the tiles are
148
+ * placed at the standard mercator tile positions, stretched from the
149
+ * world's top-left corner.
150
+ */
151
+ zoomify?:
152
+ | {
153
+ path?: string;
154
+ width?: number;
155
+ height?: number;
156
+ tolerance?: number;
157
+ attribution?: string;
158
+ }
159
+ | boolean;
160
+ /**
161
+ * Ask for permission before loading anything from external services
162
+ * (media embeds, map tiles, external font CSS) — GDPR consent mode.
163
+ * Grants are remembered per service in a cookie for 90 days.
164
+ */
165
+ consent_required: boolean;
166
+ /** Slide text color override, sets --vco-color-text (issue #177) */
167
+ text_color: string;
168
+ /** Slide panel background color override (issue #177) */
169
+ text_background_color: string;
170
+ /** Show the great-circle route distance in the menubar (issue #341) */
171
+ show_distance: boolean;
172
+ /**
173
+ * Raw OpenLayers map configuration. `controls` and `interactions` replace
174
+ * the StoryMapJS defaults, `view` is merged over the computed default view
175
+ * and `element` (an HTMLElement or DOM id) replaces the auto-created map
176
+ * container div.
177
+ */
178
+ map_options: StorymapMapOptions;
179
+ map_popup: boolean;
180
+ zoom_distance: number;
181
+ calculate_zoom: boolean;
182
+ line_follows_path: boolean;
183
+ line_color: string;
184
+ line_color_inactive: string;
185
+ line_join: string;
186
+ line_weight: number;
187
+ line_opacity: number;
188
+ line_dash: string;
189
+ show_lines: boolean;
190
+ show_history_line: boolean;
191
+ use_custom_markers: boolean;
192
+ iiif: { url: string; attribution: string };
193
+ map_height: number;
194
+ storyslider_height: number;
195
+ slide_padding_lr: number;
196
+ slide_default_fade: string;
197
+ menubar_default_y: number;
198
+ path_gfx: string;
199
+ script_path: string;
200
+ font_css: string;
201
+ language: string;
202
+ api_key_flickr: string;
203
+ [key: string]: unknown;
204
+ }
205
+
206
+ // ---------- animation ----------
207
+
208
+ export interface AnimateOptions extends Record<string, unknown> {
209
+ duration?: number;
210
+ easing?: unknown;
211
+ complete?: unknown;
212
+ left?: string | number;
213
+ top?: string | number;
214
+ }
215
+
216
+ export interface AnimationHandle {
217
+ stop: (jump?: boolean) => void;
218
+ }
219
+
220
+ // ---------- map ----------
221
+
222
+ /**
223
+ * A stacked raster overlay above the base map (StorymapOptions.overlays).
224
+ * Presentation is declarative: hosts no longer need to reach into the
225
+ * layer objects for blend modes, clips or stacking tweaks.
226
+ */
227
+ export interface StorymapOverlayLayer {
228
+ /** Any `map_type` value the tile layer factory accepts */
229
+ map_type: string;
230
+ /** Layer opacity 0..1 (default 1) */
231
+ opacity?: number;
232
+ /** Initial visibility (default true) */
233
+ visible?: boolean;
234
+ /** Extra attribution fragment, listed while the overlay is visible */
235
+ attribution?: string;
236
+ /**
237
+ * CSS class for the layer container. OpenLayers paints every layer
238
+ * with the same class into one shared div/canvas, so a distinct
239
+ * class isolates this layer (e.g. for blend modes). The class
240
+ * replaces the default wholesale, so keep the `ol-layer` token
241
+ * (e.g. `"ol-layer historic-sheet"`) unless you know why not.
242
+ */
243
+ className?: string;
244
+ /** CSS mix-blend-mode for the layer container (needs className) */
245
+ blendMode?: string;
246
+ /** Clip box `[west, south, east, north]` in lon/lat (mercator maps) */
247
+ extent?: [number, number, number, number];
248
+ }
249
+
250
+ /** OpenLayers passthrough options (see StorymapOptions.map_options) */
251
+ export interface StorymapMapOptions {
252
+ /** HTMLElement or DOM id that becomes the real map container */
253
+ element?: HTMLElement | string;
254
+ /** Merged over the default view configuration */
255
+ view?: Record<string, unknown>;
256
+ /** Replaces the default (empty) controls list */
257
+ controls?: unknown[];
258
+ /** Replaces the default (empty) interactions list */
259
+ interactions?: unknown[];
260
+ /** Any other ol/Map constructor option (layers, pixelRatio, ...) */
261
+ [key: string]: unknown;
262
+ }
263
+
264
+ export interface LatLngLiteral {
265
+ lat: number | undefined;
266
+ lon?: number | undefined;
267
+ lng?: number | undefined;
268
+ }
269
+
270
+ export interface MapMarkerData {
271
+ real_marker?: boolean;
272
+ location?: StorymapSlideLocation;
273
+ media?: StorymapSlideMedia & { mediatype?: MediaTypeMatch | null };
274
+ text?: { headline?: string };
275
+ type?: string;
276
+ [key: string]: unknown;
277
+ }
278
+
279
+ export type IconSpec = {
280
+ url: string;
281
+ size: number[];
282
+ anchor: number[];
283
+ };
284
+
285
+ // ---------- media ----------
286
+
287
+ export interface MediaState {
288
+ loaded: boolean;
289
+ [key: string]: unknown;
290
+ }
291
+
292
+ export interface LanguageStrings {
293
+ [key: string]: unknown;
294
+ loading: string;
295
+ wikipedia: string;
296
+ start: string;
297
+ }
@@ -0,0 +1,374 @@
1
+ import { mergeData } from "../core/Util";
2
+ import { Evented, type EventedInstance } from "../core/mixins";
3
+ import Dom from "../dom/Dom";
4
+ import { DomEvent, type LegacyEvent } from "../dom/DomEvent";
5
+ import { touch } from "../core/Browser";
6
+ import { easeInOutQuint, easeOutStrong } from "../animation/easings";
7
+ import Animate from "morpheus";
8
+ import type { AnimateOptions, AnimationHandle } from "../types";
9
+
10
+ /* Draggable
11
+ Draggable allows you to add dragging capabilities to any element. Supports mobile devices too.
12
+ TODO Enable constraints
13
+ ================================================== */
14
+
15
+ interface DragEventNames {
16
+ down: string;
17
+ up: string;
18
+ leave: string;
19
+ move: string;
20
+ }
21
+
22
+ interface DraggableOptions {
23
+ enable: { x: boolean; y: boolean };
24
+ constraint: {
25
+ top: number | boolean;
26
+ bottom: number | boolean;
27
+ left: number | boolean;
28
+ right: number | boolean;
29
+ };
30
+ momentum_multiplier: number;
31
+ duration: number;
32
+ ease: unknown;
33
+ }
34
+
35
+ interface DragData {
36
+ sliding: boolean;
37
+ direction: string | null;
38
+ pagex: { start: number; end: number };
39
+ pagey: { start: number; end: number };
40
+ pos: { start: { x: number; y: number }; end: { x: number; y: number } };
41
+ new_pos: { x: number; y: number };
42
+ new_pos_parent: { x: number; y: number };
43
+ time: { start: number; end: number };
44
+ touch: boolean;
45
+ }
46
+
47
+ export class DraggableBase {
48
+ declare "_el": Record<string, HTMLElement>;
49
+ declare "options": DraggableOptions;
50
+ declare "animator": AnimationHandle | null;
51
+ declare "dragevent": DragEventNames;
52
+ declare "data": DragData;
53
+ declare "fire": EventedInstance["fire"];
54
+
55
+ mousedrag = {
56
+ down: "mousedown",
57
+ up: "mouseup",
58
+ leave: "mouseleave",
59
+ move: "mousemove",
60
+ };
61
+
62
+ touchdrag = {
63
+ down: "touchstart",
64
+ up: "touchend",
65
+ leave: "touchleave",
66
+ move: "touchmove",
67
+ };
68
+
69
+ constructor(drag_elem: HTMLElement, options: Record<string, unknown>, move_elem?: HTMLElement) {
70
+ // DOM ELements
71
+ this._el = {
72
+ drag: drag_elem,
73
+ move: drag_elem,
74
+ };
75
+
76
+ if (move_elem) {
77
+ this._el.move = move_elem;
78
+ }
79
+
80
+ //Options
81
+ this.options = {
82
+ enable: {
83
+ x: true,
84
+ y: true,
85
+ },
86
+ constraint: {
87
+ top: false,
88
+ bottom: false,
89
+ left: false,
90
+ right: false,
91
+ },
92
+ momentum_multiplier: 2000,
93
+ duration: 1000,
94
+ ease: easeInOutQuint,
95
+ };
96
+
97
+ // Animation Object
98
+ this.animator = null;
99
+
100
+ // Drag Event Type
101
+ this.dragevent = this.mousedrag;
102
+
103
+ if (touch) {
104
+ this.dragevent = this.touchdrag;
105
+ }
106
+
107
+ // Draggable Data
108
+ this.data = {
109
+ sliding: false,
110
+ direction: "none",
111
+ pagex: {
112
+ start: 0,
113
+ end: 0,
114
+ },
115
+ pagey: {
116
+ start: 0,
117
+ end: 0,
118
+ },
119
+ pos: {
120
+ start: {
121
+ x: 0,
122
+ y: 0,
123
+ },
124
+ end: {
125
+ x: 0,
126
+ y: 0,
127
+ },
128
+ },
129
+ new_pos: {
130
+ x: 0,
131
+ y: 0,
132
+ },
133
+ new_pos_parent: {
134
+ x: 0,
135
+ y: 0,
136
+ },
137
+ time: {
138
+ start: 0,
139
+ end: 0,
140
+ },
141
+ touch: false,
142
+ };
143
+
144
+ // Merge Data and Options
145
+ mergeData(this.options, options);
146
+ }
147
+
148
+ enable(e?: LegacyEvent): void {
149
+ // Temporarily disableing this until I have time to fix some issues.
150
+ //DomEvent.addListener(this._el.drag, this.dragevent.down, this._onDragStart, this);
151
+ //DomEvent.addListener(this._el.drag, this.dragevent.up, this._onDragEnd, this);
152
+
153
+ this.data.pos.start = 0 as unknown as { x: number; y: number }; //Dom.getPosition(this._el.move);
154
+ this._el.move.style.left = this.data.pos.start.x + "px";
155
+ this._el.move.style.top = this.data.pos.start.y + "px";
156
+ this._el.move.style.position = "absolute";
157
+ //this._el.move.style.zIndex = "11";
158
+ //this._el.move.style.cursor = "move";
159
+ }
160
+
161
+ disable() {
162
+ DomEvent.removeListener(this._el.drag, this.dragevent.down, this._onDragStart, this);
163
+ DomEvent.removeListener(this._el.drag, this.dragevent.up, this._onDragEnd, this);
164
+ }
165
+
166
+ stopMomentum() {
167
+ if (this.animator) {
168
+ this.animator.stop();
169
+ }
170
+ }
171
+
172
+ updateConstraint(c: DraggableOptions["constraint"]): void {
173
+ this.options.constraint = c;
174
+
175
+ // Temporary until issues are fixed
176
+ }
177
+
178
+ /* Private Methods
179
+ ================================================== */
180
+ _onDragStart(e: LegacyEvent) {
181
+ if (touch) {
182
+ if (e.originalEvent) {
183
+ this.data.pagex.start = e.originalEvent.touches[0].screenX;
184
+ this.data.pagey.start = e.originalEvent.touches[0].screenY;
185
+ } else {
186
+ this.data.pagex.start = e.targetTouches[0].screenX;
187
+ this.data.pagey.start = e.targetTouches[0].screenY;
188
+ }
189
+ } else {
190
+ this.data.pagex.start = e.pageX;
191
+ this.data.pagey.start = e.pageY;
192
+ }
193
+
194
+ // Center element to finger or mouse
195
+ if (this.options.enable.x) {
196
+ this._el.move.style.left = this.data.pagex.start - this._el.move.offsetWidth / 2 + "px";
197
+ }
198
+
199
+ if (this.options.enable.y) {
200
+ this._el.move.style.top = this.data.pagey.start - this._el.move.offsetHeight / 2 + "px";
201
+ }
202
+
203
+ this.data.pos.start = Dom.getPosition(this._el.drag);
204
+ this.data.time.start = Date.now();
205
+
206
+ this.fire("dragstart", this.data);
207
+ DomEvent.addListener(this._el.drag, this.dragevent.move, this._onDragMove, this);
208
+ DomEvent.addListener(this._el.drag, this.dragevent.leave, this._onDragEnd, this);
209
+ }
210
+
211
+ _onDragEnd(e: LegacyEvent) {
212
+ this.data.sliding = false;
213
+ DomEvent.removeListener(this._el.drag, this.dragevent.move, this._onDragMove, this);
214
+ DomEvent.removeListener(this._el.drag, this.dragevent.leave, this._onDragEnd, this);
215
+ this.fire("dragend", this.data);
216
+
217
+ // momentum
218
+ this._momentum();
219
+ }
220
+
221
+ _onDragMove(e: LegacyEvent) {
222
+ e.preventDefault();
223
+ this.data.sliding = true;
224
+
225
+ if (touch) {
226
+ if (e.originalEvent) {
227
+ this.data.pagex.end = e.originalEvent.touches[0].screenX;
228
+ this.data.pagey.end = e.originalEvent.touches[0].screenY;
229
+ } else {
230
+ this.data.pagex.end = e.targetTouches[0].screenX;
231
+ this.data.pagey.end = e.targetTouches[0].screenY;
232
+ }
233
+ } else {
234
+ this.data.pagex.end = e.pageX;
235
+ this.data.pagey.end = e.pageY;
236
+ }
237
+
238
+ this.data.pos.end = Dom.getPosition(this._el.drag);
239
+ this.data.new_pos.x = -(
240
+ this.data.pagex.start -
241
+ this.data.pagex.end -
242
+ this.data.pos.start.x
243
+ ); //-(this.data.pagex.start - this.data.pagex.end - this.data.pos.end.x);
244
+ this.data.new_pos.y = -(
245
+ this.data.pagey.start -
246
+ this.data.pagey.end -
247
+ this.data.pos.start.y
248
+ );
249
+
250
+ if (this.options.enable.x) {
251
+ this._el.move.style.left = this.data.new_pos.x + "px";
252
+ }
253
+
254
+ if (this.options.enable.y) {
255
+ this._el.move.style.top = this.data.new_pos.y + "px";
256
+ }
257
+
258
+ this.fire("dragmove", this.data);
259
+ }
260
+
261
+ _momentum() {
262
+ const pos_adjust = {
263
+ x: 0,
264
+ y: 0,
265
+ time: 0,
266
+ },
267
+ pos_change = {
268
+ x: 0,
269
+ y: 0,
270
+ time: 0,
271
+ };
272
+ let swipe = false;
273
+ const _swipe_direction = "";
274
+
275
+ if (touch) {
276
+ //this.options.momentum_multiplier = this.options.momentum_multiplier * 2;
277
+ }
278
+
279
+ pos_adjust.time = (Date.now() - this.data.time.start) * 10;
280
+ pos_change.time = (Date.now() - this.data.time.start) * 10;
281
+
282
+ pos_change.x =
283
+ this.options.momentum_multiplier *
284
+ (Math.abs(this.data.pagex.end) - Math.abs(this.data.pagex.start));
285
+ pos_change.y =
286
+ this.options.momentum_multiplier *
287
+ (Math.abs(this.data.pagey.end) - Math.abs(this.data.pagey.start));
288
+
289
+ pos_adjust.x = Math.round(pos_change.x / pos_change.time);
290
+ pos_adjust.y = Math.round(pos_change.y / pos_change.time);
291
+
292
+ this.data.new_pos.x = this.data.pos.end.x + pos_adjust.x;
293
+ this.data.new_pos.y = this.data.pos.end.y + pos_adjust.y;
294
+
295
+ if (!this.options.enable.x) {
296
+ this.data.new_pos.x = this.data.pos.start.x;
297
+ } else if (this.data.new_pos.x < 0) {
298
+ this.data.new_pos.x = 0;
299
+ }
300
+
301
+ if (!this.options.enable.y) {
302
+ this.data.new_pos.y = this.data.pos.start.y;
303
+ } else if (this.data.new_pos.y < 0) {
304
+ this.data.new_pos.y = 0;
305
+ }
306
+
307
+ // Detect Swipe
308
+ if (pos_change.time < 3000) {
309
+ swipe = true;
310
+ }
311
+
312
+ // Detect Direction
313
+ if (Math.abs(pos_change.x) > 10000) {
314
+ this.data.direction = "left";
315
+ if (pos_change.x > 0) {
316
+ this.data.direction = "right";
317
+ }
318
+ }
319
+ // Detect Swipe
320
+ if (Math.abs(pos_change.y) > 10000) {
321
+ this.data.direction = "up";
322
+ if (pos_change.y > 0) {
323
+ this.data.direction = "down";
324
+ }
325
+ }
326
+ this._animateMomentum();
327
+ if (swipe) {
328
+ this.fire("swipe_" + this.data.direction, this.data);
329
+ }
330
+ }
331
+
332
+ _animateMomentum() {
333
+ const pos = {
334
+ x: this.data.new_pos.x,
335
+ y: this.data.new_pos.y,
336
+ },
337
+ animate: AnimateOptions = {
338
+ duration: this.options.duration,
339
+ easing: easeOutStrong,
340
+ };
341
+
342
+ if (this.options.enable.y) {
343
+ if (this.options.constraint.top || this.options.constraint.bottom) {
344
+ if (pos.y > (this.options.constraint.bottom as number)) {
345
+ pos.y = this.options.constraint.bottom as number;
346
+ } else if (pos.y < (this.options.constraint.top as number)) {
347
+ pos.y = this.options.constraint.top as number;
348
+ }
349
+ }
350
+ animate.top = Math.floor(pos.y) + "px";
351
+ }
352
+
353
+ if (this.options.enable.x) {
354
+ if (this.options.constraint.left || this.options.constraint.right) {
355
+ if (pos.x > (this.options.constraint.left as number)) {
356
+ pos.x = this.options.constraint.left as number;
357
+ } else if (pos.x < (this.options.constraint.right as number)) {
358
+ pos.x = this.options.constraint.right as number;
359
+ }
360
+ }
361
+ animate.left = Math.floor(pos.x) + "px";
362
+ }
363
+
364
+ this.animator = Animate(this._el.move, animate);
365
+
366
+ this.fire("momentum", this.data);
367
+ }
368
+ }
369
+
370
+ export class Draggable extends Evented(DraggableBase) {
371
+ constructor(...args: ConstructorParameters<typeof DraggableBase>) {
372
+ super(...args);
373
+ }
374
+ }