mirror of
https://github.com/silverstripe/silverstripe-reports
synced 2024-08-26 04:25:54 +02:00
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@65351 467b73ca-7a2a-4603-9d3b-597d59a354a9
362 lines
14 KiB
JavaScript
362 lines
14 KiB
JavaScript
/**
|
|
* @author Mateusz
|
|
*/
|
|
ImageEditor.History = {
|
|
|
|
initialize: function() {
|
|
this.history = new Array();
|
|
this.historyPointer = -1;
|
|
this.isEnabled = true;
|
|
this.image = ImageEditor.Positioning.addBehaviour($('image'));
|
|
this.size = new Array();
|
|
this.fakeImage = $('fakeImg');
|
|
this.image = $('image');
|
|
this.adjust = new Array();
|
|
this.undo = ImageEditor.History.undo.bind(this);
|
|
this.redo = ImageEditor.History.redo.bind(this);
|
|
this.add = ImageEditor.History.add.bind(this);
|
|
this.addListeners = ImageEditor.History.addListeners.bind(this);
|
|
this.hasOperation = ImageEditor.History.hasOperation.bind(this);
|
|
this.isInHistory = ImageEditor.History.isInHistory.bind(this);
|
|
this.onImageLoad = ImageEditor.History.onImageLoad.bind(this);
|
|
this.removeLastOperation = ImageEditor.History.removeLastOperation.bind(this);
|
|
this.getOptimizedHistory = ImageEditor.History.getOptimizedHistory.bind(this);
|
|
this.addCrop = ImageEditor.History.addCrop.bind(this);
|
|
this.addResize = ImageEditor.History.addResize.bind(this);
|
|
this.addEffect = ImageEditor.History.addEffect.bind(this);
|
|
this.addAdjust = ImageEditor.History.addAdjust.bind(this);
|
|
this.enable = ImageEditor.History.enable.bind(this);
|
|
this.disable = ImageEditor.History.disable.bind(this);
|
|
this.clear = ImageEditor.History.clear.bind(this);
|
|
this.onlyResized = ImageEditor.History.onlyResized.bind(this);
|
|
this.optimizeOtherEffects = ImageEditor.History.optimizeOtherEffects.bind(this);
|
|
this.optimizeCrop = ImageEditor.History.optimizeCrop.bind(this);
|
|
this.optimizeResize = ImageEditor.History.optimizeResize.bind(this);
|
|
this.optimizeRotate = ImageEditor.History.optimizeRotate.bind(this);
|
|
this.checkSpecialOperation = ImageEditor.History.checkSpecialOperation.bind(this);
|
|
this.addListeners();
|
|
},
|
|
|
|
undo: function() {
|
|
if(this.isEnabled) {
|
|
if(this.historyPointer >= 1) {
|
|
var operation = this.history[this.historyPointer].operation;
|
|
this.checkSpecialOperation('undo',this.history[this.historyPointer]);
|
|
Event.observe('image','load',this.onImageLoad);
|
|
this.historyPointer = this.historyPointer - 1;
|
|
this.image.src = this.history[this.historyPointer].fileUrl;
|
|
} else {
|
|
ImageEditor.statusMessageWrapper.statusMessage("No more undo","bad");
|
|
}
|
|
}
|
|
},
|
|
|
|
redo: function() {
|
|
if(this.isEnabled) {
|
|
if(this.historyPointer < this.history.length-1) {
|
|
var operation = this.history[this.historyPointer+1].operation;
|
|
this.checkSpecialOperation('redo',this.history[this.historyPointer+1]);
|
|
Event.observe('image','load',this.onImageLoad);
|
|
this.historyPointer = this.historyPointer + 1;
|
|
this.image.src = this.history[this.historyPointer].fileUrl;
|
|
} else {
|
|
ImageEditor.statusMessageWrapper.statusMessage("No more redo","bad");
|
|
}
|
|
}
|
|
},
|
|
|
|
add: function(operation,url,additionalInfo) {
|
|
var imageWidth = isNaN(parseInt($('image').style.width)) ? Element.getDimensions($('image')).width : parseInt($('image').style.width);//IE hack
|
|
var imageHeight = isNaN(parseInt($('image').style.height)) ? Element.getDimensions($('image')).height : parseInt($('image').style.height);//IE hack
|
|
//code above should be moved to Positioning.addBehaviour
|
|
if(!this.isInHistory(operation,url)) {
|
|
this.historyPointer++;
|
|
this.size[this.historyPointer] = {'width': imageWidth,'height': imageHeight};
|
|
this.history[this.historyPointer] = {'operation': operation,'fileUrl' : url,'additionalInfo': additionalInfo};
|
|
this.size = this.size.slice(0,this.historyPointer+1);
|
|
this.history = this.history.slice(0,this.historyPointer+1);
|
|
}
|
|
},
|
|
|
|
addCrop: function(url,top,left,width,height) {
|
|
this.add('crop',url,{
|
|
'top':top,
|
|
'left': left,
|
|
'width': width,
|
|
'height': height
|
|
});
|
|
},
|
|
|
|
addResize: function(url,width,height) {
|
|
this.add('resize',url,{
|
|
'width': width,
|
|
'height': height
|
|
});
|
|
},
|
|
|
|
addEffect: function(url,name) {
|
|
this.add(name,url);
|
|
},
|
|
|
|
addAdjust: function(name,value,url) {
|
|
this.add(name,url,{'value': value});
|
|
if(this.adjust[name] == undefined) {
|
|
this.adjust[name] = {'pointer': 0,'values': Array()}
|
|
this.adjust[name].values[0] = ImageEditor.effects.getEffect(name).getDefaultValue();
|
|
}
|
|
this.adjust[name].values[this.adjust[name].values.length] = value;
|
|
this.adjust[name].pointer++;
|
|
},
|
|
|
|
addListeners: function() {
|
|
this.undoListener = Event.observe('UndoButton','click',this.undo);
|
|
this.redoListener = Event.observe('RedoButton','click',this.redo);
|
|
},
|
|
|
|
hasOperation: function(operation,historyPointer) {
|
|
if(historyPointer == undefined) historyPointer = this.history.length-1;
|
|
for(i=historyPointer;i>=0;i--) {
|
|
if(this.history[i].operation == operation) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
|
|
getOptimizedHistory: function(without) {
|
|
var history = this.history.slice(0,this.historyPointer+1);
|
|
var result = {};
|
|
var historyPointer = 1;
|
|
result[0] = {fileUrl : history[0].fileUrl};
|
|
var resize = this.optimizeResize(history,this.size);
|
|
var rotate = this.optimizeRotate(history);
|
|
var crop = this.optimizeCrop(history,this.size);
|
|
var other = this.optimizeOtherEffects(history,without);
|
|
if(rotate != undefined) {
|
|
for(var i =0;i<rotate.length;i++) {
|
|
result[historyPointer] = rotate[i];
|
|
historyPointer++;
|
|
}
|
|
}
|
|
if(resize != undefined){
|
|
result[historyPointer] = resize;
|
|
historyPointer++;
|
|
}
|
|
if(crop != undefined) {
|
|
result[historyPointer] = crop;
|
|
historyPointer++;
|
|
}
|
|
if(other != undefined) {
|
|
for(var i =0;i<other.length;i++) {
|
|
result[historyPointer] = other[i];
|
|
historyPointer++;
|
|
}
|
|
}
|
|
return result;
|
|
},
|
|
|
|
enable: function() {
|
|
this.isEnabled = true;
|
|
},
|
|
|
|
disable: function() {
|
|
this.isEnabled = false;
|
|
},
|
|
|
|
clear: function() {
|
|
this.history = new Array();
|
|
this.historyPointer = -1;
|
|
this.size = new Array();
|
|
},
|
|
|
|
removeLastOperation: function() {
|
|
this.history.pop();
|
|
this.size.pop();
|
|
this.historyPointer--;
|
|
},
|
|
|
|
isInHistory: function(operation,url) {
|
|
if(operation == 'initialize' && this.historyPointer != -1) return true;
|
|
for(var k=0;k<this.history.length;k++) {
|
|
if(this.history[k].operation == operation && this.history[k].fileUrl == url) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
|
|
onImageLoad: function(event) {
|
|
Event.stopObserving($('image'),'load',this.onImageLoad);
|
|
this.image.style.width = this.size[this.historyPointer].width + 'px';
|
|
this.image.style.height = this.size[this.historyPointer].height + 'px';
|
|
$('imageContainer').style.width = this.size[this.historyPointer].width + 'px';
|
|
$('imageContainer').style.height = this.size[this.historyPointer].height + 'px';
|
|
ImageEditor.resize.imageContainerResize.originalWidth = this.size[this.historyPointer].width;
|
|
ImageEditor.resize.imageContainerResize.originalHeight = this.size[this.historyPointer].height;
|
|
ImageEditor.imageToResize.onImageLoad();
|
|
},
|
|
|
|
onlyResized: function() {
|
|
for(i=this.historyPointer;i>=0;i--) {
|
|
if(this.history[i].operation != 'resize') {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
},
|
|
|
|
optimizeResize: function(history,size) {
|
|
var scallingXFactor = 1;var scallingYFactor = 1;
|
|
var initWidth = size[0].width;var initHeight = size[0].height;
|
|
for(var i=0;i<history.length && i < (this.historyPointer+1);i++) {
|
|
switch(history[i].operation) {
|
|
case 'resize':
|
|
if(i == 0) {
|
|
var previousWidth = 0;
|
|
var previousHeight = 0;
|
|
} else {
|
|
previousWidth = size[i-1].width;
|
|
previousHeight = size[i-1].height;
|
|
}
|
|
if(i != 0) {
|
|
scallingXFactor *= history[i].additionalInfo.width/previousWidth
|
|
scallingYFactor *= history[i].additionalInfo.height/previousHeight;
|
|
}
|
|
break;
|
|
case 'rotate':
|
|
var tempX = scallingXFactor;
|
|
scallingXFactor = scallingYFactor;
|
|
scallingYFactor = tempX;
|
|
|
|
var tempW = initWidth;
|
|
initWidth = initHeight;
|
|
initHeight = tempW;
|
|
break;
|
|
}
|
|
}
|
|
if(scallingXFactor != 1 || scallingYFactor != 1) return {'operation': 'resize','additionalInfo': {'width': initWidth*scallingXFactor,'height': initHeight*scallingYFactor}};
|
|
},
|
|
|
|
optimizeCrop: function(history,size) {
|
|
var imageWidth = size[0].width;var imageHeight = size[0].height;
|
|
var topCrop = 0;var leftCrop = 0;
|
|
var scallingXFactor = 1;var scallingYFactor = 1;
|
|
var crops = new Array();var cropNumber = 0;var resizeNumber = 0;
|
|
var lastResizeNumber = 0;
|
|
for(var i=0;i<history.length && i < (this.historyPointer+1);i++) {
|
|
switch(history[i].operation) {
|
|
case 'crop':
|
|
crops[cropNumber] = {
|
|
'width': history[i].additionalInfo.width, 'height': history[i].additionalInfo.height,
|
|
'top': history[i].additionalInfo.top, 'left': history[i].additionalInfo.left,
|
|
'parent': {'width': size[i-1].width,'height': size[i-1].height}
|
|
};
|
|
imageWidth = crops[cropNumber].width;
|
|
imageHeight = crops[cropNumber].height;
|
|
cropNumber++;
|
|
scallingXFactor = 1;scallingYFactor = 1;
|
|
break;
|
|
case 'resize':
|
|
if(crops.length != 0) {
|
|
resizeNumber++;
|
|
if(i == 0) {
|
|
var previousWidth = 0;
|
|
var previousHeight = 0;
|
|
} else {
|
|
previousWidth = size[i-1].width;
|
|
previousHeight = size[i-1].height;
|
|
}
|
|
if(i != 0) {
|
|
scallingXFactor = history[i].additionalInfo.width/previousWidth
|
|
scallingYFactor = history[i].additionalInfo.height/previousHeight;
|
|
}
|
|
for(var k=0;k<crops.length;k++) {
|
|
crops[k].top *= scallingYFactor;
|
|
crops[k].left *= scallingXFactor;
|
|
crops[k].parent.width *= scallingXFactor;
|
|
crops[k].parent.height *= scallingYFactor;
|
|
crops[k].width *= scallingXFactor;
|
|
crops[k].height *= scallingYFactor;
|
|
}
|
|
crops[cropNumber-1].width = history[i].additionalInfo.width;
|
|
crops[cropNumber-1].height = history[i].additionalInfo.height;
|
|
}
|
|
break;
|
|
case 'rotate':
|
|
if(crops.length != 0) {
|
|
for(var k = 0;k<crops.length;k++) {
|
|
var tempTop = crops[k].top;
|
|
crops[k].top = crops[k].parent.width - crops[k].width - crops[k].left;
|
|
crops[k].left = tempTop;
|
|
|
|
tempWidth = crops[k].parent.width;
|
|
crops[k].parent.width = crops[k].parent.height;
|
|
crops[k].parent.height = tempWidth;
|
|
|
|
var tempWidth = crops[k].width;
|
|
crops[k].width = crops[k].height;
|
|
crops[k].height = tempWidth;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
for(var l=0;l<crops.length;l++) {
|
|
topCrop += crops[l].top;
|
|
leftCrop += crops[l].left;
|
|
}
|
|
if(cropNumber == 0) return;
|
|
if((topCrop + leftCrop + crops[cropNumber-1].width + crops[cropNumber-1].height) == 0) return;
|
|
return {'operation': 'crop','additionalInfo': {'top': topCrop,'left': leftCrop,'width': crops[cropNumber-1].width,'height': crops[cropNumber-1].height}};
|
|
},
|
|
|
|
optimizeOtherEffects: function(history,without) {
|
|
var result = Array();var effectsNumber = 0;var isInResult = false;
|
|
for(var i=0;i<history.length;i++) {
|
|
if(history[i].operation == 'resize' || history[i].operation == 'crop' || history[i].operation == 'rotate' || history[i].operation == without) continue;
|
|
if(history[i].operation.indexOf('adjust') != -1) {
|
|
isInResult = false;
|
|
for(var k=0;k<result.length;k++) {
|
|
if(result[k].operation == history[i].operation) {
|
|
result[k] = history[i];
|
|
isInResult = true;
|
|
}
|
|
}
|
|
if(!isInResult) {
|
|
result[effectsNumber] = history[i];
|
|
effectsNumber++;
|
|
}
|
|
} else {
|
|
result[effectsNumber] = history[i];
|
|
effectsNumber++;
|
|
}
|
|
}
|
|
return result;
|
|
},
|
|
|
|
optimizeRotate: function(history) {
|
|
var result = Array();var rotateNumber = 0;var rotate;
|
|
for(var i=0;i<history.length;i++) {
|
|
if(history[i].operation.indexOf('rotate') != -1) {
|
|
rotateNumber++;
|
|
rotate = history[i];
|
|
}
|
|
}
|
|
rotateNumber = rotateNumber % 4;
|
|
for(var i=0;i<rotateNumber;i++) {
|
|
result[result.length] = rotate;
|
|
}
|
|
return result.length == 0 ? undefined : result;
|
|
},
|
|
|
|
checkSpecialOperation: function(operationType,historyEntry) {
|
|
if(this.adjust[historyEntry.operation] != undefined) {
|
|
if(operationType == 'undo') {
|
|
if(this.adjust[historyEntry.operation].pointer > 0) this.adjust[historyEntry.operation].pointer--;
|
|
} else {
|
|
this.adjust[historyEntry.operation].pointer++;
|
|
}
|
|
ImageEditor.effects.getEffect(historyEntry.operation).setValue(this.adjust[historyEntry.operation].values[this.adjust[historyEntry.operation].pointer]);
|
|
}
|
|
}
|
|
}; |