Skip to content

Instantly share code, notes, and snippets.

@clouddueling
Created April 20, 2014 00:07
Show Gist options
  • Save clouddueling/11101291 to your computer and use it in GitHub Desktop.
Save clouddueling/11101291 to your computer and use it in GitHub Desktop.
Fabric controls
<div ng-controller="ImagesCtrl">
<div class="form-horizontal">
<div style="position: relative;">
<div ng-if="Fabric.isLoading" class="image-loading">
<div class="loading-indicator"></div>
</div>
<div class="row-fluid">
<div class="span12">
<div class="btn-toolbar">
<div class='btn-group'>
<button
ng-disabled="!Fabric.hasActiveObject()"
confirm="Fabric.discardActiveObject()"
title="Delete this object?"
confirm-placement='bottom'
class='btn'>
<i class='icon-remove'></i>
<div class='clearfix'></div>
Delete
</button>
<button modal="/apps/builders/builders/images/addImage.modal.html" ng-click="imageHandle = {}; loadUploads()" class='btn'>
<i class='icon-picture'></i>
<div class='clearfix'></div>
Image
</button>
<button ng-click="Fabric.addText()" class='btn'>
<i class='icon-font'></i>
<div class='clearfix'></div>
&nbsp; Text &nbsp;
</button>
<button
modal="/apps/builders/builders/images/addShape.modal.html"
class='btn'>
<i class='icon-star'></i>
<div class='clearfix'></div>
Shapes
</button>
<button
modal="/apps/builders/builders/images/history.modal.html"
class='btn'>
<i class='icon-archive'></i>
<div class='clearfix'></div>
History
</button>
<button confirm="restart()" confirm-placement='bottom'
title="Delete all elements on this page?"
class='btn'>
<i class='icon-refresh'></i>
<div class='clearfix'></div>
Restart
</button>
</div>
<div class="btn-group">
<button class='btn' ng-click="Fabric.zoomIn()">
<i class="icon-zoom-in"></i>
<div class="clearfix"></div>
In
</button>
<button class='btn' ng-click="Fabric.resetZoom()">
<i class="icon-screenshot"></i>
<div class="clearfix"></div>
Reset
</button>
<button class='btn' ng-click="Fabric.zoomOut()">
<i class="icon-zoom-out"></i>
<div class="clearfix"></div>
Out
</button>
</div>
<div class="pull-right">
<button ng-click="updatePage(main.card.selectedPage)" class='btn mrs'>
<i class='icon-save'></i>
<div class='clearfix'></div>
Save <strong ng-if="Fabric.isUnsaved" class="text-error">*</strong>
</button>
<button ng-click="Fabric.resetZoom(); Fabric.download(main.card.selectedPage.name)" class='btn btn-success'>
<i class='icon-download'></i>
<div class='clearfix'></div>
Download
</button>
</div>
</div>
</div>
</div>
<div class="row-fluid mbm">
<div class="span12 form-inline">
<label>Name</label>
<input
type="text"
ng-change="Fabric.isUnsaved = true"
ng-model="main.card.selectedPage.name"
class="input-large mrm">
<label>Background Color</label>
<input type="text" class='input-small mrm' ng-change="Fabric.setCanvasBgColor(canvasFacade.background); Fabric.isUnsaved = true" ng-model="canvasFacade.background" colorpicker>
<label>Width</label>
<input
type='number'
ng-click="Fabric.resetZoom()"
ng-change="Fabric.setWidth(canvasFacade.width)"
ng-model="canvasFacade.width"
class='input-small mrm'>
<label>Height</label>
<input
type='number'
ng-click="Fabric.resetZoom()"
ng-change="Fabric.setHeight(canvasFacade.height); Fabric.isUnsaved = true"
ng-model="canvasFacade.height"
class='input-small mrm'>
<div class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
Preset Sizes
<span class="caret"></span>
</a>
<ul class="dropdown-menu pull-right">
<li
ng-click='setPresetSize(size)'
ng-repeat='size in ImagesService.exampleSizes'>
<a>{{ size.name }}</a>
</li>
</ul>
</div>
</div>
</div>
<div style="position: relative;">
<div style="position: absolute; z-index: 1; background: white; left: -250px; top: 0px; padding: 5px; width: 240px;" ng-if='Fabric.hasActiveObject() && Fabric.getSize() > 0'>
<div ng-switch='Fabric.getType()'>
<div ng-switch-when='text'>
<div class="row-fluid mbm">
<div class="span12">
<textarea
style="font-size: 12px; text-align: {{ Fabric.getTextAlign() }}"
class="input-full"
rows="6"
fabric-value="text"></textarea>
</div>
</div>
<div class="row-fluid mbm">
<div class="span12">
<p title="Font size">
<i class="icon-text-height"></i> <input type='number' class="input-mini" fabric-value="fontSize">
</p>
</div>
</div>
<div class="row-fluid mbm">
<div class="span12">
<p class="mbm" title="Line height">
<i class="icon-align-left"></i> <input type='number' class="input-mini" fabric-value="lineHeight" step=".1">
</p>
</div>
</div>
<div class='btn-group mbm'>
<button
ng-class="{ active: Fabric.getTextAlign() == 'Left' }"
ng-click="Fabric.setTextAlign('Left')"
class='btn btn-small'>
<i class='icon-align-left'></i>
</button>
<button
ng-class="{ active: Fabric.getTextAlign() == 'Center' }"
ng-click="Fabric.setTextAlign('Center')"
class='btn btn-small'>
<i class='icon-align-center'></i>
</button>
<button
ng-class="{ active: Fabric.getTextAlign() == 'Right' }"
ng-click="Fabric.setTextAlign('Right')"
class='btn btn-small'>
<i class='icon-align-right'></i>
</button>
</div>
<div class="clearfix"></div>
<div class='btn-group mbm'>
<button
ng-class="{ active: Fabric.isBold() }"
ng-click="Fabric.toggleBold()"
class='btn btn-small'>
<i class='icon-bold'></i>
</button>
<button
ng-class="{ active: Fabric.isItalic() }"
ng-click="Fabric.toggleItalic()"
class='btn btn-small'>
<i class='icon-italic'></i>
</button>
<button
ng-class="{ active: Fabric.isUnderline() }"
ng-click="Fabric.toggleUnderline()"
class='btn btn-small'>
<i class='icon-underline'></i>
</button>
<button
ng-class="{ active: Fabric.isLinethrough() }"
ng-click="Fabric.toggleLinethrough()"
class='btn btn-small'>
<i class='icon-strikethrough'></i>
</button>
</div>
<div class="clearfix"></div>
<div class="row-fluid">
<div class="btn-group mbm span12">
<a class="btn btn-small btn-block dropdown-toggle" data-toggle="dropdown" href="#">
<span style='text-transform: capitalize; font-family: "{{ Fabric.canvas.getActiveObject().fontFamily }}";'>{{ Fabric.canvas.getActiveObject().fontFamily }}</span>
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li
ng-repeat='font in ImagesService.fonts'
ng-click='Fabric.setFontFamily(font.name)'
style='font-family: "{{ font.name }}";'>
<a>{{ font.name }}</a>
</li>
</ul>
</div>
</div>
</div>
<div ng-switch-when="image">
<button
ng-class="{ active: Fabric.isTinted() }"
ng-click="Fabric.toggleTint()"
class='btn btn-small'>
<i class='icon-tint'></i>
</button>
<input
type="text"
class='input-small'
ng-change="Fabric.setTint(tint)"
ng-model="tint"
fabric-value="tint"
colorpicker>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<input
class='span12'
title="Transparency"
type='range'
min="0"
max="100"
step="1"
fabric-value="opacity">
</div>
</div>
<div class="row-fluid mbm">
<div class="span12">
<button
class='btn btn-small btn-block'
ng-class="{ active: Fabric.getFlipX() }"
ng-click="{ active: Fabric.toggleFlipX(true) }">
<i class='icon-exchange'></i> Flip
</button>
</div>
</div>
<div class="row-fluid mbm" ng-if="Fabric.getType() != 'image'">
<div class="span12">
<input
type="text"
class='input-small'
ng-change="Fabric.setFill(fill)"
ng-model="fill"
fabric-value="fill"
colorpicker>
</div>
</div>
<div class="row-fluid mbm">
<div class="btn-group span12 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>
<div class="row-fluid mbm">
<div class="btn-group span12 btn-group-vertical">
<button
ng-click='Fabric.bringToFront()'
class='btn btn-small btn-block'>
Bring to front
</button>
<button
ng-click='Fabric.bringForward()'
class='btn btn-small btn-block'>
Bring forwards
</button>
<button
ng-click='Fabric.sendBackwards()'
class='btn btn-small btn-block'>
Send backwards
</button>
<button
ng-click='Fabric.sendToBack()'
class='btn btn-small btn-block'>
Send to back
</button>
</div>
</div>
<div class="row-fluid mbm">
<button
ng-click='Fabric.toggleLockActiveObject()'
ng-class="{ active: Fabric.getActiveObject().lockObject }"
class='btn btn-small btn-block'>
Lock
</button>
</div>
</div>
</div>
<div class='image-builder' parent-click="Fabric.deactivateAll()">
<div class='fabric-container'>
<canvas fabric-canvas></canvas>
</div>
</div>
</div>
</div>
(function() {
'use strict';
angular.module('builders.images', [
'common.fabric',
'fabric.defaults'
])
.controller('ImagesCtrl', ['$scope', 'Api', '$localStorage', 'ImagesService', 'Modal', 'Fabric', '$timeout', '$interval', '$window', 'Keypress', function($scope, Api, $localStorage, ImagesService, Modal, Fabric, $timeout, $interval, $window, Keypress) {
$scope.ImagesService = ImagesService;
$scope.Fabric = Fabric;
ImagesService.setDefaults();
ImagesService.selectedShapeCategory = ImagesService.shapeCategories[0];
Fabric.setScope($scope);
Fabric.isUnsaved = false;
$localStorage.pageHistory = {};
$scope.canvasFacade = {};
$scope.selectPage = function(pageId) {
if (Fabric.isUnsaved && $scope.main.card.selectedPage !== undefined) {
toastr.error("Please save before changing pages.");
return;
}
$scope.pageId = pageId;
$scope.main.card.selectedPage = _.findWhere($scope.main.card.pages, { id: +pageId });
$scope.pageCopy = angular.copy($scope.main.card.selectedPage);
Fabric.loadJson(formatJson($scope.main.card.selectedPage.json), function() {
Fabric.canvas.on('object:added', function() {
Fabric.isUnsaved = true;
}).on('object:modified', function() {
Fabric.isUnsaved = true;
});
});
$localStorage.pageHistory['page' + $scope.main.card.selectedPage.id] = $localStorage.pageHistory['page' + $scope.main.card.selectedPage.id] || [];
$localStorage.pageHistory['page' + $scope.main.card.selectedPage.id].push({
date: moment(),
json: $scope.main.card.selectedPage.json
});
// Don't put this in a callback so the user can see the shape and color of the canvas while it loads.
Fabric.isUnsaved = false;
var page = $scope.main.card.selectedPage.json ? angular.fromJson($scope.main.card.selectedPage.json) : {};
Fabric.canvas.scale = page.scale || 1;
Fabric.setCanvasScale(Fabric.canvas.scale);
page.width = page.width || 300;
var staticWidth = Math.ceil(page.width * (1 / page.scale));
$scope.canvasFacade.width = staticWidth;
Fabric.canvas.setWidth(page.width);
page.height = page.height || 300;
var staticHeight = Math.ceil(page.height * (1 / page.scale));
$scope.canvasFacade.height = staticHeight;
Fabric.canvas.setHeight(page.height);
$scope.canvasFacade.background = page.background || '#ffffff';
Fabric.canvas.setBackgroundColor($scope.canvasFacade.background);
};
$scope.updatePage = function() {
Fabric.canvas.calcOffset();
var json = JSON.stringify(Fabric.canvas.toJSON(Fabric.jsonExportProperties));
$scope.main.card.selectedPage.json = json;
};
$scope.addShape = function(path) {
Fabric.addShape('/lib/svg/' + path + '.svg');
Modal.close();
};
$scope.addImage = function(image) {
Fabric.addImage('/image?image=' + image + '&size=full');
Modal.close();
};
$scope.addImageUpload = function(data) {
var obj = angular.fromJson(data);
toastr.info('Loading image...');
Fabric.addImage('/image?image=' + obj.filename + '&size=full');
Modal.close();
};
$scope.restart = function() {
$scope.canvasFacade.background = '#ffffff';
Fabric.clear();
Fabric.isUnsaved = true;
};
$interval(function() {
if (Fabric.isUnsaved) {
$scope.updatePage();
}
}, 60000 * 3);
var initCanvas = function() {
$scope.showCanvas = true;
Fabric.canvas.selection = false;
Fabric.canvas.on('object:selected', function() {
$scope.fill = Fabric.getFill();
$scope.tint = Fabric.getTint();
$scope.opacity = Fabric.getOpacity();
});
};
$scope.deactivateAll = function() {
Fabric.deactivateAll();
};
$scope.$watch(function(Fabric) {
if (!Fabric.canvas) {
return;
}
var object = Fabric.canvas.getActiveObject();
return object.type;
}, function() {
Fabric.render();
});
$scope.$on('canvas:created', initCanvas);
$timeout(function() {
Fabric.render();
}, 1000);
}])
.filter('reverse', [function() {
return function(items) {
if (items) {
return items.slice().reverse();
}
};
}]);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment