knockout/Layout

Knockout Layout

by MKGaru

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>
<script src="https://mbest.github.io/knockout.punches/knockout.punches.js"></script>
<script src="https://rawgit.com/SteveSanderson/knockout-es5/master/dist/knockout-es5.js"></script>
<div class="gridder">
    <div class="gridder-item" x="2" y="0" width="1" height="1">
		<div class="gridder-item-content">運転席</div>
    </div>
    <div class="gridder-item"  x="0" y="0" width="1" height="1">
		<div class="gridder-item-content">添乗員</div>
    </div>
    <div class="gridder-item" x="0" y="1" width="1" height="2">
		<div class="gridder-item-content">ベッド</div>
    </div>
    <div class="gridder-item" x="1" y="1" width="1" height="1">
		<div class="gridder-item-content">B</div>
    </div>
    <div class="gridder-item" x="2" y="1" width="1" height="1">
		<div class="gridder-item-content">C</div>
    </div>
    <div class="gridder-item" x="1" y="2" width="2" height="1">
		<div class="gridder-item-content">車いす</div>
    </div>
</div>

CSS

body{
    width: calc(100px * 12);
    overflow:hidden;
}
.gridder{
	position:relative;
}
.gridder-item{
	position:absolute;
	transition: all 500ms ease;
}
.gridder-item.over{
	border: 1px dashed #000;
}
.gridder-item[draggable]{
	user-select: none;
  /* Required to make elements draggable in old WebKit */
  -khtml-user-drag: element;
  -webkit-user-drag: element;
  cursor:pointer;
}
.gridder-item.drag{
	opacity: 0.7;
}

.gridder-item-content {
    background: white;
    color: #2c3e50;
    font-family: 'Indie Flower', cursive;
    text-align: center;
    font-size: 20px;
	height:100%;
	width:100%;
}

.gridder-item-content .fa {
    font-size: 64px;
    display: block;
    margin: 20px 0 10px;
}

body{
  background:#cecece;
}

TypeScript

namespace gridder{
	var defaultOptions = {
		prefix: '', //data-gs-
		columns: 3,
		rows: 4,
		margin: 5,
		width: 50,
		height: 50
	};
	export class Gridder{
		private observer: MutationObserver;
		private latestDragInfo={
			element:null,
			offsetX:0,
			offsetY:0
		};
		public options;
		constructor(element,options={}){
			var gridder = this;
			gridder.options = options;
			Object.keys(defaultOptions).forEach((key)=>{
				if(options[key] === void 0) options[key] = defaultOptions[key];
			});
			
			if(typeof element =='string')
				element = document.querySelector(element);
			if(element.jquery)
				element = element[0];
			
			gridder.onInitGrid(element);
        }
		public getCollisions(x,y,w,h,excludes=[]){
			var gridder = this;
			var options = gridder.options;
			var collisions =[];
			var blocks = [];
			for(var c=0;c<w;c++)
				for(var r=0;r<h;r++)
					blocks.push([x+c,y+r]);
			
			blocks.forEach(block=>{
				document.elementsFromPoint(
					options.margin * (block[0]) + block[0] * (options.width + options.margin)+options.width/2,
					options.margin * (block[1]) + block[1] * (options.height + options.margin)+options.height/2
				)
				.filter((collision)=>collision.classList.contains('gridder-item'))
				.filter((collision)=>excludes.indexOf(collision)==-1)
				.forEach((collision)=>collisions.push(collision))
			});
			
			return collisions;
		}
		public isEmpty(column,row){
			var gridder = this;
		}
		public onInitGrid(element){
			var gridder = this;
			var options = gridder.options;
			element.style.width = `${(options.width+options.margin*2)*options.columns}px`;
			element.style.height =  `${(options.height+options.margin*2)*options.rows}px`;
			
			element.addEventListener('dragover',function(event){
				event.preventDefault();
				var x = event.pageX - gridder.latestDragInfo.offsetX;
				var y = event.pageY - gridder.latestDragInfo.offsetY;
				var w = gridder.latestDragInfo.element.getAttribute(options.prefix+'width');
				var h =...