Sunday, September 8, 2013

AngularJs and FabricJs: Fabric.canvas changes behavior once code is moved to a Angular Directive

AngularJs and FabricJs: Fabric.canvas changes behavior once code is moved
to a Angular Directive

I have a simple AngularJS / FabricJs application, the intent is to allow
an image to be moved /re-sized prior to upload. Essentially four steps:
1) I present a form with a canvas, and a rectangle inside of form to
represent a clip area
2) browse for a local file
3) add it to the canvas
4) and have a button to capture the clip area inside of the canvas
The problem occurs when I move the code from a directly embedded form to
sitting behind an angular directive. Once I moved the form into the
directive an issue popped up, the image is loaded and added to the canvas
without (any obvious) issues. However once you click anywhere on the
canvas (for instance, in an attempt to move the image) the image you added
no longer appears on the canvas (although inspection of the fabricJs
Canvas object still shows it as inside of its object array).
The JS App and Controller:
var myApp = angular.module('myApp', [])
// helper function to bind tot he on change of a input/file object
(angularJs workaround)
var invokeImageChange = function(that) {
angular.element(that).scope().imageChange(that)
angular.element(that).scope().$digest();
}
var ImageCtrl = function($scope) {
var desiredHeight = 300
var desiredWidth = 770
// I understand this docucment.gelElementById is not the angular way -
and needs to be changed
var myImageData = document.getElementById('fileData')
var myImage = document.getElementById('myImage')
var canvas = new fabric.Canvas('myCanvas')
var rect = new fabric.Rect({
fill: 'lightgray',
left: canvas.width / 2,
top: canvas.height / 2,
width: desiredWidth,
height: desiredHeight,
stroke: 'darkgray',
strokeDashArray: [5, 5],
selectable: false
});
canvas.add(rect)
var clipZone = {
y: rect.top - (.5 * rect.height),
x: rect.left - (.5 * rect.width),
width: desiredWidth,
height: desiredHeight,
quality: 1
}
$scope.caption = "" ;
$scope.fileUrl = "" ;
$scope.imageChange = function(inp) {
console.log('imageChange')
file = inp.files[0];
fr = new FileReader();
fr.onload = createImage;
fr.readAsDataURL(file);
var img = null
function createImage() {
console.log('createImage')
img = new Image();
img.onload = imageLoaded;
img.src = fr.result;
}
function imageLoaded() {
console.log('imageLoaded')
var fabImg = new fabric.Image(img)
fabImg.scale(1.0).set({
left: canvas.width / 2,
top: canvas.height / 2
});
canvas.add(fabImg)
canvas.setActiveObject(fabImg)
}
}
$scope.submit = function(event) {
}
$scope.capture = function() {
console.log('capture')
console.log($scope.file)
var active = canvas.getActiveObject()
canvas.deactivateAll()
var data = canvas.toDataURLWithCropping(
'png', clipZone)
myImageData.value = data
myImage.src = data
canvas.setActiveObject(active)
}
}
The Directive code:
myApp.directive('ngImageEditor', function() {
return {
restrict: 'E',
transclude: true,
replace: true,
controller: 'ImageCtrl',
templateUrl: '\blah\pathToForm'
};
});
where the TemplateUrl refers to this form
<form name="uploadForm" ng-controller="ImageCtrl" method="post"
enctype="multipart/form-data"
action="/main/update" ng-submit="submit()">
<div class="control-group">
<label class="control-label" for="file">Image File</label>
<div class="controls">
<input type="file" name="file" ng-model="file"
onchange="invokeImageChange(this)"/>
<input type="text" id="fileData" name="fileData"
ng-model="fileUrl"/>
</div>
</div>
<div class="control-group">
<div class="controls">
<input type="button" value="Upload" ng-click="capture()"/>
</div>
</div>
<div>
<canvas id="myCanvas" width="800" height="400" style="border:1px
solid #000000;"></canvas>
</div>
<img id="myImage" style="border: 1px solid burlywood">
</form>
Hopefully the JsFiddle below helps folks understand what I am talking
about. Thanks in advance!
To reproduce
1) browse to an image
2) move the image (notice the image disappears in the second link)
Working (image can be moved) (without directive):
http://jsfiddle.net/PNwbp/1/
Broken / Issues (image disappears when moved) (with directive):
http://jsfiddle.net/faFVW/23/

No comments:

Post a Comment