1
Files cropper.1.2/applyArrow.png and cropper/applyArrow.png differ
2
diff -dPNurbB cropper.1.2/cropper.css cropper/cropper.css
3
--- cropper.1.2/cropper.css 2006-10-30 20:58:25.000000000 +0100
4
+++ cropper/cropper.css 2008-01-26 17:14:11.000000000 +0100
11
+ background: url(applyArrow.png);
12
+ border: green solid 1px;
21
+ DS: Replacing selected part
22
background-color: #000;
24
filter:alpha(opacity=50);
35
+ background-color: #FFB;
37
+ filter:alpha(opacity=50);
45
diff -dPNurbB cropper.1.2/cropper.js cropper/cropper.js
46
--- cropper.1.2/cropper.js 2006-10-30 20:58:25.000000000 +0100
47
+++ cropper/cropper.js 2008-01-26 17:09:23.000000000 +0100
50
onEndCrop: Prototype.emptyFunction,
53
+ * The call back function to be called if crop is canceled
55
+ onCancelCrop: Prototype.emptyFunction,
58
+ * The call back function to pass the final values to
60
+ onDblClick: Prototype.emptyFunction,
63
+ * The call back function to pass the final values to
68
+ * The call back function to handle click event
73
* Whether to capture key presses or not
77
* The maximum height for the select areas in pixels (if both minHeight & maxHeight set to same the height of the cropper will be fixed)
82
+ * @var obj Coordinate object left, top, right, bottom
83
+ * The non-selectable margins
85
+ margins: { left: 0, top: 0, right: 0, bottom: 0 },
88
+ * If width is below this value, we are selecting whole horizontal range
93
+ * If height is below this value, we are selecting whole vertical range
98
+ * Whether to monitor reloading of picture
100
+ monitorImage: true,
103
+ * Whether the image is already loaded
108
+ * Maximal duration of the click event in ms (after dragging is started)
116
this.resizing = false;
119
+ * Whether the selected area is present on the screen
121
+ this.selected = false;
124
+ * Whether the selected area is present on the screen
126
+ this.altered = false;
129
* Whether the user is on a webKit browser
131
this.isWebKit = /Konqueror|Safari|KHTML/.test( navigator.userAgent );
133
// only load the event observers etc. once the image is loaded
134
// this is done after the subInitialize() call just in case the sub class does anything
135
// that will affect the result of the call to onLoad()
136
- if( this.img.complete || this.isWebKit ) this.onLoad(); // for some reason Safari seems to support img.complete but returns 'undefined' on the this.img object
137
- else Event.observe( this.img, 'load', this.onLoad.bindAsEventListener( this) );
138
+ if( this.options.imageReady || this.img.complete || this.isWebKit ) {
139
+ this.onLoad(); // for some reason Safari seems to support img.complete but returns 'undefined' on the this.img object
140
+ if (this.options.monitorImage) Event.observe( this.img, 'load', this.onLoad.bindAsEventListener( this) );
141
+ } else Event.observe( this.img, 'load', this.onLoad.bindAsEventListener( this) );
150
+ if (this.attached) {
151
+ if (this.monitorImage) {
157
var cNamePrefix = 'imgCrop_';
159
// get the point to insert the container
160
@@ -447,12 +518,19 @@
161
if( this.isOpera8 ) fixOperaClass = ' opera8';
162
this.imgWrap = Builder.node( 'div', { 'class': cNamePrefix + 'wrap' + fixOperaClass } );
164
+ this.applyLinked = 0;
165
+ this.applyButton = Builder.node( 'div', { 'class': cNamePrefix + 'apply' } );
167
this.north = Builder.node( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'north' }, [Builder.node( 'span' )] );
168
+ this.north_east = Builder.node( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'north' }, [Builder.node( 'span' )] );
169
+ this.north_west = Builder.node( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'north' }, [Builder.node( 'span' )] );
170
this.east = Builder.node( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'east' } , [Builder.node( 'span' )] );
171
this.south = Builder.node( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'south' }, [Builder.node( 'span' )] );
172
+ this.south_east = Builder.node( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'south' }, [Builder.node( 'span' )] );
173
+ this.south_west = Builder.node( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'south' }, [Builder.node( 'span' )] );
174
this.west = Builder.node( 'div', { 'class': cNamePrefix + 'overlay ' + cNamePrefix + 'west' } , [Builder.node( 'span' )] );
176
- var overlays = [ this.north, this.east, this.south, this.west ];
177
+ var overlays = [ this.north_west, this.north, this.north_east, this.east, this.south_east, this.south, this.south_west, this.west ];
179
this.dragArea = Builder.node( 'div', { 'class': cNamePrefix + 'dragArea' }, overlays );
183
this.endCropBind = this.endCrop.bindAsEventListener( this );
184
Event.observe( document, 'mouseup', this.endCropBind );
185
+// Event.observe( this.imgWrap, 'mouseup', this.endCropBind );
187
+ this.dblClickBind = this.dblClick.bindAsEventListener( this );
188
+ Event.observe( this.selArea, 'dblclick', this.dblClickBind );
190
+ this.applyClickBind = this.applyClick.bindAsEventListener( this );
191
+ Event.observe( this.applyButton, 'mousedown', this.applyClickBind );
192
+// Event.observe( this.applyButton, 'click', this.applyClickBind );
194
this.resizeBind = this.startResize.bindAsEventListener( this );
195
this.handles = [ this.handleN, this.handleNE, this.handleE, this.handleSE, this.handleS, this.handleSW, this.handleW, this.handleNW ];
197
this.imgH = this.img.height;
199
$( this.north ).setStyle( { height: 0 } );
200
+ $( this.north_east ).setStyle( { height: 0 } );
201
+ $( this.north_west ).setStyle( { height: 0 } );
202
$( this.east ).setStyle( { width: 0, height: 0 } );
203
$( this.south ).setStyle( { height: 0 } );
204
+ $( this.south_east ).setStyle( { height: 0 } );
205
+ $( this.south_west ).setStyle( { height: 0 } );
206
$( this.west ).setStyle( { width: 0, height: 0 } );
208
// resize the container to fit the image
210
// hide the select area
211
$( this.selArea ).hide();
213
+ // hide apply button
214
+ if (this.applyLinked) {
215
+ this.dragArea.removeChild(this.applyButton);
216
+ this.applyLinked = false;
219
+ this.selected = false;
220
+ this.altered = false;
222
// setup the starting position of the select area
223
- var startCoords = { x1: 0, y1: 0, x2: 0, y2: 0 };
224
+ var startCoords = { x1: this.options.margins.left, y1: this.options.margins.top, x2: this.options.margins.left, y2: this.options.margins.top };
225
var validCoordsSet = false;
227
// display the select area
229
Event.stopObserving( this.dragArea, 'mousedown', this.startDragBind );
230
Event.stopObserving( document, 'mousemove', this.onDragBind );
231
Event.stopObserving( document, 'mouseup', this.endCropBind );
232
+// Event.stopObserving( this.imgWrap, 'mouseup', this.endCropBind );
233
+ Event.stopObserving( this.selArea, 'dblclick', this.dblClickBind );
234
+ Event.stopObserving( this.applyButton, 'mousedown', this.applyClickBind );
236
this.registerHandles( false );
237
if( this.options.captureKeys ) Event.stopObserving( document, 'keypress', this.keysBind );
243
+ * Resets the cropper selection
248
+ clear: function() {
249
+ $( this.north ).setStyle( { height: 0 } );
250
+ $( this.north_east ).setStyle( { height: 0 } );
251
+ $( this.north_west ).setStyle( { height: 0 } );
252
+ $( this.east ).setStyle( { width: 0, height: 0 } );
253
+ $( this.south ).setStyle( { height: 0 } );
254
+ $( this.south_east ).setStyle( { height: 0 } );
255
+ $( this.south_west ).setStyle( { height: 0 } );
256
+ $( this.west ).setStyle( { width: 0, height: 0 } );
258
+ // hide the select area
259
+ $( this.selArea ).hide();
261
+ // hide apply button
262
+ if (this.applyLinked) {
263
+ this.dragArea.removeChild(this.applyButton);
264
+ this.applyLinked = false;
268
+ this.selected = false;
269
+ this.altered = false;
271
+ this.setAreaCoords( { x1: this.options.margins.left, y1: this.options.margins.top, x2: this.options.margins.left, y2: this.options.margins.top }, false, false, null );
276
* Handles the key functionality, currently just using arrow keys to move, if the user
277
* presses shift then the area will move by 10 pixels
281
moveArea: function( point ) {
282
// dump( 'moveArea : ' + point[0] + ',' + point[1] + ',' + ( point[0] + ( this.areaCoords.x2 - this.areaCoords.x1 ) ) + ',' + ( point[1] + ( this.areaCoords.y2 - this.areaCoords.y1 ) ) + '\n' );
283
+ this.altered = true;
287
@@ -754,28 +891,28 @@
288
var targH = coords.y2 - coords.y1;
290
// ensure we're within the bounds
291
- if( coords.x1 < 0 ) {
294
+ if( coords.x1 < this.options.margins.left ) {
295
+ coords.x1 = this.options.margins.left;
296
+ coords.x2 = this.options.margins.left + targW;
298
- if( coords.y1 < 0 ) {
301
+ if( coords.y1 < this.options.margins.top ) {
302
+ coords.y1 = this.options.margins.top;
303
+ coords.y2 = this.options.margins.top + targH;
305
- if( coords.x2 > this.imgW ) {
306
- coords.x2 = this.imgW;
307
- coords.x1 = this.imgW - targW;
308
+ if( coords.x2 > (this.imgW - this.options.margins.right) ) {
309
+ coords.x2 = this.imgW - this.options.margins.right;
310
+ coords.x1 = coords.x2 - targW;
312
- if( coords.y2 > this.imgH ) {
313
- coords.y2 = this.imgH;
314
- coords.y1 = this.imgH - targH;
315
+ if( coords.y2 > (this.imgH - this.options.margins.bottom) ) {
316
+ coords.y2 = this.imgH - this.options.margins.bottom;
317
+ coords.y1 = coords.y2 - targH;
320
// ensure we're within the bounds
321
- if( coords.x1 < 0 ) coords.x1 = 0;
322
- if( coords.y1 < 0 ) coords.y1 = 0;
323
- if( coords.x2 > this.imgW ) coords.x2 = this.imgW;
324
- if( coords.y2 > this.imgH ) coords.y2 = this.imgH;
325
+ if( coords.x1 < this.options.margins.left ) coords.x1 = this.options.margins.left;
326
+ if( coords.y1 < this.options.margins.top ) coords.y1 = this.options.margins.top;
327
+ if( coords.x2 > (this.imgW - this.options.margins.right) ) coords.x2 = this.imgW - this.options.margins.right;
328
+ if( coords.y2 > (this.imgH - this.options.margins.bottom) ) coords.y2 = this.imgH - this.options.margins.bottom;
330
// This is passed as null in onload
331
if( direction != null ) {
336
- // dump( 'setAreaCoords (out) : ' + coords.x1 + ',' + coords.y1 + ',' + coords.x2 + ',' + coords.y2 + '\n' );
337
+// dump( 'setAreaCoords (out) : ' + coords.x1 + ',' + coords.y1 + ',' + coords.x2 + ',' + coords.y2 + '\n' );
338
this.areaCoords = coords;
341
@@ -1000,8 +1137,58 @@
342
this.handleS.style.left = horizHandlePos;
343
this.handleW.style.top = vertHandlePos;
345
+ if ((areaWidth < this.options.allWidth)&&(areaHeight<this.options.allHeight)) {
346
+ if (this.applyLinked) {
347
+ this.dragArea.removeChild(this.applyButton);
348
+ this.applyLinked = false;
350
+ this.east.className = "imgCrop_overlay";
351
+ this.west.className = "imgCrop_overlay";
352
+ this.north.className = "imgCrop_overlay";
353
+ this.south.className = "imgCrop_overlay";
354
+ } else if (areaWidth < this.options.allWidth) {
355
+ if ((this.options.onApplyClick)&&(!this.applyLinked)) {
356
+ this.dragArea.appendChild(this.applyButton);
357
+ this.applyLinked = true;
359
+ this.east.className = "imgCrop_selArea";
360
+ this.west.className = "imgCrop_selArea";
361
+ this.north.className = "imgCrop_overlay";
362
+ this.south.className = "imgCrop_overlay";
363
+ } else if (areaHeight < this.options.allHeight) {
364
+ if ((this.options.onApplyClick)&&(!this.applyLinked)) {
365
+ this.dragArea.appendChild(this.applyButton);
366
+ this.applyLinked = true;
368
+ this.east.className = "imgCrop_overlay";
369
+ this.west.className = "imgCrop_overlay";
370
+ this.north.className = "imgCrop_selArea";
371
+ this.south.className = "imgCrop_selArea";
373
+ if ((this.options.onApplyClick)&&(!this.applyLinked)) {
374
+ this.dragArea.appendChild(this.applyButton);
375
+ this.applyLinked = true;
377
+ this.east.className = "imgCrop_overlay";
378
+ this.west.className = "imgCrop_overlay";
379
+ this.north.className = "imgCrop_overlay";
380
+ this.south.className = "imgCrop_overlay";
383
// draw the four overlays
384
- this.north.style.height = params[1];
385
+ var northStyle = this.north.style;
386
+ northStyle.height = params[1];
387
+ northStyle.left = params[0];
388
+ northStyle.width = params[2];
390
+ var neStyle = this.north_east.style;
391
+ neStyle.height = params[1];
392
+ neStyle.width = params[0];
394
+ var nwStyle = this.north_west.style;
395
+ nwStyle.height = params[1];
396
+ nwStyle.left = params[4];
397
+ nwStyle.width = params[6];
399
var eastStyle = this.east.style;
400
eastStyle.top = params[1];
401
@@ -1012,12 +1199,33 @@
402
var southStyle = this.south.style;
403
southStyle.top = params[5];
404
southStyle.height = params[7];
405
+ southStyle.left = params[0];
406
+ southStyle.width = params[2];
408
+ var seStyle = this.south_east.style;
409
+ seStyle.top = params[5];
410
+ seStyle.height = params[7];
411
+ seStyle.width = params[0];
413
+ var swStyle = this.south_west.style;
414
+ swStyle.top = params[5];
415
+ swStyle.height = params[7];
416
+ swStyle.left = params[4];
417
+ swStyle.width = params[6];
419
var westStyle = this.west.style;
420
westStyle.top = params[1];
421
westStyle.height = params[3];
422
westStyle.width = params[0];
425
+ if (this.applyButton.parentNode) {
426
+ var applyStyle = this.applyButton.style;
427
+ applyStyle.left = params[4];
428
+ applyStyle.top = params[5];
432
// call the draw method on sub classes
435
@@ -1067,7 +1275,9 @@
436
startResize: function( e ) {
437
this.startCoords = this.cloneCoords( this.areaCoords );
439
+ this.altered = true;
440
this.resizing = true;
442
this.resizeHandle = Event.element( e ).classNames().toString().replace(/([^N|NE|E|SE|S|SW|W|NW])+/, '');
443
// dump( 'this.resizeHandle : ' + this.resizeHandle + '\n' );
445
@@ -1081,12 +1291,22 @@
448
startDrag: function( e ) {
449
+ if (!this.dragging) {
450
+ var curtime = new Date();
451
+ this.start_time = curtime.getTime();
455
this.clickCoords = this.getCurPos( e );
457
this.setAreaCoords( { x1: this.clickCoords.x, y1: this.clickCoords.y, x2: this.clickCoords.x, y2: this.clickCoords.y }, false, false, null );
459
+ this.altered = true;
460
this.dragging = true;
462
+ if (this.options.onClick)
463
+ this.dragged = false;
465
this.onDrag( e ); // incase the user just clicks once after already making a selection
468
@@ -1101,12 +1321,15 @@
469
getCurPos: function( e ) {
470
// get the offsets for the wrapper within the document
471
var el = this.imgWrap, wrapOffsets = Position.cumulativeOffset( el );
473
// remove any scrolling that is applied to the wrapper (this may be buggy) - don't count the scroll on the body as that won't affect us
474
+/* DS: Causes problems in Opera9 (IE, Seamonkey are OK)
475
while( el.nodeName != 'BODY' ) {
476
wrapOffsets[1] -= el.scrollTop || 0;
477
wrapOffsets[0] -= el.scrollLeft || 0;
482
x: Event.pointerX(e) - wrapOffsets[0],
483
y: Event.pointerY(e) - wrapOffsets[1]
484
@@ -1122,6 +1345,7 @@
486
onDrag: function( e ) {
487
if( this.dragging || this.resizing ) {
488
+ this.dragged = true;
490
var resizeHandle = null;
491
var curPos = this.getCurPos( e );
492
@@ -1191,17 +1415,108 @@
496
- endCrop : function() {
497
+ endCrop : function(e) {
501
+ if ((this.dragging)&&(this.start_time)) {
502
+ var curtime = new Date();
503
+ var duration = curtime.getTime() - this.start_time;
505
+ if (duration < this.options.clickDuration) click = true;
509
this.dragging = false;
510
this.resizing = false;
516
+ if ((w>this.options.allWidth)||(h>this.options.allHeight)) click = false;
520
+ var x = this.areaCoords.x1;
521
+ var y = this.areaCoords.y1;
523
+ if (this.selected) {
524
+ this.options.onCancelCrop();
526
+ } else if (this.options.onClick) {
527
+ this.options.onClick(e,
535
+ } else if ((w>this.options.allWidth)||(h>this.options.allHeight)) {
536
+ if (!this.dragged) this.onDrag( e );
538
+ if (this.altered) {
539
this.options.onEndCrop(
546
+ this.altered = false;
548
+ this.selected = true;
555
+ * Passes the values of the select area on to the appropriate
556
+ * callback function on double click in cropping area
561
+ dblClick : function() {
562
+ this.dragging = false;
563
+ this.resizing = false;
565
+ var w = this.calcW();
566
+ var h = this.calcH();
568
+ if ((w > this.options.allWidth)&&(h > this.options.allHeight)) {
569
+ this.options.onDblClick(
580
+ * Passes the values of the select area on to the appropriate
581
+ * callback function on a click on apply button
586
+ applyClick : function(ev) {
587
+ this.dragging = false;
588
+ this.resizing = false;
590
+ this.options.onApplyClick(
597
+ //ev.cancelBubble = true;
602
diff -dPNurbB cropper.1.2/licence.txt cropper/licence.txt
603
--- cropper.1.2/licence.txt 2006-10-30 20:58:25.000000000 +0100
604
+++ cropper/licence.txt 1970-01-01 01:00:00.000000000 +0100
606
-Copyright (c) 2006, David Spurr (www.defusion.org.uk)
607
-All rights reserved.
609
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
611
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
612
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
613
- * Neither the name of the David Spurr nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
615
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
617
-http://www.opensource.org/licenses/bsd-license.php
618
\ No newline at end of file