Floorplan configurator
(c) PvH
by PhilQ
HTML
<div id="blockmodules">
<ul id="blockmodule_categories">
</ul>
</div>
<div id="plan">
<div id="plan_head">
<div class="plan_head"></div>
</div>
<div id="plan_blocks">
<div class="plan_block badkamer1"></div>
<div class="plan_block eetkamer2"></div>
<div class="plan_block badkamer3"></div>
</div>
<div id="plan_tail">
<div class="plan_tail"></div>
</div>
</div>
<div id="drag_module"></div>
SCSS
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #eee;
font-family: sans-serif;
}
.hide {
display: none !important;
}
#plan {
position: fixed;
z-index: 1;
left: 0px;
right: 0px;
top: 35vh;
height: 30vh;
background: #fff;
display: inline-flex;
justify-content: center;
#plan_head {
display: inline-flex;
}
.plan_head {
width: 3vh;
background: #ccc;
}
#plan_blocks {
display: inline-flex;
}
.plan_block {
width: 20vh; // or wider
}
#plan_tail {
display: inline-flex;
}
.plan_tail {
width: 3vh;
background: #ccc;
}
.plan_head, .plan_block, .plan_tail {
height: 100%;
position: relative;
&::before {
content: '';
display: none;
position: absolute;
top: 0px;
height: 100%;
width: 40px; // Same as drag_inbetween_size
background: rgba(255,255,0, 0.3);
}
&.overwrite::before {
width: 100%;
left: 0px;
display: inline-block;
z-index: 1;
}
&.insertleft::before {
left: 0px;
transform: translate(-50%, 0);
display: inline-block;
z-index: 1;
}
&.insertright::before {
right: 0px;
transform: translate(50%, 0);
display: inline-block;
z-index: 1;
}
}
}
#drag_module {
position: fixed;
z-index: 10;
top: 0px;
left: 0px;
width: 15vh;
height: 15vh;
transform: translate(-50%, -50%);
pointer-events: none;
background: yellow; //TODO: remove
display: none;
&.show {
display: inline-block;
}
}
#blockmodules {
position: fixed;
z-index: 2;
bottom: 0px;
left: 0px;
right: 0px;
height: 15vh;
}
#blockmodule_categories {
display: flex;
justify-content: center;
list-style: none;
> li {
display: inline-flex;
width: 15vh;
height: 15vh;
text-align: center;
align-items: center;
border: 1px solid #ccc;
> h3 {
text-align: center;
}
> ul {
position: absolute;
bottom: 100%;
width: 100vw;
left: 0vw;
list-style: none;
display: none;
justify-content:...
JavaScript
var config = {
head: 0,
tail: 0,
blocks: [ null, null, null ],
};
var blockmodules = {
heads: [
{ name: 'Standaard', id: 'kop1' },
],
tails: [
{ name: 'Standaard', id: 'staart1' },
],
categories: [],
};
blockmodules.categories['badkamers'] = {
name: 'Badkamers',
items: [
{ name: 'Badkamer 1', id: 'badkamer1' },
{ name: 'Badkamer 2', id: 'badkamer2' },
{ name: 'Badkamer 3', id: 'badkamer3' },
],
};
blockmodules.categories['eetkamers'] = {
name: 'Eetkamers',
items: [
{ name: 'Eetkamer 1', id: 'eetkamer1' },
{ name: 'Eetkamer 2', id: 'eetkamer2' },
{ name: 'Eetkamer 3', id: 'eetkamer3' },
],
};
var is_module_dragging = false,
drag_target_class = '',
$drag_module = null,
$drag_target = null,
drag_target_bbox = { left: 0, top: 0, right: 0, bottom: 0 },
drag_inbetween_size = 20,
mouse_x = 0,
mouse_y = 0,
resize_timer = null;
$( document ).ready(function() {
var $blockmodule_categories = $('#blockmodule_categories');
$drag_module = $('#drag_module');
for (var k in blockmodules.categories) {
var v = blockmodules.categories[ k ];
var $oLi = $('<li />');
var $iUl = $('<ul />');
v.items.forEach(function(vv, ii, aa) {
var $iLi = $('<li />');
$iLi
.append('<b>' + vv.name + '</b>')
.append('<div id="' + vv.id + '"></div>')
.data('targetclass', 'block')
.data('moduleclass', vv.id )
.appendTo( $iUl )
.on('mousedown touchstart', function( ev ) {
ev.preventDefault();
var $this = $( this );
mouse_x = ev.pageX;
mouse_y = ev.pageY;
drag_target_class = 'plan_' + $this.data('targetclass');
//TODO: clone element + set initial mouse coords
$( window )
.on('mouseup.moduledrag touchend.moduledrag', function( ev2 ) {
$( window ).off('.moduledrag');
if ( ! is_module_dragging ) {
console.log('Clicked:', $this);
} else {
ev2.preventDefault();
ev2.stopImmediatePropagation();
is_module_dragging =...