ImageCropper Upload enabled

The cropper can now fully replace the upload datatype
This commit is contained in:
perploug
2014-02-17 16:12:21 +01:00
parent a4b1b31a24
commit 2bd2f12831
21 changed files with 225 additions and 88 deletions

View File

@@ -47,6 +47,10 @@ angular.module("umbraco.directives.html")
var winHeight = $(window).height();
scope.$watch(function () {
if(!bar){
bar = $(".tab-content .active .umb-tab-buttons")[0] || $(".tab-content .umb-tab-buttons")[0];
}
var bottom = bar.offsetTop + bar.offsetHeight;
return bottom > winHeight;
}, function(val) {

View File

@@ -175,13 +175,7 @@ angular.module("umbraco.directives")
scope.dimensions.image.left = left;
scope.dimensions.image.top = top;
};
//sets scope.crop to the recalculated % based crop
var calculateCropBox = function(){
scope.crop = cropperHelper.pixelsToCoordinates(scope.dimensions.image, scope.dimensions.cropper.width, scope.dimensions.cropper.height, scope.dimensions.margin);

View File

@@ -60,14 +60,28 @@ angular.module("umbraco.directives")
scope.center.top = (scope.dimensions.top+10) / scope.dimensions.height;
};
var lazyEndEvent = _.debounce(function(){
scope.$apply(function(){
scope.$emit("imageFocalPointStop");
});
}, 2000);
//Drag and drop positioning, using jquery ui draggable
//TODO ensure that the point doesnt go outside the box
$overlay.draggable({
containment: "parent",
start: function(){
scope.$apply(function(){
scope.$emit("imageFocalPointStart");
});
},
stop: function() {
scope.$apply(function(){
calculateGravity();
});
lazyEndEvent();
}
});

View File

@@ -1,10 +1,31 @@
/**
* @ngdoc service
* @name umbraco.services.mediaHelper
* @description A helper object used for dealing with media items
* @name umbraco.services.cropperHelper
* @description A helper object used for dealing with image cropper data
**/
function cropperHelper(umbRequestHelper) {
function cropperHelper(umbRequestHelper, $http) {
var service = {
/**
* @ngdoc method
* @name umbraco.services.cropperHelper#configuration
* @methodOf umbraco.services.cropperHelper
*
* @description
* Returns a collection of plugins available to the tinyMCE editor
*
*/
configuration: function (mediaTypeAlias) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"imageCropperApiBaseUrl",
"GetConfiguration",
[{ mediaTypeAlias: mediaTypeAlias}])),
'Failed to retreive tinymce configuration');
},
//utill for getting either min/max aspect ratio to scale image after
calculateAspectRatioFit : function(srcWidth, srcHeight, maxWidth, maxHeight, maximize) {
var ratio = [maxWidth / srcWidth, maxHeight / srcHeight ];
@@ -31,10 +52,10 @@ function cropperHelper(umbRequestHelper) {
var coordinates_px = service.coordinatesToPixels(coordinates, originalSize, offset);
var _offset = offset || 0;
var x = coordinates.x1 + Math.abs(coordinates.x2);
var left_of_x = originalSize.width - (originalSize.width * x);
var x = 1 - (coordinates.x1 + Math.abs(coordinates.x2));
var left_of_x = originalSize.width * x;
var ratio = viewPort.width / left_of_x;
var style = {
position: "absolute",
top: -(coordinates_px.y1*ratio)+ _offset,
@@ -69,8 +90,9 @@ function cropperHelper(umbRequestHelper) {
var x1_px = Math.abs(image.left-offset);
var y1_px = Math.abs(image.top-offset);
var x2_px = (x1_px + width) - image.width;
var y2_px = (y1_px + height) - image.height;
var x2_px = image.width - (x1_px + width);
var y2_px = image.height - (y1_px + height);
//crop coordinates in %
var crop = {};

View File

@@ -1,21 +1,23 @@
// Animations
// -------------------------
.fade-hide, .fade-show {
.fade-hide, .fade-show , .fade-leave, .fade-enter {
-webkit-transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.3s;
-moz-transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.3s;
-o-transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.3s;
transition: all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.3s;
}
.fade-hide {
.fade-enter {
opacity: 1;
}
.fade-hide.fade-hide-active {
opacity: 0;
}
.fade-show {
.fade-leave {
opacity: 0;
}
.fade-show.fade-show-active {
opacity: 1;
}
@@ -63,6 +65,7 @@
display: block;
position: relative;
}
@-webkit-keyframes leave {
to {
opacity: 0;

View File

@@ -245,12 +245,13 @@ ul.color-picker li a {
}
.umb-cropper-gravity .overlay{
width: 26px;
height: 26px;
width: 14px;
height: 14px;
text-align: center;
border-radius: 20px;
opacity: 0.6;
background: white;
background: @blue;
border: 3px solid white;
opacity: 0.8;
}
.umb-cropper-gravity .overlay i{
@@ -312,6 +313,7 @@ ul.color-picker li a {
left: 0;
bottom: 0;
height: 100%;
width: 100%;
}

View File

@@ -12,4 +12,9 @@
.tipmenu:hover .tooltip a{
color: white;
}
.tipmenu .tooltip-inner{
margin-left:auto;
margin-right:auto;
}

View File

@@ -1,5 +1,4 @@
<div class="umb-cropper umb-editor" ng-show="src">
<div class="crop-container">
<div class="viewport" ng-style="style()">
<img src="{{src}}" ng-style="dimensions.image"/>

View File

@@ -4,7 +4,7 @@
<img src="{{src}}" style="max-width: 100%; max-height: 100%" />
<div class="overlay" ng-style="style()">
<i class="icon-crosshair"></i>
</div>
</div>

View File

@@ -1,57 +1,81 @@
//this controller simply tells the dialogs service to open a mediaPicker window
//with a specified callback, this callback will receive an object with a selection on it
angular.module('umbraco').controller("Umbraco.PropertyEditors.ImageCropperController",
function($rootScope, $scope, mediaHelper, $timeout, editorState) {
//check the pre-values for multi-picker
var multiPicker = $scope.model.config.multiPicker !== '0' ? true : false;
function($rootScope, $routeParams, $scope, mediaHelper, cropperHelper, $timeout, editorState, umbRequestHelper, fileManager) {
//used to reference the part of the data we will either crop or "point"
$scope.currentCrop = undefined;
$scope.currentPoint = undefined;
var imgPath = mediaHelper.getImagePropertyValue({imageModel: editorState.current});
cropperHelper.configuration("Image").then(function(config){
//move previously saved value to the editor
if($scope.model.value){
//backwards compat with the old file upload (incase some-one swaps them..)
if(angular.isString($scope.model.value)){
config.src = $scope.model.value;
$scope.model.value = config;
}
$scope.imageSrc = $scope.model.value.src;
}
//crop a specific crop
$scope.crop = function(crop){
$scope.currentCrop = crop;
$scope.currentPoint = undefined;
};
//done cropping
$scope.done = function(){
$scope.currentCrop = undefined;
$scope.currentPoint = undefined;
};
//crop a specific crop
$scope.clear = function(crop){
//clear current uploaded files
fileManager.setFiles($scope.model.alias, []);
//clear the ui
$scope.imageSrc = undefined;
if($scope.model.value.src){
delete $scope.model.value.src;
}
};
//Data sample
if(!$scope.model.value){
$scope.model.value = {
//image to crops
src: imgPath,
//show previews
$scope.togglePreviews = function(){
if($scope.showPreviews){
$scope.showPreviews = false;
$scope.tempShowPreviews = false;
}else{
$scope.showPreviews = true;
}
};
//global intrestpoint, used if no crop is specified
center: {left: 0.5, top: 0.4},
crops:{
thumbnail:
{
//crop dimensions
width: 100,
height: 100,
//crops in percentages
crop:{
"x1": 0.31731772342645215,
"y1": 0.17420325244997603,
"x2": -0.36246473116627076,
"y2": -0.30226197981593617
}
},
highrise:
{
width: 90,
height: 340
}
}
};
}
$scope.$on("imageFocalPointStart", function(){
$scope.tempShowPreviews = true;
});
$scope.$on("imageFocalPointStop", function(){
$scope.tempShowPreviews = false;
});
//on image selected, update the cropper
$scope.$on("filesSelected", function (ev, args) {
$scope.model.value = config;
if(args.files && args.files[0]){
fileManager.setFiles($scope.model.alias, args.files);
var reader = new FileReader();
reader.onload = function (e) {
$scope.$apply(function(){
$scope.imageSrc = e.target.result;
});
};
reader.readAsDataURL(args.files[0]);
}
});
});
});

View File

@@ -1,43 +1,57 @@
<div class="umb-editor umb-mediapicker"
ng-controller="Umbraco.PropertyEditors.ImageCropperController">
<span class="fileinput-button umb-upload-button-big"
style="margin-bottom: 5px;"
ng-hide="imageSrc">
<i class="icon icon-page-up"></i>
<p><localize key="media_clickToUpload">Click to upload</localize></p>
<umb-single-file-upload></umb-single-file-upload>
</span>
<div ng-if="model.value.src">
<div ng-if="imageSrc">
<div style="border-bottom: 1px solid #f8f8f8; padding-bottom: 10px; margin-bottom: 15px;">
<div ng-if="currentCrop">
<div>
<div style="margin-bottom: 10px">
<umb-image-crop
height="{{currentCrop.height}}"
width= "{{currentCrop.width}}"
crop="currentCrop.crop"
center="model.value.center"
src="model.value.src" />
crop="currentCrop.coordinates"
center="model.value.focalPoint"
src="imageSrc" />
</div>
<a href class="btn btn-success" ng-click="done()">Done</a>
</div>
<div ng-if="!currentCrop">
<umb-image-gravity
src="model.value.src"
center="model.value.center" />
<div>
<umb-image-gravity
src="imageSrc"
center="model.value.focalPoint" />
</div>
<a href class="btn btn-link" ng-click="clear()"><i class="icon-delete red"></i> Remove file</a></li>
<a href class="btn btn-link" ng-click="togglePreviews()"><i class="icon-picture"></i> Toggle crop previews</a></li>
</div>
</div>
<ul class="umb-sortable-thumbnails">
<ul ng-animate="'fade'" class="umb-sortable-thumbnails" ng-if="showPreviews || tempShowPreviews">
<li class="tipmenu" ng-repeat="(key,value) in model.value.crops">
<a href ng-click="crop(value)">
<umb-image-thumbnail
center="model.value.center"
crop="value.crop"
src="model.value.src"
center="model.value.focalPoint"
crop="value.coordinates"
src="imageSrc"
height="{{value.height}}"
width="{{value.width}}" />
</a>
<div class="tooltip bottom" ng-if="value.crop">
<div class="tooltip bottom" ng-if="value.coordinates">
<div class="tooltip-arrow"></div>
<div class="tooltip-inner">
<a href ng-click="value.crop = undefined">Reset</a>
<a href ng-click="value.coordinates = undefined">Reset</a>
</div>
</div>
</li>