Angular Inventory System - Drag and Drop Resizable Grid
by dekkard
HTML
<div ng-app="AngularInventory">
<div ng-controller="Controller">
<ng-inventory source="items" id="personal-inventory">
</ng-inventory>
</div>
</div>
<!--
<div class="inventory-table" id="personal-inventory">
<div class="inventory-row">
<div class="inventory-cell">
<div class="inventory-item grape"></div>
</div>
<div class="inventory-cell">
<div class="inventory-item sword1" data-item-type="weapon sword"></div>
</div>
<div class="inventory-cell">
<div class="inventory-item carrot"></div>
</div>
<div class="inventory-cell">
</div>
<div class="inventory-cell">
</div>
</div>
<div class="inventory-row">
<div class="inventory-cell">
<div class="inventory-item carrot" data-item-type="food"></div>
</div>
<div class="inventory-cell">
<div class="inventory-item meat1" data-item-type="food cookable"></div>
</div>
<div class="inventory-cell">
<div class="inventory-item meat1" data-item-type="food cookable"></div>
</div>
<div class="inventory-cell"></div>
<div class="inventory-cell"></div>
</div>
<div class="inventory-row">
<div class="inventory-cell">
<div class="inventory-item axe1" data-item-type="weapon axe"></div>
</div>
<div class="inventory-cell">
</div>
<div class="inventory-cell">
<div class="inventory-item grape" data-item-type="food"></div>
</div>
<div class="inventory-cell"></div>
<div class="inventory-cell"></div>
</div>
</div>
<br />
Chest:
<div class="inventory-table">
<div class="inventory-row">
<div class="inventory-cell">
<div class="inventory-item grape" data-item-type="food"></div>
</div>
<div class="inventory-cell">
<div class="inventory-item sword1"...
CSS
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body
{
background: #332f2c;
color: #dddddd;
font-family: Arial;
}
/* Item atlas: http://i.imgur.com/ngGK5MF.png
* Table atlas: http://i.imgur.com/nOqKSbE.png
*/
a, a:link, a:visited {
color: #c00;
text-decoration: none;
-webkit-transition: all 0.3s ease;
transition: all 0.3s ease;
}
a:hover {
color: #ff5c19;
text-decoration: underline;
}
a:active {
color: #6aff19;
}
input[type="range"]
{
width: 400px;
}
.inventory-table
{
}
.inventory-row
{
display: flex;
flex-direction: row;
justify-content: flex-start; /* align items in Main Axis */
align-items: flex-start; /* align items in Cross Axis */
align-content: flex-start; /* Extra space in Cross Axis */
}
.inventory-cell
{
width: 36px;
height: 36px;
flex-shrink: 0;
display: flex;
flex-direction: row;
justify-content: center; /* align items in Main Axis */
align-items: center; /* align items in Cross Axis */
align-content: center; /* Extra space in Cross Axis */
background-image: url('http://i.imgur.com/nOqKSbE.png');
background-position: -229px -331px;
}
/* left */
.inventory-cell:first-child
{
width: 38px;
padding-left: 2px;
background-position: -190px -331px;
}
/* right */
.inventory-cell:last-child
{
width: 38px;
padding-right: 2px;
background-position: -266px -331px;
}
/* top ROW */
.inventory-row:first-child .inventory-cell
{
height: 38px;
padding-top: 2px;
background-position: -229px -292px;
}
/* bottom ROW */
.inventory-row:last-child .inventory-cell
{
height: 38px;
padding-bottom: 2px;
background-position: -229px -368px;
}
/* top left */
.inventory-row:first-child .inventory-cell:first-child
{
width: 38px;
height: 38px;
background-position: -190px -292px;
}
/* top right */
.inventory-row:first-child...
JavaScript
var app = angular.module("AngularInventory", [])
.controller('Controller', function Controller($scope) {
// 4x2 table
$scope.items = [
// row 1
[
{ name: "grape" },
{ name: "sword1", type: "weapon sword" },
{ name: "carrot" },
{}
],
// row 2
[
{ name: "meat1", type: "food cookable" },
{},
{ name: "axe1", type: "weapon axe" },
{ name: "meat1", type: "food cookable" }
]
];
$scope.tableLength = $scope.tableHeight = 0;
var tableDimensions = (function scopeGetDimensions() {
var tableLength = 0;
var tableHeight = $scope.items.length;
for (var i = 0; i < tableHeight; ++i ) {
var rowLength = $scope.items[i].length;
if ( tableLength < rowLength ) {
tableLength = rowLength;
}
}
return { length: tableLength, height: tableHeight };
})();
$scope.tableLength = tableDimensions.length;
$scope.tableHeight = tableDimensions.height;
})
.directive('ng-inventory', function directiveNgInventory(){
return {
restrict: 'E',
replace: true,
scope: {
rows: '=source',
id: '@'
},
template:
'<div class="inventory-table" id="{{id}}">' +
'<div class="inventory-row" ng-repeat="row in items">' +
'<div class="inventory-cell" ng-repeat="column in row">' +
'<div class="inventory-item {{column.name}}" ' +
'{{ column.type && "data-item-type=\"" + column.type + "\"" }}' +
'></div>' +
'</div>' +
'</div>' +
'</div>'
}
})
;
/*
"use...