For a while now, I have been trying to create dynamic-resizable-split-panes in javascript (something like vs code). I successfully created the dynamic split panes. It creates the split panes by checking the parent element and its children and decides whether to create a split pane vertically or horizontally. What I mean is, if the parent already has vertically split panes and the new pane that has to be created is also vertical, it simply created the structure and appends it in the parent. Otherwise, it will wrap the active pane with a new parent and split the pane horizontally. (Same goes for the other way around). The problem I am facing is, how can I make them resizable like vs code. What I want is, on mouse drag the panes should be resized.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dynamic Split Panes</title>
<script src="jquery.js"></script>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div id="container">
<div class="ep">
<div class="ec" id="ec"></div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
CSS:
html,
body{
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#container{
display: flex;
width: 100%;
height: 100%;
background-color: black;
}
.ep{
display: flex;
flex: 1;
}
.ec{
flex: auto;
background-color: white;
}
.gutter-ver{
height: 10px;
width: 100%;
background-color: red;
}
.gutter-hor{
height: 100%;
width: 10px;
background-color: red;
}
.ui-resizable-ghost {
border: 1px dotted gray;
background-color: rgba(128, 128, 128, 0.544);
}
JavaScript:
var ec_active = document.querySelector(".ec");
var ec = null;
function createEC(dir){
if(dir == "ver"){
if(ec_active.parentElement.style.flexDirection == "row"){
// `element` is the element you want to wrap
var parent = ec_active.parentNode;
var wrapper = document.createElement('div');
wrapper.classList.add("ep");
wrapper.style.flexDirection = "column";
// set the wrapper as child (instead of the element)
parent.replaceChild(wrapper, ec_active);
// set element as child of wrapper
wrapper.appendChild(ec_active);
ec = document.createElement("div");
ec.classList.add("ec");
var gv = document.createElement("div");
gv.classList.add("gutter-ver");
ec_active.parentElement.appendChild(gv);
ec_active.parentElement.appendChild(ec);
}else if(ec_active.parentElement.style.flexDirection == "column"){
ec = document.createElement("div");
ec.classList.add("ec");
var gv = document.createElement("div");
gv.classList.add("gutter-ver");
ec_active.parentElement.appendChild(gv);
ec_active.parentElement.appendChild(ec);
}else{
ec = document.createElement("div");
ec.classList.add("ec");
var gv = document.createElement("div");
gv.classList.add("gutter-ver");
ec_active.parentElement.style.flexDirection = "column";
ec_active.parentElement.appendChild(gv);
ec_active.parentElement.appendChild(ec);
}
}else{
if(ec_active.parentElement.style.flexDirection == "column"){
// `element` is the element you want to wrap
var parent = ec_active.parentNode;
var wrapper = document.createElement('div');
wrapper.classList.add("ep");
wrapper.style.flexDirection = "row";
// set the wrapper as child (instead of the element)
parent.replaceChild(wrapper, ec_active);
// set element as child of wrapper
wrapper.appendChild(ec_active);
ec = document.createElement("div");
ec.classList.add("ec");
var gv = document.createElement("div");
gv.classList.add("gutter-hor");
ec_active.parentElement.appendChild(gv);
ec_active.parentElement.appendChild(ec);
}else if(ec_active.parentElement.style.flexDirection == "row"){
ec = document.createElement("div");
ec.classList.add("ec");
var gv = document.createElement("div");
gv.classList.add("gutter-hor");
ec_active.parentElement.appendChild(gv);
ec_active.parentElement.appendChild(ec);
// resizeEC(ec_active, ec);
}else{
ec = document.createElement("div");
ec.classList.add("ec");
var gv = document.createElement("div");
gv.classList.add("gutter-hor");
ec_active.parentElement.style.flexDirection = "row";
ec_active.parentElement.appendChild(gv);
ec_active.parentElement.appendChild(ec);
// resizeEC(ec_active, ec);
}
}
}
document.addEventListener("click", (e)=>{
ec_active = e.target;
});
function refreshGutters(){
var gutters_hor = document.querySelectorAll(".gutter-hor");
gutters_hor.forEach((gutter_hor)=>{
gutter_hor.onmousedown = (e)=>{
var elm_prev_gutter = gutter_hor.previousElementSibling;
var elm_next_gutter = gutter_hor.nextElementSibling;
var elm_prev_gutter_width = $(elm_prev_gutter).width();
var elm_next_gutter_width = $(elm_next_gutter).width();
init_pos = gutter_hor.getBoundingClientRect().x;
init_mouse_pos = e.clientX;
gutter_hor.onmousemove = (e)=>{
if(e.clientX > init_mouse_pos){
gutter_hor.style.left = e.clientX;
}
};
};
});
}
I tried using the split.js library and also jquery-ui but wasn't able to achieve the desired result.