mirror of
https://github.com/silverstripe/silverstripe-reports
synced 2024-10-22 11:05:53 +02:00
mujma: All PHP and JS files for ImageEditor?, works on FF 1.5/2.0.
(merged from branches/gsoc) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@41872 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
a3d8e8c9e2
commit
bd58e931bb
@ -15,9 +15,10 @@ Director::addRules(100, array(
|
|||||||
'admin/comments/$Action' => 'CommentAdmin',
|
'admin/comments/$Action' => 'CommentAdmin',
|
||||||
'admin/ReportField/$Action/$ID/$Type/$OtherID' => 'ReportField_Controller',
|
'admin/ReportField/$Action/$ID/$Type/$OtherID' => 'ReportField_Controller',
|
||||||
'admin/bulkload/$Action/$ID/$OtherID' => 'BulkLoaderAdmin',
|
'admin/bulkload/$Action/$ID/$OtherID' => 'BulkLoaderAdmin',
|
||||||
|
'admin/ImageEditor/$Action' => 'ImageEditor',
|
||||||
'admin/$Action/$ID/$OtherID' => 'CMSMain',
|
'admin/$Action/$ID/$OtherID' => 'CMSMain',
|
||||||
'unsubscribe/$Email/$MailingList' => 'Unsubscribe_Controller',
|
'unsubscribe/$Email/$MailingList' => 'Unsubscribe_Controller',
|
||||||
'membercontrolpanel/$Email' => 'MemberControlPanel'
|
'membercontrolpanel/$Email' => 'MemberControlPanel'
|
||||||
));
|
));
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -11,6 +11,7 @@ class AssetTableField extends ComplexTableField {
|
|||||||
|
|
||||||
$this->sourceSort = "Title";
|
$this->sourceSort = "Title";
|
||||||
$this->Markable = true;
|
$this->Markable = true;
|
||||||
|
Requirements::javascript("cms/javascript/ImageEditor/Activator.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
function setFolder($folder) {
|
function setFolder($folder) {
|
||||||
@ -85,7 +86,8 @@ class AssetTableField extends ComplexTableField {
|
|||||||
$detailFormFields->addFieldToTab("BottomRoot",
|
$detailFormFields->addFieldToTab("BottomRoot",
|
||||||
new Tab("Image",
|
new Tab("Image",
|
||||||
new LiteralField("ImageFull",
|
new LiteralField("ImageFull",
|
||||||
"<img src='{$thumbnail}' alt='{$childData->Name}' />"
|
'<a id="ImageEditorActivator" href="javascript: void(0)">' . "<img id='thumbnailImage' src='{$thumbnail}' alt='{$childData->Name}' />" . '</a>' .
|
||||||
|
'<script type="text/javascript" src="cms/javascript/ImageEditor/Activator.js"></script><script type="text/javascript">imageActivator = new ImageEditorActivator.initialize();Event.observe("ImageEditorActivator","click",imageActivator.onOpen);</script>'
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
'Main'
|
'Main'
|
||||||
|
127
code/ImageEditor.php
Normal file
127
code/ImageEditor.php
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class ImageEditor extends Controller {
|
||||||
|
|
||||||
|
public $fileToEdit = "";
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function index() {
|
||||||
|
Requirements::clear();
|
||||||
|
Requirements::javascript("jsparty/prototype.js");
|
||||||
|
Requirements::javascript("jsparty/scriptaculous/scriptaculous.js");
|
||||||
|
Requirements::javascript("/cms/javascript/ImageEditor/Require.js");
|
||||||
|
Requirements::javascript("cms/javascript/ImageEditor/ImageEditor.js");
|
||||||
|
Requirements::css("cms/css/ImageEditor/ImageEditor.css");
|
||||||
|
|
||||||
|
if(!isset($this->requestParams['fileToEdit'])) $this->raiseError();
|
||||||
|
$fileWithPath = $this->requestParams['fileToEdit'];
|
||||||
|
$this->fileToEdit = $this->file2Origin($fileWithPath);
|
||||||
|
|
||||||
|
return $this->renderWith(__CLASS__);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function raiseError()
|
||||||
|
{
|
||||||
|
Debug::friendlyError(500,"Bad arguments",__FILE__,__LINE__,'');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function manipulate() {
|
||||||
|
$fileName = $this->requestParams['file'];
|
||||||
|
$command = $this->requestParams['command'];
|
||||||
|
$this->checkFileExists($fileName);
|
||||||
|
$gd = new GD($fileName);
|
||||||
|
switch($command) {
|
||||||
|
case 'rotate':
|
||||||
|
$angle = $_POST['angle'];
|
||||||
|
$gd = $gd->rotate($angle);
|
||||||
|
break;
|
||||||
|
case 'resize':
|
||||||
|
$imageNewWidth = $_POST['newImageWidth'];
|
||||||
|
$imageNewHeight = $_POST['newImageHeight'];
|
||||||
|
$gd = $gd->resize($imageNewWidth,$imageNewHeight);
|
||||||
|
break;
|
||||||
|
case 'crop':
|
||||||
|
$top = $_POST['top'];
|
||||||
|
$left = $_POST['left'];
|
||||||
|
$width = $_POST['width'];
|
||||||
|
$height = $_POST['height'];
|
||||||
|
$gd = $gd->crop($top,$left,$width,$height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$rand = md5(rand(1,100000));
|
||||||
|
$gd->writeTo('../assets/tmp/' . $rand . '.jpg');
|
||||||
|
$this->returnImage($gd,'/assets/tmp/' . $rand . '.jpg');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save() {
|
||||||
|
if(isset($this->requestParams['originalFile']) && isset($this->requestParams['editedFile'])) {
|
||||||
|
$originalFile = $this->requestParams['originalFile'];
|
||||||
|
$editedFile = $this->requestParams['editedFile'];
|
||||||
|
if($this->checkFileExists($originalFile) && $this->checkFileExists($editedFile)) {
|
||||||
|
if($editedFile != $originalFile && copy($this->url2File($editedFile),$this->url2File($originalFile))) {
|
||||||
|
$image = DataObject::get_one('File',"Filename = '" . substr($this->url2File($originalFile),3) . "'");
|
||||||
|
$image->generateFormattedImage('AssetLibraryPreview');
|
||||||
|
} else {
|
||||||
|
$this->raiseError();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->raiseError();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->raiseError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function returnImage(GD $gd,$strFile)
|
||||||
|
{
|
||||||
|
list($width, $height) = getimagesize('..' . $strFile);
|
||||||
|
echo json_encode(array(
|
||||||
|
'fileName' => $strFile,
|
||||||
|
'width' => $width,
|
||||||
|
'height' => $height)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function file2Origin($file) {
|
||||||
|
$file = str_replace('_resampled/','',$file);
|
||||||
|
$file = str_replace('_resampled/','',$file);
|
||||||
|
$file = str_replace('AssetLibraryPreview-','',$file);
|
||||||
|
$this->checkFileExists($file);
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function url2File($url) {
|
||||||
|
return '..' . substr($url,strpos($url,'/assets'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function checkFileExists($url) {
|
||||||
|
$pathInfo = pathinfo($url);
|
||||||
|
if(count($pathInfo) <= 3) $this->raiseError();
|
||||||
|
if(!in_array($pathInfo['extension'],array('jpeg','jpg','jpe','png','gif'))) $this->raiseError();
|
||||||
|
$path = explode('/',$pathInfo['dirname']);
|
||||||
|
if(count($path) > 1) {
|
||||||
|
$assetId = array_search('assets',$path);
|
||||||
|
if($assetId > 0) {
|
||||||
|
$realPath = '../' . implode('/',array_slice($path,$assetId,count($path) - $assetId));
|
||||||
|
if(strpos($pathInfo['basename'],'AssetLibraryPreview') !== false) {
|
||||||
|
$realPath .= '/' . substr($pathInfo['basename'],strpos($pathInfo['basename'],'-'));
|
||||||
|
} else {
|
||||||
|
$realPath .= '/' . $pathInfo['basename'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->raiseError();
|
||||||
|
}
|
||||||
|
if(file_exists($realPath)) {
return true;
|
||||||
|
} else {
|
||||||
|
$this->raiseError();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->raiseError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
109
css/ImageEditor/ImageEditor.css
Normal file
109
css/ImageEditor/ImageEditor.css
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
*
|
||||||
|
{
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clickBox
|
||||||
|
{
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
background-color: red;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.leftUpperClickBox
|
||||||
|
{
|
||||||
|
cursor: nw-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftMiddleClickBox
|
||||||
|
{
|
||||||
|
cursor: e-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftLowerClickBox
|
||||||
|
{
|
||||||
|
cursor: ne-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightUpperClickBox
|
||||||
|
{
|
||||||
|
cursor: ne-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightMiddleClickBox
|
||||||
|
{
|
||||||
|
cursor: w-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightLowerClickBox
|
||||||
|
{
|
||||||
|
cursor: nw-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upperMiddleClickBox
|
||||||
|
{
|
||||||
|
cursor: n-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lowerMiddleClickBox
|
||||||
|
{
|
||||||
|
cursor: n-resize;
|
||||||
|
}
|
||||||
|
.inline
|
||||||
|
{
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
#mainContainer
|
||||||
|
{
|
||||||
|
width: 100%;
|
||||||
|
height:600px;
|
||||||
|
}
|
||||||
|
#imageContainer
|
||||||
|
{
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
#menuBarContainer
|
||||||
|
{
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
.floatRight
|
||||||
|
{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
#loadingIndicatorContainer
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
z-index: 1000;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
#fakeImg
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#image
|
||||||
|
{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
#cropBox
|
||||||
|
{
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.greyBox
|
||||||
|
{
|
||||||
|
background-color: black;
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
#mainContainer
|
||||||
|
{
|
||||||
|
border-color: black;
|
||||||
|
border-style: solid;
|
||||||
|
background-color: white;
|
||||||
|
margin: 0px;
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
BIN
images/ImageEditor/clickBox.JPG
Normal file
BIN
images/ImageEditor/clickBox.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 633 B |
BIN
images/ImageEditor/indicator.gif
Normal file
BIN
images/ImageEditor/indicator.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
11
javascript/ImageEditor/.project
Normal file
11
javascript/ImageEditor/.project
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>ImageEditor-SS</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
24
javascript/ImageEditor/Activator.js
Normal file
24
javascript/ImageEditor/Activator.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
var ImageEditorActivator = {
|
||||||
|
initialize: function() {
|
||||||
|
this.onOpen = ImageEditorActivator.onOpen.bind(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
onOpen: function() {
|
||||||
|
iframe = window.top.document.getElementById('imageEditorIframe');
|
||||||
|
if(iframe != null) {
|
||||||
|
iframe.parentNode.removeChild(iframe);
|
||||||
|
}
|
||||||
|
iframe = document.createElement('iframe');
|
||||||
|
fileToEdit = $('ImageEditorActivator').firstChild.src;
|
||||||
|
iframe.setAttribute("src","/admin/ImageEditor?fileToEdit=" + fileToEdit);
|
||||||
|
iframe.id = 'imageEditorIframe';
|
||||||
|
iframe.style.width = "97%";
|
||||||
|
iframe.style.height = "300%";
|
||||||
|
iframe.style.zIndex = "1000";
|
||||||
|
iframe.style.position = "absolute";
|
||||||
|
iframe.style.top = "-2%";
|
||||||
|
iframe.style.left = "1.5%";
|
||||||
|
window.top.document.body.appendChild(iframe);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
143
javascript/ImageEditor/Crop.js
Normal file
143
javascript/ImageEditor/Crop.js
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
var Crop = {
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
this.cropBox = $('cropBox');
|
||||||
|
new Positioning.addBehaviour(this.cropBox);
|
||||||
|
this.imageContainer = $('imageContainer');
|
||||||
|
this.leftGreyBox = $('leftGreyBox');
|
||||||
|
this.rightGreyBox = $('rightGreyBox');
|
||||||
|
this.upperGreyBox = $('upperGreyBox');
|
||||||
|
this.lowerGreyBox = $('lowerGreyBox');
|
||||||
|
options = {
|
||||||
|
resizeStop: Crop.resizeStop.bind(this),
|
||||||
|
onDrag: Crop.onDrag.bind(this),
|
||||||
|
onResize: Crop.onResize.bind(this),
|
||||||
|
getMousePos: Crop.getMousePos.bind(this)
|
||||||
|
};
|
||||||
|
this.centerCropBox = Crop.centerCropBox.bind(this);
|
||||||
|
this.placeGreyBox = Crop.placeGreyBox.bind(this);
|
||||||
|
this.setListeners = Crop.setListeners.bind(this);
|
||||||
|
this.onCropStop = Crop.onCropStop.bind(this);
|
||||||
|
this.onCropStart = Crop.onCropStart.bind(this);
|
||||||
|
this.onCropOk = Crop.onCropOk.bind(this);
|
||||||
|
this.onCropCancel = Crop.onCropCancel.bind(this);
|
||||||
|
this.doCrop = Crop.doCrop.bind(this);
|
||||||
|
this.setVisible = Crop.setVisible.bind(this);
|
||||||
|
Event.observe('image','load',this.centerCropBox);
|
||||||
|
this.resizeCropBox = new Resizeable.initialize(this.cropBox,options);
|
||||||
|
Event.observe(this.cropBox,'dblclick',this.onCropStop);
|
||||||
|
this.setListeners();
|
||||||
|
this.setVisible(false);
|
||||||
|
},
|
||||||
|
|
||||||
|
resizeStop: function(event) {
|
||||||
|
EventStack.clearStack();
|
||||||
|
this.resizeCropBox.originalHeight = this.cropBox.getHeight();
|
||||||
|
this.resizeCropBox.originalWidth = this.cropBox.getWidth();
|
||||||
|
},
|
||||||
|
|
||||||
|
onDrag: function() {
|
||||||
|
if(this.cropBox.getLeft() <= 0 ) this.cropBox.style.left = '0px';
|
||||||
|
if(this.cropBox.getTop() <= 0 ) this.cropBox.style.top = '0px';
|
||||||
|
if(this.cropBox.getLeft() + this.cropBox.getWidth() > this.cropBox.getParentWidth()) this.cropBox.style.left = this.cropBox.getParentWidth()- this.cropBox.getWidth() + 'px';
|
||||||
|
if(this.cropBox.getTop() + this.cropBox.getHeight() > this.cropBox.getParentHeight()) this.cropBox.style.top = this.cropBox.getParentHeight() - this.cropBox.getHeight() + 'px';
|
||||||
|
this.placeGreyBox();
|
||||||
|
},
|
||||||
|
|
||||||
|
centerCropBox: function() {
|
||||||
|
this.cropBox.style.width = this.cropBox.getParentWidth()/2 + 'px';
|
||||||
|
this.cropBox.style.height = this.cropBox.getParentHeight()/2 + 'px';
|
||||||
|
this.cropBox.style.left = (this.cropBox.getParentWidth() - this.cropBox.getWidth())/2 + "px";
|
||||||
|
this.cropBox.style.top = (this.cropBox.getParentHeight() - this.cropBox.getHeight())/2 + "px";
|
||||||
|
this.placeGreyBox();
|
||||||
|
this.leftBoxConstraint = this.cropBox.getParentLeft();
|
||||||
|
this.topBoxConstraint = this.cropBox.getParentTop();
|
||||||
|
this.rightBoxConstraint = this.cropBox.getParentLeft() + this.cropBox.getParentWidth();
|
||||||
|
this.bottomBoxConstraint = this.cropBox.getParentTop() + this.cropBox.getParentHeight()-1;//hack without 1 doesn't work;
|
||||||
|
},
|
||||||
|
|
||||||
|
placeGreyBox: function() {
|
||||||
|
this.leftGreyBox.style.width = this.cropBox.getLeft() + "px";
|
||||||
|
this.leftGreyBox.style.height = "100%";
|
||||||
|
this.rightGreyBox.style.width = this.cropBox.getParentWidth() - this.cropBox.getLeft() - this.cropBox.getWidth() + "px";
|
||||||
|
this.rightGreyBox.style.height = "100%";
|
||||||
|
this.rightGreyBox.style.left = this.cropBox.getLeft() + this.cropBox.getWidth() + "px";
|
||||||
|
this.upperGreyBox.style.width = this.cropBox.getWidth() + 'px';
|
||||||
|
this.upperGreyBox.style.left = this.cropBox.getLeft() + 'px';
|
||||||
|
this.upperGreyBox.style.height = this.cropBox.getTop() + 'px';
|
||||||
|
this.lowerGreyBox.style.width = "100%";
|
||||||
|
this.lowerGreyBox.style.height = this.cropBox.getParentHeight() - this.cropBox.getTop() - this.cropBox.getHeight() + "px";
|
||||||
|
this.lowerGreyBox.style.top = this.cropBox.getTop() + this.cropBox.getHeight() + "px";
|
||||||
|
this.lowerGreyBox.style.width = this.cropBox.getWidth() + 'px';
|
||||||
|
this.lowerGreyBox.style.left = this.cropBox.getLeft() + 'px';
|
||||||
|
},
|
||||||
|
|
||||||
|
onResize: function(event) {
|
||||||
|
x = Event.pointerX(event);
|
||||||
|
this.placeGreyBox();
|
||||||
|
},
|
||||||
|
getMousePos: function(event) {
|
||||||
|
x = Event.pointerX(event);
|
||||||
|
y = Event.pointerY(event);
|
||||||
|
if(x <= this.leftBoxConstraint) x = this.leftBoxConstraint;
|
||||||
|
if(y <= this.topBoxConstraint) y = this.topBoxConstraint;
|
||||||
|
if(x >= this.rightBoxConstraint) x = this.rightBoxConstraint;
|
||||||
|
if(y >= this.bottomBoxConstraint) y = this.bottomBoxConstraint;
|
||||||
|
return {x: x,y: y};
|
||||||
|
},
|
||||||
|
|
||||||
|
onCropStop: function(event) {
|
||||||
|
this.doCrop();
|
||||||
|
},
|
||||||
|
|
||||||
|
doCrop: function() {
|
||||||
|
newWidth = this.cropBox.getWidth()
|
||||||
|
newHeight = this.cropBox.getHeight() ;
|
||||||
|
startTop = this.cropBox.getTop() ;
|
||||||
|
startLeft = this.cropBox.getLeft() ;
|
||||||
|
if(newWidth > 30 && newHeight > 30) {
|
||||||
|
imageTransformation.crop(startTop,startLeft,newWidth,newHeight);
|
||||||
|
imageHistory.enable();
|
||||||
|
} else {
|
||||||
|
alert('Crop area too small');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setListeners: function() {
|
||||||
|
Event.observe('cropStart','click',this.onCropStart);
|
||||||
|
Event.observe('cropOk','click',this.onCropOk);
|
||||||
|
Event.observe('cropCancel','click',this.onCropCancel);
|
||||||
|
},
|
||||||
|
|
||||||
|
onCropStart: function() {
|
||||||
|
this.setVisible(true);
|
||||||
|
Element.show($('cropOk'),$('cropCancel'));
|
||||||
|
imageHistory.disable();
|
||||||
|
},
|
||||||
|
|
||||||
|
onCropOk: function() {
|
||||||
|
Element.hide($('cropOk'),$('cropCancel'));
|
||||||
|
this.doCrop();
|
||||||
|
},
|
||||||
|
|
||||||
|
onCropCancel: function() {
|
||||||
|
Element.hide($('cropOk'),$('cropCancel'));
|
||||||
|
this.setVisible(false);
|
||||||
|
imageHistory.enable();
|
||||||
|
},
|
||||||
|
|
||||||
|
setVisible: function(setVisible) {
|
||||||
|
if(setVisible) {
|
||||||
|
Element.show(this.cropBox,this.leftGreyBox,this.rightGreyBox,this.upperGreyBox,this.lowerGreyBox);
|
||||||
|
this.centerCropBox();
|
||||||
|
this.placeGreyBox();
|
||||||
|
} else {
|
||||||
|
Element.hide(this.cropBox,this.leftGreyBox,this.rightGreyBox,this.upperGreyBox,this.lowerGreyBox,$('cropOk'),$('cropCancel'));
|
||||||
|
}
|
||||||
|
resize.imageContainerResize.setVisible(!setVisible);
|
||||||
|
this.resizeCropBox.setVisible(setVisible);
|
||||||
|
}
|
||||||
|
}
|
18
javascript/ImageEditor/Effects.js
Normal file
18
javascript/ImageEditor/Effects.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
var Effects = {
|
||||||
|
initialize: function() {
|
||||||
|
this.setListeners = Effects.setListeners.bind(this);
|
||||||
|
this.rotate = Effects.rotate.bind(this);
|
||||||
|
this.setListeners();
|
||||||
|
},
|
||||||
|
|
||||||
|
rotate: function() {
|
||||||
|
imageTransformation.rotate(90);
|
||||||
|
},
|
||||||
|
|
||||||
|
setListeners: function() {
|
||||||
|
Event.observe('rotateButton','click',this.rotate);
|
||||||
|
}
|
||||||
|
}
|
9
javascript/ImageEditor/Environment.js
Normal file
9
javascript/ImageEditor/Environment.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
var Environment = {
|
||||||
|
initialize: function (imageFile) {
|
||||||
|
imageBox = new ImageBox.initialize();
|
||||||
|
image = new Image.initialize(imageFile);
|
||||||
|
},
|
||||||
|
}
|
30
javascript/ImageEditor/Image.js
Normal file
30
javascript/ImageEditor/Image.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
var Image = {
|
||||||
|
initialize: function(imageFile) {
|
||||||
|
this.image = $('image');
|
||||||
|
this.image.src = imageFile;
|
||||||
|
this.reportSize = Image.reportSize.bind(this);
|
||||||
|
this.onImageLoad = Image.onImageLoad.bind(this);
|
||||||
|
Event.observe('image','load',this.onImageLoad);
|
||||||
|
imageHistory.add('initialize',this.image.src);
|
||||||
|
},
|
||||||
|
|
||||||
|
reportSize: function() {
|
||||||
|
$('imageWidth').innerHTML = this.image.width + "px";
|
||||||
|
$('imageHeight').innerHTML = this.image.height + "px";
|
||||||
|
},
|
||||||
|
|
||||||
|
onImageLoad: function() {
|
||||||
|
this.reportSize();
|
||||||
|
if(resize.imageContainerResize.originalHeight == 0 && resize.imageContainerResize.originalWidth == 0) {
|
||||||
|
imageBox.center();
|
||||||
|
}
|
||||||
|
$('imageContainer').style.width = this.image.width + 'px';
|
||||||
|
$('imageContainer').style.height = this.image.height + 'px';
|
||||||
|
resize.imageContainerResize.originalWidth = this.image.width;
|
||||||
|
resize.imageContainerResize.originalHeight = this.image.height;
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
50
javascript/ImageEditor/ImageBox.js
Normal file
50
javascript/ImageEditor/ImageBox.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
var ImageBox = {
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
this.showIndicator = ImageBox.showIndicator.bind(this);
|
||||||
|
this.hideIndicator = ImageBox.hideIndicator.bind(this);
|
||||||
|
this.reCenterIndicator = ImageBox.reCenterIndicator.bind(this);
|
||||||
|
this.centerIndicator = ImageBox.centerIndicator.bind(this);
|
||||||
|
this.center = ImageBox.center.bind(this);
|
||||||
|
this.imageContainer = $('imageContainer');
|
||||||
|
Element.hide(this.imageContainer);
|
||||||
|
},
|
||||||
|
|
||||||
|
showIndicator: function() {
|
||||||
|
this.centerIndicator();
|
||||||
|
indicator.style.display = 'inline';
|
||||||
|
},
|
||||||
|
|
||||||
|
hideIndicator: function() {
|
||||||
|
indicator = $('loadingIndicatorContainer');
|
||||||
|
indicator.style.display = 'none';
|
||||||
|
},
|
||||||
|
|
||||||
|
centerIndicator: function() {
|
||||||
|
indicator = $('loadingIndicatorContainer');
|
||||||
|
indicatorImage = $('loadingIndicator');
|
||||||
|
top = this.imageContainer.getTop();
|
||||||
|
left = this.imageContainer.getLeft();
|
||||||
|
width = this.imageContainer.getWidth();
|
||||||
|
height = this.imageContainer.getHeight();
|
||||||
|
indicator.style.left = left + width/2 - indicatorImage.width/2 + "px";
|
||||||
|
indicator.style.top = top + height/2 - indicatorImage.height/2 + "px";
|
||||||
|
},
|
||||||
|
|
||||||
|
reCenterIndicator: function() {
|
||||||
|
if($('loadingIndicatorContainer').style.display == 'inline') {
|
||||||
|
this.centerIndicator();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
center: function() {
|
||||||
|
$('imageContainer').style.left = this.imageContainer.getParentWidth()/2 - this.imageContainer.getWidth()/2 + 'px';
|
||||||
|
$('imageContainer').style.top = this.imageContainer.getParentHeight()/2 - this.imageContainer.getHeight()/2 + 'px';
|
||||||
|
Element.show(this.imageContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
42
javascript/ImageEditor/ImageEditor.js
Normal file
42
javascript/ImageEditor/ImageEditor.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
|
||||||
|
Scriptaculous.require('cms/javascript/ImageEditor/Utils.js');
|
||||||
|
Scriptaculous.require('cms/javascript/ImageEditor/ImageHistory.js');
|
||||||
|
Scriptaculous.require('cms/javascript/ImageEditor/Image.js"');
|
||||||
|
Scriptaculous.require('cms/javascript/ImageEditor/ImageTransformation.js');
|
||||||
|
Scriptaculous.require('cms/javascript/ImageEditor/Resizeable.js');
|
||||||
|
Scriptaculous.require('cms/javascript/ImageEditor/Effects.js');
|
||||||
|
Scriptaculous.require('cms/javascript/ImageEditor/Environment.js');
|
||||||
|
Scriptaculous.require('cms/javascript/ImageEditor/Crop.js');
|
||||||
|
Scriptaculous.require('cms/javascript/ImageEditor/Resize.js');
|
||||||
|
Scriptaculous.require('cms/javascript/ImageEditor/ImageBox.js');
|
||||||
|
var ImageEditor = {
|
||||||
|
initialize: function(imageFile) {
|
||||||
|
imageHistory = new ImageHistory.initialize();
|
||||||
|
environment = new Environment.initialize(imageFile);
|
||||||
|
imageTransformation = new ImageTransformation.initialize();
|
||||||
|
resize = new Resize.initialize($('imageContainer'));
|
||||||
|
effects = new Effects.initialize();
|
||||||
|
crop = new Crop.initialize();
|
||||||
|
this.originalImageFile = imageFile;
|
||||||
|
this.tottalyOriginalImageFile = imageFile;
|
||||||
|
this.onSave = ImageEditor.onSave.bind(this);
|
||||||
|
this.onClose = ImageEditor.onClose.bind(this);
|
||||||
|
Event.observe($('saveButton'),'click',this.onSave);
|
||||||
|
Event.observe($('closeButton'),'click',this.onClose);
|
||||||
|
},
|
||||||
|
onSave: function() {
|
||||||
|
if(this.tottalyOriginalImageFile != $('image').src) {
|
||||||
|
imageTransformation.save(this.tottalyOriginalImageFile,$('image').src);
|
||||||
|
} else {
|
||||||
|
this.onClose();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onClose: function() {
|
||||||
|
window.parent.frames[1].location.reload(1);
|
||||||
|
Element.hide(window.frameElement);
|
||||||
|
}
|
||||||
|
}
|
88
javascript/ImageEditor/ImageHistory.js
Normal file
88
javascript/ImageEditor/ImageHistory.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
ImageHistory = {
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
this.history = new Array();
|
||||||
|
this.historyPointer = -1;
|
||||||
|
this.modifiedOriginalImage = false;
|
||||||
|
this.undo = ImageHistory.undo.bind(this);
|
||||||
|
this.redo = ImageHistory.redo.bind(this);
|
||||||
|
this.add = ImageHistory.add.bind(this);
|
||||||
|
this.addLinsteners = ImageHistory.addLinsteners.bind(this);
|
||||||
|
this.addLinsteners();
|
||||||
|
this.operationMade = ImageHistory.operationMade.bind(this);
|
||||||
|
this.onFakeImageLoad = ImageHistory.onFakeImageLoad.bind(this);
|
||||||
|
this.enable = ImageHistory.enable.bind(this);
|
||||||
|
this.disable = ImageHistory.disable.bind(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
undo: function() {
|
||||||
|
if(this.historyPointer >= 1) {
|
||||||
|
image = $('image');
|
||||||
|
fakeImage = $('fakeImg');
|
||||||
|
operation = this.history[this.historyPointer].operation;
|
||||||
|
if(operation == 'rotate' || operation == 'crop') {
|
||||||
|
if(this.operationMade(this.historyPointer-1,'rotate') || this.operationMade(this.historyPointer-1,'crop'))
|
||||||
|
this.modifiedOriginalImage = true; else this.modifiedOriginalImage = false;
|
||||||
|
}
|
||||||
|
image.src = this.history[this.historyPointer-1].fileUrl;
|
||||||
|
fakeImage.src = this.history[this.historyPointer-1].fileUrl;
|
||||||
|
Event.observe('fakeImg','load',this.onFakeImageLoad);
|
||||||
|
this.historyPointer--;
|
||||||
|
} else {
|
||||||
|
alert("No more undo");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
redo: function() {
|
||||||
|
if(this.historyPointer < this.history.length-1) {
|
||||||
|
operation = this.history[this.historyPointer+1].operation;
|
||||||
|
if(operation == 'rotate' || operation == 'crop') this.modifiedOriginalImage = true;
|
||||||
|
$('image').src = this.history[this.historyPointer+1].fileUrl;
|
||||||
|
$('fakeImg').src = $('image').src;
|
||||||
|
Event.observe('fakeImg','load',this.onFakeImageLoad);
|
||||||
|
this.historyPointer++;
|
||||||
|
} else {
|
||||||
|
alert("No more redo");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
add: function(operation,url) {
|
||||||
|
this.historyPointer++;
|
||||||
|
this.history[this.historyPointer] = {'operation': operation,'fileUrl' : url};
|
||||||
|
if(operation == 'rotate' || operation == 'crop') this.modifiedOriginalImage = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
addLinsteners: function() {
|
||||||
|
this.undoListener = Event.observe('undoButton','click',this.undo);
|
||||||
|
this.redoListener = Event.observe('redoButton','click',this.redo);
|
||||||
|
},
|
||||||
|
|
||||||
|
operationMade: function(historyPointer,operation) {
|
||||||
|
for(i=historyPointer;i>=0;i--) {
|
||||||
|
if(this.history[i].operation == operation) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
onFakeImageLoad: function() {
|
||||||
|
$('imageContainer').style.width = fakeImage.width + 'px';
|
||||||
|
$('imageContainer').style.height = fakeImage.height + 'px';
|
||||||
|
resize.imageContainerResize.originalWidth = fakeImage.width;
|
||||||
|
resize.imageContainerResize.originalHeight = fakeImage.height;
|
||||||
|
resize.imageContainerResize.placeClickBox();
|
||||||
|
},
|
||||||
|
|
||||||
|
enable: function() {
|
||||||
|
this.addLinsteners();
|
||||||
|
},
|
||||||
|
|
||||||
|
disable: function() {
|
||||||
|
Event.stopObserving($('undoButton'),'click', this.undo);
|
||||||
|
Event.stopObserving($('redoButton'),'click', this.redo);
|
||||||
|
},
|
||||||
|
};
|
79
javascript/ImageEditor/ImageTransformation.js
Normal file
79
javascript/ImageEditor/ImageTransformation.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
var ImageTransformation = {
|
||||||
|
initialize: function() {
|
||||||
|
this.resize = ImageTransformation.resize.bind(this);
|
||||||
|
this.rotate = ImageTransformation.rotate.bind(this);
|
||||||
|
this.crop = ImageTransformation.crop.bind(this);
|
||||||
|
this.save = ImageTransformation.save.bind(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
resize: function(width,height) {
|
||||||
|
if(imageHistory.modifiedOriginalImage) {
|
||||||
|
fileToResize = $('image').src;
|
||||||
|
} else {
|
||||||
|
fileToResize = imageEditor.originalImageFile;
|
||||||
|
}
|
||||||
|
var options = {
|
||||||
|
method: 'post',
|
||||||
|
postBody: 'command=resize&file=' + fileToResize + '&newImageWidth=' + width + '&newImageHeight=' + height,
|
||||||
|
onSuccess: function(transport) {
|
||||||
|
imageBox.hideIndicator();
|
||||||
|
response = eval('(' + transport.responseText + ')');
|
||||||
|
$('image').src = response.fileName;
|
||||||
|
imageHistory.add('resize',$('image').src);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
imageBox.showIndicator();
|
||||||
|
new Ajax.Request('/admin/ImageEditor/manipulate', options);
|
||||||
|
},
|
||||||
|
|
||||||
|
rotate: function(angle) {
|
||||||
|
var options = {
|
||||||
|
method: 'post',
|
||||||
|
postBody: 'command=rotate&file=' + $('image').src + '&angle=' + angle ,
|
||||||
|
onSuccess: function(transport) {
|
||||||
|
imageBox.hideIndicator();
|
||||||
|
response = eval('(' + transport.responseText + ')');
|
||||||
|
$('image').src = response.fileName;
|
||||||
|
$('imageContainer').style.width = response.width + 'px';
|
||||||
|
$('imageContainer').style.height = response.height + 'px';
|
||||||
|
imageHistory.add('rotate',$('image').src);
|
||||||
|
resize.imageContainerResize.placeClickBox();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
imageBox.showIndicator();
|
||||||
|
new Ajax.Request('/admin/ImageEditor/manipulate', options);
|
||||||
|
},
|
||||||
|
|
||||||
|
crop: function(top,left,width,height) {
|
||||||
|
var options = {
|
||||||
|
method: 'post',
|
||||||
|
postBody: 'command=crop&file=' + $('image').src + '&top=' + top + '&left=' + left + '&width=' + width + '&height=' + height,
|
||||||
|
onSuccess: function(transport) {
|
||||||
|
imageBox.hideIndicator();
|
||||||
|
response = eval('(' + transport.responseText + ')');
|
||||||
|
$('image').src = response.fileName;
|
||||||
|
$('imageContainer').style.width = response.width + 'px';
|
||||||
|
$('imageContainer').style.height = response.height + 'px';
|
||||||
|
imageHistory.add('crop',$('image').src);
|
||||||
|
crop.setVisible(false);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
imageBox.showIndicator();
|
||||||
|
new Ajax.Request('/admin/ImageEditor/manipulate', options);
|
||||||
|
},
|
||||||
|
|
||||||
|
save: function(originalFile,editedFile) {
|
||||||
|
var options = {
|
||||||
|
method: 'post',
|
||||||
|
postBody: 'command=save&editedFile=' + editedFile + '&originalFile=' + originalFile,
|
||||||
|
onSuccess: function(transport) {
|
||||||
|
imageEditor.onClose();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
new Ajax.Request('/admin/ImageEditor/save', options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
3
javascript/ImageEditor/Require.js
Normal file
3
javascript/ImageEditor/Require.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
60
javascript/ImageEditor/Resize.js
Normal file
60
javascript/ImageEditor/Resize.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
var Resize = {
|
||||||
|
|
||||||
|
initialize: function(element) {
|
||||||
|
this.element = element;
|
||||||
|
this.leftBoxConstraint = 20;
|
||||||
|
this.topBoxConstraint = 100;
|
||||||
|
this.getRelativeMousePos = Resize.getRelativeMousePos.bind(this);
|
||||||
|
options = {
|
||||||
|
resizeStop: Resize.resizeStop.bind(this),
|
||||||
|
onDrag: Resize.onDrag.bind(this),
|
||||||
|
onResize: Resize.onResize,
|
||||||
|
getMousePos: Resize.getMousePos.bind(this)
|
||||||
|
};
|
||||||
|
new Positioning.addBehaviour(this.element);
|
||||||
|
this.imageContainerResize = new Resizeable.initialize(element,options);
|
||||||
|
this.imageContainerResize.setVisible(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
resizeStop: function(event) {
|
||||||
|
if(EventStack.getLastEvent() != null) {
|
||||||
|
imageElement = $('image');
|
||||||
|
EventStack.clearStack();
|
||||||
|
if(this.imageContainerResize.originalWidth != imageElement.width || this.imageContainerResize.originalHeight != imageElement.height) {
|
||||||
|
imageTransformation.resize(imageElement.width,imageElement.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onDrag: function()
|
||||||
|
{
|
||||||
|
if(this.element.getTop() < this.topBoxConstraint) this.element.style.top = this.topBoxConstraint + "px";
|
||||||
|
if(this.element.getLeft() < this.leftBoxConstraint) this.element.style.left = this.leftBoxConstraint + "px";
|
||||||
|
if(this.element.getTop() + this.element.getHeight() >= this.element.getParentHeight()) this.element.style.top = this.element.getParentHeight() - this.element.getHeight() - 3 + 'px';
|
||||||
|
if(this.element.getLeft() + this.element.getWidth() > this.element.getParentWidth()) this.element.style.left = this.element.getParentWidth() - this.element.getWidth() - 3 + 'px';
|
||||||
|
imageBox.reCenterIndicator();
|
||||||
|
},
|
||||||
|
|
||||||
|
onResize: function() {
|
||||||
|
},
|
||||||
|
getMousePos: function(event) {
|
||||||
|
relativeMouseX = this.getRelativeMousePos(event).x;
|
||||||
|
relativeMouseY = this.getRelativeMousePos(event).y;
|
||||||
|
if(relativeMouseX <= this.leftBoxConstraint) x = this.leftBoxConstraint + this.element.getParentLeft(); else x = relativeMouseX + this.element.getParentLeft();
|
||||||
|
if(relativeMouseY <= this.topBoxConstraint) y = this.topBoxConstraint + this.element.getParentTop(); else y = relativeMouseY + this.element.getParentTop();
|
||||||
|
if(relativeMouseX >= this.element.getParentWidth()) {
|
||||||
|
x = this.element.getParentLeft() + this.element.getParentWidth();
|
||||||
|
}
|
||||||
|
if(relativeMouseY >= this.element.getParentHeight()) y = this.element.getParentTop() + this.element.getParentHeight();
|
||||||
|
return {x: x,y: y};
|
||||||
|
},
|
||||||
|
|
||||||
|
getRelativeMousePos: function(event) {
|
||||||
|
relativeMouseX = Event.pointerX(event) - this.element.getParentLeft();
|
||||||
|
relativeMouseY = Event.pointerY(event) - this.element.getParentTop();
|
||||||
|
return {x: relativeMouseX,y: relativeMouseY};
|
||||||
|
}
|
||||||
|
}
|
278
javascript/ImageEditor/Resizeable.js
Normal file
278
javascript/ImageEditor/Resizeable.js
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
Resizeable = {
|
||||||
|
|
||||||
|
initialize: function(element,options) {
|
||||||
|
this.resizeStop = options.resizeStop.bind(this);
|
||||||
|
this.onDrag = options.onDrag.bind(this);
|
||||||
|
this.customOnResize = options.onResize.bind(this);
|
||||||
|
this.getMousePos = options.getMousePos.bind(this);
|
||||||
|
this.bindAll = Resizeable.bindAll.bind(this);
|
||||||
|
this.bindAll();
|
||||||
|
this.element = element;
|
||||||
|
this.createClickBoxes();
|
||||||
|
this.setListeners();
|
||||||
|
this.placeClickBoxOnImageLoad();
|
||||||
|
this.originalHeight = 0;
|
||||||
|
this.originalWidth = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
resizeStart: function(event) {
|
||||||
|
EventStack.addEvent(event);
|
||||||
|
Event.stop(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
leftUpperDrag: function(event,top,left,height,width,parentTop,parentLeft,relativeMouseX,relativeMouseY) {
|
||||||
|
newWidth = left - relativeMouseX + width;
|
||||||
|
newHeight = top - relativeMouseY + height;
|
||||||
|
if(this.resize(newWidth,newHeight)) {
|
||||||
|
this.element.style.top = top - (newHeight - height) + "px";
|
||||||
|
this.element.style.left = left - (newWidth - width) + "px";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
leftMiddleDrag: function(event,top,left,height,width,parentTop,parentLeft,relativeMouseX,relativeMouseY) {
|
||||||
|
newWidth = left - relativeMouseX + width;
|
||||||
|
if(this.resize(newWidth,-1000)) this.element.style.left = left - (left - relativeMouseX) + "px";
|
||||||
|
},
|
||||||
|
|
||||||
|
leftLowerDrag: function(event,top,left,height,width,parentTop,parentLeft,relativeMouseX,relativeMouseY) {
|
||||||
|
newWidth = left - relativeMouseX + width;
|
||||||
|
newHeight = relativeMouseY - (top + height) + height;
|
||||||
|
if(this.resize(newWidth,newHeight)) this.element.style.left = left - (left - relativeMouseX) + "px";
|
||||||
|
},
|
||||||
|
|
||||||
|
rightUpperDrag: function(event,top,left,height,width,parentTop,parentLeft,relativeMouseX,relativeMouseY) {
|
||||||
|
newWidth = relativeMouseX - left - width + width;
|
||||||
|
newHeight = top - relativeMouseY + height;
|
||||||
|
if(this.resize(newWidth,newHeight)) this.element.style.top = (top - (newHeight - height) ) + 'px';
|
||||||
|
},
|
||||||
|
|
||||||
|
rightMiddleDrag: function(event,top,left,height,width,parentTop,parentLeft,relativeMouseX,relativeMouseY) {
|
||||||
|
newWidth = relativeMouseX - left;
|
||||||
|
this.resize(newWidth,-1000);
|
||||||
|
},
|
||||||
|
|
||||||
|
rightLowerDrag: function(event,top,left,height,width,parentTop,parentLeft,relativeMouseX,relativeMouseY) {
|
||||||
|
newWidth = relativeMouseX - left;
|
||||||
|
newHeight = relativeMouseY - top;
|
||||||
|
this.resize(newWidth,newHeight);
|
||||||
|
},
|
||||||
|
|
||||||
|
upperMiddleDrag: function(event,top,left,height,width,parentTop,parentLeft,relativeMouseX,relativeMouseY) {
|
||||||
|
newHeight = top - relativeMouseY + height;
|
||||||
|
if(this.resize(-1000,newHeight)) {
|
||||||
|
this.element.style.top = (top - (newHeight - height)) + 'px';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
lowerMiddleDrag: function(event,top,left,height,width,parentTop,parentLeft,relativeMouseX,relativeMouseY) {
|
||||||
|
newHeight = relativeMouseY - (top + height) + height;
|
||||||
|
this.resize(-1000,newHeight);
|
||||||
|
},
|
||||||
|
|
||||||
|
onResize: function(event) {
|
||||||
|
if(EventStack.getLastEvent() != null && this.isVisible) {
|
||||||
|
lastEventElement = Event.element(EventStack.getLastEvent());
|
||||||
|
var relativeMouseX = this.getMousePos(event).x - this.element.getParentLeft();
|
||||||
|
var relativeMouseY = this.getMousePos(event).y - this.element.getParentTop();
|
||||||
|
if(Element.hasClassName(lastEventElement,'leftUpperClickBox')) {
|
||||||
|
this.leftUpperDrag(event,this.element.getTop(),this.element.getLeft(),this.element.getHeight(),this.element.getWidth(),this.element.getParentTop(),this.element.getParentLeft(),relativeMouseX,relativeMouseY);
|
||||||
|
}
|
||||||
|
if(Element.hasClassName(lastEventElement,'leftMiddleClickBox')) {
|
||||||
|
this.leftMiddleDrag(event,this.element.getTop(),this.element.getLeft(),this.element.getHeight(),this.element.getWidth(),this.element.getParentTop(),this.element.getParentLeft(),relativeMouseX,relativeMouseY);
|
||||||
|
}
|
||||||
|
if(Element.hasClassName(lastEventElement,'leftLowerClickBox')) {
|
||||||
|
this.leftLowerDrag(event,this.element.getTop(),this.element.getLeft(),this.element.getHeight(),this.element.getWidth(),this.element.getParentTop(),this.element.getParentLeft(),relativeMouseX,relativeMouseY);
|
||||||
|
}
|
||||||
|
if(Element.hasClassName(lastEventElement,'rightUpperClickBox')) {
|
||||||
|
this.rightUpperDrag(event,this.element.getTop(),this.element.getLeft(),this.element.getHeight(),this.element.getWidth(),this.element.getParentTop(),this.element.getParentLeft(),relativeMouseX,relativeMouseY);
|
||||||
|
}
|
||||||
|
if(Element.hasClassName(lastEventElement,'rightMiddleClickBox')) {
|
||||||
|
this.rightMiddleDrag(event,this.element.getTop(),this.element.getLeft(),this.element.getHeight(),this.element.getWidth(),this.element.getParentTop(),this.element.getParentLeft(),relativeMouseX,relativeMouseY);
|
||||||
|
}
|
||||||
|
if(Element.hasClassName(lastEventElement,'rightLowerClickBox')) {
|
||||||
|
this.rightLowerDrag(event,this.element.getTop(),this.element.getLeft(),this.element.getHeight(),this.element.getWidth(),this.element.getParentTop(),this.element.getParentLeft(),relativeMouseX,relativeMouseY);
|
||||||
|
}
|
||||||
|
if(Element.hasClassName(lastEventElement,'upperMiddleClickBox')) {
|
||||||
|
this.upperMiddleDrag(event,this.element.getTop(),this.element.getLeft(),this.element.getHeight(),this.element.getWidth(),this.element.getParentTop(),this.element.getParentLeft(),relativeMouseX,relativeMouseY);
|
||||||
|
}
|
||||||
|
if(Element.hasClassName(lastEventElement,'lowerMiddleClickBox')) {
|
||||||
|
this.lowerMiddleDrag(event,this.element.getTop(),this.element.getLeft(),this.element.getHeight(),this.element.getWidth(),this.element.getParentTop(),this.element.getParentLeft(),relativeMouseX,relativeMouseY);
|
||||||
|
}
|
||||||
|
this.placeClickBox();
|
||||||
|
imageBox.reCenterIndicator();
|
||||||
|
this.customOnResize();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
resize: function(width,height) {
|
||||||
|
if(width < 30 && height == -1000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(height < 30 && width == -1000) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if((width < 30 || height < 30) && (width != -1000 && height != -1000)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(width != -1000) {
|
||||||
|
this.element.style.width = width + "px";
|
||||||
|
} else {
|
||||||
|
this.element.style.width = this.originalWidth + "px";
|
||||||
|
}
|
||||||
|
if(height != -1000) {
|
||||||
|
this.element.style.height = height + "px";
|
||||||
|
} else {
|
||||||
|
this.element.style.height = this.originalHeight + "px";
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
placeClickBoxOnImageLoad: function() {
|
||||||
|
Event.observe('image','load',this.placeClickBox);
|
||||||
|
},
|
||||||
|
|
||||||
|
placeClickBox: function(event) {
|
||||||
|
if(event != null) {
|
||||||
|
this.originalHeight = Element.getDimensions(this.element).height;
|
||||||
|
this.originalWidth = Element.getDimensions(this.element).width;
|
||||||
|
}
|
||||||
|
width = Element.getDimensions(this.element).width;
|
||||||
|
height = Element.getDimensions(this.element).height;
|
||||||
|
|
||||||
|
clickBoxHalfWidth = Math.floor(Element.getDimensions(this.leftUpperClickBox).width/2);
|
||||||
|
|
||||||
|
leftUpper = new Point.initialize(-clickBoxHalfWidth,-clickBoxHalfWidth);
|
||||||
|
leftMiddle = new Point.initialize(-clickBoxHalfWidth,height/2-clickBoxHalfWidth);
|
||||||
|
leftLower = new Point.initialize(-clickBoxHalfWidth,height-clickBoxHalfWidth);
|
||||||
|
rightUpper = new Point.initialize(width-clickBoxHalfWidth,-clickBoxHalfWidth);
|
||||||
|
rightMiddle = new Point.initialize(width-clickBoxHalfWidth,height/2-clickBoxHalfWidth);
|
||||||
|
rightLower = new Point.initialize(width-clickBoxHalfWidth,height-clickBoxHalfWidth);
|
||||||
|
upperMiddle = new Point.initialize(width/2-clickBoxHalfWidth,-clickBoxHalfWidth);
|
||||||
|
lowerMiddle = new Point.initialize(width/2-clickBoxHalfWidth,height-clickBoxHalfWidth);
|
||||||
|
|
||||||
|
this.leftUpperClickBox.style.left = leftUpper.x + 'px';
|
||||||
|
this.leftUpperClickBox.style.top = leftUpper.y + 'px';
|
||||||
|
this.leftMiddleClickBox.style.left = leftMiddle.x + 'px';
|
||||||
|
this.leftMiddleClickBox.style.top = leftMiddle.y + 'px';
|
||||||
|
this.leftLowerClickBox.style.left = leftLower.x + 'px';
|
||||||
|
this.leftLowerClickBox.style.top = leftLower.y + 'px';
|
||||||
|
|
||||||
|
this.rightUpperClickBox.style.left = rightUpper.x + 'px';
|
||||||
|
this.rightUpperClickBox.style.top = rightUpper.y + 'px';
|
||||||
|
this.rightMiddleClickBox.style.left = rightMiddle.x + 'px';
|
||||||
|
this.rightMiddleClickBox.style.top = rightMiddle.y + 'px';
|
||||||
|
this.rightLowerClickBox.style.left = rightLower.x + 'px';
|
||||||
|
this.rightLowerClickBox.style.top = rightLower.y + 'px';
|
||||||
|
|
||||||
|
this.upperMiddleClickBox.style.left = upperMiddle.x + 'px';
|
||||||
|
this.upperMiddleClickBox.style.top = upperMiddle.y + 'px';
|
||||||
|
this.lowerMiddleClickBox.style.left = lowerMiddle.x + 'px';
|
||||||
|
this.lowerMiddleClickBox.style.top = lowerMiddle.y + 'px';
|
||||||
|
},
|
||||||
|
|
||||||
|
createClickBoxes: function() {
|
||||||
|
this.leftUpperClickBox = this.createElement('div',Math.random(),["leftUpperClickBox","clickBox"]);
|
||||||
|
this.leftMiddleClickBox = this.createElement('div',Math.random(),["leftMiddleClickBox","clickBox"]);
|
||||||
|
this.leftLowerClickBox = this.createElement('div',Math.random(),["leftLowerClickBox","clickBox"]);
|
||||||
|
this.rightUpperClickBox = this.createElement('div',Math.random(),["rightUpperClickBox","clickBox"]);
|
||||||
|
this.rightMiddleClickBox = this.createElement('div',Math.random(),["rightMiddleClickBox","clickBox"]);
|
||||||
|
this.rightLowerClickBox = this.createElement('div',Math.random(),["rightLowerClickBox","clickBox"]);
|
||||||
|
this.upperMiddleClickBox = this.createElement('div',Math.random(),["upperMiddleClickBox","clickBox"]);
|
||||||
|
this.lowerMiddleClickBox = this.createElement('div',Math.random(),["lowerMiddleClickBox","clickBox"]);
|
||||||
|
},
|
||||||
|
|
||||||
|
createElement: function(tag,id,classes) {
|
||||||
|
newElement = document.createElement(tag);
|
||||||
|
newElement.id = id;
|
||||||
|
classes.each(function(item) {
|
||||||
|
Element.addClassName(newElement,item);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.addListener(newElement);
|
||||||
|
this.element.appendChild(newElement);
|
||||||
|
return newElement;
|
||||||
|
},
|
||||||
|
|
||||||
|
bindAll: function() {
|
||||||
|
this.setListeners = Resizeable.setListeners.bind(this);
|
||||||
|
this.placeClickBox = Resizeable.placeClickBox.bind(this);
|
||||||
|
this.resizeStart = Resizeable.resizeStart.bind(this);
|
||||||
|
this.onResize = Resizeable.onResize.bind(this);
|
||||||
|
this.resize = Resizeable.resize.bind(this);
|
||||||
|
this.placeClickBoxOnImageLoad = Resizeable.placeClickBoxOnImageLoad.bind(this);
|
||||||
|
this.createClickBoxes = Resizeable.createClickBoxes.bind(this);
|
||||||
|
this.createElement = Resizeable.createElement.bind(this);
|
||||||
|
this.addListener = Resizeable.addListener.bind(this);
|
||||||
|
this.addDraging = Resizeable.addDraging.bind(this);
|
||||||
|
this.setVisible = Resizeable.setVisible.bind(this);
|
||||||
|
this.removeDraging = Resizeable.removeDraging.bind(this);
|
||||||
|
|
||||||
|
this.leftUpperDrag = Resizeable.leftUpperDrag.bind(this);
|
||||||
|
this.leftMiddleDrag = Resizeable.leftMiddleDrag.bind(this);
|
||||||
|
this.leftLowerDrag = Resizeable.leftLowerDrag.bind(this);
|
||||||
|
this.rightUpperDrag = Resizeable.rightUpperDrag.bind(this);
|
||||||
|
this.rightMiddleDrag = Resizeable.rightMiddleDrag.bind(this);
|
||||||
|
this.rightLowerDrag = Resizeable.rightLowerDrag.bind(this);
|
||||||
|
this.upperMiddleDrag = Resizeable.upperMiddleDrag.bind(this);
|
||||||
|
this.lowerMiddleDrag = Resizeable.lowerMiddleDrag.bind(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
setListeners: function() {
|
||||||
|
Event.observe('mainContainer','mousemove',this.onResize);
|
||||||
|
Event.observe('mainContainer','mouseup',this.resizeStop);
|
||||||
|
},
|
||||||
|
|
||||||
|
addListener: function(element) {
|
||||||
|
Event.observe(element,'mousedown',this.resizeStart);
|
||||||
|
Event.observe(element,'mousemove',this.onResize);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
addDraging: function() {
|
||||||
|
if(this.draggableImage) this.removeDraging();
|
||||||
|
var options = {
|
||||||
|
starteffect: function() {},
|
||||||
|
endeffect: function() {},
|
||||||
|
change: this.onDrag,
|
||||||
|
};
|
||||||
|
this.draggableImage = new Draggable(this.element,options);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeDraging: function() {
|
||||||
|
if(this.draggableImage) {
|
||||||
|
this.draggableImage.destroy();
|
||||||
|
this.draggableImage = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setVisible: function(setVisible) {
|
||||||
|
this.isVisible = setVisible;
|
||||||
|
if(setVisible) {
|
||||||
|
Element.show(
|
||||||
|
this.leftUpperClickBox,
|
||||||
|
this.leftMiddleClickBox,
|
||||||
|
this.leftLowerClickBox,
|
||||||
|
this.rightUpperClickBox,
|
||||||
|
this.rightMiddleClickBox,
|
||||||
|
this.rightLowerClickBox,
|
||||||
|
this.upperMiddleClickBox,
|
||||||
|
this.lowerMiddleClickBox);
|
||||||
|
this.addDraging();
|
||||||
|
this.placeClickBox();
|
||||||
|
} else {
|
||||||
|
Element.hide(
|
||||||
|
this.leftUpperClickBox,
|
||||||
|
this.leftMiddleClickBox,
|
||||||
|
this.leftLowerClickBox,
|
||||||
|
this.rightUpperClickBox,
|
||||||
|
this.rightMiddleClickBox,
|
||||||
|
this.rightLowerClickBox,
|
||||||
|
this.upperMiddleClickBox,
|
||||||
|
this.lowerMiddleClickBox);
|
||||||
|
this.removeDraging();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
javascript/ImageEditor/Utils.js
Normal file
72
javascript/ImageEditor/Utils.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* @author Mateusz
|
||||||
|
*/
|
||||||
|
Point = {
|
||||||
|
initialize: function(x,y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EventStack = {
|
||||||
|
lastEvent: null,
|
||||||
|
getLastEvent: function(){
|
||||||
|
return EventStack.lastEvent
|
||||||
|
},
|
||||||
|
|
||||||
|
addEvent: function(event) {
|
||||||
|
EventStack.lastEvent = event;
|
||||||
|
},
|
||||||
|
|
||||||
|
clearStack: function() {
|
||||||
|
this.lastEvent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Positioning = {
|
||||||
|
addBehaviour: function(element) {
|
||||||
|
this.element = element;
|
||||||
|
this.element.getTop = Positioning.getTop.bind(this);
|
||||||
|
this.element.getLeft = Positioning.getLeft.bind(this);
|
||||||
|
this.element.getWidth = Positioning.getWidth.bind(this);
|
||||||
|
this.element.getHeight = Positioning.getHeight.bind(this);
|
||||||
|
this.element.getParentLeft = Positioning.getParentLeft.bind(this);
|
||||||
|
this.element.getParentTop = Positioning.getParentTop.bind(this);
|
||||||
|
this.element.getParentHeight = Positioning.getParentHeight.bind(this);
|
||||||
|
this.element.getParentWidth = Positioning.getParentWidth.bind(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
getTop: function() {
|
||||||
|
return Position.positionedOffset(this.element)[1];
|
||||||
|
},
|
||||||
|
|
||||||
|
getLeft: function() {
|
||||||
|
return Position.positionedOffset(this.element)[0];
|
||||||
|
},
|
||||||
|
|
||||||
|
getWidth: function() {
|
||||||
|
return Element.getDimensions(this.element).width;
|
||||||
|
},
|
||||||
|
|
||||||
|
getHeight: function() {
|
||||||
|
return Element.getDimensions(this.element).height;
|
||||||
|
},
|
||||||
|
|
||||||
|
getParentLeft: function() {
|
||||||
|
parentLeft = Position.cumulativeOffset(Position.offsetParent(this.element))[0];
|
||||||
|
return parentLeft;
|
||||||
|
},
|
||||||
|
|
||||||
|
getParentTop: function() {
|
||||||
|
parentTop = Position.cumulativeOffset(Position.offsetParent(this.element))[1];
|
||||||
|
return parentTop;
|
||||||
|
},
|
||||||
|
|
||||||
|
getParentHeight: function() {
|
||||||
|
return Element.getDimensions(Position.offsetParent(this.element)).height;
|
||||||
|
},
|
||||||
|
|
||||||
|
getParentWidth: function() {
|
||||||
|
return Element.getDimensions(Position.offsetParent(this.element)).width
|
||||||
|
}
|
||||||
|
}
|
53
templates/ImageEditor.ss
Normal file
53
templates/ImageEditor.ss
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||||
|
<% base_tag %>
|
||||||
|
<title>Untitled Document</title>
|
||||||
|
<link rel="stylesheet" type="text/css" media="all" href="/css/main.css" />
|
||||||
|
</head>
|
||||||
|
<body id="body">
|
||||||
|
<div id="mainContainer">
|
||||||
|
<div id="menuBarContainer">
|
||||||
|
<div id="photoInfoContainer" class="floatRight">
|
||||||
|
<p>Size</p>
|
||||||
|
<p class="inline">Width:</p><p id="imageWidth" class="inline">0px</p>
|
||||||
|
<p class="inline">Height:</p><p id="imageHeight" class="inline">0px</p>
|
||||||
|
</div>
|
||||||
|
<div id="historyContainer" class="floatRight">
|
||||||
|
<p><a id="undoButton" href="#">Undo</a></p>
|
||||||
|
<p><a id="redoButton" href="#">Redo</a></p>
|
||||||
|
</div>
|
||||||
|
<div id="effectsContainer" class="floatRight">
|
||||||
|
<p><a id="rotateButton" href="#">Rotate</a></p>
|
||||||
|
</div>
|
||||||
|
<div id="cropContainer" class="floatRight">
|
||||||
|
<p><a id="cropStart" href="#">Crop start</a></p>
|
||||||
|
<p><a id="cropOk" href="#" class="hidden">Ok</a></p>
|
||||||
|
<p><a id="cropCancel" href="#" class="hidden">Cancel</a></p>
|
||||||
|
</div>
|
||||||
|
<div id="operationContainer" class="floatRight">
|
||||||
|
<p><a id="saveButton" href="#">Save</a></p>
|
||||||
|
<p><a id="closeButton" href="#">Cancel</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="imageEditorContainer">
|
||||||
|
<div id="imageContainer">
|
||||||
|
<div id="leftGreyBox" class="greyBox"></div>
|
||||||
|
<div id="rightGreyBox" class="greyBox"></div>
|
||||||
|
<div id="upperGreyBox" class="greyBox"></div>
|
||||||
|
<div id="lowerGreyBox" class="greyBox"></div>
|
||||||
|
<img id="image" src="#" alt="We have encountered an error"/>
|
||||||
|
<div id="cropBox"></div>
|
||||||
|
</div>
|
||||||
|
<div id="loadingIndicatorContainer">
|
||||||
|
<img id="loadingIndicator" alt="indicator" src="/cms/images/ImageEditor/indicator.gif">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="fakeImgContainer">
|
||||||
|
<img id="fakeImg" src="#" alt="fakeImg"/>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">imageEditor = new ImageEditor.initialize("$fileToEdit")</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user