Skip to content

Instantly share code, notes, and snippets.

@iongion
Created September 28, 2017 13:48
Show Gist options
  • Save iongion/8aa85a87a66f9736d615e8501a06a81b to your computer and use it in GitHub Desktop.
Save iongion/8aa85a87a66f9736d615e8501a06a81b 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">
fabric.Object.prototype.originX = 'left';
fabric.Object.prototype.originY = 'top';
var DataGroup = fabric.util.createClass(fabric.Group, {
type: 'data-group',
initialize: function(options) {
var defaults = {
fill: 'red',
top: 0,
left: 0,
width: 120,
height: 80,
angle: 0,
opacity: 1,
lockScalingFlip: true,
lockRotation: true,
}
options = _.merge(defaults, _.isObject(options) ? 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();
this._invalidateDimensions();
},
// helpers
_createBackground: function() {
this.elementBackground = new fabric.Rect({
fill: 'red',
top: this.top,
left: this.left,
width: this.width,
height: this.height,
});
this.addWithUpdate(this.elementBackground);
},
_createForeground: function() {
var textHeight = 18;
var text = '000';
this.elementForeground = new fabric.Text(text, {
fill: 'green',
top: this.top,
left: this.left,
textAlign: 'center',
borderColor: 'yellow',
textBackgroundColor: 'white',
});
this.addWithUpdate(this.elementForeground);
},
_invalidateDimensions: function() {
var dX = -this.width/2, dY = -this.height/2;
this.set({
width: this.width * this.scaleX,
height: this.height * this.scaleY,
scaleX: 1,
scaleY: 1
}).setCoords();
this.elementBackground.set({
fill: 'blue',
top: dY,
left: dX,
width: this.width,
height: this.height,
scaleX: 1,
scaleY: 1,
}).setCoords();
this.elementForeground.set({
top: dY,
left: dX,
width: this.width,
scaleX: 1,
scaleY: 1,
}).setCoords();
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">fabric.Object.prototype.originX = 'left';
fabric.Object.prototype.originY = 'top';
var DataGroup = fabric.util.createClass(fabric.Group, {
type: 'data-group',
initialize: function(options) {
var defaults = {
fill: 'red',
top: 0,
left: 0,
width: 120,
height: 80,
angle: 0,
opacity: 1,
lockScalingFlip: true,
lockRotation: true,
}
options = _.merge(defaults, _.isObject(options) ? 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();
this._invalidateDimensions();
},
// helpers
_createBackground: function() {
this.elementBackground = new fabric.Rect({
fill: 'red',
top: this.top,
left: this.left,
width: this.width,
height: this.height,
});
this.addWithUpdate(this.elementBackground);
},
_createForeground: function() {
var textHeight = 18;
var text = '000';
this.elementForeground = new fabric.Text(text, {
fill: 'green',
top: this.top,
left: this.left,
textAlign: 'center',
borderColor: 'yellow',
textBackgroundColor: 'white',
});
this.addWithUpdate(this.elementForeground);
},
_invalidateDimensions: function() {
var dX = -this.width/2, dY = -this.height/2;
this.set({
width: this.width * this.scaleX,
height: this.height * this.scaleY,
scaleX: 1,
scaleY: 1
}).setCoords();
this.elementBackground.set({
fill: 'blue',
top: dY,
left: dX,
width: this.width,
height: this.height,
scaleX: 1,
scaleY: 1,
}).setCoords();
this.elementForeground.set({
top: dY,
left: dX,
width: this.width,
scaleX: 1,
scaleY: 1,
}).setCoords();
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;
}
fabric.Object.prototype.originX = 'left';
fabric.Object.prototype.originY = 'top';
var DataGroup = fabric.util.createClass(fabric.Group, {
type: 'data-group',
initialize: function(options) {
var defaults = {
fill: 'red',
top: 0,
left: 0,
width: 120,
height: 80,
angle: 0,
opacity: 1,
lockScalingFlip: true,
lockRotation: true,
}
options = _.merge(defaults, _.isObject(options) ? 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();
this._invalidateDimensions();
},
// helpers
_createBackground: function() {
this.elementBackground = new fabric.Rect({
fill: 'red',
top: this.top,
left: this.left,
width: this.width,
height: this.height,
});
this.addWithUpdate(this.elementBackground);
},
_createForeground: function() {
var textHeight = 18;
var text = '000';
this.elementForeground = new fabric.Text(text, {
fill: 'green',
top: this.top,
left: this.left,
textAlign: 'center',
borderColor: 'yellow',
textBackgroundColor: 'white',
});
this.addWithUpdate(this.elementForeground);
},
_invalidateDimensions: function() {
var dX = -this.width/2, dY = -this.height/2;
this.set({
width: this.width * this.scaleX,
height: this.height * this.scaleY,
scaleX: 1,
scaleY: 1
}).setCoords();
this.elementBackground.set({
fill: 'blue',
top: dY,
left: dX,
width: this.width,
height: this.height,
scaleX: 1,
scaleY: 1,
}).setCoords();
this.elementForeground.set({
top: dY,
left: dX,
width: this.width,
scaleX: 1,
scaleY: 1,
}).setCoords();
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