Skip to content

Instantly share code, notes, and snippets.

@rmaceissoft
Created August 23, 2014 04:28
Show Gist options
  • Save rmaceissoft/e5d18f54c201b53f575f to your computer and use it in GitHub Desktop.
Save rmaceissoft/e5d18f54c201b53f575f to your computer and use it in GitHub Desktop.
'use strict';
// Load Dependencies
var $ = require('jquery');
require('jquery-guillotine');
var angular = require('angular');
var _ = require('lodash');
var app = angular.module('pageApp', []);
app.directive('guillotine', ['$http', function($http) {
return {
scope: {},
restrict: 'E',
//replace: true,
template: require('./templates/guillotine.html'),
link: function(scope, elem, attrs, ctrl, transclude) {
var initX = scope.x = scope.$eval(attrs.initX) || 0;
var initY = scope.y = scope.$eval(attrs.initY) || 0;
var initScale = scope.scale = scope.$eval(attrs.initScale) || 1.0000;
var cropField = attrs.cropField;
scope.width = scope.$eval(attrs.width);
scope.height = scope.$eval(attrs.height);
scope.src = attrs.src;
scope.cropping = false;
var $img = elem.find('img');
$img.on('load', function() {
// initialize guillotine
$img.guillotine({
width: scope.width,
height: scope.height,
init: {x: scope.x, y: scope.y, scale: scope.scale},
onChange: function(data, action) {
var phase = scope.$root.$$phase;
// FIXME: for some reason I don't know, when action is not drag,
// phase is always equal to $apply and scope is not updated. I was
// checking how guillotine triggers the events and seems to be no error
// https://github.com/matiasgagliano/guillotine/blob/1.2.1/js/jquery.guillotine.js#L233
if (phase != '$apply' && phase != '$digest') {
scope.$apply(function() {
scope.y = data.y;
scope.x = data.x;
scope.scale = parseFloat(data.scale.toFixed(4));
});
}
}
});
$img.guillotine('disable');
});
scope.startCropping = function() {
scope.cropping = true;
$img.guillotine('enable');
}
scope.stopCropping = function() {
scope.cropping = false;
// TODO: find a way to revert coordinates before disable the plugin
// https://github.com/matiasgagliano/guillotine/issues/6
// $img.guillotine('setData', {x: initX, y: initY, scale: initScale});
$img.guillotine('disable');
}
scope.zoomIn = function() {
$img.guillotine('zoomIn');
}
scope.zoomOut = function() {
$img.guillotine('zoomOut');
}
scope.fit = function() {
$img.guillotine('fit');
}
scope.saveChanges = function() {
var data = $img.guillotine('getData');
var request = $http({
method: 'get',
url: '/accounts/ajax-save-crop-info/',
params: {
crop_field: cropField,
crop_info: [data.x, data.y, parseFloat(data.scale.toFixed(4))].join(";")
}
});
request.then(function() {
scope.cropping = false;
// update init coordinates
initX = data.x;
initY = data.y;
initScale = data.scale;
$img.guillotine('disable');
}, function() {
// TODO: handle error response
});
}
}
}
}]);
<div class="wrapper">
<div class="frame" style="width: 100%;">
<img src="{{ src }}" class="original-image img-responsive">
</div>
<div class="crop-actions-wrap top">
<a id="btn-crop" class="label label-primary" href="#" ng-hide="cropping" ng-click="startCropping($event)">
<i class="fa fa-pencil"></i> Edit Image</a>
<div class="crop-actions" ng-hide="!cropping" ng-cloak>
<a href="#" class="label label-primary" ng-click="zoomIn($event)">
<i class="fa fa-search-plus"></i> Zoom In</a>
<a href="#" class="label label-primary" ng-click="zoomOut($event)">
<i class="fa fa-search-minus"></i> Zoom Out</a>
<a href="#" class="label label-primary" ng-click="fit($event)"><i class="fa fa-arrows-alt"></i> Fit</a>
</div>
<div class="crop-info hidden">
<strong>X:</strong>{{ x }}
<strong>Y:</strong>{{ y }}
<strong>Scale:</strong>{{ scale }}
</div>
</div>
<div class="crop-actions-wrap bottom">
<div class="crop-actions" ng-hide="!cropping" ng-cloak>
<a href="#" class="btn btn-success btn-sm" ng-click="saveChanges($event)">Save Changes</a>
<a href="#" class="btn btn-danger btn-sm" ng-click="stopCropping($event)">Cancel</a>
</div>
</div>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment