mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 13:24:24 +00:00
improve seatplan editor significantly
This commit is contained in:
@@ -11,8 +11,8 @@
|
|||||||
</title>
|
</title>
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200">
|
||||||
<script defer src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
<script defer src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
||||||
<link rel="stylesheet" href="coloris.min.css">
|
<link rel="stylesheet" href="/coloris.min.css">
|
||||||
<script defer src="coloris.min.js"></script>
|
<script defer src="/coloris.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -14,36 +14,53 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>Position X:</td>
|
<td>Position X:</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" min="20" v-model="internal[ active ].x" @focusout="resubmit()">
|
<input type="number" min="20" v-model="internal[ active ].x" @change="resubmit()">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Position Y:</td>
|
<td>Position Y:</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" min="20" v-model="internal[ active ].y" @focusout="resubmit()">
|
<input type="number" min="20" v-model="internal[ active ].y" @change="resubmit()">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Width:</td>
|
<td>Width:</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" min="20" v-model="internal[ active ].w" @focusout="resubmit()">
|
<input type="number" min="20" v-model="internal[ active ].w" @change="resubmit()">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Height:</td>
|
<td>Height:</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" min="20" v-model="internal[ active ].h" @focusout="resubmit()">
|
<input type="number" min="20" v-model="internal[ active ].h" @change="resubmit()">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Starting row:</td>
|
||||||
|
<td>
|
||||||
|
<input type="number" min="1" max="20" v-model="internal[ active ].startingRow" @change="resubmit()">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Origin:</td>
|
<td>Origin:</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" min="1" max="4" v-model="internal[ active ].origin" @focusout="resubmit()">
|
<input type="number" min="1" max="4" v-model="internal[ active ].origin" @change="resubmit()">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Type:</td>
|
||||||
|
<td>
|
||||||
|
<select min="20" v-model="internal[ active ].type" @change="resubmit()">
|
||||||
|
<option value="seat">Seat</option>
|
||||||
|
<option value="stand">Stand</option>
|
||||||
|
<option value="stage">Stage</option>
|
||||||
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Shape:</td>
|
<td>Shape:</td>
|
||||||
<td><select min="20" v-model="internal[ active ].shape" @change="resubmit()">
|
<td>
|
||||||
|
<select min="20" v-model="internal[ active ].shape" @change="resubmit()">
|
||||||
<option value="rectangular">Rectangular</option>
|
<option value="rectangular">Rectangular</option>
|
||||||
<option value="trapezoid">Trapezoid</option>
|
<option value="trapezoid">Trapezoid</option>
|
||||||
<option value="circular">Circular</option>
|
<option value="circular">Circular</option>
|
||||||
|
|||||||
@@ -13,11 +13,11 @@
|
|||||||
<div class="parent">
|
<div class="parent">
|
||||||
<div class="content-parent">
|
<div class="content-parent">
|
||||||
<Vue3DraggableResizable v-for="draggable in draggables" :initW="draggable.w" :initH="draggable.h" v-model:x="draggable.x" v-model:y="draggable.y" v-model:w="draggable.w" v-model:h="draggable.h"
|
<Vue3DraggableResizable v-for="draggable in draggables" :initW="draggable.w" :initH="draggable.h" v-model:x="draggable.x" v-model:y="draggable.y" v-model:w="draggable.w" v-model:h="draggable.h"
|
||||||
v-model:active="draggable.active" :draggable="draggable.draggable" :resizable="draggable.resizable" :parent="true" @activated="activateComponent( draggable.id );"
|
v-model:active="draggable.active" v-model:draggable="draggable.draggable" :resizable="draggable.resizable" :parent="true" @activated="activateComponent( draggable.id );"
|
||||||
@drag-end="saveHistory();" @resize-end="saveHistory();" @contextmenu="( e ) => { e.preventDefault(); }" class="draggable-box">
|
@drag-end="saveHistory();" @resize-end="saveHistory();" @contextmenu="( e ) => { e.preventDefault(); }" class="draggable-box">
|
||||||
<circularSeatplanComponent v-if="draggable.shape == 'circular' && draggable.kind == 'seat'" :scale-factor="scaleFactor" :w="draggable.w" :h="draggable.h" :origin="draggable.origin"></circularSeatplanComponent>
|
<circularSeatplanComponent v-if="draggable.shape == 'circular' && draggable.type == 'seat'" :scale-factor="scaleFactor" :w="draggable.w" :h="draggable.h" :origin="draggable.origin" :starting-row="draggable.startingRow"></circularSeatplanComponent>
|
||||||
<trapezoidSeatplanComponent v-if="draggable.shape == 'trapezoid' && draggable.kind == 'seat'" :scale-factor="scaleFactor" :w="draggable.w" :h="draggable.h" :origin="draggable.origin"></trapezoidSeatplanComponent>
|
<trapezoidSeatplanComponent v-if="draggable.shape == 'trapezoid' && draggable.type == 'seat'" :scale-factor="scaleFactor" :w="draggable.w" :h="draggable.h" :origin="draggable.origin" :starting-row="draggable.startingRow"></trapezoidSeatplanComponent>
|
||||||
<rectangularSeatplanComponent v-if="draggable.shape == 'rectangular' && draggable.kind == 'seat'" :scale-factor="scaleFactor" :w="draggable.w" :h="draggable.h" :origin="draggable.origin"></rectangularSeatplanComponent>
|
<rectangularSeatplanComponent v-if="draggable.shape == 'rectangular' && draggable.type == 'seat'" :scale-factor="scaleFactor" :w="draggable.w" :h="draggable.h" :origin="draggable.origin"></rectangularSeatplanComponent>
|
||||||
</Vue3DraggableResizable>
|
</Vue3DraggableResizable>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -26,6 +26,8 @@
|
|||||||
<button v-else disabled>Undo</button>
|
<button v-else disabled>Undo</button>
|
||||||
<button v-if="available.redo" @click="historyOp( 'redo' )">Redo</button>
|
<button v-if="available.redo" @click="historyOp( 'redo' )">Redo</button>
|
||||||
<button v-else disabled>Redo</button>
|
<button v-else disabled>Redo</button>
|
||||||
|
<button @click="zoom( 1.2 )">+</button>
|
||||||
|
<button @click="zoom( 0.8 )">-</button>
|
||||||
<button @click="addNewElement()">Add</button>
|
<button @click="addNewElement()">Add</button>
|
||||||
<button @click="deleteSelected()">Delete</button>
|
<button @click="deleteSelected()">Delete</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -52,11 +54,12 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
active: 0,
|
active: 0,
|
||||||
draggables: { 1: { 'x': 100, 'y':100, 'h': 100, 'w': 250, 'active': false, 'draggable': true, 'resizable': true, 'id': 1, 'origin': 1, 'categories': { 1: 0 }, 'shape':'rectangular', 'kind': 'seat' } },
|
draggables: { 1: { 'x': 100, 'y':100, 'h': 100, 'w': 250, 'active': false, 'draggable': true, 'resizable': true, 'id': 1, 'origin': 1, 'shape':'rectangular', 'type': 'seat', 'startingRow': 1 } },
|
||||||
available: { 'redo': false, 'undo': false },
|
available: { 'redo': false, 'undo': false },
|
||||||
scaleFactor: 1,
|
scaleFactor: 1,
|
||||||
sizePoll: null,
|
sizePoll: null,
|
||||||
prevSize: { 'h': window.innerHeight, 'w': window.innerWidth },
|
prevSize: { 'h': window.innerHeight, 'w': window.innerWidth },
|
||||||
|
zoomFactor: 1,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -71,6 +74,7 @@
|
|||||||
*/
|
*/
|
||||||
runHook () {
|
runHook () {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
this.zoomFactor = sessionStorage.getItem( 'zoom' ) ? sessionStorage.getItem( 'zoom' ) : 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Keybinds:
|
Keybinds:
|
||||||
@@ -100,8 +104,6 @@
|
|||||||
|
|
||||||
this.loadSeatplan();
|
this.loadSeatplan();
|
||||||
|
|
||||||
// TODO: build Zoom function (including touch gesture support)
|
|
||||||
|
|
||||||
if ( !sessionStorage.getItem( 'seatplan-history' ) ) {
|
if ( !sessionStorage.getItem( 'seatplan-history' ) ) {
|
||||||
sessionStorage.setItem( 'seatplan-history', JSON.stringify( { '1': this.scaleDown( this.draggables ) } ) );
|
sessionStorage.setItem( 'seatplan-history', JSON.stringify( { '1': this.scaleDown( this.draggables ) } ) );
|
||||||
}
|
}
|
||||||
@@ -118,6 +120,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let supportedBrowser = [];
|
let supportedBrowser = [];
|
||||||
|
this.save();
|
||||||
// TODO: Add warning for untested browsers & suboptimal window sizes!
|
// TODO: Add warning for untested browsers & suboptimal window sizes!
|
||||||
},
|
},
|
||||||
eventHandler ( e ) {
|
eventHandler ( e ) {
|
||||||
@@ -131,8 +134,9 @@
|
|||||||
Calculate scale factor (this adds support for differently sized screens)
|
Calculate scale factor (this adds support for differently sized screens)
|
||||||
900px is the "default" height
|
900px is the "default" height
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let height = $( document ).height() * 0.8;
|
let height = $( document ).height() * 0.8;
|
||||||
this.scaleFactor = height / 900;
|
this.scaleFactor = ( height / 900 ) * this.zoomFactor;
|
||||||
/*
|
/*
|
||||||
Load seatplan
|
Load seatplan
|
||||||
*/
|
*/
|
||||||
@@ -231,7 +235,7 @@
|
|||||||
sessionStorage.setItem( 'seatplan', JSON.stringify( this.scaleDown( this.draggables ) ) );
|
sessionStorage.setItem( 'seatplan', JSON.stringify( this.scaleDown( this.draggables ) ) );
|
||||||
},
|
},
|
||||||
addNewElement () {
|
addNewElement () {
|
||||||
this.draggables[ Object.keys( this.draggables ).length + 1 ] = { 'x': 100, 'y':100, 'h': 100, 'w': 250, 'active': false, 'draggable': true, 'resizable': true, 'id': Object.keys( this.draggables ).length + 1, 'origin': 1, 'categories': { 1: 0 }, 'shape':'rectangular', 'kind': 'seat' };
|
this.draggables[ Object.keys( this.draggables ).length + 1 ] = { 'x': 100, 'y':100, 'h': 100, 'w': 250, 'active': false, 'draggable': true, 'resizable': true, 'id': Object.keys( this.draggables ).length + 1, 'origin': 1, 'shape':'rectangular', 'type': 'seat', 'startingRow': 1 };
|
||||||
this.saveHistory();
|
this.saveHistory();
|
||||||
},
|
},
|
||||||
deleteSelected () {
|
deleteSelected () {
|
||||||
@@ -245,6 +249,12 @@
|
|||||||
this.draggables = value;
|
this.draggables = value;
|
||||||
this.selectedObject = value;
|
this.selectedObject = value;
|
||||||
this.saveHistory();
|
this.saveHistory();
|
||||||
|
},
|
||||||
|
zoom ( scale ) {
|
||||||
|
this.zoomFactor = this.zoomFactor * scale;
|
||||||
|
sessionStorage.setItem( 'zoom', this.zoomFactor );
|
||||||
|
this.scaleFactor = this.scaleFactor * scale;
|
||||||
|
this.draggables = this.scaleUp( JSON.parse( sessionStorage.getItem( 'seatplan' ) ) );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ export default {
|
|||||||
type: Number,
|
type: Number,
|
||||||
"default": 1,
|
"default": 1,
|
||||||
},
|
},
|
||||||
|
startingRow: {
|
||||||
|
type: Number,
|
||||||
|
"default": 1,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -56,7 +60,7 @@ export default {
|
|||||||
const size = 33;
|
const size = 33;
|
||||||
let count = Math.min( Math.floor( w / size ), Math.floor( h / size ) );
|
let count = Math.min( Math.floor( w / size ), Math.floor( h / size ) );
|
||||||
this.seats = {};
|
this.seats = {};
|
||||||
for ( let row = 0; row < count; row++ ) {
|
for ( let row = this.startingRow; row < count; row++ ) {
|
||||||
let nn = row * ( Math.PI / 2 );
|
let nn = row * ( Math.PI / 2 );
|
||||||
let r = row * size;
|
let r = row * size;
|
||||||
this.seats[ row ] = {};
|
this.seats[ row ] = {};
|
||||||
@@ -95,6 +99,9 @@ export default {
|
|||||||
},
|
},
|
||||||
origin() {
|
origin() {
|
||||||
this.calculateChairs();
|
this.calculateChairs();
|
||||||
|
},
|
||||||
|
startingRow() {
|
||||||
|
this.calculateChairs();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ export default {
|
|||||||
type: Number,
|
type: Number,
|
||||||
"default": 1,
|
"default": 1,
|
||||||
},
|
},
|
||||||
|
startingRow: {
|
||||||
|
type: Number,
|
||||||
|
"default": 1,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -60,7 +64,7 @@ export default {
|
|||||||
let count = Math.floor( heightTriangle / ( sideOffset * 2 ) );
|
let count = Math.floor( heightTriangle / ( sideOffset * 2 ) );
|
||||||
const angle = Math.PI / 4;
|
const angle = Math.PI / 4;
|
||||||
this.seats = {};
|
this.seats = {};
|
||||||
for ( let row = 0; row < count; row++ ) {
|
for ( let row = this.startingRow; row < count; row++ ) {
|
||||||
let nn = 2 + ( row - 1 ) * 2;
|
let nn = 2 + ( row - 1 ) * 2;
|
||||||
this.seats[ row ] = {};
|
this.seats[ row ] = {};
|
||||||
for ( let n = 0; n < nn; n++ ) {
|
for ( let n = 0; n < nn; n++ ) {
|
||||||
@@ -98,6 +102,9 @@ export default {
|
|||||||
},
|
},
|
||||||
origin() {
|
origin() {
|
||||||
this.calculateChairs();
|
this.calculateChairs();
|
||||||
|
},
|
||||||
|
startingRow() {
|
||||||
|
this.calculateChairs();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<!--
|
||||||
|
* libreevent - properties.vue
|
||||||
|
*
|
||||||
|
* Created by Janis Hutz 05/12/2023, Licensed under the GPL V3 License
|
||||||
|
* https://janishutz.com, development@janishutz.com
|
||||||
|
*
|
||||||
|
*
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div id="stages">
|
||||||
|
<div id="rectangular" v-if="origin == 'rectangular'"></div>
|
||||||
|
<div id="trapezoid" v-if="origin == 'trapezoid'"></div>
|
||||||
|
<div id="circular" v-if="origin == 'circular'"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'stagesSeatplanComponent',
|
||||||
|
props: {
|
||||||
|
origin: {
|
||||||
|
type: Number,
|
||||||
|
"default": 1,
|
||||||
|
},
|
||||||
|
origin: {
|
||||||
|
type: String,
|
||||||
|
"default": "rectangular",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user