1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,680 @@ |
1 |
+/*! |
|
2 |
+ * ScrollMagic v2.0.7 (2019-05-07) |
|
3 |
+ * The javascript library for magical scroll interactions. |
|
4 |
+ * (c) 2019 Jan Paepke (@janpaepke) |
|
5 |
+ * Project Website: http://scrollmagic.io |
|
6 |
+ * |
|
7 |
+ * @version 2.0.7 |
|
8 |
+ * @license Dual licensed under MIT license and GPL. |
|
9 |
+ * @author Jan Paepke - e-mail@janpaepke.de |
|
10 |
+ * |
|
11 |
+ * @file Debug Extension for ScrollMagic. |
|
12 |
+ */ |
|
13 |
+/** |
|
14 |
+ * This plugin was formerly known as the ScrollMagic debug extension. |
|
15 |
+ * |
|
16 |
+ * It enables you to add visual indicators to your page, to be able to see exactly when a scene is triggered. |
|
17 |
+ * |
|
18 |
+ * To have access to this extension, please include `plugins/debug.addIndicators.js`. |
|
19 |
+ * @mixin debug.addIndicators |
|
20 |
+ */ |
|
21 |
+(function (root, factory) { |
|
22 |
+ if (typeof define === 'function' && define.amd) { |
|
23 |
+ // AMD. Register as an anonymous module. |
|
24 |
+ define(['ScrollMagic'], factory); |
|
25 |
+ } else if (typeof exports === 'object') { |
|
26 |
+ // CommonJS |
|
27 |
+ factory(require('scrollmagic')); |
|
28 |
+ } else { |
|
29 |
+ // no browser global export needed, just execute |
|
30 |
+ factory(root.ScrollMagic || (root.jQuery && root.jQuery.ScrollMagic)); |
|
31 |
+ } |
|
32 |
+}(this, function (ScrollMagic) { |
|
33 |
+ "use strict"; |
|
34 |
+ var NAMESPACE = "debug.addIndicators"; |
|
35 |
+ |
|
36 |
+ var |
|
37 |
+ console = window.console || {}, |
|
38 |
+ err = Function.prototype.bind.call(console.error || console.log || function () {}, console); |
|
39 |
+ if (!ScrollMagic) { |
|
40 |
+ err("(" + NAMESPACE + ") -> ERROR: The ScrollMagic main module could not be found. Please make sure it's loaded before this plugin or use an asynchronous loader like requirejs."); |
|
41 |
+ } |
|
42 |
+ |
|
43 |
+ // plugin settings |
|
44 |
+ var |
|
45 |
+ FONT_SIZE = "0.85em", |
|
46 |
+ ZINDEX = "9999", |
|
47 |
+ EDGE_OFFSET = 15; // minimum edge distance, added to indentation |
|
48 |
+ |
|
49 |
+ // overall vars |
|
50 |
+ var |
|
51 |
+ _util = ScrollMagic._util, |
|
52 |
+ _autoindex = 0; |
|
53 |
+ |
|
54 |
+ |
|
55 |
+ |
|
56 |
+ ScrollMagic.Scene.extend(function () { |
|
57 |
+ var |
|
58 |
+ Scene = this, |
|
59 |
+ _indicator; |
|
60 |
+ |
|
61 |
+ var log = function () { |
|
62 |
+ if (Scene._log) { // not available, when main source minified |
|
63 |
+ Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->"); |
|
64 |
+ Scene._log.apply(this, arguments); |
|
65 |
+ } |
|
66 |
+ }; |
|
67 |
+ |
|
68 |
+ /** |
|
69 |
+ * Add visual indicators for a ScrollMagic.Scene. |
|
70 |
+ * @memberof! debug.addIndicators# |
|
71 |
+ * |
|
72 |
+ * @example |
|
73 |
+ * // add basic indicators |
|
74 |
+ * scene.addIndicators() |
|
75 |
+ * |
|
76 |
+ * // passing options |
|
77 |
+ * scene.addIndicators({name: "pin scene", colorEnd: "#FFFFFF"}); |
|
78 |
+ * |
|
79 |
+ * @param {object} [options] - An object containing one or more options for the indicators. |
|
80 |
+ * @param {(string|object)} [options.parent] - A selector, DOM Object or a jQuery object that the indicators should be added to. |
|
81 |
+ If undefined, the controller's container will be used. |
|
82 |
+ * @param {number} [options.name=""] - This string will be displayed at the start and end indicators of the scene for identification purposes. If no name is supplied an automatic index will be used. |
|
83 |
+ * @param {number} [options.indent=0] - Additional position offset for the indicators (useful, when having multiple scenes starting at the same position). |
|
84 |
+ * @param {string} [options.colorStart=green] - CSS color definition for the start indicator. |
|
85 |
+ * @param {string} [options.colorEnd=red] - CSS color definition for the end indicator. |
|
86 |
+ * @param {string} [options.colorTrigger=blue] - CSS color definition for the trigger indicator. |
|
87 |
+ */ |
|
88 |
+ Scene.addIndicators = function (options) { |
|
89 |
+ if (!_indicator) { |
|
90 |
+ var |
|
91 |
+ DEFAULT_OPTIONS = { |
|
92 |
+ name: "", |
|
93 |
+ indent: 0, |
|
94 |
+ parent: undefined, |
|
95 |
+ colorStart: "green", |
|
96 |
+ colorEnd: "red", |
|
97 |
+ colorTrigger: "blue", |
|
98 |
+ }; |
|
99 |
+ |
|
100 |
+ options = _util.extend({}, DEFAULT_OPTIONS, options); |
|
101 |
+ |
|
102 |
+ _autoindex++; |
|
103 |
+ _indicator = new Indicator(Scene, options); |
|
104 |
+ |
|
105 |
+ Scene.on("add.plugin_addIndicators", _indicator.add); |
|
106 |
+ Scene.on("remove.plugin_addIndicators", _indicator.remove); |
|
107 |
+ Scene.on("destroy.plugin_addIndicators", Scene.removeIndicators); |
|
108 |
+ |
|
109 |
+ // it the scene already has a controller we can start right away. |
|
110 |
+ if (Scene.controller()) { |
|
111 |
+ _indicator.add(); |
|
112 |
+ } |
|
113 |
+ } |
|
114 |
+ return Scene; |
|
115 |
+ }; |
|
116 |
+ |
|
117 |
+ /** |
|
118 |
+ * Removes visual indicators from a ScrollMagic.Scene. |
|
119 |
+ * @memberof! debug.addIndicators# |
|
120 |
+ * |
|
121 |
+ * @example |
|
122 |
+ * // remove previously added indicators |
|
123 |
+ * scene.removeIndicators() |
|
124 |
+ * |
|
125 |
+ */ |
|
126 |
+ Scene.removeIndicators = function () { |
|
127 |
+ if (_indicator) { |
|
128 |
+ _indicator.remove(); |
|
129 |
+ this.off("*.plugin_addIndicators"); |
|
130 |
+ _indicator = undefined; |
|
131 |
+ } |
|
132 |
+ return Scene; |
|
133 |
+ }; |
|
134 |
+ |
|
135 |
+ }); |
|
136 |
+ |
|
137 |
+ |
|
138 |
+ /* |
|
139 |
+ * ---------------------------------------------------------------- |
|
140 |
+ * Extension for controller to store and update related indicators |
|
141 |
+ * ---------------------------------------------------------------- |
|
142 |
+ */ |
|
143 |
+ // add option to globally auto-add indicators to scenes |
|
144 |
+ /** |
|
145 |
+ * Every ScrollMagic.Controller instance now accepts an additional option. |
|
146 |
+ * See {@link ScrollMagic.Controller} for a complete list of the standard options. |
|
147 |
+ * @memberof! debug.addIndicators# |
|
148 |
+ * @method new ScrollMagic.Controller(options) |
|
149 |
+ * @example |
|
150 |
+ * // make a controller and add indicators to all scenes attached |
|
151 |
+ * var controller = new ScrollMagic.Controller({addIndicators: true}); |
|
152 |
+ * // this scene will automatically have indicators added to it |
|
153 |
+ * new ScrollMagic.Scene() |
|
154 |
+ * .addTo(controller); |
|
155 |
+ * |
|
156 |
+ * @param {object} [options] - Options for the Controller. |
|
157 |
+ * @param {boolean} [options.addIndicators=false] - If set to `true` every scene that is added to the controller will automatically get indicators added to it. |
|
158 |
+ */ |
|
159 |
+ ScrollMagic.Controller.addOption("addIndicators", false); |
|
160 |
+ // extend Controller |
|
161 |
+ ScrollMagic.Controller.extend(function () { |
|
162 |
+ var |
|
163 |
+ Controller = this, |
|
164 |
+ _info = Controller.info(), |
|
165 |
+ _container = _info.container, |
|
166 |
+ _isDocument = _info.isDocument, |
|
167 |
+ _vertical = _info.vertical, |
|
168 |
+ _indicators = { // container for all indicators and methods |
|
169 |
+ groups: [] |
|
170 |
+ }; |
|
171 |
+ |
|
172 |
+ var log = function () { |
|
173 |
+ if (Controller._log) { // not available, when main source minified |
|
174 |
+ Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->"); |
|
175 |
+ Controller._log.apply(this, arguments); |
|
176 |
+ } |
|
177 |
+ }; |
|
178 |
+ if (Controller._indicators) { |
|
179 |
+ log(2, "WARNING: Scene already has a property '_indicators', which will be overwritten by plugin."); |
|
180 |
+ } |
|
181 |
+ |
|
182 |
+ // add indicators container |
|
183 |
+ this._indicators = _indicators; |
|
184 |
+ /* |
|
185 |
+ needed updates: |
|
186 |
+ +++++++++++++++ |
|
187 |
+ start/end position on scene shift (handled in Indicator class) |
|
188 |
+ trigger parameters on triggerHook value change (handled in Indicator class) |
|
189 |
+ bounds position on container scroll or resize (to keep alignment to bottom/right) |
|
190 |
+ trigger position on container resize, window resize (if container isn't document) and window scroll (if container isn't document) |
|
191 |
+ */ |
|
192 |
+ |
|
193 |
+ // event handler for when associated bounds markers need to be repositioned |
|
194 |
+ var handleBoundsPositionChange = function () { |
|
195 |
+ _indicators.updateBoundsPositions(); |
|
196 |
+ }; |
|
197 |
+ |
|
198 |
+ // event handler for when associated trigger groups need to be repositioned |
|
199 |
+ var handleTriggerPositionChange = function () { |
|
200 |
+ _indicators.updateTriggerGroupPositions(); |
|
201 |
+ }; |
|
202 |
+ |
|
203 |
+ _container.addEventListener("resize", handleTriggerPositionChange); |
|
204 |
+ if (!_isDocument) { |
|
205 |
+ window.addEventListener("resize", handleTriggerPositionChange); |
|
206 |
+ window.addEventListener("scroll", handleTriggerPositionChange); |
|
207 |
+ } |
|
208 |
+ // update all related bounds containers |
|
209 |
+ _container.addEventListener("resize", handleBoundsPositionChange); |
|
210 |
+ _container.addEventListener("scroll", handleBoundsPositionChange); |
|
211 |
+ |
|
212 |
+ |
|
213 |
+ // updates the position of the bounds container to aligned to the right for vertical containers and to the bottom for horizontal |
|
214 |
+ this._indicators.updateBoundsPositions = function (specificIndicator) { |
|
215 |
+ var // constant for all bounds |
|
216 |
+ groups = specificIndicator ? [_util.extend({}, specificIndicator.triggerGroup, { |
|
217 |
+ members: [specificIndicator] |
|
218 |
+ })] : // create a group with only one element |
|
219 |
+ _indicators.groups, // use all |
|
220 |
+ g = groups.length, |
|
221 |
+ css = {}, |
|
222 |
+ paramPos = _vertical ? "left" : "top", |
|
223 |
+ paramDimension = _vertical ? "width" : "height", |
|
224 |
+ edge = _vertical ? |
|
225 |
+ _util.get.scrollLeft(_container) + _util.get.width(_container) - EDGE_OFFSET : |
|
226 |
+ _util.get.scrollTop(_container) + _util.get.height(_container) - EDGE_OFFSET, |
|
227 |
+ b, triggerSize, group; |
|
228 |
+ while (g--) { // group loop |
|
229 |
+ group = groups[g]; |
|
230 |
+ b = group.members.length; |
|
231 |
+ triggerSize = _util.get[paramDimension](group.element.firstChild); |
|
232 |
+ while (b--) { // indicators loop |
|
233 |
+ css[paramPos] = edge - triggerSize; |
|
234 |
+ _util.css(group.members[b].bounds, css); |
|
235 |
+ } |
|
236 |
+ } |
|
237 |
+ }; |
|
238 |
+ |
|
239 |
+ // updates the positions of all trigger groups attached to a controller or a specific one, if provided |
|
240 |
+ this._indicators.updateTriggerGroupPositions = function (specificGroup) { |
|
241 |
+ var // constant vars |
|
242 |
+ groups = specificGroup ? [specificGroup] : _indicators.groups, |
|
243 |
+ i = groups.length, |
|
244 |
+ container = _isDocument ? document.body : _container, |
|
245 |
+ containerOffset = _isDocument ? { |
|
246 |
+ top: 0, |
|
247 |
+ left: 0 |
|
248 |
+ } : _util.get.offset(container, true), |
|
249 |
+ edge = _vertical ? |
|
250 |
+ _util.get.width(_container) - EDGE_OFFSET : |
|
251 |
+ _util.get.height(_container) - EDGE_OFFSET, |
|
252 |
+ paramDimension = _vertical ? "width" : "height", |
|
253 |
+ paramTransform = _vertical ? "Y" : "X"; |
|
254 |
+ var // changing vars |
|
255 |
+ group, |
|
256 |
+ elem, |
|
257 |
+ pos, |
|
258 |
+ elemSize, |
|
259 |
+ transform; |
|
260 |
+ while (i--) { |
|
261 |
+ group = groups[i]; |
|
262 |
+ elem = group.element; |
|
263 |
+ pos = group.triggerHook * Controller.info("size"); |
|
264 |
+ elemSize = _util.get[paramDimension](elem.firstChild.firstChild); |
|
265 |
+ transform = pos > elemSize ? "translate" + paramTransform + "(-100%)" : ""; |
|
266 |
+ |
|
267 |
+ _util.css(elem, { |
|
268 |
+ top: containerOffset.top + (_vertical ? pos : edge - group.members[0].options.indent), |
|
269 |
+ left: containerOffset.left + (_vertical ? edge - group.members[0].options.indent : pos) |
|
270 |
+ }); |
|
271 |
+ _util.css(elem.firstChild.firstChild, { |
|
272 |
+ "-ms-transform": transform, |
|
273 |
+ "-webkit-transform": transform, |
|
274 |
+ "transform": transform |
|
275 |
+ }); |
|
276 |
+ } |
|
277 |
+ }; |
|
278 |
+ |
|
279 |
+ // updates the label for the group to contain the name, if it only has one member |
|
280 |
+ this._indicators.updateTriggerGroupLabel = function (group) { |
|
281 |
+ var |
|
282 |
+ text = "trigger" + (group.members.length > 1 ? "" : " " + group.members[0].options.name), |
|
283 |
+ elem = group.element.firstChild.firstChild, |
|
284 |
+ doUpdate = elem.textContent !== text; |
|
285 |
+ if (doUpdate) { |
|
286 |
+ elem.textContent = text; |
|
287 |
+ if (_vertical) { // bounds position is dependent on text length, so update |
|
288 |
+ _indicators.updateBoundsPositions(); |
|
289 |
+ } |
|
290 |
+ } |
|
291 |
+ }; |
|
292 |
+ |
|
293 |
+ // add indicators if global option is set |
|
294 |
+ this.addScene = function (newScene) { |
|
295 |
+ |
|
296 |
+ if (this._options.addIndicators && newScene instanceof ScrollMagic.Scene && newScene.controller() === Controller) { |
|
297 |
+ newScene.addIndicators(); |
|
298 |
+ } |
|
299 |
+ // call original destroy method |
|
300 |
+ this.$super.addScene.apply(this, arguments); |
|
301 |
+ }; |
|
302 |
+ |
|
303 |
+ // remove all previously set listeners on destroy |
|
304 |
+ this.destroy = function () { |
|
305 |
+ _container.removeEventListener("resize", handleTriggerPositionChange); |
|
306 |
+ if (!_isDocument) { |
|
307 |
+ window.removeEventListener("resize", handleTriggerPositionChange); |
|
308 |
+ window.removeEventListener("scroll", handleTriggerPositionChange); |
|
309 |
+ } |
|
310 |
+ _container.removeEventListener("resize", handleBoundsPositionChange); |
|
311 |
+ _container.removeEventListener("scroll", handleBoundsPositionChange); |
|
312 |
+ // call original destroy method |
|
313 |
+ this.$super.destroy.apply(this, arguments); |
|
314 |
+ }; |
|
315 |
+ return Controller; |
|
316 |
+ |
|
317 |
+ }); |
|
318 |
+ |
|
319 |
+ /* |
|
320 |
+ * ---------------------------------------------------------------- |
|
321 |
+ * Internal class for the construction of Indicators |
|
322 |
+ * ---------------------------------------------------------------- |
|
323 |
+ */ |
|
324 |
+ var Indicator = function (Scene, options) { |
|
325 |
+ var |
|
326 |
+ Indicator = this, |
|
327 |
+ _elemBounds = TPL.bounds(), |
|
328 |
+ _elemStart = TPL.start(options.colorStart), |
|
329 |
+ _elemEnd = TPL.end(options.colorEnd), |
|
330 |
+ _boundsContainer = options.parent && _util.get.elements(options.parent)[0], |
|
331 |
+ _vertical, |
|
332 |
+ _ctrl; |
|
333 |
+ |
|
334 |
+ var log = function () { |
|
335 |
+ if (Scene._log) { // not available, when main source minified |
|
336 |
+ Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->"); |
|
337 |
+ Scene._log.apply(this, arguments); |
|
338 |
+ } |
|
339 |
+ }; |
|
340 |
+ |
|
341 |
+ options.name = options.name || _autoindex; |
|
342 |
+ |
|
343 |
+ // prepare bounds elements |
|
344 |
+ _elemStart.firstChild.textContent += " " + options.name; |
|
345 |
+ _elemEnd.textContent += " " + options.name; |
|
346 |
+ _elemBounds.appendChild(_elemStart); |
|
347 |
+ _elemBounds.appendChild(_elemEnd); |
|
348 |
+ |
|
349 |
+ // set public variables |
|
350 |
+ Indicator.options = options; |
|
351 |
+ Indicator.bounds = _elemBounds; |
|
352 |
+ // will be set later |
|
353 |
+ Indicator.triggerGroup = undefined; |
|
354 |
+ |
|
355 |
+ // add indicators to DOM |
|
356 |
+ this.add = function () { |
|
357 |
+ _ctrl = Scene.controller(); |
|
358 |
+ _vertical = _ctrl.info("vertical"); |
|
359 |
+ |
|
360 |
+ var isDocument = _ctrl.info("isDocument"); |
|
361 |
+ |
|
362 |
+ if (!_boundsContainer) { |
|
363 |
+ // no parent supplied or doesnt exist |
|
364 |
+ _boundsContainer = isDocument ? document.body : _ctrl.info("container"); // check if window/document (then use body) |
|
365 |
+ } |
|
366 |
+ if (!isDocument && _util.css(_boundsContainer, "position") === 'static') { |
|
367 |
+ // position mode needed for correct positioning of indicators |
|
368 |
+ _util.css(_boundsContainer, { |
|
369 |
+ position: "relative" |
|
370 |
+ }); |
|
371 |
+ } |
|
372 |
+ |
|
373 |
+ // add listeners for updates |
|
374 |
+ Scene.on("change.plugin_addIndicators", handleTriggerParamsChange); |
|
375 |
+ Scene.on("shift.plugin_addIndicators", handleBoundsParamsChange); |
|
376 |
+ |
|
377 |
+ // updates trigger & bounds (will add elements if needed) |
|
378 |
+ updateTriggerGroup(); |
|
379 |
+ updateBounds(); |
|
380 |
+ |
|
381 |
+ setTimeout(function () { // do after all execution is finished otherwise sometimes size calculations are off |
|
382 |
+ _ctrl._indicators.updateBoundsPositions(Indicator); |
|
383 |
+ }, 0); |
|
384 |
+ |
|
385 |
+ log(3, "added indicators"); |
|
386 |
+ }; |
|
387 |
+ |
|
388 |
+ // remove indicators from DOM |
|
389 |
+ this.remove = function () { |
|
390 |
+ if (Indicator.triggerGroup) { // if not set there's nothing to remove |
|
391 |
+ Scene.off("change.plugin_addIndicators", handleTriggerParamsChange); |
|
392 |
+ Scene.off("shift.plugin_addIndicators", handleBoundsParamsChange); |
|
393 |
+ |
|
394 |
+ if (Indicator.triggerGroup.members.length > 1) { |
|
395 |
+ // just remove from memberlist of old group |
|
396 |
+ var group = Indicator.triggerGroup; |
|
397 |
+ group.members.splice(group.members.indexOf(Indicator), 1); |
|
398 |
+ _ctrl._indicators.updateTriggerGroupLabel(group); |
|
399 |
+ _ctrl._indicators.updateTriggerGroupPositions(group); |
|
400 |
+ Indicator.triggerGroup = undefined; |
|
401 |
+ } else { |
|
402 |
+ // remove complete group |
|
403 |
+ removeTriggerGroup(); |
|
404 |
+ } |
|
405 |
+ removeBounds(); |
|
406 |
+ |
|
407 |
+ log(3, "removed indicators"); |
|
408 |
+ } |
|
409 |
+ }; |
|
410 |
+ |
|
411 |
+ /* |
|
412 |
+ * ---------------------------------------------------------------- |
|
413 |
+ * internal Event Handlers |
|
414 |
+ * ---------------------------------------------------------------- |
|
415 |
+ */ |
|
416 |
+ |
|
417 |
+ // event handler for when bounds params change |
|
418 |
+ var handleBoundsParamsChange = function () { |
|
419 |
+ updateBounds(); |
|
420 |
+ }; |
|
421 |
+ |
|
422 |
+ // event handler for when trigger params change |
|
423 |
+ var handleTriggerParamsChange = function (e) { |
|
424 |
+ if (e.what === "triggerHook") { |
|
425 |
+ updateTriggerGroup(); |
|
426 |
+ } |
|
427 |
+ }; |
|
428 |
+ |
|
429 |
+ /* |
|
430 |
+ * ---------------------------------------------------------------- |
|
431 |
+ * Bounds (start / stop) management |
|
432 |
+ * ---------------------------------------------------------------- |
|
433 |
+ */ |
|
434 |
+ |
|
435 |
+ // adds an new bounds elements to the array and to the DOM |
|
436 |
+ var addBounds = function () { |
|
437 |
+ var v = _ctrl.info("vertical"); |
|
438 |
+ // apply stuff we didn't know before... |
|
439 |
+ _util.css(_elemStart.firstChild, { |
|
440 |
+ "border-bottom-width": v ? 1 : 0, |
|
441 |
+ "border-right-width": v ? 0 : 1, |
|
442 |
+ "bottom": v ? -1 : options.indent, |
|
443 |
+ "right": v ? options.indent : -1, |
|
444 |
+ "padding": v ? "0 8px" : "2px 4px", |
|
445 |
+ }); |
|
446 |
+ _util.css(_elemEnd, { |
|
447 |
+ "border-top-width": v ? 1 : 0, |
|
448 |
+ "border-left-width": v ? 0 : 1, |
|
449 |
+ "top": v ? "100%" : "", |
|
450 |
+ "right": v ? options.indent : "", |
|
451 |
+ "bottom": v ? "" : options.indent, |
|
452 |
+ "left": v ? "" : "100%", |
|
453 |
+ "padding": v ? "0 8px" : "2px 4px" |
|
454 |
+ }); |
|
455 |
+ // append |
|
456 |
+ _boundsContainer.appendChild(_elemBounds); |
|
457 |
+ }; |
|
458 |
+ |
|
459 |
+ // remove bounds from list and DOM |
|
460 |
+ var removeBounds = function () { |
|
461 |
+ _elemBounds.parentNode.removeChild(_elemBounds); |
|
462 |
+ }; |
|
463 |
+ |
|
464 |
+ // update the start and end positions of the scene |
|
465 |
+ var updateBounds = function () { |
|
466 |
+ if (_elemBounds.parentNode !== _boundsContainer) { |
|
467 |
+ addBounds(); // Add Bounds elements (start/end) |
|
468 |
+ } |
|
469 |
+ var css = {}; |
|
470 |
+ css[_vertical ? "top" : "left"] = Scene.triggerPosition(); |
|
471 |
+ css[_vertical ? "height" : "width"] = Scene.duration(); |
|
472 |
+ _util.css(_elemBounds, css); |
|
473 |
+ _util.css(_elemEnd, { |
|
474 |
+ display: Scene.duration() > 0 ? "" : "none" |
|
475 |
+ }); |
|
476 |
+ }; |
|
477 |
+ |
|
478 |
+ /* |
|
479 |
+ * ---------------------------------------------------------------- |
|
480 |
+ * trigger and trigger group management |
|
481 |
+ * ---------------------------------------------------------------- |
|
482 |
+ */ |
|
483 |
+ |
|
484 |
+ // adds an new trigger group to the array and to the DOM |
|
485 |
+ var addTriggerGroup = function () { |
|
486 |
+ var triggerElem = TPL.trigger(options.colorTrigger); // new trigger element |
|
487 |
+ var css = {}; |
|
488 |
+ css[_vertical ? "right" : "bottom"] = 0; |
|
489 |
+ css[_vertical ? "border-top-width" : "border-left-width"] = 1; |
|
490 |
+ _util.css(triggerElem.firstChild, css); |
|
491 |
+ _util.css(triggerElem.firstChild.firstChild, { |
|
492 |
+ padding: _vertical ? "0 8px 3px 8px" : "3px 4px" |
|
493 |
+ }); |
|
494 |
+ document.body.appendChild(triggerElem); // directly add to body |
|
495 |
+ var newGroup = { |
|
496 |
+ triggerHook: Scene.triggerHook(), |
|
497 |
+ element: triggerElem, |
|
498 |
+ members: [Indicator] |
|
499 |
+ }; |
|
500 |
+ _ctrl._indicators.groups.push(newGroup); |
|
501 |
+ Indicator.triggerGroup = newGroup; |
|
502 |
+ // update right away |
|
503 |
+ _ctrl._indicators.updateTriggerGroupLabel(newGroup); |
|
504 |
+ _ctrl._indicators.updateTriggerGroupPositions(newGroup); |
|
505 |
+ }; |
|
506 |
+ |
|
507 |
+ var removeTriggerGroup = function () { |
|
508 |
+ _ctrl._indicators.groups.splice(_ctrl._indicators.groups.indexOf(Indicator.triggerGroup), 1); |
|
509 |
+ Indicator.triggerGroup.element.parentNode.removeChild(Indicator.triggerGroup.element); |
|
510 |
+ Indicator.triggerGroup = undefined; |
|
511 |
+ }; |
|
512 |
+ |
|
513 |
+ // updates the trigger group -> either join existing or add new one |
|
514 |
+ /* |
|
515 |
+ * Logic: |
|
516 |
+ * 1 if a trigger group exist, check if it's in sync with Scene settings – if so, nothing else needs to happen |
|
517 |
+ * 2 try to find an existing one that matches Scene parameters |
|
518 |
+ * 2.1 If a match is found check if already assigned to an existing group |
|
519 |
+ * If so: |
|
520 |
+ * A: it was the last member of existing group -> kill whole group |
|
521 |
+ * B: the existing group has other members -> just remove from member list |
|
522 |
+ * 2.2 Assign to matching group |
|
523 |
+ * 3 if no new match could be found, check if assigned to existing group |
|
524 |
+ * A: yes, and it's the only member -> just update parameters and positions and keep using this group |
|
525 |
+ * B: yes but there are other members -> remove from member list and create a new one |
|
526 |
+ * C: no, so create a new one |
|
527 |
+ */ |
|
528 |
+ var updateTriggerGroup = function () { |
|
529 |
+ var |
|
530 |
+ triggerHook = Scene.triggerHook(), |
|
531 |
+ closeEnough = 0.0001; |
|
532 |
+ |
|
533 |
+ // Have a group, check if it still matches |
|
534 |
+ if (Indicator.triggerGroup) { |
|
535 |
+ if (Math.abs(Indicator.triggerGroup.triggerHook - triggerHook) < closeEnough) { |
|
536 |
+ // _util.log(0, "trigger", options.name, "->", "no need to change, still in sync"); |
|
537 |
+ return; // all good |
|
538 |
+ } |
|
539 |
+ } |
|
540 |
+ // Don't have a group, check if a matching one exists |
|
541 |
+ // _util.log(0, "trigger", options.name, "->", "out of sync!"); |
|
542 |
+ var |
|
543 |
+ groups = _ctrl._indicators.groups, |
|
544 |
+ group, |
|
545 |
+ i = groups.length; |
|
546 |
+ while (i--) { |
|
547 |
+ group = groups[i]; |
|
548 |
+ if (Math.abs(group.triggerHook - triggerHook) < closeEnough) { |
|
549 |
+ // found a match! |
|
550 |
+ // _util.log(0, "trigger", options.name, "->", "found match"); |
|
551 |
+ if (Indicator.triggerGroup) { // do I have an old group that is out of sync? |
|
552 |
+ if (Indicator.triggerGroup.members.length === 1) { // is it the only remaining group? |
|
553 |
+ // _util.log(0, "trigger", options.name, "->", "kill"); |
|
554 |
+ // was the last member, remove the whole group |
|
555 |
+ removeTriggerGroup(); |
|
556 |
+ } else { |
|
557 |
+ Indicator.triggerGroup.members.splice(Indicator.triggerGroup.members.indexOf(Indicator), 1); // just remove from memberlist of old group |
|
558 |
+ _ctrl._indicators.updateTriggerGroupLabel(Indicator.triggerGroup); |
|
559 |
+ _ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup); |
|
560 |
+ // _util.log(0, "trigger", options.name, "->", "removing from previous member list"); |
|
561 |
+ } |
|
562 |
+ } |
|
563 |
+ // join new group |
|
564 |
+ group.members.push(Indicator); |
|
565 |
+ Indicator.triggerGroup = group; |
|
566 |
+ _ctrl._indicators.updateTriggerGroupLabel(group); |
|
567 |
+ return; |
|
568 |
+ } |
|
569 |
+ } |
|
570 |
+ |
|
571 |
+ // at this point I am obviously out of sync and don't match any other group |
|
572 |
+ if (Indicator.triggerGroup) { |
|
573 |
+ if (Indicator.triggerGroup.members.length === 1) { |
|
574 |
+ // _util.log(0, "trigger", options.name, "->", "updating existing"); |
|
575 |
+ // out of sync but i'm the only member => just change and update |
|
576 |
+ Indicator.triggerGroup.triggerHook = triggerHook; |
|
577 |
+ _ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup); |
|
578 |
+ return; |
|
579 |
+ } else { |
|
580 |
+ // _util.log(0, "trigger", options.name, "->", "removing from previous member list"); |
|
581 |
+ Indicator.triggerGroup.members.splice(Indicator.triggerGroup.members.indexOf(Indicator), 1); // just remove from memberlist of old group |
|
582 |
+ _ctrl._indicators.updateTriggerGroupLabel(Indicator.triggerGroup); |
|
583 |
+ _ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup); |
|
584 |
+ Indicator.triggerGroup = undefined; // need a brand new group... |
|
585 |
+ } |
|
586 |
+ } |
|
587 |
+ // _util.log(0, "trigger", options.name, "->", "add a new one"); |
|
588 |
+ // did not find any match, make new trigger group |
|
589 |
+ addTriggerGroup(); |
|
590 |
+ }; |
|
591 |
+ }; |
|
592 |
+ |
|
593 |
+ /* |
|
594 |
+ * ---------------------------------------------------------------- |
|
595 |
+ * Templates for the indicators |
|
596 |
+ * ---------------------------------------------------------------- |
|
597 |
+ */ |
|
598 |
+ var TPL = { |
|
599 |
+ start: function (color) { |
|
600 |
+ // inner element (for bottom offset -1, while keeping top position 0) |
|
601 |
+ var inner = document.createElement("div"); |
|
602 |
+ inner.textContent = "start"; |
|
603 |
+ _util.css(inner, { |
|
604 |
+ position: "absolute", |
|
605 |
+ overflow: "visible", |
|
606 |
+ "border-width": 0, |
|
607 |
+ "border-style": "solid", |
|
608 |
+ color: color, |
|
609 |
+ "border-color": color |
|
610 |
+ }); |
|
611 |
+ var e = document.createElement('div'); |
|
612 |
+ // wrapper |
|
613 |
+ _util.css(e, { |
|
614 |
+ position: "absolute", |
|
615 |
+ overflow: "visible", |
|
616 |
+ width: 0, |
|
617 |
+ height: 0 |
|
618 |
+ }); |
|
619 |
+ e.appendChild(inner); |
|
620 |
+ return e; |
|
621 |
+ }, |
|
622 |
+ end: function (color) { |
|
623 |
+ var e = document.createElement('div'); |
|
624 |
+ e.textContent = "end"; |
|
625 |
+ _util.css(e, { |
|
626 |
+ position: "absolute", |
|
627 |
+ overflow: "visible", |
|
628 |
+ "border-width": 0, |
|
629 |
+ "border-style": "solid", |
|
630 |
+ color: color, |
|
631 |
+ "border-color": color |
|
632 |
+ }); |
|
633 |
+ return e; |
|
634 |
+ }, |
|
635 |
+ bounds: function () { |
|
636 |
+ var e = document.createElement('div'); |
|
637 |
+ _util.css(e, { |
|
638 |
+ position: "absolute", |
|
639 |
+ overflow: "visible", |
|
640 |
+ "white-space": "nowrap", |
|
641 |
+ "pointer-events": "none", |
|
642 |
+ "font-size": FONT_SIZE |
|
643 |
+ }); |
|
644 |
+ e.style.zIndex = ZINDEX; |
|
645 |
+ return e; |
|
646 |
+ }, |
|
647 |
+ trigger: function (color) { |
|
648 |
+ // inner to be above or below line but keep position |
|
649 |
+ var inner = document.createElement('div'); |
|
650 |
+ inner.textContent = "trigger"; |
|
651 |
+ _util.css(inner, { |
|
652 |
+ position: "relative", |
|
653 |
+ }); |
|
654 |
+ // inner wrapper for right: 0 and main element has no size |
|
655 |
+ var w = document.createElement('div'); |
|
656 |
+ _util.css(w, { |
|
657 |
+ position: "absolute", |
|
658 |
+ overflow: "visible", |
|
659 |
+ "border-width": 0, |
|
660 |
+ "border-style": "solid", |
|
661 |
+ color: color, |
|
662 |
+ "border-color": color |
|
663 |
+ }); |
|
664 |
+ w.appendChild(inner); |
|
665 |
+ // wrapper |
|
666 |
+ var e = document.createElement('div'); |
|
667 |
+ _util.css(e, { |
|
668 |
+ position: "fixed", |
|
669 |
+ overflow: "visible", |
|
670 |
+ "white-space": "nowrap", |
|
671 |
+ "pointer-events": "none", |
|
672 |
+ "font-size": FONT_SIZE |
|
673 |
+ }); |
|
674 |
+ e.style.zIndex = ZINDEX; |
|
675 |
+ e.appendChild(w); |
|
676 |
+ return e; |
|
677 |
+ }, |
|
678 |
+ }; |
|
679 |
+ |
|
680 |
+})); |
|
0 | 681 |
\ No newline at end of file |