| [ Index ] |
PHP Cross Reference of Wordpress 2.9.1 |
[Summary view] [Print] [Text view]
1 /* 2 * imgAreaSelect jQuery plugin 3 * version 0.9.1 4 * 5 * Copyright (c) 2008-2009 Michal Wojciechowski (odyniec.net) 6 * 7 * Dual licensed under the MIT (MIT-LICENSE.txt) 8 * and GPL (GPL-LICENSE.txt) licenses. 9 * 10 * http://odyniec.net/projects/imgareaselect/ 11 * 12 */ 13 14 (function($) { 15 16 var abs = Math.abs, 17 max = Math.max, 18 min = Math.min, 19 round = Math.round; 20 21 function div() { 22 return $('<div/>'); 23 } 24 25 $.imgAreaSelect = function (img, options) { 26 var 27 28 $img = $(img), 29 30 imgLoaded, 31 32 $box = div(), 33 $area = div(), 34 $border = div().add(div()).add(div()).add(div()), 35 $outer = div().add(div()).add(div()).add(div()), 36 $handles = $([]), 37 38 $areaOpera, 39 40 left, top, 41 42 imgOfs, 43 44 imgWidth, imgHeight, 45 46 $parent, 47 48 parOfs, 49 50 zIndex = 0, 51 52 position = 'absolute', 53 54 startX, startY, 55 56 scaleX, scaleY, 57 58 resizeMargin = 10, 59 60 resize, 61 62 aspectRatio, 63 64 shown, 65 66 x1, y1, x2, y2, 67 68 selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 }, 69 70 $p, d, i, o, w, h, adjusted; 71 72 function viewX(x) { 73 return x + imgOfs.left - parOfs.left; 74 } 75 76 function viewY(y) { 77 return y + imgOfs.top - parOfs.top; 78 } 79 80 function selX(x) { 81 return x - imgOfs.left + parOfs.left; 82 } 83 84 function selY(y) { 85 return y - imgOfs.top + parOfs.top; 86 } 87 88 function evX(event) { 89 return event.pageX - parOfs.left; 90 } 91 92 function evY(event) { 93 return event.pageY - parOfs.top; 94 } 95 96 function getSelection(noScale) { 97 var sx = noScale || scaleX, sy = noScale || scaleY; 98 99 return { x1: round(selection.x1 * sx), 100 y1: round(selection.y1 * sy), 101 x2: round(selection.x2 * sx), 102 y2: round(selection.y2 * sy), 103 width: round(selection.x2 * sx) - round(selection.x1 * sx), 104 height: round(selection.y2 * sy) - round(selection.y1 * sy) }; 105 } 106 107 function setSelection(x1, y1, x2, y2, noScale) { 108 var sx = noScale || scaleX, sy = noScale || scaleY; 109 110 selection = { 111 x1: round(x1 / sx), 112 y1: round(y1 / sy), 113 x2: round(x2 / sx), 114 y2: round(y2 / sy) 115 }; 116 117 selection.width = (x2 = viewX(selection.x2)) - (x1 = viewX(selection.x1)); 118 selection.height = (y2 = viewX(selection.y2)) - (y1 = viewX(selection.y1)); 119 } 120 121 function adjust() { 122 if (!$img.width()) 123 return; 124 125 imgOfs = { left: round($img.offset().left), top: round($img.offset().top) }; 126 127 imgWidth = $img.width(); 128 imgHeight = $img.height(); 129 130 if ($().jquery == '1.3.2' && $.browser.safari && position == 'fixed') { 131 imgOfs.top += max(document.documentElement.scrollTop, $('body').scrollTop()); 132 133 imgOfs.left += max(document.documentElement.scrollLeft, $('body').scrollLeft()); 134 } 135 136 parOfs = $.inArray($parent.css('position'), ['absolute', 'relative']) + 1 ? 137 { left: round($parent.offset().left) - $parent.scrollLeft(), 138 top: round($parent.offset().top) - $parent.scrollTop() } : 139 position == 'fixed' ? 140 { left: $(document).scrollLeft(), top: $(document).scrollTop() } : 141 { left: 0, top: 0 }; 142 143 left = viewX(0); 144 top = viewY(0); 145 } 146 147 function update(resetKeyPress) { 148 if (!shown) return; 149 150 $box.css({ left: viewX(selection.x1), top: viewY(selection.y1) }) 151 .add($area).width(w = selection.width).height(h = selection.height); 152 153 $area.add($border).add($handles).css({ left: 0, top: 0 }); 154 155 $border 156 .width(max(w - $border.outerWidth() + $border.innerWidth(), 0)) 157 .height(max(h - $border.outerHeight() + $border.innerHeight(), 0)); 158 159 $($outer[0]).css({ left: left, top: top, 160 width: selection.x1, height: imgHeight }); 161 $($outer[1]).css({ left: left + selection.x1, top: top, 162 width: w, height: selection.y1 }); 163 $($outer[2]).css({ left: left + selection.x2, top: top, 164 width: imgWidth - selection.x2, height: imgHeight }); 165 $($outer[3]).css({ left: left + selection.x1, top: top + selection.y2, 166 width: w, height: imgHeight - selection.y2 }); 167 168 w -= $handles.outerWidth(); 169 h -= $handles.outerHeight(); 170 171 switch ($handles.length) { 172 case 8: 173 $($handles[4]).css({ left: w / 2 }); 174 $($handles[5]).css({ left: w, top: h / 2 }); 175 $($handles[6]).css({ left: w / 2, top: h }); 176 $($handles[7]).css({ top: h / 2 }); 177 case 4: 178 $handles.slice(1,3).css({ left: w }); 179 $handles.slice(2,4).css({ top: h }); 180 } 181 182 if (resetKeyPress !== false) { 183 if ($.imgAreaSelect.keyPress != docKeyPress) 184 $(document).unbind($.imgAreaSelect.keyPress, 185 $.imgAreaSelect.onKeyPress); 186 187 if (options.keys) 188 $(document)[$.imgAreaSelect.keyPress]( 189 $.imgAreaSelect.onKeyPress = docKeyPress); 190 } 191 192 if ($.browser.msie && $border.outerWidth() - $border.innerWidth() == 2) { 193 $border.css('margin', 0); 194 setTimeout(function () { $border.css('margin', 'auto'); }, 0); 195 } 196 } 197 198 function doUpdate(resetKeyPress) { 199 adjust(); 200 update(resetKeyPress); 201 x1 = viewX(selection.x1); y1 = viewY(selection.y1); 202 x2 = viewX(selection.x2); y2 = viewY(selection.y2); 203 } 204 205 function hide($elem, fn) { 206 options.fadeSpeed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide(); 207 208 } 209 210 function areaMouseMove(event) { 211 var x = selX(evX(event)) - selection.x1, 212 y = selY(evY(event)) - selection.y1; 213 214 if (!adjusted) { 215 adjust(); 216 adjusted = true; 217 218 $box.one('mouseout', function () { adjusted = false; }); 219 } 220 221 resize = ''; 222 223 if (options.resizable) { 224 if (y <= resizeMargin) 225 resize = 'n'; 226 else if (y >= selection.height - resizeMargin) 227 resize = 's'; 228 if (x <= resizeMargin) 229 resize += 'w'; 230 else if (x >= selection.width - resizeMargin) 231 resize += 'e'; 232 } 233 234 $box.css('cursor', resize ? resize + '-resize' : 235 options.movable ? 'move' : ''); 236 if ($areaOpera) 237 $areaOpera.toggle(); 238 } 239 240 function docMouseUp(event) { 241 $('body').css('cursor', ''); 242 243 if (options.autoHide || selection.width * selection.height == 0) 244 hide($box.add($outer), function () { $(this).hide(); }); 245 246 options.onSelectEnd(img, getSelection()); 247 248 $(document).unbind('mousemove', selectingMouseMove); 249 $box.mousemove(areaMouseMove); 250 } 251 252 function areaMouseDown(event) { 253 if (event.which != 1) return false; 254 255 adjust(); 256 257 if (resize) { 258 $('body').css('cursor', resize + '-resize'); 259 260 x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']); 261 y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']); 262 263 $(document).mousemove(selectingMouseMove) 264 .one('mouseup', docMouseUp); 265 $box.unbind('mousemove', areaMouseMove); 266 } 267 else if (options.movable) { 268 startX = left + selection.x1 - evX(event); 269 startY = top + selection.y1 - evY(event); 270 271 $box.unbind('mousemove', areaMouseMove); 272 273 $(document).mousemove(movingMouseMove) 274 .one('mouseup', function () { 275 options.onSelectEnd(img, getSelection()); 276 277 $(document).unbind('mousemove', movingMouseMove); 278 $box.mousemove(areaMouseMove); 279 }); 280 } 281 else 282 $img.mousedown(event); 283 284 return false; 285 } 286 287 function aspectRatioXY() { 288 x2 = max(left, min(left + imgWidth, 289 x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))); 290 291 y2 = round(max(top, min(top + imgHeight, 292 y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1)))); 293 x2 = round(x2); 294 } 295 296 function aspectRatioYX() { 297 y2 = max(top, min(top + imgHeight, 298 y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1))); 299 x2 = round(max(left, min(left + imgWidth, 300 x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1)))); 301 y2 = round(y2); 302 } 303 304 function doResize() { 305 if (abs(x2 - x1) < options.minWidth) { 306 x2 = x1 - options.minWidth * (x2 < x1 || -1); 307 308 if (x2 < left) 309 x1 = left + options.minWidth; 310 else if (x2 > left + imgWidth) 311 x1 = left + imgWidth - options.minWidth; 312 } 313 314 if (abs(y2 - y1) < options.minHeight) { 315 y2 = y1 - options.minHeight * (y2 < y1 || -1); 316 317 if (y2 < top) 318 y1 = top + options.minHeight; 319 else if (y2 > top + imgHeight) 320 y1 = top + imgHeight - options.minHeight; 321 } 322 323 x2 = max(left, min(x2, left + imgWidth)); 324 y2 = max(top, min(y2, top + imgHeight)); 325 326 if (aspectRatio) 327 if (abs(x2 - x1) / aspectRatio > abs(y2 - y1)) 328 aspectRatioYX(); 329 else 330 aspectRatioXY(); 331 332 if (abs(x2 - x1) > options.maxWidth) { 333 x2 = x1 - options.maxWidth * (x2 < x1 || -1); 334 if (aspectRatio) aspectRatioYX(); 335 } 336 337 if (abs(y2 - y1) > options.maxHeight) { 338 y2 = y1 - options.maxHeight * (y2 < y1 || -1); 339 if (aspectRatio) aspectRatioXY(); 340 } 341 342 selection = { x1: selX(min(x1, x2)), x2: selX(max(x1, x2)), 343 y1: selY(min(y1, y2)), y2: selY(max(y1, y2)), 344 width: abs(x2 - x1), height: abs(y2 - y1) }; 345 346 update(); 347 348 options.onSelectChange(img, getSelection()); 349 } 350 351 function selectingMouseMove(event) { 352 x2 = resize == '' || /w|e/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2); 353 y2 = resize == '' || /n|s/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2); 354 355 doResize(); 356 357 return false; 358 359 } 360 361 function doMove(newX1, newY1) { 362 x2 = (x1 = newX1) + selection.width; 363 y2 = (y1 = newY1) + selection.height; 364 365 selection = $.extend(selection, { x1: selX(x1), y1: selY(y1), 366 x2: selX(x2), y2: selY(y2) }); 367 368 update(); 369 370 options.onSelectChange(img, getSelection()); 371 } 372 373 function movingMouseMove(event) { 374 x1 = max(left, min(startX + evX(event), left + imgWidth - selection.width)); 375 y1 = max(top, min(startY + evY(event), top + imgHeight - selection.height)); 376 377 doMove(x1, y1); 378 379 event.preventDefault(); 380 381 return false; 382 } 383 384 function startSelection() { 385 adjust(); 386 387 x2 = x1; 388 y2 = y1; 389 390 doResize(); 391 392 resize = ''; 393 394 if ($outer.is(':not(:visible)')) 395 $box.add($outer).hide().fadeIn(options.fadeSpeed||0); 396 397 shown = true; 398 399 $(document).unbind('mouseup', cancelSelection) 400 .mousemove(selectingMouseMove).one('mouseup', docMouseUp); 401 $box.unbind('mousemove', areaMouseMove); 402 403 options.onSelectStart(img, getSelection()); 404 } 405 406 function cancelSelection() { 407 $(document).unbind('mousemove', startSelection); 408 hide($box.add($outer)); 409 410 selection = { x1: selX(x1), y1: selY(y1), x2: selX(x1), y2: selY(y1), 411 width: 0, height: 0 }; 412 413 options.onSelectChange(img, getSelection()); 414 options.onSelectEnd(img, getSelection()); 415 } 416 417 function imgMouseDown(event) { 418 if (event.which != 1 || $outer.is(':animated')) return false; 419 420 adjust(); 421 startX = x1 = evX(event); 422 startY = y1 = evY(event); 423 424 $(document).one('mousemove', startSelection) 425 .one('mouseup', cancelSelection); 426 427 return false; 428 } 429 430 function parentScroll() { 431 doUpdate(false); 432 } 433 434 function imgLoad() { 435 imgLoaded = true; 436 437 setOptions(options = $.extend({ 438 classPrefix: 'imgareaselect', 439 movable: true, 440 resizable: true, 441 parent: 'body', 442 onInit: function () {}, 443 onSelectStart: function () {}, 444 onSelectChange: function () {}, 445 onSelectEnd: function () {} 446 }, options)); 447 448 $box.add($outer).css({ visibility: '' }); 449 450 if (options.show) { 451 shown = true; 452 adjust(); 453 update(); 454 $box.add($outer).hide().fadeIn(options.fadeSpeed||0); 455 } 456 457 setTimeout(function () { options.onInit(img, getSelection()); }, 0); 458 } 459 460 var docKeyPress = function(event) { 461 var k = options.keys, d, t, key = event.keyCode || event.which; 462 463 d = !isNaN(k.alt) && (event.altKey || event.originalEvent.altKey) ? k.alt : 464 !isNaN(k.ctrl) && event.ctrlKey ? k.ctrl : 465 !isNaN(k.shift) && event.shiftKey ? k.shift : 466 !isNaN(k.arrows) ? k.arrows : 10; 467 468 if (k.arrows == 'resize' || (k.shift == 'resize' && event.shiftKey) || 469 (k.ctrl == 'resize' && event.ctrlKey) || 470 (k.alt == 'resize' && (event.altKey || event.originalEvent.altKey))) 471 { 472 switch (key) { 473 case 37: 474 d = -d; 475 case 39: 476 t = max(x1, x2); 477 x1 = min(x1, x2); 478 x2 = max(t + d, x1); 479 if (aspectRatio) aspectRatioYX(); 480 break; 481 case 38: 482 d = -d; 483 case 40: 484 t = max(y1, y2); 485 y1 = min(y1, y2); 486 y2 = max(t + d, y1); 487 if (aspectRatio) aspectRatioXY(); 488 break; 489 default: 490 return; 491 } 492 493 doResize(); 494 } 495 else { 496 x1 = min(x1, x2); 497 y1 = min(y1, y2); 498 499 switch (key) { 500 case 37: 501 doMove(max(x1 - d, left), y1); 502 break; 503 case 38: 504 doMove(x1, max(y1 - d, top)); 505 break; 506 case 39: 507 doMove(x1 + min(d, imgWidth - selX(x2)), y1); 508 break; 509 case 40: 510 doMove(x1, y1 + min(d, imgHeight - selY(y2))); 511 break; 512 default: 513 return; 514 } 515 } 516 517 return false; 518 }; 519 520 function styleOptions($elem, props) { 521 for (option in props) 522 if (options[option] !== undefined) 523 $elem.css(props[option], options[option]); 524 } 525 526 function setOptions(newOptions) { 527 if (newOptions.parent) 528 ($parent = $(newOptions.parent)).append($box.add($outer)); 529 530 options = $.extend(options, newOptions); 531 532 adjust(); 533 534 if (newOptions.handles != null) { 535 $handles.remove(); 536 $handles = $([]); 537 538 i = newOptions.handles ? newOptions.handles == 'corners' ? 4 : 8 : 0; 539 540 while (i--) 541 $handles = $handles.add(div()); 542 543 $handles.addClass(options.classPrefix + '-handle').css({ 544 position: 'absolute', 545 fontSize: 0, 546 zIndex: zIndex + 1 || 1 547 }); 548 549 if (!parseInt($handles.css('width'))) 550 $handles.width(5).height(5); 551 552 if (o = options.borderWidth) 553 $handles.css({ borderWidth: o, borderStyle: 'solid' }); 554 555 styleOptions($handles, { borderColor1: 'border-color', 556 borderColor2: 'background-color', 557 borderOpacity: 'opacity' }); 558 } 559 560 scaleX = options.imageWidth / imgWidth || 1; 561 scaleY = options.imageHeight / imgHeight || 1; 562 563 if (newOptions.x1 != null) { 564 setSelection(newOptions.x1, newOptions.y1, newOptions.x2, 565 newOptions.y2); 566 newOptions.show = !newOptions.hide; 567 } 568 569 if (newOptions.keys) 570 options.keys = $.extend({ shift: 1, ctrl: 'resize' }, 571 newOptions.keys); 572 573 $outer.addClass(options.classPrefix + '-outer'); 574 $area.addClass(options.classPrefix + '-selection'); 575 for (i = 0; i++ < 4;) 576 $($border[i-1]).addClass(options.classPrefix + '-border' + i); 577 578 styleOptions($area, { selectionColor: 'background-color', 579 selectionOpacity: 'opacity' }); 580 styleOptions($border, { borderOpacity: 'opacity', 581 borderWidth: 'border-width' }); 582 styleOptions($outer, { outerColor: 'background-color', 583 outerOpacity: 'opacity' }); 584 if (o = options.borderColor1) 585 $($border[0]).css({ borderStyle: 'solid', borderColor: o }); 586 if (o = options.borderColor2) 587 $($border[1]).css({ borderStyle: 'dashed', borderColor: o }); 588 589 $box.append($area.add($border).add($handles).add($areaOpera)); 590 591 if ($.browser.msie) { 592 if (o = $outer.css('filter').match(/opacity=([0-9]+)/)) 593 $outer.css('opacity', o[1]/100); 594 if (o = $border.css('filter').match(/opacity=([0-9]+)/)) 595 $border.css('opacity', o[1]/100); 596 } 597 598 if (newOptions.hide) 599 hide($box.add($outer)); 600 else if (newOptions.show && imgLoaded) { 601 shown = true; 602 $box.add($outer).fadeIn(options.fadeSpeed||0); 603 doUpdate(); 604 } 605 606 aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1]; 607 608 if (options.disable || options.enable === false) { 609 $box.unbind('mousemove', areaMouseMove).unbind('mousedown', areaMouseDown); 610 $img.add($outer).unbind('mousedown', imgMouseDown); 611 $(window).unbind('resize', parentScroll); 612 $img.add($img.parents()).unbind('scroll', parentScroll); 613 } 614 else if (options.enable || options.disable === false) { 615 if (options.resizable || options.movable) 616 $box.mousemove(areaMouseMove).mousedown(areaMouseDown); 617 618 if (!options.persistent) 619 $img.add($outer).mousedown(imgMouseDown); 620 $(window).resize(parentScroll); 621 $img.add($img.parents()).scroll(parentScroll); 622 } 623 624 options.enable = options.disable = undefined; 625 } 626 627 this.getOptions = function () { return options; }; 628 629 this.setOptions = setOptions; 630 631 this.getSelection = getSelection; 632 633 this.setSelection = setSelection; 634 635 this.update = doUpdate; 636 637 $p = $img; 638 639 while ($p.length && !$p.is('body')) { 640 if (!isNaN($p.css('z-index')) && $p.css('z-index') > zIndex) 641 zIndex = $p.css('z-index'); 642 if ($p.css('position') == 'fixed') 643 position = 'fixed'; 644 645 $p = $p.parent(); 646 } 647 648 if (!isNaN(options.zIndex)) 649 zIndex = options.zIndex; 650 651 if ($.browser.msie) 652 $img.attr('unselectable', 'on'); 653 654 $.imgAreaSelect.keyPress = $.browser.msie || 655 $.browser.safari ? 'keydown' : 'keypress'; 656 657 if ($.browser.opera) 658 $areaOpera = div().css({ width: '100%', height: '100%', 659 position: 'absolute', zIndex: zIndex + 2 || 2 }); 660 661 $box.add($outer).css({ visibility: 'hidden', position: position, 662 overflow: 'hidden', zIndex: zIndex || '0' }); 663 $box.css({ zIndex: zIndex + 2 || 2 }); 664 $area.add($border).css({ position: 'absolute' }); 665 666 img.complete || img.readyState == 'complete' || !$img.is('img') ? 667 imgLoad() : $img.one('load', imgLoad); 668 669 }; 670 671 $.fn.imgAreaSelect = function (options) { 672 options = options || {}; 673 674 this.each(function () { 675 if ($(this).data('imgAreaSelect')) 676 $(this).data('imgAreaSelect').setOptions(options); 677 else { 678 if (options.enable === undefined && options.disable === undefined) 679 options.enable = true; 680 681 $(this).data('imgAreaSelect', new $.imgAreaSelect(this, options)); 682 } 683 }); 684 685 if (options.instance) 686 return $(this).data('imgAreaSelect'); 687 688 return this; 689 }; 690 691 })(jQuery);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Fri Jan 8 00:19:48 2010 | Cross-referenced by PHPXref 0.7 |