Skip to content

Instantly share code, notes, and snippets.

@flymio
Last active February 8, 2019 18:07
Show Gist options
  • Save flymio/d90a6906ea69886df421bc595507eda1 to your computer and use it in GitHub Desktop.
Save flymio/d90a6906ea69886df421bc595507eda1 to your computer and use it in GitHub Desktop.
<body>
<style>
body, html {
background: white;
}
.resizable {
background: transparent;
position: absolute;
}
.resizable .resizers{
width: 100%;
height: 100%;
border: 1px dotted #4286f4;
box-sizing: border-box;
}
.resizable .resizers .resizer{
width: 10px;
height: 10px;
background: #000;
border: 1px solid #000;
position: absolute;
}
.resizable .resizers .resizer.top-left {
left: -5px;
top: -5px;
cursor: nwse-resize;
}
.resizable .resizers .resizer.top-right {
right: -5px;
top: -5px;
cursor: nesw-resize;
}
.resizable .resizers .resizer.bottom-left {
left: -5px;
bottom: -5px;
cursor: nesw-resize;
}
.resizable .resizers .resizer.bottom-right {
right: -5px;
bottom: -5px;
cursor: nwse-resize;
}
.resizeArea {
border:2px dotted black;
width:0px;
height:0px;
position:absolute;
display: none;
}
.g-hidden {display:none;}
</style>
<script type="text/x-tmpl" id="resizeTemplate">
<div class='resizable' data-target="%id%" id="r%id%">
<div class='resizers'>
<div class='resizer top-left'></div>
<div class='resizer top-right'></div>
<div class='resizer bottom-left'></div>
<div class='resizer bottom-right'></div>
</div>
</div>
</script>
<div class="resizeArea"></div>
<div class="buttons"></div>
<script>
var grid = document.querySelector(".resizeArea");
var tmpl = document.getElementById("resizeTemplate").innerHTML;
let original_mouse_x = 0;
let original_mouse_y = 0;
let buttons_selected = false;
let resizes = {};
function magick(){
let buttonsCount = Math.random()*5;
let buttons = document.querySelector(".buttons");
for(let i=0;i<buttonsCount;i++){
let div = document.createElement("button");
div.id = "button_"+i;
div.style.position = "absolute";
var w = Math.random()*50+50;
var h = Math.random()*50+50;
var l = Math.random()*500+50;
var t = Math.random()*300+50;
div.style.width = w+"px";
div.style.height = h+"px";
div.style.left = l+"px";
div.style.top = t+"px";
div.innerHTML = "hello";
buttons.append(div);
}
document.addEventListener("keydown", function(e){
if (buttons_selected && (e.which == 27 || e.code == 'Escape')){
const resizers = document.querySelectorAll('.resizer');
for (let i = 0;i < resizers.length; i++) {
resizers[i].style.display = "none";
}
buttons_selected = false;
}
});
document.addEventListener('mousedown', function(e) {
console.log(e);
if (e.shiftKey){
original_mouse_x = e.pageX;
original_mouse_y = e.pageY;
grid.style.left = original_mouse_x+"px";
grid.style.top = original_mouse_y+"px";
grid.style.display = "block";
window.addEventListener('mousemove', GridMove)
window.addEventListener('mouseup', GridMoveStop)
}
});
}
function GridMove(e){
//console.log(e.pageX, e.pageY);
e.preventDefault();
const width = e.pageX - original_mouse_x;
const height = e.pageY - original_mouse_y;
if (width < 0){
grid.style.left = e.pageX + "px";
grid.style.width = (original_mouse_x - e.pageX) + "px";
}
else{
grid.style.width = width + "px"
}
if (height < 0){
grid.style.top = e.pageY + "px";
grid.style.height = (original_mouse_y - e.pageY) + "px";
}
else{
grid.style.height = height + "px";
}
}
function GridMoveStop(e){
window.removeEventListener('mousemove', GridMove);
window.removeEventListener('mouseup', GridMoveStop);
let x, y, w, h, el;
var buttons = document.getElementsByTagName('button');
var rect = getRect(grid);
for (let i = 0;i < buttons.length; i++) {
el = getRect(buttons[i]);
if (rect.left <= el.left && rect.top <= el.top && rect.bottom >= el.bottom && rect.right >= el.right){
var id = buttons[i].id;
console.log(id);
if (!resizes[id]){
var html = tmpl.replace(/%id%/g, id);
buttons[i].insertAdjacentHTML('afterend', html);
resizes[id] = cloneCoords("r"+id, el);
makeMagick("#r"+id, "#"+id);
}
else{
makeMagick("#r"+id, "#"+id);
}
}
}
grid.style.display = "none";
buttons_selected = true;
}
function cloneCoords(id, coords){
var el = document.getElementById(id);
el.style.left = coords.left + "px";
el.style.top = coords.top + "px";
el.style.width = coords.width + "px";
el.style.height = coords.height + "px";
return el;
}
function makeMagick(div, parent) {
var element = document.querySelector(div);
var element2 = document.querySelector(parent);
console.log(div, parent, element, element2);
var resizers = document.querySelectorAll(div + ' .resizer')
console.log(resizers);
var minimum_size = 20;
let original_width = 0;
let original_height = 0;
let original_x = 0;
let original_y = 0;
let original_mouse_x = 0;
let original_mouse_y = 0;
for (let i = 0;i < resizers.length; i++) {
const currentResizer = resizers[i];
currentResizer.style.display="block";
currentResizer.addEventListener('mousedown', function(e) {
e.preventDefault()
original_width = parseFloat(getComputedStyle(element, null).getPropertyValue('width').replace('px', ''));
original_height = parseFloat(getComputedStyle(element, null).getPropertyValue('height').replace('px', ''));
original_x = element.getBoundingClientRect().left;
original_y = element.getBoundingClientRect().top;
original_mouse_x = e.pageX;
original_mouse_y = e.pageY;
window.addEventListener('mousemove', resize)
window.addEventListener('mouseup', stopResize)
})
function resize(e) {
if (currentResizer.classList.contains('bottom-right')) {
const width = original_width + (e.pageX - original_mouse_x);
const height = original_height + (e.pageY - original_mouse_y)
if (width > minimum_size) {
element.style.width = width + 'px'
element2.style.width = width + 'px'
}
if (height > minimum_size) {
element.style.height = height + 'px'
element2.style.height = height + 'px'
}
}
else if (currentResizer.classList.contains('bottom-left')) {
const height = original_height + (e.pageY - original_mouse_y)
const width = original_width - (e.pageX - original_mouse_x)
if (height > minimum_size) {
element.style.height = height + 'px';
element2.style.height = height + 'px';
}
if (width > minimum_size) {
element.style.width = width + 'px';
element2.style.width = width + 'px';
element.style.left = original_x + (e.pageX - original_mouse_x) + 'px';
element2.style.left = original_x + (e.pageX - original_mouse_x) + 'px';
}
}
else if (currentResizer.classList.contains('top-right')) {
const width = original_width + (e.pageX - original_mouse_x)
const height = original_height - (e.pageY - original_mouse_y)
if (width > minimum_size) {
element.style.width = width + 'px';
element2.style.width = width + 'px';
}
if (height > minimum_size) {
element.style.height = height + 'px';
element2.style.height = height + 'px';
element.style.top = original_y + (e.pageY - original_mouse_y) + 'px';
element2.style.top = original_y + (e.pageY - original_mouse_y) + 'px';
}
}
else {
const width = original_width - (e.pageX - original_mouse_x)
const height = original_height - (e.pageY - original_mouse_y)
if (width > minimum_size) {
element.style.width = width + 'px';
element2.style.width = width + 'px'
element.style.left = original_x + (e.pageX - original_mouse_x) + 'px';
element2.style.left = original_x + (e.pageX - original_mouse_x) + 'px';
}
if (height > minimum_size) {
element.style.height = height + 'px';
element2.style.height = height + 'px';
element.style.top = original_y + (e.pageY - original_mouse_y) + 'px';
element2.style.top = original_y + (e.pageY - original_mouse_y) + 'px'
}
}
}
function stopResize() {
window.removeEventListener('mousemove', resize)
}
}
}
function getRect(element){
let obj = {};
obj.width = parseFloat(getComputedStyle(element, null).getPropertyValue('width').replace('px', ''));
obj.height = parseFloat(getComputedStyle(element, null).getPropertyValue('height').replace('px', ''));
obj.left = parseFloat(element.getBoundingClientRect().left);
obj.top = parseFloat(element.getBoundingClientRect().top);
obj.bottom = obj.top + obj.height;
obj.right = obj.left + obj.width;
return obj;
}
magick();
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment