PluginProbe
Float menu – awesome floating side menu / 3.3.1
Float menu – awesome floating side menu v3.3.1
7.2.5 trunk 2.1 2.2 3.0.1 3.1 3.2.2 3.3.1 3.5 3.5.1 3.5.2 3.5.3. 3.5.4 4.0 4.1 4.1.1 4.2 4.3 4.3.1 4.3.2 5.0 5.0.1 5.0.2 5.0.3 5.1 All 57 releases
float-menu / assets / js / floatMenu.js

floatMenu.js in Float menu – awesome floating side menu 3.3.1, at assets/js/floatMenu.js

1,158 lines 36.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1
2 (function($) {
3 "use strict";
4
5 var defaults = {
6 // Main
7 position: ["left", "center"],
8 offset: [0, 0],
9 buttonShape: "round",
10 buttonColor: "custom",
11 buttonOverColor: "custom",
12 iconColor: "white",
13 iconOverColor: "white",
14 labelColor: "match",
15 labelTextColor: "match",
16 labelEffect: "slide-out-fade",
17 labelAnimate: "default",
18 labelConnected: false,
19 labelsOn: true,
20 sideSpace: false,
21 buttonSpace: false,
22 labelSpace: false,
23 mobileEnable: false,
24 mobileScreen: 768,
25 // Subbar
26 subPosition: ["circular", 100, -90, 90],
27 subEffect: ["slide", 30],
28 subAnimate: [400, "easeOutQuad"],
29 subSpace: false,
30 subOpen: "mouseover",
31 // Window
32 windowPosition: ["center", "center"],
33 windowOffset: [0, 0],
34 windowCorners: "match",
35 windowColor: "match",
36 windowShadow: true,
37 // Other
38 showAfterPosition: false,
39 barAnimate: [250, "easeOutQuad"],
40 hideUnderWidth: false,
41 shareTarget: "default"
42 };
43 var labelAnimateDefaults = {
44 "default": [400, "easeOutQuad"],
45 "fade": [200, "easeOutQuad"],
46 "slide-in-in": {
47 show: [400, "easeOutQuad"],
48 hide: [400, "swing"]
49 }
50 };
51
52
53 var methods = {
54 "build": build,
55 "destroy": destroy
56 };
57
58 $.fn.floatingMenu = function(arg) {
59 if (typeof arg === "object" || !arg) {
60 build.apply(this, arguments);
61 } else if (methods[arg]) {
62 methods[arg].apply(this, Array.prototype.slice.call(arguments, 1));
63 } else {
64 $.error("The method " + arg + " does not exist in Float Menu.");
65 }
66 };
67
68 function build(options) {
69 var settings = createSettings(options);
70
71 return this.each(function() {
72 var sidebar = $(this);
73
74 if (sidebar.data("fm-built")) destroy.apply(this);
75 sidebar.data("fm-built", true);
76
77 // VARS
78 var bar = sidebar.children(".fm-bar");
79 var barList = bar.children();
80 var sbwindow = sidebar.children(".fm-window");
81
82 var $window = $(window);
83 var $document = $(document);
84
85 var barVisible = true;
86 var right = false;
87 var csub = null;
88 var cwindow = null;
89 var nextMargins = [];
90
91
92 // INIT
93 if (settings.position[0] === "right") {
94 right = true;
95 bar.addClass("fm-right");
96 }
97
98 if (settings.buttonShape !== "square") bar.addClass("fm-" + settings.buttonShape);
99
100 if (settings.labelConnected) bar.addClass("fm-connected");
101
102 if (settings.buttonColor !== "custom") bar.addClass("fm-" + settings.buttonColor + "-button");
103 if (settings.buttonOverColor !== "custom") bar.addClass("fm-" + settings.buttonOverColor + "-button-over");
104
105 if (settings.iconColor !== "custom") bar.addClass("fm-" + settings.iconColor + "-icon");
106 if (settings.iconOverColor !== "custom") bar.addClass("fm-" + settings.iconOverColor + "-icon-over");
107
108 if (settings.labelColor !== "custom") bar.addClass("fm-" + settings.labelColor + "-label");
109 if (settings.labelTextColor !== "custom") bar.addClass("fm-" + settings.labelTextColor + "-label-text");
110
111 if (settings.sideSpace) bar.addClass("fm-side-space");
112 if (settings.buttonSpace) bar.addClass("fm-button-space");
113 if (settings.labelSpace) bar.addClass("fm-label-space");
114
115 if (settings.windowCorners === "round") sbwindow.addClass("fm-round");
116 if (settings.windowColor !== "custom") sbwindow.addClass("fm-" + settings.windowColor);
117 if (settings.windowShadow) sbwindow.addClass("fm-winshadow");
118
119
120 buildList(bar);
121
122 // Subbar animate fix.
123 barList.each(function(ind) {
124 nextMargins[ind] = getInt(barList.eq(ind).css("margin-top"));
125 });
126
127 sbwindow.children(".fm-shadow").on("click", closeWindow);
128
129 sbwindow.children(".fm-panel").each(buildPanel);
130
131 resize();
132
133 $window.on("resize.superSidebar", resize);
134
135 if (settings.showAfterPosition) {
136 if ($window.scrollTop() < settings.showAfterPosition) {
137 bar.css("opacity", 0).addClass("fm-hide");
138 barVisible = false;
139 }
140
141 $window.on("scroll.superSidebar", function() {
142 if ($window.scrollTop() < settings.showAfterPosition) {
143 if (barVisible) hideBar();
144 } else {
145 if (!barVisible) showBar();
146 }
147 });
148 }
149
150 bar.addClass("fm-css-anim");
151
152 sidebar.addClass("fm-ready");
153
154
155 // FUNCTIONS
156 function buildList(list) {
157 list.children().each(function(i) {
158 if ($(this).hasClass("fm-sub")) buildSub(this, i);
159 else buildButton(this);
160 });
161 }
162
163 function buildButton(btn) {
164 var button = $(btn);
165 var link = button.children("a");
166 var icon = link.children(".fm-icon");
167 var label = link.children(".fm-label");
168 var mask, hit = null;
169
170 var linkClick = 0;
171 var screen = $(window).width();
172
173 var maskHtml = '<div class="fm-mask"></div>';
174 var hitHtml = '<div class="fm-hit"></div>';
175
176 var iw, lw;
177 var side = right ? "right" : "left";
178 var dist = 40;
179 var maskOff = false;
180 var start = {}, show = {}, end = {};
181 var showLabel, hideLabel;
182
183 var showTime = settings.labelAnimate.show[0];
184 var showEase = settings.labelAnimate.show[1];
185 var hideTime = settings.labelAnimate.hide[0];
186 var hideEase = settings.labelAnimate.hide[1];
187
188 if (settings.labelsOn && label.length) {
189 iw = getInt(icon.css("width"));
190 lw = label.outerWidth(true);
191
192 if (settings.buttonShape === "round" || settings.buttonShape === "rounded") maskOff = true;
193
194 if (!settings.labelConnected && (settings.labelSpace || settings.buttonShape === "round" || settings.buttonShape === "rounded" || settings.buttonShape === "rounded-out"))
195 hit = $(hitHtml).appendTo(link);
196
197 switch (settings.labelEffect) {
198 case "fade":
199 start = {"opacity": 0};
200 show = {"opacity": 1};
201
202 label.css(start);
203
204 showLabel = function() {
205 if (hit) hit.addClass("fm-show");
206 label.velocity("stop").addClass("fm-show").velocity(show, showTime, showEase);
207 };
208 hideLabel = function() {
209 label.velocity("stop").velocity(start, hideTime, hideEase, function() {
210 label.removeClass("fm-show");
211 if (hit) hit.removeClass("fm-show");
212 });
213 };
214 break;
215 case "slide-out":
216 case "slide-out-fade":
217 mask = link.wrap(maskHtml).parent();
218 mask.css("width", iw);
219 if (maskOff) mask.addClass("fm-off");
220
221 start[side] = -lw + iw;
222 if (settings.labelConnected) show[side] = 0;
223 else show[side] = iw;
224
225 if (settings.labelEffect === "slide-out-fade") {
226 start["opacity"] = 0;
227 show["opacity"] = 1;
228 }
229
230 label.css(start);
231
232 showLabel = function() {
233 mask.css("width", iw + lw);
234 if (maskOff) mask.removeClass("fm-off");
235 if (hit) hit.addClass("fm-show");
236 label.velocity("stop").addClass("fm-show").velocity(show, showTime, showEase);
237 };
238 hideLabel = function() {
239 label.velocity("stop").velocity(start, hideTime, hideEase, function() {
240 label.removeClass("fm-show");
241 mask.css("width", iw);
242 if (maskOff) mask.addClass("fm-off");
243 if (hit) hit.removeClass("fm-show");
244 });
245 };
246 break;
247 case "slide-in":
248 start = {"opacity": 0};
249 start[side] = iw + dist;
250 show = {"opacity": 1};
251 show[side] = iw;
252
253 label.css(start);
254
255 showLabel = function() {
256 if (hit) hit.addClass("fm-show");
257 label.velocity("stop").addClass("fm-show").velocity(show, showTime, showEase);
258 };
259 hideLabel = function() {
260 label.velocity("stop").velocity(start, hideTime, hideEase, function() {
261 label.removeClass("fm-show");
262 if (hit) hit.removeClass("fm-show");
263 });
264 };
265 break;
266 case "slide-out-out":
267 case "slide-in-in":
268 mask = link.wrap(maskHtml).parent();
269 mask.css("width", iw);
270 if (maskOff) mask.addClass("fm-off");
271
272 if (settings.labelEffect === "slide-out-out") {
273 start[side] = -lw + iw;
274 show[side] = iw;
275 end[side] = iw + dist;
276 } else {
277 start[side] = iw + dist;
278 show[side] = iw;
279 end[side] = -lw + iw;
280 }
281 start["opacity"] = 0;
282 show["opacity"] = 1;
283 end["opacity"] = 0;
284
285 showLabel = function() {
286 mask.css("width", iw + lw + dist);
287 if (maskOff) mask.removeClass("fm-off");
288 if (hit) hit.addClass("fm-show");
289 label.velocity("stop").css(start).addClass("fm-show").velocity(show, showTime, showEase, function() {
290 mask.css("width", iw + lw);
291 });
292 };
293 hideLabel = function() {
294 mask.css("width", iw + lw + dist);
295 label.velocity("stop").velocity(end, hideTime, hideEase, function() {
296 label.removeClass("fm-show");
297 mask.css("width", iw);
298 if (maskOff) mask.addClass("fm-off");
299 if (hit) hit.removeClass("fm-show");
300 });
301 };
302 break;
303 default:
304 showLabel = function() {
305 if (hit) hit.addClass("fm-show");
306 label.addClass("fm-show");
307 };
308 hideLabel = function() {
309 label.removeClass("fm-show");
310 if (hit) hit.removeClass("fm-show");
311 };
312 break;
313 }
314
315
316 if (settings.mobileEnable == true && settings.mobileScreen >= screen) {
317
318 link.on('touchend', function(e) {
319
320 if (linkClick == 0 ) {
321 e.preventDefault();
322 showLabel();
323 linkClick = 1;
324 return;
325 }
326 else if (linkClick == 1) {
327 hideLabel();
328 linkClick = 0;
329 }
330 });
331 }
332 else {
333 link.on("mouseenter", showLabel);
334 link.on("mouseleave", hideLabel);
335 }
336 }
337
338
339 var shareVal = link.data("share");
340 var shareData;
341 var shareUrl;
342 var shareTarget;
343 var href;
344 var labelShow;
345
346 if (shareVal) {
347 if (shareVal === "pinterest") {
348 link.on("click", pinterestShare);
349 } else {
350 shareData = settings.shareServices[shareVal];
351
352 if (shareData) {
353 shareUrl = shareData.url.replace("{URL}", PAGE_URL)
354 .replace("{TITLE}", PAGE_TITLE);
355
356 link.attr("href", shareUrl);
357
358 if (shareData.target === "app") {
359 link.attr("target", "_self");
360 } else {
361 if (settings.shareTarget === "default") shareTarget = shareData.target;
362 else shareTarget = settings.shareTarget;
363
364 if (shareTarget === "popup") {
365 link.on("click", {"url": shareUrl, "params": shareData.popup}, sharePopup);
366 } else {
367 link.attr("target", "_blank");
368 }
369 }
370 } else {
371 warn('There is no share data for "' + shareVal + '".');
372 }
373 }
374 } else {
375 href = link.attr("href");
376
377 if (href && href.charAt(0) === "#" && href !== "#") {
378 link.on("click", function() {
379 openWindow(href);
380 return false;
381 });
382 }
383 }
384
385 labelShow = link.attr("data-label");
386
387 if (labelShow === 'show') {
388 showLabel();
389 }
390
391 }
392
393 function buildSub(sub, ind) {
394 var sub = $(sub);
395 var icon = sub.children(".fm-icon");
396 var list = sub.children("ul");
397 var buttonList = list.children();
398 var hit = null;
399 var nextButton = null;
400
401 var hitHtml = '<div class="fm-subhit"></div>';
402
403 var position = settings.subPosition[0];
404 var effect = settings.subEffect[0];
405 var side = right ? "right" : "left";
406 var total = buttonList.length;
407 var iw = getInt(icon.css("width"));
408 var ih = getInt(icon.css("height"));
409 var positions = [];
410 var status = null;
411 var start = {}, show = {};
412 var interval;
413 var showList, hideList;
414 var i;
415 var nextOffset = 0;
416 var prevOffset = 0;
417 var nextMargin;
418 var buttonMargin;
419 var barMargin;
420 var subOpen = false;
421
422 var showTime = settings.subAnimate.show[0];
423 var showEase = settings.subAnimate.show[1];
424 var hideTime = settings.subAnimate.hide[0];
425 var hideEase = settings.subAnimate.hide[1];
426
427
428 buildList(list);
429
430 if (position === "side") sub.addClass("fm-side");
431 if (settings.subSpace) sub.addClass("fm-sub-space");
432
433 if (effect === "linear-slide" || position === "circular")
434 sub.addClass("fm-posabs");
435
436 if ((position === "under" && effect === "linear-slide") ||
437 (position === "circular" && effect === "slide") ||
438 (position === "circular" && effect === "linear-slide")) {
439 buttonList.each(function(i) {
440 $(this).css("z-index", 100 - i);
441 });
442 }
443
444 if (barList[ind + 1]) {
445 nextButton = barList.eq(ind + 1);
446 //nextMargin = getInt(nextButton.css("margin-top"));
447 }
448
449 if (position === "circular") {
450 sub.addClass("fm-circular");
451
452 var r = settings.subPosition[1];
453 var sa = settings.subPosition[2];
454 var ea = settings.subPosition[3];
455
456 var startRad = sa * Math.PI / 180;
457 var endRad = ea * Math.PI / 180;
458 var stepRad = (endRad - startRad) / (total - 1);
459 var a, s, t, p;
460
461 buttonList.each(function(i) {
462 a = i * stepRad + startRad;
463 s = Math.round(r * Math.cos(a));
464 t = Math.round(r * Math.sin(a));
465
466 p = {"top": t};
467 p[side] = s;
468 $(this).css(p);
469 positions[i] = [s, t];
470 });
471
472 hit = $(hitHtml).appendTo(sub);
473 hit.css({
474 "width": r + iw,
475 "height": 2 * r + iw,
476 "border-radius": right ? r + "px 0 0 " + r + "px" : "0 " + r + "px " + r + "px 0",
477 "top": -r
478 });
479
480 buttonMargin = getInt(barList.eq(0).css("margin-bottom"));
481
482 if (ind !== 0) {
483 prevOffset = r + buttonMargin;
484 barMargin = getInt(bar.css("margin-top"));
485 sub.css("margin-top", buttonMargin);
486 }
487
488 if (nextButton) {
489 nextOffset = r + buttonMargin;
490 }
491 } else {
492 if (effect === "linear-slide") {
493 var c = 0;
494 buttonList.each(function(i) {
495 var btn = $(this);
496 btn.css("top", c);
497 positions[i] = c;
498 c += getInt(btn.css("height")) + getInt(btn.css("margin-bottom"));
499 });
500
501 list.css({"width": iw, "height": c});
502 }
503
504 hit = $(hitHtml).appendTo(sub);
505 if (position === "side")
506 hit.css({"width": iw + getInt(list.css("margin-" + side)), "height": ih});
507 else
508 hit.css({"width": iw, "height": ih + getInt(list.css("margin-top"))});
509
510 if (position === "under" && nextButton) {
511 nextOffset = list.outerHeight(true) + getInt(nextButton.css("margin-top")) + getInt(list.css("margin-top"));
512 }
513 }
514
515
516 list.addClass("fm-hide");
517
518 switch (effect) {
519 case "fade":
520 start = {"opacity": 0};
521 show = {"opacity": 1};
522
523 list.css(start);
524
525 showList = function() {
526 list.velocity("stop").removeClass("fm-hide").velocity(show, showTime, showEase);
527 };
528 hideList = function() {
529 list.velocity("stop").velocity(start, hideTime, hideEase, function() {
530 list.addClass("fm-hide");
531 });
532 };
533 break;
534 case "slide":
535 if (position === "circular") {
536 start = {"top": 0, "opacity": 0};
537 start[side] = 0;
538 buttonList.css(start);
539
540 showList = function() {
541 list.removeClass("fm-hide");
542 buttonList.each(function(i) {
543 show = {"top": positions[i][1], "opacity": 1};
544 show[side] = positions[i][0];
545 $(this).velocity("stop").velocity(show, showTime, showEase);
546 });
547 };
548 hideList = function() {
549 buttonList.each(function(i) {
550 $(this).velocity("stop").velocity(start, hideTime, hideEase, function() {
551 if (i === total - 1) list.addClass("fm-hide");
552 });
553 });
554 };
555 } else {
556 if (position === "side") {
557 start[side] = 0;
558 show[side] = iw;
559 } else {
560 start = {"top": 0};
561 show = {"top": 42};
562 }
563 start["opacity"] = 0;
564 show["opacity"] = 1;
565
566 list.css(start);
567
568 showList = function() {
569 list.velocity("stop").removeClass("fm-hide").velocity(show, showTime, showEase);
570 };
571 hideList = function() {
572 list.velocity("stop").velocity(start, hideTime, hideEase, function() {
573 list.addClass("fm-hide");
574 });
575 };
576 }
577 break;
578 case "linear-fade":
579 start = {"opacity": 0};
580 show = {"opacity": 1};
581
582 buttonList.css(start);
583
584 showList = function() {
585 status="show";
586 list.removeClass("fm-hide");
587 stopInterval();
588 i = 0;
589 interval = setInterval(function() {
590 buttonList.eq(i).velocity("stop").velocity(show, showTime, showEase);
591 if (i === total - 1) stopInterval();
592 else i++;
593 }, settings.subEffect[1]);
594 };
595 hideList = function() {
596 status="hide";
597 stopInterval();
598 i = total - 1;
599 interval = setInterval(function() {
600 var bi = i;
601 buttonList.eq(i).velocity("stop").velocity(start, showTime, showEase, function() {
602 if (status === "hide" && bi === 0) list.addClass("fm-hide");
603 });
604 if (i === 0) stopInterval();
605 else i--;
606 }, settings.subEffect[1]);
607 };
608 break;
609 case "linear-slide":
610 var first, last, step;
611
612 if (position === "side") start[side] = -iw;
613 else if (position === "circular") {
614 start = {"top": 0};
615 start[side] = 0;
616 } else start = {"top": -ih};
617 start["opacity"] = 0;
618
619 buttonList.css(start);
620
621 showList = function() {
622 status = "show";
623 list.removeClass("fm-hide");
624 stopInterval();
625 i = 0;
626 interval = setInterval(function() {
627 if (position === "side") show[side] = 0;
628 else if (position === "circular") {
629 show = {"top": positions[i][1]};
630 show[side] = positions[i][0];
631 } else show = {"top": positions[i]};
632 show["opacity"] = 1;
633
634 buttonList.eq(i).velocity("stop").velocity(show, showTime, showEase);
635 if (i === total - 1) stopInterval();
636 else i++;
637 }, settings.subEffect[1]);
638 };
639 hideList = function() {
640 status = "hide";
641
642 if (position === "side" || position === "circular") {
643 first = 0;
644 last = total - 1;
645 step = 1;
646 } else {
647 first = total - 1;
648 last = 0;
649 step = -1;
650 }
651
652 stopInterval();
653 i = first;
654 interval = setInterval(function() {
655 var bi = i;
656 buttonList.eq(i).velocity("stop").velocity(start, showTime, showEase, function() {
657 if (status === "hide" && bi === last) list.addClass("fm-hide");
658 });
659 if (i === last) stopInterval();
660 else i += step;
661 }, settings.subEffect[1]);
662 };
663 break;
664 default:
665 showList = function() {
666 list.removeClass("fm-hide");
667 };
668 hideList = function() {
669 list.addClass("fm-hide");
670 };
671 break;
672 }
673
674 function stopInterval() {
675 clearInterval(interval);
676 }
677
678 function showSub() {
679 showList();
680 if (hit) hit.addClass("fm-show");
681
682 if (prevOffset) {
683 bar.velocity("stop").velocity({"margin-top": barMargin - prevOffset + buttonMargin}, showTime, showEase);
684 sub.velocity("stop").velocity({"margin-top": prevOffset}, showTime, showEase);
685 }
686
687 if (nextOffset) {
688 nextButton.velocity("stop").velocity({"margin-top": nextOffset}, showTime, showEase);
689 }
690
691 subOpen = true;
692 csub = sub;
693 }
694
695 function hideSub() {
696 hideList();
697 if (hit) hit.removeClass("fm-show");
698
699 if (prevOffset) {
700 bar.velocity("stop").velocity({"margin-top": barMargin}, showTime, showEase);
701 sub.velocity("stop").velocity({"margin-top": buttonMargin}, showTime, showEase);
702 }
703
704 if (nextOffset) {
705 nextButton.velocity("stop").velocity({"margin-top": nextMargins[ind + 1]}, showTime, showEase);
706 }
707
708 subOpen = false;
709 csub = null;
710 }
711
712 sub.show = showSub;
713 sub.hide = hideSub;
714
715 if (settings.subOpen === "click") {
716 icon.on("click", function(event) {
717 if (subOpen) {
718 hideSub();
719 } else {
720 if (csub) {
721 csub.hide();
722 }
723 showSub();
724 }
725 event.stopPropagation();
726 });
727
728 $document.on("click", function(event) {
729 if (subOpen && !cwindow && !$(event.target).closest(sub).length) {
730 hideSub();
731 }
732 });
733 } else {
734 sub.on("mouseenter", showSub);
735 sub.on("mouseleave", hideSub);
736 }
737 }
738
739 function buildPanel() {
740 var panel = $(this);
741 panel.find(".fm-close").on("click", function(event) {
742 closeWindow();
743 event.stopPropagation();
744 });
745
746 }
747
748
749
750 function openWindow(name) {
751 sbwindow.addClass("fm-show");
752 cwindow = $(name).addClass("fm-show");
753 posWindow(cwindow);
754 }
755 function closeWindow() {
756 sbwindow.removeClass("fm-show");
757 cwindow.removeClass("fm-show");
758 cwindow = null;
759 }
760
761 function position() {
762 posBar();
763 if (cwindow) posWindow(cwindow);
764 }
765
766 function resize() {
767 position();
768
769 if (settings.hideUnderWidth) {
770 if ($window.width() < settings.hideUnderWidth) {
771 sidebar.addClass("fm-vhide");
772 } else {
773 sidebar.removeClass("fm-vhide");
774 }
775 }
776 }
777
778 function posBar () {
779 posObject(bar, settings.position, settings.offset);
780 }
781 function posWindow(win) {
782 var pos, off;
783
784 if (win.data("position")) {
785 pos = win.data("position").split("-");
786 if (!pos[1]) pos[1] = defaults.windowPosition[1];
787 } else {
788 pos = settings.windowPosition;
789 }
790
791 if (win.data("offset")) {
792 off = splitOffset(win.data("offset"));
793 } else {
794 off = settings.windowOffset;
795 }
796
797 posObject(win, pos, off);
798 }
799 function posObject(tar, pos, off) {
800 if (pos) {
801 var ww = $window.width();
802 var wh = $window.height();
803 var tw = tar.outerWidth(true);
804 var th = tar.outerHeight(true);
805 var x, y;
806 var p;
807
808 if (typeof pos[0] === "number") x = {"left": pos[0] + off[0]};
809 else if (typeof pos[0] === "string") {
810 if (pos[0].indexOf("%") !== -1) {
811 p = getInt(pos[0].split("%")[0]);
812 x = {"left": p / 100 * ww + off[0]};
813 } else {
814 if (pos[0] === "left") x = {"left": 0 + off[0]};
815 else if (pos[0] === "center") x = {"left": (ww - tw) / 2 + off[0]};
816 else if (pos[0] === "right") x = {"right": 0 + off[0]};
817
818 else x = {"left": getInt(pos[0]) + off[0]};
819 }
820 }
821
822 if (typeof pos[1] === "number") y = {"top": pos[1] + off[1]};
823 else if (typeof pos[1] === "string") {
824 if (pos[1].indexOf("%") !== -1) {
825 p = getInt(pos[1].split("%")[0]);
826 y = {"top": p / 100 * wh + off[1]};
827 } else {
828 if (pos[1] === "top") y = {"top": 0 + off[1]};
829 else if (pos[1] === "center") y = {"top": (wh - th) / 2 + off[1]};
830 else if (pos[1] === "bottom") y = {"bottom": 0 + off[1]};
831
832 else y = {"top": getInt(pos[1]) + off[1]};
833 }
834 }
835
836 if (x.left) x.left = Math.round(x.left);
837 if (x.right) x.right = Math.round(x.right);
838
839 if (y.top) y.top = Math.round(y.top);
840 if (y.bottom) y.bottom = Math.round(y.bottom);
841
842 tar.css($.extend({}, x, y));
843 }
844 }
845
846 function pinterestShare(event) {
847 $("body").append('<script src="https://assets.pinterest.com/js/pinmarklet.js" type="text/javascript"></script>');
848 event.preventDefault();
849 }
850
851 function sharePopup(event) {
852 var url = event.data.url;
853 var params = event.data.params;
854 var winLeft;
855 var winParams;
856
857 if (params.left === "center") {
858 winLeft = ($window.width() - params.width) / 2;
859 } else {
860 winLeft = params.left;
861 }
862
863 winParams = "menubar=no,toolbar=no,location=no,scrollbars=no,status=no,resizable=yes,width=" + params.width + ",height=" + params.height + ",top=" + params.top + ",left=" + winLeft;
864
865 window.open(url, "sbShareWindow", winParams);
866
867 event.preventDefault();
868 }
869
870 function showBar() {
871 bar.removeClass("fm-hide");
872 bar.velocity("stop").velocity({"opacity": 1}, settings.barAnimate.show[0], settings.barAnimate.show[1]);
873 barVisible = true;
874 }
875 function hideBar() {
876 bar.velocity("stop").velocity({"opacity": 0}, settings.barAnimate.show[0], settings.barAnimate.show[1], function() {
877 bar.addClass("fm-hide");
878 });
879 barVisible = false;
880 }
881 });
882 }
883
884 function destroy() {
885 return this.each(function() {
886 var sidebar = $(this);
887 var bar, sbwindow;
888
889 if (sidebar.data("fm-built")) {
890 sidebar.data("fm-built", false);
891
892 bar = sidebar.children(".fm-bar");
893 sbwindow = sidebar.children(".fm-window");
894
895 bar.attr("class", "fm-bar").removeAttr("style");
896 sbwindow.attr("class", "fm-window");
897
898 destroyList(bar);
899
900 sbwindow.removeClass("fm-show");
901 sbwindow.children(".fm-shadow").off("click");
902 sbwindow.children(".fm-panel").removeClass("fm-show").removeAttr("style").each(destroyPanel);
903
904 $(window).off("resize.superSidebar scroll.superSidebar");
905
906 sidebar.removeClass("fm-ready");
907 }
908
909 function destroyList(list) {
910 list.children().each(function() {
911 if ($(this).hasClass("fm-sub")) destroySub(this);
912 else destroyButton(this);
913 });
914 }
915 function destroyButton(btn) {
916 var button = $(btn);
917 var link = button.find("a");
918 var label = link.children(".fm-label");
919
920 if (link.data("share")) link.removeAttr("href target");
921
922 link.children(".fm-hit").remove();
923
924 if (button.children(".fm-mask").length) link.unwrap();
925
926 label.removeAttr("style");
927
928 link.off("mouseenter mouseleave click");
929 }
930 function destroySub(sub) {
931 var sub = $(sub);
932 var list = sub.children("ul");
933
934 sub.removeClass("fm-side fm-circular fm-sub-space fm-posabs");
935
936 list.removeClass("fm-hide");
937 list.removeAttr("style");
938 list.children().removeAttr("style");
939
940 sub.children(".fm-subhit").remove();
941
942 sub.off("mouseenter mouseleave");
943 }
944 function destroyPanel() {
945 var panel = $(this);
946
947 panel.find(".fm-close").off("click");
948
949 var form = panel.find("form");
950 if (form.length) destroyForm(form);
951 }
952 function destroyForm(form) {
953 var fieldList = form.find("input, textarea");
954
955 form.find(".fm-submit").off("click");
956 form.off("submit");
957
958 fieldList.removeClass("fm-formerror").off("focus");
959 fieldList.each(function() {
960 $(this).val("");
961 });
962
963 form.find(".fm-status").attr("class", "fm-status");
964 }
965 });
966 }
967
968 function createSettings(options) {
969 var settings = $.extend({}, defaults, options);
970
971 if (typeof settings.position === "string") {
972 settings.position = settings.position.split("-");
973 }
974 if (settings.position[0] === "center") {
975 settings.position[0] = defaults.position[0];
976 warn('Bar horizontal position cannot be "center". Horizontal position reset to "left".');
977 }
978 if (!settings.position[1]) {
979 settings.position[1] = defaults.position[1];
980 }
981
982 if (settings.offset === 0 || settings.offset === false) {
983 settings.offset = [0, 0];
984 } else if (typeof settings.offset === "string") {
985 settings.offset = splitOffset(settings.offset);
986 }
987
988 if (!options.buttonShape && options.shape) {
989 settings.buttonShape = settings.shape;
990 }
991 if (settings.buttonShape !== "square") {
992 if (settings.buttonShape !== "round" && settings.buttonShape !== "rounded" && settings.buttonShape !== "rounded-out") {
993 settings.buttonShape = "square";
994 }
995 }
996
997 if (!options.buttonColor && options.color) {
998 settings.buttonColor = settings.color;
999 }
1000 if (settings.buttonColor === "default") {
1001 settings.buttonColor = "custom";
1002 }
1003
1004 if (!options.buttonOverColor && options.overColor) {
1005 settings.buttonOverColor = settings.overColor;
1006 }
1007 if (settings.buttonOverColor === "default") {
1008 settings.buttonOverColor = "custom";
1009 }
1010
1011 if (settings.labelColor === "match") {
1012 settings.labelColor = settings.buttonOverColor;
1013 }
1014 if (settings.labelTextColor === "match") {
1015 settings.labelTextColor = settings.iconOverColor;
1016 }
1017
1018 if (settings.labelEffect === "slide") settings.labelEffect = "slide-out";
1019 if (settings.labelEffect === "slide-in-fade") settings.labelEffect = "slide-in";
1020
1021 if (!options.labelAnimate && options.labelAnim) {
1022 settings.labelAnimate = settings.labelAnim;
1023 }
1024 if (settings.labelAnimate === "default") {
1025 if (labelAnimateDefaults[settings.labelEffect]) {
1026 settings.labelAnimate = labelAnimateDefaults[settings.labelEffect];
1027 } else {
1028 settings.labelAnimate = labelAnimateDefaults[0];
1029 }
1030 }
1031 settings.labelAnimate = extendAnimateSetting(settings.labelAnimate);
1032
1033 if (settings.labelConnected) {
1034 if (settings.labelEffect === "slide-in" || settings.labelEffect === "slide-out-out" || settings.labelEffect === "slide-in-in") {
1035 settings.labelConnected = false;
1036 warn('"labelConnected: true" incompatible with "labelEffect: ' + settings.labelEffect + '". "labelConnected" reset to false.');
1037 } else if (settings.labelSpace) {
1038 settings.labelSpace = false;
1039 warn('"labelSpace: true" incompatible with "labelConnected: true". "labelSpace" reset to false.');
1040 }
1041 }
1042
1043
1044 if (typeof settings.subPosition === "string") {
1045 settings.subPosition = [settings.subPosition];
1046 }
1047 if (settings.subPosition[0] === "circular") {
1048 if (!settings.subPosition[1]) settings.subPosition[1] = defaults.subPosition[1];
1049 if (typeof settings.subPosition[2] === "undefined") settings.subPosition[2] = defaults.subPosition[2];
1050 if (typeof settings.subPosition[3] === "undefined") settings.subPosition[3] = defaults.subPosition[3];
1051
1052 if (settings.subSpace) settings.subSpace = false;
1053 }
1054
1055 if (!options.subAnimate && options.subAnim) {
1056 settings.subAnimate = settings.subAnim;
1057 }
1058 if (settings.subAnimate === "default") settings.subAnimate = defaults.subAnimate;
1059
1060 if (typeof settings.subEffect === "string") {
1061 settings.subEffect = [settings.subEffect];
1062 }
1063 if ((settings.subEffect[0] === "linear-fade" || settings.subEffect[0] === "linear-slide") && !settings.subEffect[1]) {
1064 settings.subEffect[1] = defaults.subEffect[1];
1065 }
1066
1067 settings.subAnimate = extendAnimateSetting(settings.subAnimate);
1068
1069
1070 if (typeof settings.windowPosition === "string") {
1071 settings.windowPosition = settings.windowPosition.split("-");
1072 }
1073 if (!settings.windowPosition[1]) {
1074 settings.windowPosition[1] = defaults.windowPosition[1];
1075 }
1076
1077 if (settings.windowOffset === 0 || settings.windowOffset === false) {
1078 settings.windowOffset = [0, 0];
1079 } else if (typeof settings.windowOffset === "string") {
1080 settings.windowOffset = splitOffset(settings.windowOffset);
1081 }
1082
1083 if (settings.windowCorners === "match") {
1084 if (settings.buttonShape === "round" || settings.buttonShape === "rounded" || settings.buttonShape === "rounded-out") {
1085 settings.windowCorners = "round";
1086 }
1087 }
1088
1089 if (settings.windowColor === "match") {
1090 settings.windowColor = settings.buttonColor;
1091 } else if (settings.windowColor === "default") {
1092 settings.windowColor = "custom";
1093 }
1094
1095
1096 if (settings.barAnimate === "default") {
1097 settings.barAnimate = defaults.barAnimate;
1098 }
1099
1100 settings.barAnimate = extendAnimateSetting(settings.barAnimate);
1101
1102 if (settings.hideUnder) {
1103 settings.hideUnderWidth = settings.hideUnder;
1104 }
1105
1106
1107
1108
1109 return settings;
1110 }
1111
1112 function splitOffset(off) {
1113 off = off.split("-");
1114 off[0] = getInt(off[0]);
1115 if (off[1]) off[1] = getInt(off[1]);
1116 return off;
1117 }
1118
1119 function extendAnimateSetting(animate) {
1120 if (Object.prototype.toString.call(animate) === "[object Array]") {
1121 return {
1122 show: animate,
1123 hide: animate
1124 };
1125 } else {
1126 return animate;
1127 }
1128 }
1129
1130 function warn(msg) {
1131 if (window.console) {
1132 console.log("(!) Float Menu: " + msg);
1133 }
1134 }
1135
1136 function getInt(val) {
1137 return parseInt(val, 10);
1138 }
1139
1140
1141 }(jQuery));
1142
1143
1144 function scrollToTop() {
1145 jQuery('body,html').animate({
1146 scrollTop: 0
1147 }, 777);
1148 }
1149
1150 function pageprint() {
1151 window.print();
1152 }
1153
1154 function smoothscroll(section) {
1155 jQuery('html, body').animate({
1156 scrollTop: jQuery(section).offset().top,
1157 }, 777);
1158 }