ImageCropper Upload enabled
The cropper can now fully replace the upload datatype
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -12,4 +12,9 @@
|
||||
|
||||
.tipmenu:hover .tooltip a{
|
||||
color: white;
|
||||
}
|
||||
|
||||
.tipmenu .tooltip-inner{
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
}
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user