(function(window) { function startHLayout() { var md var grabEl var sectionResizeEl // Global mouse update document.addEventListener("mousemove", function(e) { if (md === undefined) md = {x: e.clientX, y: e.clientY} md.deltaX = e.clientX - md.x md.deltaY = e.clientY - md.y md.x = e.clientX md.y = e.clientY }) // Handle dragstart document.addEventListener("mousedown", function(e) { // Check for section resize if (e.target.matches("section")) { e.preventDefault() e.stopPropagation() sectionResizeEl = e.target sectionResizeEl.classList.add("resizing") return } // Check if element is our if (!e.target.matches(".hpane > header")) { return } e.preventDefault() e.stopPropagation() grabEl = e.target.parentElement var parent = grabEl.parentElement var elDim = grabEl.getBoundingClientRect() document.body.appendChild(grabEl) grabEl.classList.add("detached", "moving") grabEl.style.width = elDim.width + "px" grabEl.style.height = elDim.height + "px" // Add discover to other panes // $('.hpane:not(.detached)').addClass("discover"); // All childs to pointer event none if (parent.matches("section")) { var child = parent.querySelector(".hpane, section") // hpane or section child.removeAttribute("style") child.style["flex-basis"] = parent.style["flex-basis"] parent.parentElement.insertBefore(child, parent) parent.parentElement.removeChild(parent) } }) // Handle drag document.addEventListener("mousemove", function(e) { if (sectionResizeEl != null) { var firstEl = sectionResizeEl.children[0] var secondEl = sectionResizeEl.children[1] // Default vertical var tDim = "offsetWidth" var tDelta = "deltaX" if (sectionResizeEl.matches(".horizontal")) { tDim = "offsetHeight" tDelta = "deltaY" } var parentValue = sectionResizeEl[tDim] var firstNewDim = (firstEl[tDim] + md[tDelta]) / parentValue * 100 var secondNewDim = (secondEl[tDim] - md[tDelta]) / parentValue * 100 firstEl.style["flex-basis"] = firstNewDim + "%" secondEl.style["flex-basis"] = secondNewDim + "%" return } // console.log("Drag:",e) // if (!e.target.matches(".hpane > header")) { // we only deal with header // return // } if (grabEl === undefined) return // Get Absolute position somehow // var pos = $grab.position(); var elDim = grabEl.getBoundingClientRect() // var nx = elDim.left + md.deltaX // var ny = elDim.top + md.deltaY var offX = elDim.width / 2 var offY = 0 grabEl.style.left = e.clientX - offX + "px" grabEl.style.top = e.clientY - offY + "px" var targetEl = e.target // if(!targetEl.matches(".hpane")) { for (;targetEl !== null && !targetEl.matches(".hpane"); targetEl = targetEl.parentElement); // find Parent ".hpane" if (targetEl != null && targetEl.matches(".hpane:not(.preview)")) { // check attachment var placement = checkAttach(targetEl, e) if (placement !== 0) { previewPanel(grabEl, targetEl, placement) } else { removePreviews() } } else { removePreviews() } }) document.addEventListener("mouseup", function(e) { if (sectionResizeEl) { sectionResizeEl.classList.remove("resizing") sectionResizeEl = null return } // Drag if (grabEl === undefined) return removePreviews() grabEl.classList.remove("moving") var targetEl = e.target for (;targetEl !== null && !targetEl.matches(".hpane"); targetEl = targetEl.parentElement); // find Parent ".hpane" if (targetEl !== null) { var placement = checkAttach(targetEl, e) if (placement !== 0) { grabEl.classList.remove("detached") grabEl.removeAttribute("style") attachPanel(grabEl, targetEl, placement) } } grabEl = undefined }) } function attachPanel(grabEl, targetEl, placement) { if (!placement) { return } var type if ((placement % 2) === 1)type = "horizontal" // else if ((placement % 2) === 0)type = "vertical" var parentEl = targetEl.parentElement var sectionEl var sibEl = targetEl // it will be new sibling var newSectionEl = document.createElement("section") newSectionEl.classList.add(type) newSectionEl.style["flex-basis"] = targetEl.style["flex-basis"] if (sibEl.nextElementSibling !== null && sibEl.nextElementSibling.matches("section, .hpane")) { parentEl.insertBefore(newSectionEl, parentEl.children[0]) } else { parentEl.appendChild(newSectionEl) } // parentEl.removeChild(sibEl) grabEl.style["flex-basis"] = "33%" sibEl.style["flex-basis"] = "66%" if (placement < 3) { newSectionEl.appendChild(grabEl) newSectionEl.appendChild(sibEl) // will this work? // $section.append(what); // $section.append("
"); // $section.append($sib); } else { newSectionEl.appendChild(sibEl) newSectionEl.appendChild(grabEl) // will this work? // $section.append($sib); // $section.append("
"); // $section.append(what); } } function removePreviews() { var previewEls = document.querySelectorAll(".attach-preview") if (previewEls === null) { // not sure if it is needed return } for (var i = previewEls.length; i--; i >= 0) { previewEls[i].style.display = "none" } } function checkAttach(targetEl, e) { var targetDim = targetEl.getBoundingClientRect() var tW = targetDim.width / 3 var tH = targetDim.height / 3 var rPos = {x: e.pageX - targetDim.left, y: e.pageY - targetDim.top} // Calc dists and check the closest one // Counter clock wise 1 TOP 2 RIGHT 3 BOTTOM 4 LEFT if (rPos.x > tW && rPos.x < targetDim.width - tW && rPos.y < tH) { // 1 Top return 1 } else if (rPos.x > tW && rPos.x < targetDim.width - tW && rPos.y > targetDim.height - tH) { // 3 Bottom return 3 } else if (rPos.x < tW) { // 2 Left return 2 } else if (rPos.x > targetDim.width - tW) { // 4 Right return 4 } return 0 } function previewPanel(grabEl, targetEl, placement) { var previewEl = document.querySelector(".attach-preview") if (previewEl === undefined || previewEl === null) { previewEl = document.createElement("div") previewEl.setAttribute("class", "attach-preview") previewEl.setAttribute("style", "display:none;position:fixed") document.body.appendChild(previewEl) } previewEl.style.display = "block" // Show element var targetDim = targetEl.getBoundingClientRect() if ((placement % 2) === 1) { // Odd is top or bottom previewEl.style.height = (targetDim.height / 3) + "px" previewEl.style.width = targetDim.width + "px" previewEl.style.left = targetDim.left + "px" if (placement === 1) { previewEl.style.top = targetDim.top + "px" } else { previewEl.style.top = (targetDim.top + targetDim.height - (targetDim.height / 3)) + "px" } } else if ((placement % 2) === 0) { previewEl.style.height = targetDim.height + "px" previewEl.style.width = (targetDim.width / 3) + "px" previewEl.style.top = targetDim.top + "px" if (placement === 2) { previewEl.style.left = targetDim.left + "px" } else { previewEl.style.left = (targetDim.left + targetDim.width - (targetDim.width / 3)) + "px" } } } window.onload = startHLayout })(window) /* var md function startHLayoutEvents() { document.addEventListener("mousemove", function(e) { if (md === undefined) md = {x: e.clientX, y: e.clientY} md.deltaX = e.clientX - md.x md.deltaY = e.clientY - md.y md.x = e.clientX md.y = e.clientY }) // Global mouse event; var $grab = undefined; // Start drag $(document).on('mousedown','.hpane > header',function(e){ if(e.which != 1) return; if(!$(e.target).is(".hpane > header")) return; e.preventDefault(); e.stopPropagation(); $grab = $(this).parent(); $parent = $grab.parent(); var next = $grab.next(); var origW = $grab.width(); var origH = $grab.height(); // Check if we are root? var dim = {w: $grab.width(), h: $grab.height()}; var pos = $grab.position(); $($grab).detach().appendTo('body').addClass("detached").addClass("moving").css({width:dim.w,height:dim.h}); $('.hpane:not(.detached)').addClass("discover"); // All childs to pointer event none if($parent.is('section')) { // We aren't $child = $parent.children('.hpane, section'); $child.attr('style',''); $child.css('flex-basis',$parent.css('flex-basis')); $child.detach(); $parent.replaceWith($child); } }) var $sectionResize = null; $(document).on('mousedown','section',function(e) { var $target = $(e.target); if(!$target.is("section"))return; e.preventDefault(); $sectionResize = $target; $sectionResize.addClass("resizing"); }); $(document).on('mousemove',function(e) { if($sectionResize == null) return; var $first = $sectionResize.children(':nth-child(1)'); var $second = $sectionResize.children(':nth-child(2)'); var common; var common2; if( $sectionResize.is(".horizontal")) {common = "height",common2 = "deltaY"}; if( $sectionResize.is(".vertical")) {common = "width", common2 = "deltaX"}; var parentValue = $sectionResize[common](); var hFirst = $first[common](); var hSec = $second[common](); var newVal1 = (hFirst + md[common2]) / parentValue * 100; var newVal2 = (hSec -md[common2]) / parentValue * 100; $first.css('flex-basis',newVal1 + "%"); $second.css('flex-basis',newVal2 + "%"); }); $(document).on('mouseup',function(e) { if($sectionResize) { $sectionResize.removeClass("resizing"); } $sectionResize = null; }); $(document).on('mousemove',function(e) { if($grab == undefined) return; var pos = $grab.position(); var nx = pos.left + md.deltaX; var ny = pos.top + md.deltaY; var offX = $grab.width() / 2; var offY = 0; $grab.css({left: e.clientX - offX, top: e.clientY -offY}); // Check target var $target = $(e.target); if(!$target.is(".hpane")) { $target = $target.parents(".hpane"); } if($target.is(".hpane:not(.preview)")){ var placement = checkAttach($target,e); if(placement != 0 ) { previewPanel($grab,$target,placement); } else { removePreviews(); } } else { removePreviews(); } }); $(document).on('mouseup',function(e) { if($grab == undefined) return; removePreviews(); $grab.removeClass("moving"); $('.hpane').removeClass("discover"); $target = $(e.target); if(!$target.is(".hpane")) $target = $target.parents('.hpane'); if($target.is(".hpane")){ var placement = checkAttach($target,e); if(placement != 0 ) { $grab.removeClass("detached"); $grab.attr('style',''); attachPanel($grab,$target,placement); } } $grab = undefined; return; }); } function recalcFlex() { $('section.horizontal > section, section.horizontal > .hpane').each(function() { var parentH = $(this).parent().height(); var curH = $(this).height(); var flex = 100 * curH / parentH; $(this).css({'flex-basis':flex + "%"}); }); $('section.vertical > section, section.vertical > .hpane').each(function() { var parentW = $(this).parent().width(); var curW = $(this).width(); var flex = 100 * curW / parentW; $(this).css({'flex-basis':flex + "%"}); }); } recalcFlex(); function checkAttach($target,e) { var tW = $target.width()/3; var tH = $target.height()/3; var targetPos = $target.offset(); var dim = { w: $target.width(), h: $target.height()}; var rPos = { x: e.pageX - targetPos.left, y: e.pageY - targetPos.top}; //Calc dists and check the closest one if(rPos.x > tW && rPos.x < dim.w - tW && rPos.y < tH) { // 1 Top return 1; } else if(rPos.x > tW && rPos.x < dim.w - tW && rPos.y > dim.h - tH){ // 3 Bottom return 3; } else if(rPos.x < tW) { // 2 Left return 2; } else if( rPos.x > dim.w - tW){ // 4 Right return 4; } return 0; } function removePreviews() { $('.attach-preview').hide(); } function previewPanel($grab,$target,attach) { $previewDiv = $(".attach-preview"); if($previewDiv.length == 0 ) { $previewDiv = $('').appendTo('body'); } $previewDiv.show(); var dim = {w:$target.width(),h:$target.height()}; var pos = $target.offset(); if((attach % 2) == 1) { $previewDiv.css('height',dim.h/3); $previewDiv.css("width",dim.w); $previewDiv.css("left",pos.left); if(attach == 1) { $previewDiv.css('top',pos.top); } else { $previewDiv.css('top',pos.top + dim.h - dim.h/3); } } else if((attach % 2) == 0) { $previewDiv.css("height",dim.h); $previewDiv.css('width',dim.w/3); $previewDiv.css("top",pos.top); if(attach == 2) { $previewDiv.css('left',pos.left); } else { $previewDiv.css('left',pos.left + dim.w - dim.w/3); } } } function attachPanel(what,target, attach) { if(attach){ var type if((attach % 2) == 1)type = "horizontal"; if((attach % 2) == 0)type = "vertical"; $target = $(target); $parent = $(target).parent(); $sib = $(target); if($sib.next().is("section, .hpane,.splitter")) { $section = $("
").prependTo($parent); } else { $section = $("
").appendTo($parent); } $sib.detach(); what.css('flex-basis','33%'); $sib.css('flex-basis','66%'); if(attach < 3) { $section.append(what); //$section.append("
"); $section.append($sib); } else { $section.append($sib); //$section.append("
"); $section.append(what); } } } $(function() { startHLayoutEvents(); });*/