Vue - Dynamic Dialogs with different Classes
Vue also bound to SVG elements
by Ben Clayton
HTML
<script type="text/x-template" id="rect-svg-template">
<g>
<rect @click="rectClick" :x="rectX()" :y="rectY()" :width="rectWidth()" :height="rectHeight()" :fill="rectFill()" stroke-width="1" />
<text :x="textX()" :y="textY()" fill="black">{{ name() }}</text>
</g>
</script>
<script type="text/x-template" id="circle-svg-template">
<g>
<circle @click="circleClick" :cx="circleX()" :cy="circleY()" :r="circleRadius()" :stroke="circleStroke()" :fill="circleFill()" stroke-width="1" />
<text :x="textX()" :y="textY()" fill="black">{{ name() }}</text>
</g>
</script>
<!-- Property template -->
<script type="text/x-template" id="circle-dialog-template">
<div class='dialog'>
<div @click="close" class="closebtn">X</div>
<div class="proplist">
<h5>Circle</h5>
<table>
<tr>
<td class='label'><label>Name:</label></td>
<td class='value'><input v-model='name'></td>
</tr>
<tr>
<td class='label'><label>Size:</label></td>
<td class='value'><input type='range' v-model='size' min='0' max='100'>{{ size }}</td>
</tr>
<tr>
<td class='label'><label>X:</label></td>
<td class='value'><input type='range' v-model='x' min='100' max='400'>{{ x }}</td>
</tr>
<tr>
<td class='label'><label>Y:</label></td>
<td class='value'><input type='range' v-model='y' min='50' max='250'>{{ y }}</td>
</tr>
<tr>
<td class='label'><label>Color:</label></td>
<td class='value'>
<my-color-selector :param="$data.getPropByRef('color')"></my-color-selector>
</td>
</tr>
</table>
</div>
</div>
</script>
<script type="text/x-template" id="rect-dialog-template">
<div class='dialog'>
<div @click="close" class="closebtn">X</div>
<div class="proplist">
<h5>Rectangle</h5>
<table>
<tr>
<td class='label'><label>Name:</label></td>
<td class='value'><input v-model='name'></td>
</tr>
<tr>
<td...
CSS
.dialogouter {
display: inline-block;
margin: 20px;
}
.dialog {
width: 240px;
height: 300px;
display: inline-block;
border: 1px solid gray;
}
.dialog .proplist {
padding: 10px;
}
.dialog table td.label {}
.dialog table td.value {
min-width: 180px;
}
.dialog .closebtn {
float: right;
border:1px solid gray;
}
JavaScript
class myclass_circle{
constructor( name, color, size, x, y ) {
this.type = 'circle';
this.name = name || "mycircle";
this.size = size || 20;
this.color = color || "gray";
this.x = x || 260;
this.y = y || 100;
}
getPropByRef( nm ){ // used to pass 'color' by ref to color selector component
return { ref : this, prop: nm };
}
getSVGViewData(){
return { ref:this, x:this.x, y:this.y, size:this.size, name:this.name, color:this.color, click:this.click, close:this.close };
}
propertyTemplate(){
return "#circle-dialog-template";
}
close(ptr){
alert("close circle dialog");
pd.deleteDialog(ptr);
}
// The click is not called with the context of the class
// but the parameter 'cls' points at this class.
click(ptr ){
// 'pd' is a global pointer to the view handling the dialogs array.
pd.singleDialog(ptr);
}
}
class myclass_rect{
constructor( name, color,width,height, x, y ) {
this.type = 'rect';
this.name = name || "mycircle";
this.width = width || 20;
this.height = height || 20;
this.color = color || "gray";
this.x = x || 260;
this.y = y || 100;
}
getPropByRef( nm ){ // used to pass 'color' by ref to color selector component
return { ref : this, prop: nm };
}
getSVGViewData(){
return { ref:this, x:this.x, y:this.y, width:this.width, height:this.height, name:this.name, color:this.color, click:this.click };
}
propertyTemplate(){
return "#rect-dialog-template";
}
close(ptr){
alert("close rect dialog");
pd.deleteDialog(ptr);
}
// The click is not called with the context of the class
// but the parameter 'cls' points at this class.
click( ptr ){
// 'pd' is a global pointer to the view handling the dialogs array.
pd.singleDialog(ptr);
}
}
var objarray = [
new myclass_circle("C1","red",10,100,100),
new myclass_circle("C2","blue",10,160,100),
new...