@@ -14,7 +14,8 @@ angular.module("umbraco.directives")
|
||||
templateUrl: 'views/components/imaging/umb-image-gravity.html',
|
||||
scope: {
|
||||
src: '=',
|
||||
center: "="
|
||||
center: "=",
|
||||
onImageLoaded: "="
|
||||
},
|
||||
link: function(scope, element, attrs) {
|
||||
|
||||
@@ -26,6 +27,8 @@ angular.module("umbraco.directives")
|
||||
top: 0
|
||||
};
|
||||
|
||||
scope.loaded = false;
|
||||
|
||||
//elements
|
||||
var $viewport = element.find(".viewport");
|
||||
var $image = element.find("img");
|
||||
@@ -42,6 +45,19 @@ angular.module("umbraco.directives")
|
||||
};
|
||||
};
|
||||
|
||||
scope.setFocalPoint = function(event) {
|
||||
|
||||
scope.$emit("imageFocalPointStart");
|
||||
|
||||
var offsetX = event.offsetX - 10;
|
||||
var offsetY = event.offsetY - 10;
|
||||
|
||||
calculateGravity(offsetX, offsetY);
|
||||
|
||||
lazyEndEvent();
|
||||
|
||||
};
|
||||
|
||||
var setDimensions = function(){
|
||||
scope.dimensions.width = $image.width();
|
||||
scope.dimensions.height = $image.height();
|
||||
@@ -54,9 +70,9 @@ angular.module("umbraco.directives")
|
||||
}
|
||||
};
|
||||
|
||||
var calculateGravity = function(){
|
||||
scope.dimensions.left = $overlay[0].offsetLeft;
|
||||
scope.dimensions.top = $overlay[0].offsetTop;
|
||||
var calculateGravity = function(offsetX, offsetY){
|
||||
scope.dimensions.left = offsetX;
|
||||
scope.dimensions.top = offsetY;
|
||||
|
||||
scope.center.left = (scope.dimensions.left+10) / scope.dimensions.width;
|
||||
scope.center.top = (scope.dimensions.top+10) / scope.dimensions.height;
|
||||
@@ -80,7 +96,9 @@ angular.module("umbraco.directives")
|
||||
},
|
||||
stop: function() {
|
||||
scope.$apply(function(){
|
||||
calculateGravity();
|
||||
var offsetX = $overlay[0].offsetLeft;
|
||||
var offsetY = $overlay[0].offsetTop;
|
||||
calculateGravity(offsetX, offsetY);
|
||||
});
|
||||
|
||||
lazyEndEvent();
|
||||
@@ -91,8 +109,26 @@ angular.module("umbraco.directives")
|
||||
$image.load(function(){
|
||||
$timeout(function(){
|
||||
setDimensions();
|
||||
scope.loaded = true;
|
||||
scope.onImageLoaded();
|
||||
});
|
||||
});
|
||||
|
||||
$(window).on('resize.umbImageGravity', function(){
|
||||
scope.$apply(function(){
|
||||
$timeout(function(){
|
||||
setDimensions();
|
||||
});
|
||||
var offsetX = $overlay[0].offsetLeft;
|
||||
var offsetY = $overlay[0].offsetTop;
|
||||
calculateGravity(offsetX, offsetY);
|
||||
});
|
||||
});
|
||||
|
||||
scope.$on('$destroy', function() {
|
||||
$(window).off('.umbImageGravity');
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -26,6 +26,7 @@ angular.module("umbraco.directives")
|
||||
link: function(scope, element, attrs) {
|
||||
//// INIT /////
|
||||
var $image = element.find("img");
|
||||
scope.loaded = false;
|
||||
|
||||
$image.load(function(){
|
||||
$timeout(function(){
|
||||
@@ -52,6 +53,7 @@ angular.module("umbraco.directives")
|
||||
}
|
||||
|
||||
setPreviewStyle();
|
||||
scope.loaded = true;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -275,11 +275,12 @@ ul.color-picker li a {
|
||||
|
||||
.umb-cropper{
|
||||
position: relative;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.umb-cropper img, .umb-cropper-gravity img{
|
||||
position: absolute;
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
@@ -293,19 +294,22 @@ ul.color-picker li a {
|
||||
left: 0;
|
||||
cursor: move;
|
||||
z-index: 6001;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.umb-cropper .viewport{
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
margin: auto;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.umb-cropper-gravity .viewport{
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 400px;
|
||||
height: 300px
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
@@ -335,27 +339,45 @@ ul.color-picker li a {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.umb-cropper-gravity .overlay i{
|
||||
.umb-cropper-gravity .overlay i {
|
||||
font-size: 26px;
|
||||
line-height: 26px;
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
|
||||
.umb-cropper .crop-container{
|
||||
.umb-cropper .crop-container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.umb-cropper .crop-slider{
|
||||
vertical-align: middle;
|
||||
padding: 10px 50px 10px 50px;
|
||||
.umb-cropper .crop-slider {
|
||||
padding: 10px;
|
||||
border-top: 1px solid @grayLighter;
|
||||
margin-top: 10px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
flex-wrap: wrap;
|
||||
|
||||
@media (min-width: 769px) {
|
||||
padding: 10px 50px 10px 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-cropper .crop-slider i{color: @gray;}
|
||||
.umb-cropper .crop-slider input{
|
||||
margin-top: 7px;
|
||||
width: 320px;
|
||||
.umb-cropper .crop-slider i {
|
||||
color: @gray;
|
||||
flex: 0 0 25px;
|
||||
padding: 0 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.umb-cropper .crop-slider i:first-of-type {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.umb-cropper .crop-slider input {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
.umb-cropper-gravity .viewport, .umb-cropper-gravity, .umb-cropper-imageholder {
|
||||
display: inline-block;
|
||||
@@ -372,55 +394,98 @@ ul.color-picker li a {
|
||||
}
|
||||
|
||||
.gravity-container .viewport {
|
||||
width: 494px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.gravity-container .viewport:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.imagecropper {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
flex-direction: row;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
flex-direction: column;
|
||||
float: left;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.imagecropper .umb-cropper__container {
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
max-width: 100%;
|
||||
border: 1px solid #f8f8f8;
|
||||
|
||||
@media (min-width: 769px) {
|
||||
width: 600px;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-close-cropper {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.umb-close-cropper:hover {
|
||||
opacity: .9;
|
||||
background: @grayLighter;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails {
|
||||
border-left: 2px solid #f8f8f8;
|
||||
margin-left: 4px;
|
||||
padding-left: 2px;
|
||||
float: left;
|
||||
width: 100px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li {
|
||||
display: block;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li.current a, .imagecropper .umb-sortable-thumbnails li.current a:hover {
|
||||
background: #eeeeee;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li:first-of-type {
|
||||
padding: 8px;
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li .crop-name, .imagecropper .umb-sortable-thumbnails li .crop-size {
|
||||
.imagecropper .umb-sortable-thumbnails li.current {
|
||||
border-color: @grayLight;
|
||||
background: @grayLighter;
|
||||
color: @black;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li:hover,
|
||||
.imagecropper .umb-sortable-thumbnails li.current:hover {
|
||||
border-color: @grayLight;
|
||||
background: @grayLighter;
|
||||
color: @black;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
opacity: .95;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li .crop-name,
|
||||
.imagecropper .umb-sortable-thumbnails li .crop-size {
|
||||
display: block;
|
||||
text-align: left;
|
||||
font-size: 11px;
|
||||
font-size: 13px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li .crop-name {
|
||||
font-weight: bold;
|
||||
margin: 10px 0 5px;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li .crop-size {
|
||||
font-size: 10px;
|
||||
font-style: italic;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li a {
|
||||
display: block;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li a:hover {
|
||||
background: #f8f8f8;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails li a:hover .crop-text {
|
||||
text-decoration: none;
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
|
||||
.btn-crop-delete {
|
||||
@@ -428,20 +493,6 @@ ul.color-picker li a {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails.many {
|
||||
width: 210px;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails.many li {
|
||||
width: 85px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.imagecropper .umb-sortable-thumbnails.many li:nth-child(2) {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
//
|
||||
// folder-browser
|
||||
// --------------------------------------------------
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<div class="umb-cropper-gravity">
|
||||
<div class="gravity-container">
|
||||
<div class="gravity-container" ng-show="loaded">
|
||||
<div class="viewport">
|
||||
<img ng-src="{{src}}" style="max-width: 100%; max-height: 100%" />
|
||||
<img ng-src="{{src}}" style="max-width: 100%; max-height: 100%" ng-click="setFocalPoint($event)" draggable="false" />
|
||||
|
||||
<div class="overlay" ng-style="style()">
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<div class="umb-crop-thumbnail-container"
|
||||
ng-style="{height: height, width: width, overflow: 'hidden', position: 'relative'}">
|
||||
<div class="umb-crop-thumbnail-container"
|
||||
ng-style="{height: height, width: width, overflow: 'hidden', position: 'relative'}"
|
||||
ng-show="loaded">
|
||||
<img ng-src="{{src}}" alt="{{}}" ng-style="preview" class="noScale" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,7 @@ angular.module('umbraco')
|
||||
function ($rootScope, $routeParams, $scope, $log, mediaHelper, cropperHelper, $timeout, editorState, umbRequestHelper, fileManager, angularHelper) {
|
||||
|
||||
var config = angular.copy($scope.model.config);
|
||||
$scope.imageIsLoaded = false;
|
||||
|
||||
//move previously saved value to the editor
|
||||
if ($scope.model.value) {
|
||||
@@ -71,6 +72,10 @@ angular.module('umbraco')
|
||||
}
|
||||
};
|
||||
|
||||
$scope.imageLoaded = function() {
|
||||
$scope.imageIsLoaded = true;
|
||||
};
|
||||
|
||||
//on image selected, update the cropper
|
||||
$scope.$on("filesSelected", function (ev, args) {
|
||||
$scope.model.value = config;
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
<div class="imagecropper clearfix">
|
||||
|
||||
<div ng-if="currentCrop" style="float:left;" class="clearfix">
|
||||
<div style="position: relative; margin-bottom: 10px; width: 492px; border: 1px solid #f8f8f8;">
|
||||
<div ng-if="currentCrop" style="float:left; max-width: 100%;" class="clearfix">
|
||||
<div class="umb-cropper__container">
|
||||
|
||||
<i ng-click="done()" style="opacity: 0.5; position: absolute; top: 3px; right: 3px" class="icon icon-delete btn-round"></i>
|
||||
<i ng-click="done()" class="icon icon-delete btn-round umb-close-cropper"></i>
|
||||
|
||||
<div>
|
||||
<umb-image-crop height="{{currentCrop.height}}"
|
||||
@@ -27,7 +27,8 @@
|
||||
crop="currentCrop.coordinates"
|
||||
center="model.value.focalPoint"
|
||||
max-size="450"
|
||||
src="imageSrc" />
|
||||
src="imageSrc">
|
||||
</umb-image-crop>
|
||||
</div>
|
||||
|
||||
<a href style="margin:auto; text-align: center; font-size: 11px;" class="btn btn-link red"
|
||||
@@ -36,30 +37,36 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="!currentCrop" class="umb-cropper-imageholder clearfix">
|
||||
<umb-image-gravity src="imageSrc"
|
||||
center="model.value.focalPoint" />
|
||||
<umb-image-gravity
|
||||
src="imageSrc"
|
||||
center="model.value.focalPoint"
|
||||
on-image-loaded="imageLoaded">
|
||||
</umb-image-gravity>
|
||||
<a href class="btn btn-link btn-crop-delete" ng-show="imageIsLoaded" ng-click="clear()"><i class="icon-delete red"></i> <localize key="content_uploadClear">Remove file</localize></a>
|
||||
</div>
|
||||
|
||||
<ul class="umb-sortable-thumbnails cropList clearfix" ng-class="{'many':model.value.crops.length >= 4}">
|
||||
<li ng-repeat=" (key,value) in model.value.crops" ng-class="{'current':currentCrop.alias === value.alias}">
|
||||
<a href title="{{value.alias}}: {{value.width}}px x {{value.height}}px" ng-click="crop(value)">
|
||||
<umb-image-thumbnail center="model.value.focalPoint"
|
||||
crop="value.coordinates"
|
||||
src="imageSrc"
|
||||
height="{{value.height}}"
|
||||
width="{{value.width}}"
|
||||
max-size="75"></umb-image-thumbnail>
|
||||
<ul class="umb-sortable-thumbnails cropList clearfix">
|
||||
<li ng-repeat=" (key,value) in model.value.crops" ng-class="{'current':currentCrop.alias === value.alias}" ng-click="crop(value)">
|
||||
|
||||
<umb-image-thumbnail center="model.value.focalPoint"
|
||||
crop="value.coordinates"
|
||||
src="imageSrc"
|
||||
height="{{value.height}}"
|
||||
width="{{value.width}}"
|
||||
max-size="75">
|
||||
</umb-image-thumbnail>
|
||||
|
||||
<div class="crop-information">
|
||||
<span class="crop-name crop-text">{{value.alias}}</span>
|
||||
<span class="crop-size crop-text">{{value.width}}px x {{value.height}}px</span>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
<a href class="btn btn-link btn-crop-delete" ng-click="clear()"><i class="icon-delete red"></i> <localize key="content_uploadClear">Remove file</localize></a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user