Skip to content

Instantly share code, notes, and snippets.

@iongion
Created September 28, 2017 13:00
Show Gist options
  • Save iongion/f34ee565e176944bdb39801a657d7872 to your computer and use it in GitHub Desktop.
Save iongion/f34ee565e176944bdb39801a657d7872 to your computer and use it in GitHub Desktop.
JS Bin // source https://jsbin.com/livosek
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.min.js"></script>
<script src="http://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>
<style id="jsbin-css">
html {
font-family: Arial;
}
#mainCanvas {
border: 1px solid #ccc;
width: 320px;
height: 240px;
}
#propertiesEditor {
border: 1px solid #ccc;
margin-top: 20px;
min-width: 320px;
}
#propertiesEditor td {
padding: 4px;
}
#propertiesEditor tr > td:first-child {
background: #bfbeba;
width: 80px;
}
#propertiesEditor tr > td:nth-child(2) {
background: #cecece;
}
#propertiesEditor td strong {
text-transform: uppercase;
}
</style>
</head>
<body>
<canvas id="mainCanvas"></canvas>
<table id="propertiesEditor">
<tr>
<td>Property</td>
<td>Value</td>
</tr>
</table>
<script id="jsbin-javascript">
var DataGroup = fabric.util.createClass(fabric.Group, {
type: 'data-group',
initialize: function(options) {
var defaults = {
fill: 'red',
originX: 'left',
originY: 'top',
top: 0,
left: 0,
width: 120,
height: 80,
angle: 0,
opacity: 1,
lockScalingFlip: true,
}
options = _.merge(defaults, _.isObject(options) ? options : {});
console.debug('>> DataGroup - created', options);
this.on('selected', _.bind(this._handleSelected, this));
this.on('scaling', _.bind(this._handleScaling, this));
this.on('moving', _.bind(this._handleMoving, this));
this.on('modified', _.bind(this._handleModified, this));
//
this.callSuper('initialize', [], options);
this._createBackground();
this._createForeground();
},
// helpers
_createBackground: function() {
this.elementBackground = new fabric.Rect({
fill: 'red',
width: this.width,
height: this.height,
});
this.addWithUpdate(this.elementBackground);
},
_createForeground: function() {
this.elementForeground = new fabric.Rect({
fill: 'green',
width: this.width,
height: this.height,
});
this.addWithUpdate(this.elementForeground);
},
_invalidateDimensions: function() {
reportProperty('top', this.top);
reportProperty('left', this.left);
reportProperty('width', this.width);
reportProperty('height', this.height);
reportProperty('unscaledWidth', this.width * this.scaleX);
reportProperty('unscaledHeight', this.height * this.scaleY);
},
// events
_handleSelected: function(e) {
this._invalidateDimensions();
},
_handleScaling: function(e) {
this._invalidateDimensions();
},
_handleMoving: function(e) {
this._invalidateDimensions();
},
_handleModified: function(e) {
this._invalidateDimensions();
},
});
// helpers
var reportProperty = function(prop, val) {
var propTable = document.querySelector('#propertiesEditor');
var propValue = document.querySelector('td[data-property="' + prop + '"]');
if (!propValue) {
var propRow = document.createElement('tr');
var propLabel = document.createElement('td');
propValue = document.createElement('td');
propValue.setAttribute('data-property', prop);
propLabel.innerHTML = prop;
propLabel.style = 'font-weight: bold';
propRow.append(propLabel, propValue);
propTable.append(propRow);
}
propValue.innerHTML = val;
};
// main
var nativeCanvas = document.getElementById('mainCanvas');
var canvas = new fabric.Canvas(nativeCanvas, {
preserveObjectStacking: true,
});
var node = new DataGroup();
canvas.add(node);
canvas.renderAll();
</script>
<script id="jsbin-source-html" type="text/html"><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.min.js"><\/script>
<script src="//cdn.jsdelivr.net/lodash/4/lodash.min.js"><\/script>
</head>
<body>
<canvas id="mainCanvas"></canvas>
<table id="propertiesEditor">
<tr>
<td>Property</td>
<td>Value</td>
</tr>
</table>
</body>
</html></script>
<script id="jsbin-source-css" type="text/css">html {
font-family: Arial;
}
#mainCanvas {
border: 1px solid #ccc;
width: 320px;
height: 240px;
}
#propertiesEditor {
border: 1px solid #ccc;
margin-top: 20px;
min-width: 320px;
}
#propertiesEditor td {
padding: 4px;
}
#propertiesEditor tr > td:first-child {
background: #bfbeba;
width: 80px;
}
#propertiesEditor tr > td:nth-child(2) {
background: #cecece;
}
#propertiesEditor td strong {
text-transform: uppercase;
}</script>
<script id="jsbin-source-javascript" type="text/javascript">var DataGroup = fabric.util.createClass(fabric.Group, {
type: 'data-group',
initialize: function(options) {
var defaults = {
fill: 'red',
originX: 'left',
originY: 'top',
top: 0,
left: 0,
width: 120,
height: 80,
angle: 0,
opacity: 1,
lockScalingFlip: true,
}
options = _.merge(defaults, _.isObject(options) ? options : {});
console.debug('>> DataGroup - created', options);
this.on('selected', _.bind(this._handleSelected, this));
this.on('scaling', _.bind(this._handleScaling, this));
this.on('moving', _.bind(this._handleMoving, this));
this.on('modified', _.bind(this._handleModified, this));
//
this.callSuper('initialize', [], options);
this._createBackground();
this._createForeground();
},
// helpers
_createBackground: function() {
this.elementBackground = new fabric.Rect({
fill: 'red',
width: this.width,
height: this.height,
});
this.addWithUpdate(this.elementBackground);
},
_createForeground: function() {
this.elementForeground = new fabric.Rect({
fill: 'green',
width: this.width,
height: this.height,
});
this.addWithUpdate(this.elementForeground);
},
_invalidateDimensions: function() {
reportProperty('top', this.top);
reportProperty('left', this.left);
reportProperty('width', this.width);
reportProperty('height', this.height);
reportProperty('unscaledWidth', this.width * this.scaleX);
reportProperty('unscaledHeight', this.height * this.scaleY);
},
// events
_handleSelected: function(e) {
this._invalidateDimensions();
},
_handleScaling: function(e) {
this._invalidateDimensions();
},
_handleMoving: function(e) {
this._invalidateDimensions();
},
_handleModified: function(e) {
this._invalidateDimensions();
},
});
// helpers
var reportProperty = function(prop, val) {
var propTable = document.querySelector('#propertiesEditor');
var propValue = document.querySelector('td[data-property="' + prop + '"]');
if (!propValue) {
var propRow = document.createElement('tr');
var propLabel = document.createElement('td');
propValue = document.createElement('td');
propValue.setAttribute('data-property', prop);
propLabel.innerHTML = prop;
propLabel.style = 'font-weight: bold';
propRow.append(propLabel, propValue);
propTable.append(propRow);
}
propValue.innerHTML = val;
};
// main
var nativeCanvas = document.getElementById('mainCanvas');
var canvas = new fabric.Canvas(nativeCanvas, {
preserveObjectStacking: true,
});
var node = new DataGroup();
canvas.add(node);
canvas.renderAll();
</script></body>
</html>
html {
font-family: Arial;
}
#mainCanvas {
border: 1px solid #ccc;
width: 320px;
height: 240px;
}
#propertiesEditor {
border: 1px solid #ccc;
margin-top: 20px;
min-width: 320px;
}
#propertiesEditor td {
padding: 4px;
}
#propertiesEditor tr > td:first-child {
background: #bfbeba;
width: 80px;
}
#propertiesEditor tr > td:nth-child(2) {
background: #cecece;
}
#propertiesEditor td strong {
text-transform: uppercase;
}
var DataGroup = fabric.util.createClass(fabric.Group, {
type: 'data-group',
initialize: function(options) {
var defaults = {
fill: 'red',
originX: 'left',
originY: 'top',
top: 0,
left: 0,
width: 120,
height: 80,
angle: 0,
opacity: 1,
lockScalingFlip: true,
}
options = _.merge(defaults, _.isObject(options) ? options : {});
console.debug('>> DataGroup - created', options);
this.on('selected', _.bind(this._handleSelected, this));
this.on('scaling', _.bind(this._handleScaling, this));
this.on('moving', _.bind(this._handleMoving, this));
this.on('modified', _.bind(this._handleModified, this));
//
this.callSuper('initialize', [], options);
this._createBackground();
this._createForeground();
},
// helpers
_createBackground: function() {
this.elementBackground = new fabric.Rect({
fill: 'red',
width: this.width,
height: this.height,
});
this.addWithUpdate(this.elementBackground);
},
_createForeground: function() {
this.elementForeground = new fabric.Rect({
fill: 'green',
width: this.width,
height: this.height,
});
this.addWithUpdate(this.elementForeground);
},
_invalidateDimensions: function() {
reportProperty('top', this.top);
reportProperty('left', this.left);
reportProperty('width', this.width);
reportProperty('height', this.height);
reportProperty('unscaledWidth', this.width * this.scaleX);
reportProperty('unscaledHeight', this.height * this.scaleY);
},
// events
_handleSelected: function(e) {
this._invalidateDimensions();
},
_handleScaling: function(e) {
this._invalidateDimensions();
},
_handleMoving: function(e) {
this._invalidateDimensions();
},
_handleModified: function(e) {
this._invalidateDimensions();
},
});
// helpers
var reportProperty = function(prop, val) {
var propTable = document.querySelector('#propertiesEditor');
var propValue = document.querySelector('td[data-property="' + prop + '"]');
if (!propValue) {
var propRow = document.createElement('tr');
var propLabel = document.createElement('td');
propValue = document.createElement('td');
propValue.setAttribute('data-property', prop);
propLabel.innerHTML = prop;
propLabel.style = 'font-weight: bold';
propRow.append(propLabel, propValue);
propTable.append(propRow);
}
propValue.innerHTML = val;
};
// main
var nativeCanvas = document.getElementById('mainCanvas');
var canvas = new fabric.Canvas(nativeCanvas, {
preserveObjectStacking: true,
});
var node = new DataGroup();
canvas.add(node);
canvas.renderAll();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment