diff --git a/plugins/Sidebar/media/Internals.coffee b/plugins/Sidebar/media/Internals.coffee new file mode 100644 index 00000000..484ecdb7 --- /dev/null +++ b/plugins/Sidebar/media/Internals.coffee @@ -0,0 +1,60 @@ +class Internals extends Class + constructor: (@sidebar) -> + @tag = null + @opened = false + if window.top.location.hash == "#internals" + setTimeout (=> @open()), 10 + + createHtmltag: -> + @when_loaded = $.Deferred() + if not @container + @container = $(""" +
+
+
+ +
+
+ + """) + @container.appendTo(document.body) + @tag = @container.find(".internals") + + open: => + @createHtmltag() + @sidebar.fixbutton_targety = @sidebar.page_height + @stopDragY() + + onOpened: => + @sidebar.onClosed() + @log "onOpened" + + onClosed: => + $(document.body).removeClass("body-internals") + + stopDragY: => + # Animate sidebar and iframe + if @sidebar.fixbutton_targety == @sidebar.fixbutton_inity + # Closed + targety = 0 + @opened = false + else + # Opened + targety = @sidebar.fixbutton_targety - @sidebar.fixbutton_inity + @onOpened() + @opened = true + + # Revent sidebar transitions + if @tag + @tag.css("transition", "0.5s ease-out") + @tag.css("transform", "translateY(#{targety}px)").one transitionEnd, => + @tag.css("transition", "") + if not @opened + @log "cleanup" + # Revert body transformations + @log "stopdrag", "opened:", @opened, targety + if not @opened + @onClosed() + +window.Internals = Internals \ No newline at end of file diff --git a/plugins/Sidebar/media/Internals.css b/plugins/Sidebar/media/Internals.css new file mode 100644 index 00000000..36b2489e --- /dev/null +++ b/plugins/Sidebar/media/Internals.css @@ -0,0 +1,17 @@ +.internals-container { width: 100%; z-index: 998; position: absolute; top: -100vh; } +.internals { background-color: #EEE; height: 100vh; transform: translateY(0px); } +.internals-middle {height: 0px; top: 50%; position: absolute; width: 100%; left: 50%; } + +.internals .mynode { + border: 0.5px solid #aaa; width: 50px; height: 50px; transform: rotateZ(45deg); margin-top: -25px; margin-left: -25px; + opacity: 1; display: inline-block; background-color: #EEE; z-index: 9; position: absolute; outline: 5px solid #EEE; +} +.internals .peers { width: 0px; height: 0px; position: absolute; left: -20px; top: -20px; text-align: center; } +.internals .peer { left: 0px; top: 0px; position: absolute; } +.internals .peer .icon { width: 20px; height: 20px; padding: 10px; display: inline-block; text-decoration: none; left: 200px; position: absolute; color: #666; } +.internals .peer .icon:before { content: "\25BC"; position: absolute; margin-top: 3px; margin-left: -1px; opacity: 0; transition: all 0.3s } +.internals .peer .icon:hover:before { opacity: 1; transition: none } +.internals .peer .line { + width: 187px; border-top: 1px solid #CCC; position: absolute; top: 20px; left: 20px; + transform: rotateZ(334deg); transform-origin: bottom left; +} \ No newline at end of file diff --git a/plugins/Sidebar/media/Sidebar.coffee b/plugins/Sidebar/media/Sidebar.coffee index e3bc6f0c..7f5c8f1d 100644 --- a/plugins/Sidebar/media/Sidebar.coffee +++ b/plugins/Sidebar/media/Sidebar.coffee @@ -4,11 +4,16 @@ class Sidebar extends Class @container = null @opened = false @width = 410 + @internals = new Internals(@) @fixbutton = $(".fixbutton") @fixbutton_addx = 0 + @fixbutton_addy = 0 @fixbutton_initx = 0 + @fixbutton_inity = 15 @fixbutton_targetx = 0 + @move_lock = null @page_width = $(window).width() + @page_height = $(window).height() @frame = $("#inner-iframe") @initFixbutton() @dragStarted = 0 @@ -41,13 +46,16 @@ class Sidebar extends Class @dragStarted = (+ new Date) @fixbutton.one "mousemove touchmove", (e) => mousex = e.pageX + mousey = e.pageY if not mousex mousex = e.originalEvent.touches[0].pageX + mousey = e.originalEvent.touches[0].pageY - @fixbutton_addx = @fixbutton.offset().left-mousex + @fixbutton_addx = @fixbutton.offset().left - mousex + @fixbutton_addy = @fixbutton.offset().top - mousey @startDrag() @fixbutton.parent().on "click touchend touchcancel", (e) => - if (+ new Date)-@dragStarted < 100 + if (+ new Date) - @dragStarted < 100 window.top.location = @fixbutton.find(".fixbutton-bg").attr("href") @stopDrag() @resized() @@ -55,6 +63,7 @@ class Sidebar extends Class resized: => @page_width = $(window).width() + @page_height = $(window).height() @fixbutton_initx = @page_width - 75 # Initial x position if @opened @fixbutton.css @@ -65,6 +74,7 @@ class Sidebar extends Class # Start dragging the fixbutton startDrag: -> + @move_lock = "x" # Temporary until internals not finished @log "startDrag" @fixbutton_targetx = @fixbutton_initx # Fallback x position @@ -81,7 +91,9 @@ class Sidebar extends Class @fixbutton.one "click", (e) => @stopDrag() @fixbutton.removeClass("dragging") - if Math.abs(@fixbutton.offset().left - @fixbutton_initx) > 5 + moved_x = Math.abs(@fixbutton.offset().left - @fixbutton_initx) + moved_y = Math.abs(@fixbutton.offset().top - @fixbutton_inity) + if moved_x > 5 or moved_y > 10 # If moved more than some pixel the button then don't go to homepage e.preventDefault() @@ -97,20 +109,45 @@ class Sidebar extends Class # Wait for moving the fixbutton waitMove: (e) => - if Math.abs(@fixbutton.offset().left - @fixbutton_targetx) > 10 and (+ new Date)-@dragStarted > 100 - @moved() + document.body.style.perspective = "1000px" + document.body.style.height = "100%" + document.body.style.willChange = "perspective" + document.documentElement.style.height = "100%" + #$(document.body).css("backface-visibility", "hidden").css("perspective", "1000px").css("height", "900px") + # $("iframe").css("backface-visibility", "hidden") + + moved_x = Math.abs(parseInt(@fixbutton[0].style.left) - @fixbutton_targetx) + moved_y = Math.abs(parseInt(@fixbutton[0].style.top) - @fixbutton_targety) + if moved_x > 5 and (+ new Date) - @dragStarted + moved_x > 50 + @moved("x") + @fixbutton.stop().animate {"top": @fixbutton_inity}, 1000 @fixbutton.parents().off "mousemove touchmove" ,@waitMove - moved: -> - @log "Moved" + else if moved_y > 5 and (+ new Date) - @dragStarted + moved_y > 50 + @moved("y") + @fixbutton.parents().off "mousemove touchmove" ,@waitMove + + moved: (direction) -> + @log "Moved", direction + @move_lock = direction + if direction == "y" + $(document.body).addClass("body-internals") + return @internals.createHtmltag() @createHtmltag() - $(document.body).css("perspective", "1000px").addClass("body-sidebar") + $(document.body).addClass("body-sidebar") + @container.on "mousedown touchend touchcancel", (e) => + if e.target != e.currentTarget + return true + @log "closing" + if $(document.body).hasClass("body-sidebar") + @close() + return true + $(window).off "resize" $(window).on "resize", => $(document.body).css "height", $(window).height() @scrollable() @resized() - $(window).trigger "resize" # Override setsiteinfo to catch changes @wrapper.setSiteInfo = (site_info) => @@ -157,7 +194,6 @@ class Sidebar extends Class @when_loaded.resolve() else # Not first update, patch the html to keep unchanged dom elements - @log "Patching content" morphdom @tag.find(".content")[0], '
'+res+'
', { onBeforeMorphEl: (from_el, to_el) -> # Ignore globe loaded state if from_el.className == "globe" or from_el.className.indexOf("noupdate") >= 0 @@ -169,19 +205,38 @@ class Sidebar extends Class animDrag: (e) => mousex = e.pageX - if not mousex + mousey = e.pageY + if not mousex and e.originalEvent.touches mousex = e.originalEvent.touches[0].pageX + mousey = e.originalEvent.touches[0].pageY - overdrag = @fixbutton_initx-@width-mousex + overdrag = @fixbutton_initx - @width - mousex if overdrag > 0 # Overdragged - overdrag_percent = 1+overdrag/300 + overdrag_percent = 1 + overdrag/300 mousex = (mousex + (@fixbutton_initx-@width)*overdrag_percent)/(1+overdrag_percent) - targetx = @fixbutton_initx-mousex-@fixbutton_addx + targetx = @fixbutton_initx - mousex - @fixbutton_addx + targety = @fixbutton_inity - mousey - @fixbutton_addy - @fixbutton[0].style.left = (mousex+@fixbutton_addx)+"px" + if @move_lock == "x" + targety = @fixbutton_inity + else if @move_lock == "y" + targetx = @fixbutton_initx - if @tag - @tag[0].style.transform = "translateX(#{0-targetx}px)" + if not @move_lock or @move_lock == "x" + @fixbutton[0].style.left = (mousex + @fixbutton_addx) + "px" + if @tag + @tag[0].style.transform = "translateX(#{0 - targetx}px)" + + if not @move_lock or @move_lock == "y" + @fixbutton[0].style.top = (mousey + @fixbutton_addy) + "px" + if @internals.tag + @internals.tag[0].style.transform = "translateY(#{0 - targety}px)" + + #if @move_lock == "x" + # @fixbutton[0].style.left = "#{@fixbutton_targetx} px" + #@fixbutton[0].style.top = "#{@fixbutton_inity}px" + #if @move_lock == "y" + # @fixbutton[0].style.top = "#{@fixbutton_targety} px" # Check if opened if (not @opened and targetx > @width/3) or (@opened and targetx > @width*0.9) @@ -189,6 +244,11 @@ class Sidebar extends Class else @fixbutton_targetx = @fixbutton_initx + if (not @internals.opened and 0 - targety > @page_height/10) or (@internals.opened and 0 - targety > @page_height*0.95) + @fixbutton_targety = @page_height - @fixbutton_inity - 50 + else + @fixbutton_targety = @fixbutton_inity + # Stop dragging the fixbutton stopDrag: -> @@ -203,45 +263,56 @@ class Sidebar extends Class # Move back to initial position if @fixbutton_targetx != @fixbutton.offset().left # Animate fixbutton - @fixbutton.stop().animate {"left": @fixbutton_targetx}, 500, "easeOutBack", => + if @move_lock == "y" + top = @fixbutton_targety + left = @fixbutton_initx + if @move_lock == "x" + top = @fixbutton_inity + left = @fixbutton_targetx + @fixbutton.stop().animate {"left": left, "top": top}, 500, "easeOutBack", => # Switch back to auto align if @fixbutton_targetx == @fixbutton_initx # Closed @fixbutton.css("left", "auto") else # Opened - @fixbutton.css("left", @fixbutton_targetx) + @fixbutton.css("left", left) $(".fixbutton-bg").trigger "mouseout" # Switch fixbutton back to normal status - # Animate sidebar and iframe - if @fixbutton_targetx == @fixbutton_initx - # Closed - targetx = 0 - @opened = false + @stopDragX() + @internals.stopDragY() + @move_lock = null + + stopDragX: -> + # Animate sidebar and iframe + if @fixbutton_targetx == @fixbutton_initx or @move_lock == "y" + # Closed + targetx = 0 + @opened = false + else + # Opened + targetx = @width + if @opened + @onOpened() else - # Opened - targetx = @width - if @opened + @when_loaded.done => @onOpened() - else - @when_loaded.done => - @onOpened() - @opened = true + @opened = true - # Revent sidebar transitions - if @tag - @tag.css("transition", "0.4s ease-out") - @tag.css("transform", "translateX(-#{targetx}px)").one transitionEnd, => - @tag.css("transition", "") - if not @opened - @container.remove() - @container = null - @tag.remove() - @tag = null + # Revent sidebar transitions + if @tag + @tag.css("transition", "0.4s ease-out") + @tag.css("transform", "translateX(-#{targetx}px)").one transitionEnd, => + @tag.css("transition", "") + if not @opened + @container.remove() + @container = null + @tag.remove() + @tag = null - # Revert body transformations - @log "stopdrag", "opened:", @opened - if not @opened - @onClosed() + # Revert body transformations + @log "stopdrag", "opened:", @opened + if not @opened + @onClosed() onOpened: -> @@ -448,19 +519,23 @@ class Sidebar extends Class # Close @tag.find(".close").off("click touchend").on "click touchend", (e) => - @startDrag() - @stopDrag() + @close() return false @loadGlobe() + close: -> + @move_lock = "x" + @startDrag() + @stopDrag() + onClosed: -> $(window).off "resize" $(window).on "resize", @resized $(document.body).css("transition", "0.6s ease-in-out").removeClass("body-sidebar").on transitionEnd, (e) => - if e.target == document.body - $(document.body).css("height", "auto").css("perspective", "").css("transition", "").off transitionEnd + if e.target == document.body and not $(document.body).hasClass("body-sidebar") and not $(document.body).hasClass("body-internals") + $(document.body).css("height", "auto").css("perspective", "").css("will-change", "").css("transition", "").off transitionEnd @unloadGlobe() # We dont need site info anymore @@ -468,7 +543,7 @@ class Sidebar extends Class loadGlobe: => - console.log "loadGlobe", @tag.find(".globe").hasClass("loading") + console.log "loadGlobe", @tag.find(".globe")[0], @tag.find(".globe").hasClass("loading") if @tag.find(".globe").hasClass("loading") setTimeout (=> if typeof(DAT) == "undefined" # Globe script not loaded, do it first @@ -487,6 +562,7 @@ class Sidebar extends Class @globe.scene.remove(@globe.points) @globe.addData( globe_data, {format: 'magnitude', name: "hello", animated: false} ) @globe.createPoints() + @tag?.find(".globe").removeClass("loading") else if typeof(DAT) != "undefined" try @globe = new DAT.Globe( @tag.find(".globe")[0], {"imgDir": "/uimedia/globe/"} ) @@ -496,8 +572,8 @@ class Sidebar extends Class catch e console.log "WebGL error", e @tag?.find(".globe").addClass("error").text("WebGL not supported") + @tag?.find(".globe").removeClass("loading") - @tag?.find(".globe").removeClass("loading") unloadGlobe: => diff --git a/plugins/Sidebar/media/Sidebar.css b/plugins/Sidebar/media/Sidebar.css index bef0a681..660b1bab 100644 --- a/plugins/Sidebar/media/Sidebar.css +++ b/plugins/Sidebar/media/Sidebar.css @@ -7,9 +7,10 @@ .fixbutton-bg:active { cursor: -webkit-grabbing; } -.body-sidebar { background-color: #666 !important; } -#inner-iframe { transition: 0.3s ease-in-out; transform-origin: left; } -.body-sidebar iframe { transform: rotateY(5deg); opacity: 0.8; pointer-events: none; outline: 1px solid transparent } /* translateX(-200px) scale(0.95)*/ +.body-sidebar, .body-internals { background-color: #666 !important; } +#inner-iframe { transition: 0.3s ease-in-out; transform-origin: left bottom; } +.body-sidebar iframe { transform: rotateY(5deg); opacity: 0.8; pointer-events: none; outline: 1px solid transparent } +.body-internals iframe { transform: rotateX(5deg); opacity: 0.8; pointer-events: none; outline: 1px solid transparent } .sidebar .link-right { color: white; text-decoration: none; border-bottom: 1px solid #666; text-transform: uppercase; float: right; margin-right: 7px; margin-top: 1px; } .sidebar .link-right:hover { border-color: #CCC; } diff --git a/plugins/Sidebar/media/all.css b/plugins/Sidebar/media/all.css index d91287c3..fcf00618 100644 --- a/plugins/Sidebar/media/all.css +++ b/plugins/Sidebar/media/all.css @@ -1,5 +1,27 @@ +/* ---- plugins/Sidebar/media/Internals.css ---- */ + + +.internals-container { width: 100%; z-index: 998; position: absolute; top: -100vh; } +.internals { background-color: #EEE; height: 100vh; -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -o-transform: translateY(0px); -ms-transform: translateY(0px); transform: translateY(0px) ; } +.internals-middle {height: 0px; top: 50%; position: absolute; width: 100%; left: 50%; } + +.internals .mynode { + border: 0.5px solid #aaa; width: 50px; height: 50px; -webkit-transform: rotateZ(45deg); -moz-transform: rotateZ(45deg); -o-transform: rotateZ(45deg); -ms-transform: rotateZ(45deg); transform: rotateZ(45deg) ; margin-top: -25px; margin-left: -25px; + opacity: 1; display: inline-block; background-color: #EEE; z-index: 9; position: absolute; outline: 5px solid #EEE; +} +.internals .peers { width: 0px; height: 0px; position: absolute; left: -20px; top: -20px; text-align: center; } +.internals .peer { left: 0px; top: 0px; position: absolute; } +.internals .peer .icon { width: 20px; height: 20px; padding: 10px; display: inline-block; text-decoration: none; left: 200px; position: absolute; color: #666; } +.internals .peer .icon:before { content: "\25BC"; position: absolute; margin-top: 3px; margin-left: -1px; opacity: 0; -webkit-transition: all 0.3s ; -moz-transition: all 0.3s ; -o-transition: all 0.3s ; -ms-transition: all 0.3s ; transition: all 0.3s } +.internals .peer .icon:hover:before { opacity: 1; -webkit-transition: none ; -moz-transition: none ; -o-transition: none ; -ms-transition: none ; transition: none } +.internals .peer .line { + width: 187px; border-top: 1px solid #CCC; position: absolute; top: 20px; left: 20px; + -webkit-transform: rotateZ(334deg); -moz-transform: rotateZ(334deg); -o-transform: rotateZ(334deg); -ms-transform: rotateZ(334deg); transform: rotateZ(334deg) ; transform-origin: bottom left; +} + + /* ---- plugins/Sidebar/media/Menu.css ---- */ @@ -86,9 +108,10 @@ .fixbutton-bg:active { cursor: -webkit-grabbing; } -.body-sidebar { background-color: #666 !important; } -#inner-iframe { -webkit-transition: 0.3s ease-in-out; -moz-transition: 0.3s ease-in-out; -o-transition: 0.3s ease-in-out; -ms-transition: 0.3s ease-in-out; transition: 0.3s ease-in-out ; transform-origin: left; } -.body-sidebar iframe { -webkit-transform: rotateY(5deg); -moz-transform: rotateY(5deg); -o-transform: rotateY(5deg); -ms-transform: rotateY(5deg); transform: rotateY(5deg) ; opacity: 0.8; pointer-events: none; outline: 1px solid transparent } /* translateX(-200px) scale(0.95)*/ +.body-sidebar, .body-internals { background-color: #666 !important; } +#inner-iframe { -webkit-transition: 0.3s ease-in-out; -moz-transition: 0.3s ease-in-out; -o-transition: 0.3s ease-in-out; -ms-transition: 0.3s ease-in-out; transition: 0.3s ease-in-out ; transform-origin: left bottom; } +.body-sidebar iframe { -webkit-transform: rotateY(5deg); -moz-transform: rotateY(5deg); -o-transform: rotateY(5deg); -ms-transform: rotateY(5deg); transform: rotateY(5deg) ; opacity: 0.8; pointer-events: none; outline: 1px solid transparent } +.body-internals iframe { -webkit-transform: rotateX(5deg); -moz-transform: rotateX(5deg); -o-transform: rotateX(5deg); -ms-transform: rotateX(5deg); transform: rotateX(5deg) ; opacity: 0.8; pointer-events: none; outline: 1px solid transparent } .sidebar .link-right { color: white; text-decoration: none; border-bottom: 1px solid #666; text-transform: uppercase; float: right; margin-right: 7px; margin-top: 1px; } .sidebar .link-right:hover { border-color: #CCC; } diff --git a/plugins/Sidebar/media/all.js b/plugins/Sidebar/media/all.js index 6e9b85b1..79124e3a 100644 --- a/plugins/Sidebar/media/all.js +++ b/plugins/Sidebar/media/all.js @@ -57,6 +57,95 @@ }).call(this); +/* ---- plugins/Sidebar/media/Internals.coffee ---- */ + + +(function() { + var Internals, + bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + hasProp = {}.hasOwnProperty; + + Internals = (function(superClass) { + extend(Internals, superClass); + + function Internals(sidebar) { + this.sidebar = sidebar; + this.stopDragY = bind(this.stopDragY, this); + this.onClosed = bind(this.onClosed, this); + this.onOpened = bind(this.onOpened, this); + this.open = bind(this.open, this); + this.tag = null; + this.opened = false; + if (window.top.location.hash === "#internals") { + setTimeout(((function(_this) { + return function() { + return _this.open(); + }; + })(this)), 10); + } + } + + Internals.prototype.createHtmltag = function() { + this.when_loaded = $.Deferred(); + if (!this.container) { + this.container = $("
\n
\n
\n"); + this.container.appendTo(document.body); + return this.tag = this.container.find(".internals"); + } + }; + + Internals.prototype.open = function() { + this.createHtmltag(); + this.sidebar.fixbutton_targety = this.sidebar.page_height; + return this.stopDragY(); + }; + + Internals.prototype.onOpened = function() { + this.sidebar.onClosed(); + return this.log("onOpened"); + }; + + Internals.prototype.onClosed = function() { + return $(document.body).removeClass("body-internals"); + }; + + Internals.prototype.stopDragY = function() { + var targety; + if (this.sidebar.fixbutton_targety === this.sidebar.fixbutton_inity) { + targety = 0; + this.opened = false; + } else { + targety = this.sidebar.fixbutton_targety - this.sidebar.fixbutton_inity; + this.onOpened(); + this.opened = true; + } + if (this.tag) { + this.tag.css("transition", "0.5s ease-out"); + this.tag.css("transform", "translateY(" + targety + "px)").one(transitionEnd, (function(_this) { + return function() { + _this.tag.css("transition", ""); + if (!_this.opened) { + return _this.log("cleanup"); + } + }; + })(this)); + } + this.log("stopdrag", "opened:", this.opened, targety); + if (!this.opened) { + return this.onClosed(); + } + }; + + return Internals; + + })(Class); + + window.Internals = Internals; + +}).call(this); + + /* ---- plugins/Sidebar/media/Menu.coffee ---- */ @@ -291,11 +380,16 @@ window.initScrollable = function () { this.container = null; this.opened = false; this.width = 410; + this.internals = new Internals(this); this.fixbutton = $(".fixbutton"); this.fixbutton_addx = 0; + this.fixbutton_addy = 0; this.fixbutton_initx = 0; + this.fixbutton_inity = 15; this.fixbutton_targetx = 0; + this.move_lock = null; this.page_width = $(window).width(); + this.page_height = $(window).height(); this.frame = $("#inner-iframe"); this.initFixbutton(); this.dragStarted = 0; @@ -321,12 +415,15 @@ window.initScrollable = function () { _this.fixbutton.off("mousemove touchmove"); _this.dragStarted = +(new Date); return _this.fixbutton.one("mousemove touchmove", function(e) { - var mousex; + var mousex, mousey; mousex = e.pageX; + mousey = e.pageY; if (!mousex) { mousex = e.originalEvent.touches[0].pageX; + mousey = e.originalEvent.touches[0].pageY; } _this.fixbutton_addx = _this.fixbutton.offset().left - mousex; + _this.fixbutton_addy = _this.fixbutton.offset().top - mousey; return _this.startDrag(); }); }; @@ -345,6 +442,7 @@ window.initScrollable = function () { Sidebar.prototype.resized = function() { this.page_width = $(window).width(); + this.page_height = $(window).height(); this.fixbutton_initx = this.page_width - 75; if (this.opened) { return this.fixbutton.css({ @@ -358,6 +456,7 @@ window.initScrollable = function () { }; Sidebar.prototype.startDrag = function() { + this.move_lock = "x"; this.log("startDrag"); this.fixbutton_targetx = this.fixbutton_initx; this.fixbutton.addClass("dragging"); @@ -367,9 +466,12 @@ window.initScrollable = function () { } this.fixbutton.one("click", (function(_this) { return function(e) { + var moved_x, moved_y; _this.stopDrag(); _this.fixbutton.removeClass("dragging"); - if (Math.abs(_this.fixbutton.offset().left - _this.fixbutton_initx) > 5) { + moved_x = Math.abs(_this.fixbutton.offset().left - _this.fixbutton_initx); + moved_y = Math.abs(_this.fixbutton.offset().top - _this.fixbutton_inity); + if (moved_x > 5 || moved_y > 10) { return e.preventDefault(); } }; @@ -385,17 +487,47 @@ window.initScrollable = function () { }; Sidebar.prototype.waitMove = function(e) { - if (Math.abs(this.fixbutton.offset().left - this.fixbutton_targetx) > 10 && (+(new Date)) - this.dragStarted > 100) { - this.moved(); + var moved_x, moved_y; + document.body.style.perspective = "1000px"; + document.body.style.height = "100%"; + document.body.style.willChange = "perspective"; + document.documentElement.style.height = "100%"; + moved_x = Math.abs(parseInt(this.fixbutton[0].style.left) - this.fixbutton_targetx); + moved_y = Math.abs(parseInt(this.fixbutton[0].style.top) - this.fixbutton_targety); + if (moved_x > 5 && (+(new Date)) - this.dragStarted + moved_x > 50) { + this.moved("x"); + this.fixbutton.stop().animate({ + "top": this.fixbutton_inity + }, 1000); + return this.fixbutton.parents().off("mousemove touchmove", this.waitMove); + } else if (moved_y > 5 && (+(new Date)) - this.dragStarted + moved_y > 50) { + this.moved("y"); return this.fixbutton.parents().off("mousemove touchmove", this.waitMove); } }; - Sidebar.prototype.moved = function() { + Sidebar.prototype.moved = function(direction) { var img; - this.log("Moved"); + this.log("Moved", direction); + this.move_lock = direction; + if (direction === "y") { + $(document.body).addClass("body-internals"); + return this.internals.createHtmltag(); + } this.createHtmltag(); - $(document.body).css("perspective", "1000px").addClass("body-sidebar"); + $(document.body).addClass("body-sidebar"); + this.container.on("mousedown touchend touchcancel", (function(_this) { + return function(e) { + if (e.target !== e.currentTarget) { + return true; + } + _this.log("closing"); + if ($(document.body).hasClass("body-sidebar")) { + _this.close(); + return true; + } + }; + })(this)); $(window).off("resize"); $(window).on("resize", (function(_this) { return function() { @@ -404,7 +536,6 @@ window.initScrollable = function () { return _this.resized(); }; })(this)); - $(window).trigger("resize"); this.wrapper.setSiteInfo = (function(_this) { return function(site_info) { _this.setSiteInfo(site_info); @@ -455,7 +586,6 @@ window.initScrollable = function () { morphdom(this.tag.find(".content")[0], '
' + res + '
'); return this.when_loaded.resolve(); } else { - this.log("Patching content"); return morphdom(this.tag.find(".content")[0], '
' + res + '
', { onBeforeMorphEl: function(from_el, to_el) { if (from_el.className === "globe" || from_el.className.indexOf("noupdate") >= 0) { @@ -469,10 +599,12 @@ window.initScrollable = function () { }; Sidebar.prototype.animDrag = function(e) { - var mousex, overdrag, overdrag_percent, targetx; + var mousex, mousey, overdrag, overdrag_percent, targetx, targety; mousex = e.pageX; - if (!mousex) { + mousey = e.pageY; + if (!mousex && e.originalEvent.touches) { mousex = e.originalEvent.touches[0].pageX; + mousey = e.originalEvent.touches[0].pageY; } overdrag = this.fixbutton_initx - this.width - mousex; if (overdrag > 0) { @@ -480,19 +612,38 @@ window.initScrollable = function () { mousex = (mousex + (this.fixbutton_initx - this.width) * overdrag_percent) / (1 + overdrag_percent); } targetx = this.fixbutton_initx - mousex - this.fixbutton_addx; - this.fixbutton[0].style.left = (mousex + this.fixbutton_addx) + "px"; - if (this.tag) { - this.tag[0].style.transform = "translateX(" + (0 - targetx) + "px)"; + targety = this.fixbutton_inity - mousey - this.fixbutton_addy; + if (this.move_lock === "x") { + targety = this.fixbutton_inity; + } else if (this.move_lock === "y") { + targetx = this.fixbutton_initx; + } + if (!this.move_lock || this.move_lock === "x") { + this.fixbutton[0].style.left = (mousex + this.fixbutton_addx) + "px"; + if (this.tag) { + this.tag[0].style.transform = "translateX(" + (0 - targetx) + "px)"; + } + } + if (!this.move_lock || this.move_lock === "y") { + this.fixbutton[0].style.top = (mousey + this.fixbutton_addy) + "px"; + if (this.internals.tag) { + this.internals.tag[0].style.transform = "translateY(" + (0 - targety) + "px)"; + } } if ((!this.opened && targetx > this.width / 3) || (this.opened && targetx > this.width * 0.9)) { - return this.fixbutton_targetx = this.fixbutton_initx - this.width; + this.fixbutton_targetx = this.fixbutton_initx - this.width; } else { - return this.fixbutton_targetx = this.fixbutton_initx; + this.fixbutton_targetx = this.fixbutton_initx; + } + if ((!this.internals.opened && 0 - targety > this.page_height / 10) || (this.internals.opened && 0 - targety > this.page_height * 0.95)) { + return this.fixbutton_targety = this.page_height - this.fixbutton_inity - 50; + } else { + return this.fixbutton_targety = this.fixbutton_inity; } }; Sidebar.prototype.stopDrag = function() { - var targetx; + var left, top; this.fixbutton.parents().off("mousemove touchmove"); this.fixbutton.off("mousemove touchmove"); this.fixbutton.css("pointer-events", ""); @@ -502,52 +653,68 @@ window.initScrollable = function () { } this.fixbutton.removeClass("dragging"); if (this.fixbutton_targetx !== this.fixbutton.offset().left) { + if (this.move_lock === "y") { + top = this.fixbutton_targety; + left = this.fixbutton_initx; + } + if (this.move_lock === "x") { + top = this.fixbutton_inity; + left = this.fixbutton_targetx; + } this.fixbutton.stop().animate({ - "left": this.fixbutton_targetx + "left": left, + "top": top }, 500, "easeOutBack", (function(_this) { return function() { if (_this.fixbutton_targetx === _this.fixbutton_initx) { _this.fixbutton.css("left", "auto"); } else { - _this.fixbutton.css("left", _this.fixbutton_targetx); + _this.fixbutton.css("left", left); } return $(".fixbutton-bg").trigger("mouseout"); }; })(this)); - if (this.fixbutton_targetx === this.fixbutton_initx) { - targetx = 0; - this.opened = false; + this.stopDragX(); + this.internals.stopDragY(); + } + return this.move_lock = null; + }; + + Sidebar.prototype.stopDragX = function() { + var targetx; + if (this.fixbutton_targetx === this.fixbutton_initx || this.move_lock === "y") { + targetx = 0; + this.opened = false; + } else { + targetx = this.width; + if (this.opened) { + this.onOpened(); } else { - targetx = this.width; - if (this.opened) { - this.onOpened(); - } else { - this.when_loaded.done((function(_this) { - return function() { - return _this.onOpened(); - }; - })(this)); - } - this.opened = true; - } - if (this.tag) { - this.tag.css("transition", "0.4s ease-out"); - this.tag.css("transform", "translateX(-" + targetx + "px)").one(transitionEnd, (function(_this) { + this.when_loaded.done((function(_this) { return function() { - _this.tag.css("transition", ""); - if (!_this.opened) { - _this.container.remove(); - _this.container = null; - _this.tag.remove(); - return _this.tag = null; - } + return _this.onOpened(); }; })(this)); } - this.log("stopdrag", "opened:", this.opened); - if (!this.opened) { - return this.onClosed(); - } + this.opened = true; + } + if (this.tag) { + this.tag.css("transition", "0.4s ease-out"); + this.tag.css("transform", "translateX(-" + targetx + "px)").one(transitionEnd, (function(_this) { + return function() { + _this.tag.css("transition", ""); + if (!_this.opened) { + _this.container.remove(); + _this.container = null; + _this.tag.remove(); + return _this.tag = null; + } + }; + })(this)); + } + this.log("stopdrag", "opened:", this.opened); + if (!this.opened) { + return this.onClosed(); } }; @@ -851,21 +1018,26 @@ window.initScrollable = function () { })(this)); this.tag.find(".close").off("click touchend").on("click touchend", (function(_this) { return function(e) { - _this.startDrag(); - _this.stopDrag(); + _this.close(); return false; }; })(this)); return this.loadGlobe(); }; + Sidebar.prototype.close = function() { + this.move_lock = "x"; + this.startDrag(); + return this.stopDrag(); + }; + Sidebar.prototype.onClosed = function() { $(window).off("resize"); $(window).on("resize", this.resized); $(document.body).css("transition", "0.6s ease-in-out").removeClass("body-sidebar").on(transitionEnd, (function(_this) { return function(e) { - if (e.target === document.body) { - $(document.body).css("height", "auto").css("perspective", "").css("transition", "").off(transitionEnd); + if (e.target === document.body && !$(document.body).hasClass("body-sidebar") && !$(document.body).hasClass("body-internals")) { + $(document.body).css("height", "auto").css("perspective", "").css("will-change", "").css("transition", "").off(transitionEnd); return _this.unloadGlobe(); } }; @@ -874,7 +1046,7 @@ window.initScrollable = function () { }; Sidebar.prototype.loadGlobe = function() { - console.log("loadGlobe", this.tag.find(".globe").hasClass("loading")); + console.log("loadGlobe", this.tag.find(".globe")[0], this.tag.find(".globe").hasClass("loading")); if (this.tag.find(".globe").hasClass("loading")) { return setTimeout(((function(_this) { return function() { @@ -895,7 +1067,7 @@ window.initScrollable = function () { return img.onload = (function(_this) { return function() { return _this.wrapper.ws.cmd("sidebarGetPeers", [], function(globe_data) { - var e, ref, ref1; + var e, ref, ref1, ref2; if (_this.globe) { _this.globe.scene.remove(_this.globe.points); _this.globe.addData(globe_data, { @@ -904,6 +1076,7 @@ window.initScrollable = function () { animated: false }); _this.globe.createPoints(); + return (ref = _this.tag) != null ? ref.find(".globe").removeClass("loading") : void 0; } else if (typeof DAT !== "undefined") { try { _this.globe = new DAT.Globe(_this.tag.find(".globe")[0], { @@ -918,12 +1091,12 @@ window.initScrollable = function () { } catch (error) { e = error; console.log("WebGL error", e); - if ((ref = _this.tag) != null) { - ref.find(".globe").addClass("error").text("WebGL not supported"); + if ((ref1 = _this.tag) != null) { + ref1.find(".globe").addClass("error").text("WebGL not supported"); } } + return (ref2 = _this.tag) != null ? ref2.find(".globe").removeClass("loading") : void 0; } - return (ref1 = _this.tag) != null ? ref1.find(".globe").removeClass("loading") : void 0; }); }; })(this);