<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<!DOCTYPE html><html lang='en' class=''>
<head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/michaeljcalkins/pen/Imupw" />
<link rel='stylesheet prefetch' href='//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css'><link rel='stylesheet prefetch' href='//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css'>
<style class="cp-pen-styles">body {
padding: 10px;
}
.image-builder-container {
position: relative;
}
.image-builder-container .image-builder {
background: #cacaca;
box-sizing: border-box;
border: 1px solid #cacaca;
min-height: 460px;
text-align: center;
position: relative;
overflow-x: scroll;
overflow-y: hidden;
width: auto;
}
.image-builder-container .image-builder .image-cover {
left: 0;
right: 0;
bottom: 0;
top: 0;
position: absolute;
z-index: 2;
}
.image-builder-container .image-builder .fabric-container {
background: white;
border-radius: 1px;
box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.4);
display: inline-block;
margin: 50px;
position: relative;
vertical-align: middle;
z-index: 0;
}
.image-builder-container .image-loading {
background: rgba(255, 255, 255, 0.4);
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 1;
}
.image-builder-container .image-loading .loading-indicator {
background: white;
background-image: url(/images/squareLoader.gif);
background-repeat: no-repeat;
background-position: center;
border-radius: 10px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
margin: 300px auto 0;
height: 160px;
width: 160px;
}
.image-builder-container .object-controls-container {
position: relative;
}
.image-builder-container .object-controls-container .object-controls {
position: absolute;
z-index: 1;
background: white;
left: -250px;
top: 0px;
padding: 5px;
width: 240px;
}
.image-builder-container .object-controls-container .object-controls textarea {
font-size: 12px;
}
.object-font-family-preview {
text-transform: capitalize;
}
</style></head><body>
<a class='btn btn-info' target='_blank' href='https://github.com/clouddueling/angular-fabric'>
<i class='fa fa-github'></i>
clouddueling/angular-fabric
</a>
<div ng-app='example' ng-controller="ExampleCtrl">
<div class='image-builder-container'>
<div ng-if="fabric.isLoading()" class="image-loading">
<div class="loading-indicator"></div>
</div>
<div class="row">
<div class="col-sm-12">
<small><em class='text-muted'>Image and shape do not work due to codepen cross-origin.</em></small>
<br />
<div class='btn-group pull-left mrm'>
<button ng-disabled="!fabric.selectedObject" ng-click="fabric.deleteActiveObject(); fabric.setDirty(true)" class='btn btn-danger'>
<i class='fa fa-trash-o'></i>
<div class='clearfix'></div>
Delete
</button>
<button ng-click='addImage()' class='btn btn-default'>
<i class='fa fa-image'></i>
<div class='clearfix'></div>
Image
</button>
<button ng-click="fabric.addText()" class='btn btn-default'>
<i class='fa fa-font'></i>
<div class='clearfix'></div>
Text
</button>
<button ng-click='addShape()' class='btn btn-default'>
<i class='fa fa-star'></i>
<div class='clearfix'></div>
Shapes
</button>
<button ng-click="fabric.clearCanvas(); fabric.setDirty(true)" class='btn btn-default'>
<i class='fa fa-refresh'></i>
<div class='clearfix'></div>
Restart
</button>
</div>
<div class='pull-left' style='margin: 15px 0 0 10px;'>
<div class='row'>
<div class='col-xs-1 text-center'>
<i class='fa fa-search-minus pull-left'></i>
</div>
<div class='col-xs-6'>
<input type='range' class='pull-left' min='.1' max='3' step='.1' ng-change='fabric.setZoom()' ng-model='fabric.canvasScale' />
</div>
<div class='col-xs-1 text-center'>
<i class='fa fa-search-plus'></i>
</div>
<div class='col-xs-3'>
<button class='btn btn-xs' ng-click="fabric.resetZoom()">
Reset
</button>
</div>
</div>
</div>
<div class="pull-right">
<button class='btn btn-default' title='Dummy button. This is where you would take the json from the canvas and save it to your database.'>
<i class='fa fa-save'></i>
<div class='clearfix'></div>
Save <span ng-show='fabric.isDirty()' class='text-danger'>*</span>
</button>
<button ng-click="fabric.download('myCanvas')" class='btn btn-success'>
<i class='fa fa-download'></i>
<div class='clearfix'></div>
Download
</button>
</div>
</div>
</div>
<br />
<div class="row">
<div class="col-xs-4">
<label>Background Color</label>
<input type="text" class='form-control' ng-change='fabric.setDirty(true); fabric.stopContinuousRendering()' ng-model="fabric.canvasBackgroundColor" />
</div>
<div class='col-xs-4'>
<label>Canvas Size</label>
<br />
<button ng-hide='canvasCopy' class='btn btn-default btn-block mrm' ng-click='selectCanvas()'>
{{ fabric.canvasOriginalWidth }} x {{ fabric.canvasOriginalHeight }}
</button>
<div class='row' ng-show='canvasCopy'>
<div class='col-xs-12'>
<form ng-submit='setCanvasSize()'>
<div class='form-group'>
<label>Width</label>
<input type='text' ng-model='canvasCopy.width' class='form-control' />
</div>
<div class='form-group'>
<label>Height</label>
<input type='text' ng-model='canvasCopy.height' class='form-control' />
</div>
<button type='submit' class='btn btn-success'>
Submit
</button>
</form>
</div>
</div>
</div>
<div class='col-xs-4'>
<label> </label>
<br />
<div class="btn-group col-xs-12">
<a class="btn btn-block btn-default dropdown-toggle" data-toggle="dropdown" href="#">
Preset Sizes
<span class="caret"></span>
</a>
<ul class="dropdown-menu pull-right">
<li ng-click='fabric.setCanvasSize(size.width, size.height); fabric.setDirty(true)' ng-repeat='size in FabricConstants.presetSizes'>
<a>{{ size.name }}</a>
</li>
</ul>
</div>
</div>
</div>
<br />
<div class='row'>
<div class='col-xs-3'>
<div ng-if='fabric.selectedObject'>
<div ng-switch='fabric.selectedObject.type'>
<div ng-switch-when='text'>
<p>
<textarea style="text-align: {{ fabric.selectedObject.textAlign }}" class="form-control" rows="6" ng-model="fabric.selectedObject.text"></textarea>
</p>
<p title="Font size">
<i class="fa fa-text-height"></i>
<input type='number' class="form-control" ng-model="fabric.selectedObject.fontSize" />
</p>
<p title="Line height">
<i class="fa fa-align-left"></i>
<input type='number' class="form-control" ng-model="fabric.selectedObject.lineHeight" step=".1" />
</p>
<div class='btn-group'>
<button ng-class="{ active: fabric.selectedObject.textAlign == 'left' }" ng-click="fabric.selectedObject.textAlign = 'left'" class='btn btn-small'>
<i class='fa fa-align-left'></i>
</button>
<button ng-class="{ active: fabric.selectedObject.textAlign == 'center' }" ng-click="fabric.selectedObject.textAlign = 'center'" class='btn btn-small'>
<i class='fa fa-align-center'></i>
</button>
<button ng-class="{ active: fabric.selectedObject.textAlign == 'right' }" ng-click="fabric.selectedObject.textAlign = 'right'" class='btn btn-small'>
<i class='fa fa-align-right'></i>
</button>
</div>
<br />
<div class='btn-group'>
<button ng-class="{ active: fabric.isBold() }" ng-click="fabric.toggleBold()" class='btn btn-small'>
<i class='fa fa-bold'></i>
</button>
<button ng-class="{ active: fabric.isItalic() }" ng-click="fabric.toggleItalic()" class='btn btn-small'>
<i class='fa fa-italic'></i>
</button>
<button ng-class="{ active: fabric.isUnderline() }" ng-click="fabric.toggleUnderline()" class='btn btn-small'>
<i class='fa fa-underline'></i>
</button>
<button ng-class="{ active: fabric.isLinethrough() }" ng-click="fabric.toggleLinethrough()" class='btn btn-small'>
<i class='fa fa-strikethrough'></i>
</button>
</div>
<br />
<div class="row">
<div class="btn-group col-sm-12">
<a class="btn btn-default btn-block dropdown-toggle" data-toggle="dropdown" href="#">
<span class='object-font-family-preview' style='font-family: "{{ fabric.selectedObject.fontFamily }}";'>
{{ fabric.selectedObject.fontFamily }}
</span>
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li ng-repeat='font in FabricConstants.fonts' ng-click='fabric.selectedObject.fontFamily = font.name' style='font-family: "{{ font.name }}";'>
<a>{{ font.name }}</a>
</li>
</ul>
</div>
</div>
</div>
<div ng-switch-when="image">
<div class="input-prepend">
<button ng-class="{ active: fabric.isTinted() }" ng-click="fabric.toggleTint()" class='btn'>
<i class='fa fa-tint'></i>
</button>
<input type="text" class='input-small' ng-model='fabric.selectedObject.tint' />
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<input class='col-sm-12' title="Transparency" type='range'
min="0"
max="1"
step=".01"
ng-model="fabric.selectedObject.opacity" />
</div>
</div>
<div class="row mbm">
<div class="col-sm-12">
<button class='btn btn-small btn-block' ng-class="{ active: fabric.getFlipX() }" ng-click="{ active: fabric.toggleFlipX() }">
<i class='fa fa-exchange'></i> Flip
</button>
</div>
</div>
<div class="row" ng-hide="fabric.selectedObject.type == 'image'">
<div class="col-sm-12">
<input type="text" class='form-control' ng-model="fabric.selectedObject.fill" />
</div>
</div>
<div class="row">
<div class="btn-group col-xs-12 btn-group-vertical">
<button ng-click='fabric.center()' class='btn btn-small btn-block'>
Center
</button>
<button ng-click='fabric.centerH()' class='btn btn-small btn-block'>
Center Horizontally
</button>
<button ng-click='fabric.centerV()' class='btn btn-small btn-block'>
Center Vertically
</button>
</div>
</div>
<br />
<div class="row">
<div class="btn-group col-xs-12 btn-group-vertical">
<button ng-click='fabric.bringToFront(); fabric.setDirty(true)' class='btn btn-small btn-block'>
Bring to front
</button>
<button ng-click='fabric.bringForward(); fabric.setDirty(true)' class='btn btn-small btn-block'>
Bring forwards
</button>
<button ng-click='fabric.sendBackwards(); fabric.setDirty(true)' class='btn btn-small btn-block'>
Send backwards
</button>
<button ng-click='fabric.sendToBack(); fabric.setDirty(true)' class='btn btn-small btn-block'>
Send to back
</button>
</div>
</div>
<br />
<button ng-click='fabric.toggleLockActiveObject(); fabric.setDirty(true)' ng-class="{ active: fabric.selectedObject.lockObject }" class='btn btn-small btn-block'>
Lock
</button>
</div>
</div>
<div class='col-xs-9'>
<div class='image-builder' parent-click="fabric.deactivateAll()">
<div class='fabric-container'>
<canvas fabric='fabric'></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
<script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script><script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script><script src='//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.8/fabric.min.js'></script><script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js'></script><script src='https://rawgithub.com/clouddueling/angular-fabric/master/assets/fabric.js'></script><script src='https://rawgithub.com/clouddueling/angular-fabric/master/assets/fabricCanvas.js'></script><script src='https://rawgithub.com/clouddueling/angular-fabric/master/assets/fabricConstants.js'></script><script src='https://rawgithub.com/clouddueling/angular-fabric/master/assets/fabricDirective.js'></script><script src='https://rawgithub.com/clouddueling/angular-fabric/master/assets/fabricDirtyStatus.js'></script><script src='https://rawgithub.com/clouddueling/angular-fabric/master/assets/fabricUtilities.js'></script><script src='https://rawgithub.com/clouddueling/angular-fabric/master/assets/fabricWindow.js'></script><script src='//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js'></script>
<script >angular.module('example', [
'common.fabric',
'common.fabric.utilities',
'common.fabric.constants'
])
.controller('ExampleCtrl', ['$scope', 'Fabric', 'FabricConstants', 'Keypress', function($scope, Fabric, FabricConstants, Keypress) {
$scope.fabric = {};
$scope.FabricConstants = FabricConstants;
//
// Creating Canvas Objects
// ================================================================
$scope.addShape = function(path) {
$scope.fabric.addShape('http://fabricjs.com/assets/15.svg');
};
$scope.addImage = function(image) {
$scope.fabric.addImage('http://stargate-sg1-solutions.com/blog/wp-content/uploads/2007/08/daniel-season-nine.jpg');
};
$scope.addImageUpload = function(data) {
var obj = angular.fromJson(data);
$scope.addImage(obj.filename);
};
//
// Editing Canvas Size
// ================================================================
$scope.selectCanvas = function() {
$scope.canvasCopy = {
width: $scope.fabric.canvasOriginalWidth,
height: $scope.fabric.canvasOriginalHeight
};
};
$scope.setCanvasSize = function() {
$scope.fabric.setCanvasSize($scope.canvasCopy.width, $scope.canvasCopy.height);
$scope.fabric.setDirty(true);
delete $scope.canvasCopy;
};
//
// Init
// ================================================================
$scope.init = function() {
$scope.fabric = new Fabric({
JSONExportProperties: FabricConstants.JSONExportProperties,
textDefaults: FabricConstants.textDefaults,
shapeDefaults: FabricConstants.shapeDefaults,
json: {}
});
};
$scope.$on('canvas:created', $scope.init);
Keypress.onSave(function() {
$scope.updatePage();
});
}]);
//# sourceURL=pen.js
</script>
</body></html>