Reputation: 6701
I am using angularjs and html2canvas for capturing a screenshot. It captures well some times on few screens and doesn't some times. I get the following error:
tried Angular changes urls to "unsafe:" in extension page and added the following in my config.js
app.config(['$compileProvider', function ($compileProvider) {
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|local|data):/);
}]);
It helped to the extent that i am not getting the unsafe:data; error any more on click of my image capture button, but the image is not getting captured as well. Now the html tag looks as below:
<img ng-src="data:," class="img-responsive" src="data:,">
instead of the actual base64 url for my image/png (e.g: <img ng-src="data:image/png;base64,Mybase64Url
).
I have added ng-csp directive in my index.html and changed every <img src="">
to <img ng-src="">
.
camera-form.html:
<form name="captureForm" ng-submit="ctrl.save()">
<div class="modal-header">
<h3 class="modal-title">Captured Screen shot</h3>
</div>
<div class="modal-body">
<div class="container-fluid padding">
<div class="row">
<div class="col-sm-8">
<img ng-src="{{ctrl.imageURL}}" class="img-responsive" id="capturedImage">
</div>
<div class="col-sm-4">
<div class="form-group">
<input placeholder="Title" name="title" required class="form-control" ng-model="ctrl.title">
<div ng-show="captureForm.$submitted || captureForm.title.$dirty"
ng-messages="captureForm.title.$error">
<div ng-message="required">Title is required</div>
</div>
</div>
<div class="form-group">
<select name="category" ng-model="ctrl.category" class="form-control" required>
<option value="1">Knowledge</option>
<option value="2">Irregular</option>
<option value="3">Periodic maintenance</option>
</select>
<div ng-show="captureForm.$submitted || captureForm.category.$dirty"
ng-messages="captureForm.category.$error">
<div ng-message="required">Category is required</div>
</div>
</div>
<div class="form-group">
<textarea placeholder="Comment" name="comment" required class="form-control"
ng-model="ctrl.comment"></textarea>
<div ng-show="captureForm.$submitted || captureForm.comment.$dirty"
ng-messages="captureForm.comment.$error">
<div ng-message="required">Comment is required</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-info" value="Save">
<a href ng-click="ctrl.cancel()" class="btn btn-danger">Cancel</a>
</div>
</form>
camera.directive.js:
(function () {
'use strict';
angular
.module('myModule')
.directive('camera', camera);
camera.$inject = ['$rootScope'];
/* @ngInject */
function camera($rootScope) {
var directive = {
link: link,
restrict: 'A'
};
return directive;
function link(scope, element, attrs) {
$rootScope.$on('capture', function (event, deferred) {
event.stopPropagation();
renderSvg(element);
//method to render the SVG's using canvg
function renderSvg(element) {
// First render all SVGs to canvases
var elements = element.find('svg').map(function () {
var svg = $(this);
var canvas = $('<canvas></canvas>');
svg.replaceWith(canvas);
// Get the raw SVG string and curate it
var content = svg.wrap('<p></p>').parent().html();
content = content.replace(/xlink:title="hide\/show"/g, "");
content = encodeURIComponent(content);
svg.unwrap();
// Create an image from the svg
var image = new Image();
image.src = 'data:image/svg+xml,' + content;
image.onload = function () {
canvas[0].width = image.width;
canvas[0].height = image.height;
// Render the image to the canvas
var context = canvas[0].getContext('2d');
context.drawImage(image, 0, 0);
};
return {
svg: svg,
canvas: canvas
};
});
// At this point the container has no SVG, it only has HTML and Canvases.
html2canvas(element[0], {
useCORS: true,
allowTaint: true,
onrendered: function (canvas) {
// Put the SVGs back in place
elements.each(function () {
this.canvas.replaceWith(this.svg);
});
var dataURL = null;
try {
dataURL = canvas.toDataURL("image/png", 0.9);
deferred.resolve(dataURL);
}
catch (e) {
deferred.reject(e);
}
}
});
}
});
}
}
})();
camera.controller.js:
/**
* CameraController.js
*/
(function () {
'use strict';
angular
.module('myModule')
.controller('CameraController', CameraController);
CameraController.$inject = ['$rootScope', 'cabinetService', 'SweetAlert', 'growl', '$q', '$uibModal', 'spinner'];
function CameraController($scope, cabinetService, SweetAlert, growl, $q, $uibModal, spinner) {
var ctrl = this;
ctrl.captureScreenShot = captureScreenShot;
function captureScreenShot($event) {
var deferred = $q.defer();
$scope.$emit('capture', deferred);
deferred.promise.then(uploadScreenShot);
}
function uploadScreenShot(imageURL) {
var modalInstance = $uibModal.open({
animation: true,
templateUrl: 'app/components/capture/camera-form.html',
controller: ModalCtrl,
controllerAs: 'ctrl',
size: 'lg',
resolve: {
imageURL: function () {
return imageURL;
}
}
});
modalInstance.result.then(function (captureData) {
var data = {
Base64Url: captureData.image.split(',')[1],
Title: captureData.title,
FileCategory:parseInt(captureData.category),
Comment: captureData.comment,
FunctionalityName: $scope.$state.current.name
};
spinner.spinnerShow();
//call the service to upload the screen shot
cabinetService
.uploadScreenShot(data)
.then(function (data) {
SweetAlert.swal({
title: 'Screen shot saved successfully!',
text: '',
type: 'info',
showCancelButton: true,
confirmButtonColor: '#DD6B55',
confirmButtonText: 'Open cabinet',
closeOnConfirm: true
},
function (isConfirm) {
if (isConfirm) {
$scope.$state.go('index.cabinet')
}
});
})
.catch(function (err) {
SweetAlert.swal("Cannot capture the screen shot", "Something went wrong, please try again !", "error");
growl.err('Unable to upload the screen shot', {ttl: 20000});
})
.finally(spinner.spinnerHide);
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
}
}
ModalCtrl.$inject = ['$scope', '$uibModalInstance', 'imageURL', 'growl'];
function ModalCtrl($scope, $uibModalInstance, imageURL, growl) {
var ctrl = this;
ctrl.imageURL = imageURL;
ctrl.save = save;
ctrl.cancel = cancel;
function activate() {
}
function save() {
var form = $scope.captureForm;
if (form.$dirty && form.$valid) {
$uibModalInstance.close({
image: imageURL,
title: ctrl.title,
comment: ctrl.comment,
category: ctrl.category
});
} else {
growl.info('Please fill out all the fields');
}
}
function cancel() {
$uibModalInstance.dismiss();
}
}
}());
Is there anything i need to do with the above regular expression or i am missing something else ? please help !
Upvotes: 1
Views: 2436
Reputation: 6701
For some reason , the element that's being passed as $event parameter on click is not passing the right div element every time. Instead passed the exact div element i wanted in the place of element and it worked.
Upvotes: 0
Reputation: 1067
Hi you need to alter image src attribute with jquery as
$("#canvas_image").attr("src", canvasdata);
I have tried with this Plunker
Within this plunker I have added directive as well if you want to utilize it.
Upvotes: 1