From 95c7668f6832030cbfa47f68fda30660eb05f49b Mon Sep 17 00:00:00 2001 From: Antoine Vandecreme Date: Wed, 5 Feb 2014 15:52:31 -0500 Subject: [PATCH 01/17] Pass degrees from the viewer to the viewport. Fix #305 --- src/viewer.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/viewer.js b/src/viewer.js index 2139678e..e7fc0a1f 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1416,7 +1416,8 @@ function openTileSource( viewer, source ) { showNavigator: false, minZoomImageRatio: 1, maxZoomPixelRatio: 1, - viewer: _this //, + viewer: _this, + degrees: _this.degrees //, //TODO: figure out how to support these in a way that makes sense //minZoomLevel: this.minZoomLevel, //maxZoomLevel: this.maxZoomLevel @@ -1438,7 +1439,8 @@ function openTileSource( viewer, source ) { defaultZoomLevel: _this.defaultZoomLevel, minZoomLevel: _this.minZoomLevel, maxZoomLevel: _this.maxZoomLevel, - viewer: _this + viewer: _this, + degrees: _this.degrees }); } From e73e5a9528069acca3d88194517a650b7fbe11e4 Mon Sep 17 00:00:00 2001 From: Ian Gilman Date: Mon, 17 Feb 2014 09:40:30 -0800 Subject: [PATCH 02/17] Changelog for #336 --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index b7086bf9..a9f13430 100644 --- a/changelog.txt +++ b/changelog.txt @@ -12,6 +12,7 @@ OPENSEADRAGON CHANGELOG * Added 'ABSOLUTE' as a navigatorPosition option, along with corresponding navigatorTop, navigatorLeft options. Allows the navigator minimap to be placed anywhere in the viewer (#310) * Enhanced the navigatorTop, navigatorLeft, navigatorHeight, and navigatorWidth options to allow a number for pixel units or a string for other element units (%, em, etc.) (#310) * Additional enhancements for IIIF support (#315) +* Fixed: Setting degrees in Viewer constructor has no effect (#336) 1.0.0: From 2fd1a849d19c26948a6f0222f0c139b4b2f088a2 Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Thu, 20 Feb 2014 13:57:39 -0700 Subject: [PATCH 03/17] Added rotate right/left buttons to default tools --- images/rotateleft_grouphover.png | Bin 0 -> 1824 bytes images/rotateleft_hover.png | Bin 0 -> 2100 bytes images/rotateleft_pressed.png | Bin 0 -> 2058 bytes images/rotateleft_rest.png | Bin 0 -> 1824 bytes images/rotateright_grouphover.png | Bin 0 -> 1832 bytes images/rotateright_hover.png | Bin 0 -> 2105 bytes images/rotateright_pressed.png | Bin 0 -> 2053 bytes images/rotateright_rest.png | Bin 0 -> 1817 bytes src/viewer.js | 62 ++++++++++++++++++++++++++++++ 9 files changed, 62 insertions(+) create mode 100644 images/rotateleft_grouphover.png create mode 100644 images/rotateleft_hover.png create mode 100644 images/rotateleft_pressed.png create mode 100644 images/rotateleft_rest.png create mode 100644 images/rotateright_grouphover.png create mode 100644 images/rotateright_hover.png create mode 100644 images/rotateright_pressed.png create mode 100644 images/rotateright_rest.png diff --git a/images/rotateleft_grouphover.png b/images/rotateleft_grouphover.png new file mode 100644 index 0000000000000000000000000000000000000000..012b195993cb38eb347f5f3441238120ea4e23bc GIT binary patch literal 1824 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 literal 0 HcmV?d00001 diff --git a/images/rotateright_rest.png b/images/rotateright_rest.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed7cc29ba9d29d09eb01abdcbdb05c0a1c37471 GIT binary patch literal 1817 zcmV+!2j=*RP)500009a7bBm000XU z000XU0RWnu7ytkO8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?2Bt|w zK~#9!)L7e36jvCZ+g@;Cx$MeyiFhkPk~W5<;+r&LjWLbd7&K|Lv3-N2NfQ%&(3JY% zKj4G$g%?Y)#l)0EeZV$pQ)42f#HvUEl>mE@U07Ilm))J&>F*n7n!_-&pbw2b$(LDX z&gFN0-|su$ci>f3<=&Mhz0DvVZKHkFH`pz|(Y|j2;BA4e3&sKjZ+aG7-}Ed9svsB> z5Z=bjz*qoQW(&v`3lzvSeqnC zHAO{5wdS$ubUL`QvJ&a(>G|#2wQCD_B{OD#(y-7vETA>aSO5`q(2k*@p%Wz~CCy&1 zx4yWzxC($oGZG0pb7~{*xz9o~f>` zZt-|Lm7*xBilV6bd|owcMi2xt9^ZsyG8qYlLVsMoeEEmIzP>0vXBbdx0NH^tG~qaR z?%d{6r%rtZARoXj#RLGmH#Vd7!!ScX+I#%1fHlnxaM^M=93HuN@nTPZfBzi%tiZB5 zAVX8D!I)SPbl12>Mn=AFXlQ72p#el5W?&b=fCO{HoET0l5?h2cOHaJlKxHzS)QcA{ ze%ZZycMr)*2b9rWW(b?J0%M5P`QX8W&$eybb`<(3V}Z~nXmPZn+1c66eSP2io0^)G z9Xoc&J9oa9b-UeZfXTp>8T3oTWVkH$ZxWx6RR|xmd6{+=Ro24}XNH31Go2!Ziy(vfdQ+H8sSHi(FJ+9{_6#XV}EVq%b%* z=)8LMY6ZFq*oaJkDk>_rc6N4tsFNTu+T;o`BS5ST*o_AhWp%-lO9j#iCU!a;j?(Gr zX+K=#MZ^eJ=hcA&2U6HXHkZqhJ7mbt13&?NT~RmLV8-gu(*R-Dn@RC#3XIdEM8bQw z)9LiWB{es0-0;|?5@=1?zrQ__N~Mw*pTT$q8xSzo#{gNCR_sa$9tT$%q6=aYFPM>t z8S!;?~XiGFN;~s&{ZV_1)!zR8AHAdvwm~;)Fc{*oD7SB4Te`Bcatd=y!orJa5P7nurbfcw zl0|N_XXetSOQGx6uhY@aVR9aGr4|+zvN*tU09AhP-k^lvTHlV26X}kQj;PmLn(OZV zruO;sNeNmR`Wp>l9|F7NA{oKJ(|ph%XOZ;_S9+kA1FhQ8PLoi;;Yr6l2OyeY!9e!( z>CeXjG@MGM)iY6KA$g7 zd5B(7RN=Q$S67$At{pfxa*0GDj^DG`aR#h~F)oiNiz7*1Os1vya%!%l$0Qe$#W^8OM6buFvV1S~KHbRFZ zk5inVnVAug&F7iJj;(Pl!Dt`v+`02Bl+TTij|&iQ5;!Gj0K>godW@bIuJ znOycFT#HBxq$}78bRq+Ip2m=i1A%}rF)<-vKDD>E_fH+n8bE?wg*GrSuz<*kK6>;> zD+kKT%2ez&H#ax8ga`|FcYpiWu3fuQV1m=nqC6O)q)4oiJ4yUpd3m`&>EiL@$CN@A zv4KUV*vhl6GABwSV^fZCQJ(4Q>iQCHqV%A^ZA7yOt&~<(RrwJ5Zm^JsWMTlA02^|i zkiV{JIFudSmMvTOyLayjm0qD5n9-1{v9Zy& zef##-Xf*13`SRtOa|#-faW*Z0jbVI`>x*U?KpU%p*Sj5 Date: Thu, 20 Feb 2014 14:04:26 -0700 Subject: [PATCH 04/17] Fixed code style issue. --- src/viewer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/viewer.js b/src/viewer.js index 6c3a91fb..ca20ca98 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -2152,7 +2152,7 @@ function onFullScreen() { function onRotateLeft() { if ( this.viewport ) { var currRotation = this.viewport.getRotation(); - if (currRotation == 0) { + if (currRotation === 0) { currRotation = 270; } else { @@ -2168,7 +2168,7 @@ function onRotateLeft() { function onRotateRight() { if ( this.viewport ) { var currRotation = this.viewport.getRotation(); - if (currRotation == 270) { + if (currRotation === 270) { currRotation = 0; } else { From e8697e5c19d220536b002af02d7deadb59e95a15 Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Thu, 20 Feb 2014 15:03:13 -0700 Subject: [PATCH 05/17] Updated images for rotate left/right to better match existing buttons. --- images/rotateleft_grouphover.png | Bin 1824 -> 1902 bytes images/rotateleft_hover.png | Bin 2100 -> 2289 bytes images/rotateleft_pressed.png | Bin 2058 -> 2242 bytes images/rotateleft_rest.png | Bin 1824 -> 1943 bytes images/rotateright_grouphover.png | Bin 1832 -> 1970 bytes images/rotateright_hover.png | Bin 2105 -> 2338 bytes images/rotateright_pressed.png | Bin 2053 -> 2228 bytes images/rotateright_rest.png | Bin 1817 -> 1961 bytes 8 files changed, 0 insertions(+), 0 deletions(-) diff --git a/images/rotateleft_grouphover.png b/images/rotateleft_grouphover.png index 012b195993cb38eb347f5f3441238120ea4e23bc..9aec7ac9454f6e5d71401d2994f7929823da57a8 100644 GIT binary patch delta 1843 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 delta 1764 zcmV5ks&>Qtw}^dRCwCdSX)dKR~Vi%Gs`Y_MB^3I zNP?|sTR{R^`(h=H)x^d`tLaN0mDr@FF;)83%X4djNn>m1lb1vj#28<+q&~F9C=enD zA_!WIid^IlyECWXcY0~0_ z0Amgf4T<65VTotU#*G_4$IoMsQT?3Mpqxa8%sBu_1sg?8O-*+fFJ8QU`SRs*!GZ-b z%d(;|-v9_c9RAMtm}lhY=dW#SZ2WWY-o5LvPYxuL`{{i>-;19cWG2s1`7V5apjM zkrp>o0xNXT2sLSFXt)avQ_|DZ9cb@jsOez9^pj>lQ9t7=fR-0K!8|9AM!93x`|x?%lJlT)AQ$ zKVEG=d-lxI$_W5cN^%WZ42Q!mm<`w0*Z+(;boz9ytnG`)8D}+G{(xnnnWMJO3ki~auEz;7`1kAR7di(b6g_kZ} zYSyew>geLR((ge2#1`7IW5;(`EKJjML9?QFag!+l5^_Dt1zE5!#UkeN6rP-`G@(L|EWP&0nsw(Vm# zh#gPPo;@R;K7DF(kQr?%NmGxEjJVv_S5o{AERy9JF*rDAz+oMKY&;I_EI6Q@o0}^U z6>`(2_e0mN{lV}ykO+-Oj~-3i;KGGkv1iYx5@vIeg&hI`TgH+lOCsD?gYd*m7ESR% zdbNWJXe7as)8F4ODaFMlMs00vXw|A!#{T`4(00VAtE)55oH?yF?da$bTef`YK7Rbz z)#fo!J_PsUzCL$99T_nW@8e?)*f8MXSF4 zcfqxcC<*~6f53pb)jOSWXJlYISyP0F7{%t{`Sa)7&cB0zRD=)^!ag=OHb%!Z5J3WF zkeI7B$ji&~d_^h2w1Y@8nHceTLgyAw+}Xe=K+vKYCMidM!Lz}RiYToqMZ$Ed3^2FM zn>SBUegA%!TD)~@g+ZVILpBAHr$Ak^Zr{FbVSZack0awrFM$GgqcIS@47%qM{H|j?D|F~1^@s6)rDaEks&;P2!2UKK~#9!)R=pWR979xf9G*uGk0FQ z?80_|hGn7PgMf{Il!caRZAGgwHDG^{N{6izu)

^zeo`9 zkY#1meBN>k1;&a6F0EAO62qXxj4CV=i&Ub~xO4%@zc+N~w*D>K+vL=j7a(<+XQxsb792D`iawREKF;HH{$QzaM<y}J@m5hr#g1+jtSMr7b{I8@=TO0Y{Q;);Ai)zEd#Y-=;E_l8_| zbfl!FlBvkz-oE>{Y*{DmNB!^z-mjO3X3yZjEBeayx9pUwf`?P@PnIW+A!F6tjx$-+ zOpR(JnbsPXvkQqh6LS-P1yPtZ2zEFjj0$i$RtZH$I2_6xJyM#h>ACW3FWD z39w`(un`B_1&J+WQs|}ggPuNTPM)>TnJ=f9K@yjOI#dP1O;xskn!GRn`qA$>oRdg8 zRVtpjAl#&j=0S!ny>XmdRvz;CJXn@h*U7Uk+V#9jFBL4^=uE1rmQ;wHreIAH$Y%X| zq?8BGaWkEEn6&$wZ4Z6j&&eQ6v{jhuITP>b*n~_lrP(R`izi{vHdlaovHG;5=1Ckj)V&6ey%qfV*yBi+Xxi%dhWi-cp)j zsz9#eP-@#kEab5-tjLmGf9xU%wcbX?#sDvlPN*vl&YhydNy_7- z?0~{t89obhyCPi1YUN|f-qvbwLLPGwFop>C6x9=ei=4WDLmXEW=B@6_dP^60_?@$1 zr0X1R=wxttM4MvZcLSL0`Np`yG(&Lt@Z3W#7D846X~(zgIC?`QP~+vstB6m3? z4fxAcQ(U3aJSN`zlz8uAc=)a{u2KiSy5YKb=Ep-~|IR`2<&D?Db=|7QlQJvgGUGdK zMbWsbA)%;$2oxd&bsdH(9%rrkp;n#|{sakwm2g-Zk>%bu#DUOBjNKs(8xf9va(hy& zxv>n+u@Lx=`M~EgP$*+K_;##n< zEMCb?Q&l1n4;2fP$Y>!46aImU8OP|>E(g%04$Q)TfDH~f>cZSOs~cI?<{&s1LfApF z5F$j(2<9OZPgHDNymaYQLlqXS!c=dJe(=Pur=4O^Ty(h-y6GlGW*L?4p}u#BCwrq3 z2XRe)IVB01CpRb;u;PJLBvnJ7Uz>x7zdvUP#tdTuh!{(kD3?4=eY@NDJol$yPx2bK zgl3q3dWRM*SjppsBGHyDr&QAjQ8=b;HYifmWI$9Gh$3Y=K-(O^rVDSMHX&qq@Wb0v z0P=-p`Vw6xtfCTa`6tNnVv&S%*=$gGr&Ql6Owda-wu?Toeg4FWpQmMUd!u5L&>goS zAA}|xS%jn_5+KTe#w3)K4{~-~gVdw~yY3r*f%&rXLJq1P^FI%NWdj_l*eI2^;LSsa zo(Y<)a&sHe?3r5MYCrbsfxpemWl!%P9fK^*YySW}b5>be)boC{aL(PXX#&1{e25z^JlvtLgYiS{72PNjX>TD!(ZMRhkb92$hzagng#lW zU;W|GBT&tvD#Wy%-mH4y04UzSp?8yN#GXZnMyxBaD4b^0Fs+^4?GJXGYFdxW`6(9CEs=hSuH-SS@n`mz&rW-14Azc?k@+) zYW>HjgPG1v0aQ4+8o_5wsAH7YZW?1^@s69@(>5ks&;P2f;~1K~#9!)R=8-97h?)pPilEz1utc z&OX1yj^C2lDNtxb)wmT>N(n+iAgFG^2~KEy96(e?acmv z=0DHO^NbbOb>U(8&=1o{!OvEobsu1~^g{wD572JQV9Nc#D?pU1swow8PpEsslzvu<(Jg=!A#{}I z$dMy$s2A$$>h^oR-p=y2>2!KN8jYTR8yp-wb>_^O2;Rz~GEzASRd7zcrxfTeXDWaQ z2m@uFKY#wWO-)T-HcgXIN;mOd9NV*!sS<61jIjVhx#4j5?12LZUKEU|l)Ppo6f1Y= z4wxz+UUZ^!U|`_2P$<-Z5UZR!Yl+0B^?n;d#jJ>KI2T|9YHDg~2_YfQd1!5aZEf?! zi4)%#9v%+k<4Fl+R|2X8qeu`D7v95%5AQgB{P@L&hLA%DETq#(i}MWinQ8zOhR=#V z#6{zb>)0LTmStNAp!=85%TVcmx~4)(MQ_378aVlSCzo%^Ijq*%vBW56~g0|6|V^f{n%fB$N2d8a9>~F zOZfMi1hPtk+AUvAx2NdPp+jxKVDL*+C9B!^LN@4MZ@#rO8W_8}pkKS5QLasY&?r<7 zu)B*xCShr=<5zI@nClXRQFxHjU@96-dqbg(j*gB`_xAR-kBp2IS65boD7RrsTq&*y zt-rtj1+i*KI+b*-q*pb6H}zk<{GO4?+`TXL>~cUQ%T!ZqL@X00SI->g6~T3BSiiIJ6V^S;GIH4L0aVc%n zZ979Y;$9`0)%m7Qp4->Vc6T$egzwTEF5DmfY*QH;dxsjn>$(mRgQgP(x?-p)OVg~R z2mj7f(`=A2sh7ZrcPgY>T1q4mV9(ESXJUf5^UDO*70P3^et+7Ao3WcJ zr7Kj+ZlE)krrcV8qHJHYQWrYfT?o%>g@(BE7OtoMmVlo>8&`6#Gc`ArQnImi7q+$Nys4Sk zDlMj=qDXO?s@5~vY!*m9?=>+EC_p?)ETQB_W1!?R@cc7>7QBA019o=W@bY&SA)Zm; zPiI5$mwz-C+P*c4vGma?a93+^R0h#i#lR(kA?UcG-;!{+qZFwMBb>=Qj-mVgD$_X- zjTg2j7E!^uuEQ@6MxZX3hx~s$U}Cr5-5-PHRUQ8IMgTGy0*cB(F<3$P4b*^7buhR@ zzcQ=y@>+*~Rx66UiMSnBiMO@A8QhgAP!L8)EJik~L3IbD%3b`rG2Jo zAOGjMf4`KnEV!J`g1+}Dv|HM)vBIb!k5G;nJ*v)uO*H7r+kR+o%|ibkBosIBInhRc z@+r7%WkK|J`pj#8C@CZIrBz@x80XJ#Ub@kg-gs|#c>`7(wu82-8%N3Cm$07-r?4L! zxo~TLX3hhTKazrz-=71vh^rN+Pu$nKdSE5A9fl&CP?v}{*p>ndZM=#jOiiZtJiQtK$lb;HM#-@I#Z88&3Mnm?`Z;TNd>lw3BB%P zklVE%esk#-Fo&~WpFDj;CdsJ0#!E^Ge$T9bEvmN9Ki2bjp!?CkHu`lq`l$}+;t}98 z=W&V>g%u-~fTAIoj?*Su=Fktf7D)Ru5O&*O@QrzhS~-|~=gN;qZZ2Mv5EZlbed`$k z^w~$d9^1CF=Z~>;o__6#HaOV39enX=aFdHTreq;D3d7KAL8)zpl>Z~}_mL%dWpoLD z8cdB%PrUonD>ISn_{7GR>X~Ylo&*w8799A>zEf|86FbGT`#-)7KJ$qds5R;Bvq2*5 z!0>nkhQ^l*VeoWk&BE_qz4#OP;<$vkf2DV?8W`o1P_<9@G(Gak-P@1fjM+VJ&#oKg zd%~U_^|>7l#>~j%;>oMCYhhU`i0MdXJWvgMzte$)GNn9axkV}2O}UJNj64x+>2yFV z9n>Wdm$z~yr^38^K}tg2k?6{|2idmLxrtRe$URgi%KwkE_Cxnyi2ud^XSM=S{QOsd Z0RVcRRkdh^Ag2HT002ovPDHLkV1jGH?Qj49 diff --git a/images/rotateleft_pressed.png b/images/rotateleft_pressed.png index e72c917f0020c32a1ce4a9f3208e15d99130d627..b968ebf8ca3bff215d92ac0b41af76e317cff80b 100644 GIT binary patch delta 2186 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 M07*qoM6N<$f}&J83jhEB delta 2001 zcmV;?2QK)+5sDCy7YZW?1^@s69@(>5ks&;P2bW1iK~#9!)R=E<6ZaX%zxU5R$Fbws zj`KfFGYA?;9qpzf4Xvs~KvU^9b<@T=q&BaRs#O|$(Wx);3RRoB4Na2}5^wgR+l0DE z*}75`0a^qFbqLBJ2(*Mi8YdxuV>@>2-1+|eZqHqQ&Wy1`sP=-L^ysX+`#tx$=lTAB zp5ODc;5ZJRmP7tBg9JJ@`mFN=Un_q}0O1M7Z5T{=9C!_gYO5QR8n!Ofx-b8qQDv{~j3=ZW*&V5fM&?Awl z0pddV$r^@-hljemyZ1YcNvW&~kQMp4#G&l!2t5Q-2P8nz=o}gv8ulql*W4#33X3DdammmT2sOeN2&^T4r?jF$ zTP}e4Rm8skgG|@n?*uhnzjyH9!MCnozdlD#EpsTX7Emo1frBUsvbCSVBd`!Hi$?d?TK^&|P4 z_nTF}zxC+Rqi@r#FjA`#eNw(W`mkwhzUfB##=woH*`*LPhl^2jKawW@BKV)6LEgKJk8Wz&G7Hp13y zyu2k1+qNFDi{mPeoQuKew9wS2!QZSCkO_yGV3tXMLAZVvu6&+<>+9>=!9jc+X04Lf zgAr9#-JZE{9zHbyTeqQS7{1n!M_+s4p{SH?=B|vxpCoWc6%l?$hY~80Gm4NK9lGzQ z5|I7pXNW{1{S_cmrDnu>%aUPGM3$Di1ez7bvJO4Vu$*-8%2!i0qf@p&o^3`k%HVG@ zDDD&;x@Kt_1je9$=5h(wFW0JEC19b}a^T%4l}ca^gSE1PqOL(-bYSFdv@0d-{7MRc zITwdaV(slLVQOYo%#tK|HgZ|VkE3aNUP1Am<4tv&wB!17{Z@h0olR?p2g97T>MHrD zu80Jb7VzrxSzMZG#HMZ?KYQ&iG)u(Cm!kOKqXb3A#?@PYG6n}$&={j^m@@Pw2{tjf z{y265H7rv7v@3?;)xq^o7=vfOoz*SO);KEQ* z^QjCDRfr~k&4Nf3!lwEuQUDw(WvwyObI{jG0uH!i7?^28q;%>6{oc|q%+1Z+uIhEl zP)hU1w;FHs24t-iNsSGDunOKC_HEq`!z zjE}|&%@VAZ_AnK^D^)!XtG66D<(s3Uqr-(_k?PMtb+hOgL0MZ@LPicA^Cnx39cP2agQ zG8cR{m{ubO`~=ZJX(Dr9qNpTjy5=sHA_?n$O2N+Uc^v-fZ7}LuB**cfp)ln95hQ)j z25#Peyg8PpgRj`7%2oTJeuggz6 z;zSasK$?*V3bH^Np)Xk$JS!}Vc#u`_hv|X*iX|7RIeUkEx-cnz&Q-J$tX5>oeXF~W zt(-o6`mI#Hq#l`kF*}tH8k+5Rf^>mA5UQbnB28I`T(SZ=a9bzKL6K}S+i3iL{KfoY z-te6~dGbBpHk2Ez%J!jVWFF~f+=Vw33iWQ=w(W=_i>*6)?rA^z#@$FPY(e!Ckht1l zxz&P-HAcY^TS8+>}Lndwbsw1Oj`1 zMFHZbL@~FsKaWivR-!z9YC(Q*VKOXC-48ZVuvoEJ9HZv^&-}$X4)OR-Z@nIvH$yH| zSW%R=U@-VSS(bN*qS#+u6BuJtrfFU&77Ax9+fMV8Py&&Eq8|8hy8{l@z^%Gd6Dsyh zj89vg?+7-uJCJK_)Hx92myC*CVOiKbMGh%ftuLs8G3xA_>{=VSr)o#}|FPG8>i&iJ jU;IC_5s32f9{~mc0t+~-Olpk_00000NkvXXu0mjfY~IlX diff --git a/images/rotateleft_rest.png b/images/rotateleft_rest.png index 21f630b312eb1ad1624aa097666f3e530925d93a..ebbf081b8aa0a038f4ecdd594087150cba1e8ea8 100644 GIT binary patch delta 1885 zcmV-j2cr0(4wny*7YZT>1^@s6)rDaEks&;P2P8>EK~#9!%$Q3|6j>C8tE#IXG&Io7 zt3ePD1d_qmBm#zDT+G5za3*o%XpGU!Bsv>i>fpkSChAf*CPv)h!oE9xzWqC+ z(U_N>p6*OdP0bPnK~%;?qtVFn^75R2*Xwl!gTd)1Po8v~J$rTxx56rmCIb2bMhAo@ zGxqlO9t6O*Sy@??R;$$x2#H<1YOHL4;{AUA!ra{4TPXEcLqo$KxE+Lr7*IqHXcbH% zkiNdYpL23@b^@fFATXIkp@H#i46iuFpHYLsz?0!QVSavo*yVEd)zsA7!6SixwSeL< z2|{B6$S(y21-mmcG74x+I2@)i27cudU?PPIzr`?l2!J#hQA!9W-RC_X&&0=%A3JMn zYYE8DfI`}k33|E9em8b^cOT5l%i9HzLIQ|HB4$i%6-Cj8iR{cAZnrxJIbw$zW*SQi zB-KKp5CKXE?*?48PoF;h9``MOv`F%=DG{9E!i5W3Rpey7apOkW=FOWMolfT#S~;Aj zV6rpS$V;%@5!ZV4{lR1cPy$*=)Asd)Q{PO>}m4 zE^4;A{IHln6>;m5M5=6(at2ts2bfM?Iz9HXP7#?jG#Rw?Rq=1awY#U&A_LrxqIhhDJdxe{8jJYzyH(a%ayBTJn4C+O;h# zXGC@02s-BukA&LNw-iBvbS%V3>R=&Z zq9KK;DB_+43){dH5!CbQ?k0@q78VvhJG! z;#n(|4giok#1sbb9Q;m_f7KBakBpcIW@2K(g*^B)GBOg)%*?dY<#0GW)zw?1^78VE zw{M3;h$rRd=5XWVBe$}=;6GqVI3FH{O1K72$te*9QvV`G#5I7#aXmN;=gFIRu!%k9sjxSXh{P?AUQjU0vM*O8pEa z>#0+}<|7PMZEb(jPT_`zhBAtZipq4w zr-YuIoOHw4NL5wUEZ{hVz=ughJZFS*VYY3#%F0R)?gya)jpMK(h?L@o%(7YQ=c;Yhhe$rwT|%wt!0ne-A4&~(}@curQJp<#CbaMQ>SFO;Co z#G~K|$U^~taMHz#7l*XHjdp9ROLGj)eDB`96R=udX`pC@a2|si5v)3Z6FERDr%*si zLvL@78I@K#bm*sXD1h9ZUIciU4p9K}!^6W=)&knftC*nawv?VV^7{4b4hqBI;Glta z0p$#-L!YD&t&mo{(lzh`Kx|ZN&Yk=1Jqp`A3uNoT(EcVUg}XKC`I9tPh{3=3RL3J>!ju9=Q~gktyI`( z2O%%qw3|vwN~rhYA3uI9;JKMASFW^S+%mHOYr148Elm8>W({S8VEv3@K~*cN z+g!yPD@CCbCr%t08ymCM*VjvEkYWe{hg~I~#-tEyvg8vQIfGN&$)SIdUc7k0cXf5~ zDF6PJmX-%h3BO7ab%Vtv?ev(X96frp@xzCI4|$l3M}3iY?ARfv8v!Xk=pJ==0|Nv6 z^XJd0rl7Sbo^5SyZD#<1wK~0Z^}r0sg2uWO&3HX}8Vj`qSiP)-auFD|FNXx?01?2B z>POo;&Qu7jy9Zt;kXcb{&z?QoFm{8^tB$LqqvLP3>aa?M|Mqr}?7d0H4BC@dRUV>9 zn)juo?@hXA6MN<0RgPEHAm&umYXelz{XcJ%U){U*SNC6tukQadNubt!N$Z&CUjYUH X&TTd8(aBJD00000NkvXXu0mjf8^(p9 delta 1765 zcmV5ks&;P2CYd%K~#9!)L2_+6lWBk+um|nO=dUE zRnvq@YhJ3wnt)VNOtmPbNeN{8prsTnA{1MM*ayLfD%4k@;!Bq1c7PY%=qo|NFo5oy#n%sw(rUe1w;O zS;XSA-e=VpI4!&0XI})s%K}>yOb!sN>ALFvrt7MpRs~}M!djRam=QoOvjk)b#sI{) zF$d%ID`x^^W`s=9Eu~+xK$!sv>jaVpA)GjILTqViX%qyZ%;j>Go7XNcFF%XNPft(ZIdkUBPhDMILEM)NpjH5~0+ZH+t-Zb7d+^}FuK?tKZGx`NqUy4B^jLl{vcPv7-G&3{v_sNqdJ1$ws~a5-hYKO#@H~%41(+QS2s*ndfJ^{n99J3lG_is~7NKMliG=j{@#EfY+qQL( ztaLz<9E=GLuSzVh;a@_M`7o`+2cfD_Igbj68Xqoe=WA3l623=IwOZEe0_ zMMXt`fEgt~Ck9JS+^g^H?F}?GHeS|4WX`Y^U@}@ce*CxyeY}OxxB-MVa6Ntc)brrM zgTnFgN5c5{IG0|uVZ%lh>?Oef{i&p$i%Hu6Uny%ir_)*J@p#_Yzkk1fcn**Cm04`Iw4B}*PD31Ic zIdbG(fcZryA}g~v3uZVhu7*zXv3Vki4>n2c-n}~p-7seB>$}6BKK-3IH8te{Xg3aE zBLI}|>N3#Wu50f!PCM)&M#@^9L-DU}P*tIOW)xn0WC8>*NdQdXo~Q%i4b@!Rle20|C|t{^6VKpeS$h77qPj+! zo0}KlpRuye&L8uiJed%27zfoN97ZN1Ke1SBn*5sDN~Wb)WfL=hJ3G4w(arh&eyRrr zsJa`yUhjg}TcYgR^JaUVYXWik{B&7uki0bmKN#LCLb z1o#yUbu24PmctcJk`4hI4u_*~EWuG2sUF$8cW?CS)yoYvHMMek`?t>`k+7}1yW7*< z-Q}XS6BFZt&-ZD62pXCJm0=x=gHd)LKeq&>OafK5(kQ*6Lo|_YDa-f>dIC1_CcwC&4O7fgtDOxD8?DbiWwEB z@Ppz?WDiG;k?18sQflDdB7vgxrOpj4hyc$&dNii_Yijx+1hK}kCIvRNK7}sN-oJkz z1aU!&87F6IYd5c7zy3RP$Bd4Sa@dU6(PEAes9-||&^WY2S;io2u2?MU?(gq+R8&;T z`}Tb}0*x(yU_D`Hz!ZnJ!I6$TJ3Id}6uT@yoYjPO<;st7(9=pjT?4q@<(}rx){o^733@E{?j13F$}_qF1~@eefzcwBjGB;!^6LhjEsbI0G9L2nv-6dA+pxi){n-< z#)|0Cy1F_Q8ezanW<4UrV8md+fHr8?)YOD8UApv}zOkf(SbNf2Z3Z@I$gyS17O}Rr zwmujPiqO!C(y)2+W*N0<9&Geu=2_4;O&9=Bt#1Zi>+Qf~g2lU&@tsLFy&0_k?O;9c zO$Ou5jm`upUD$HHH|2bhd!^ne{~zz#uiUQ?|Ml-P{|YbwWK7*7{^bWb00000NkvXX Hu0mjf@9R}! diff --git a/images/rotateright_grouphover.png b/images/rotateright_grouphover.png index 62956b4251070604dd2e645205aedef269106dfa..86e8689c14b1ef1af96adc7aa3ba9531113a31c4 100644 GIT binary patch delta 1912 zcmV-;2Z#8m4zdrB7YZT>1^@s6)rDaEks&;P2R}(fK~#9!q*zN#6;~LZb7n4Zd4muP zj{v%GV{Kd%NQ@|$bU`JyNmsVIaM#AvV%x-}CUwzuEyV^CO=Cz}Oc#>I8Zm`N5E0RZ zkMfEyTW9&G_4;X zYYRYJ5CLV$u%w$eZ+?-Rn_G)HB?!lH*f`s^jpgNK4s)W>==iN$x4u1d=FDGsv7)#{(1r;xjWd#_a5D&;I@U zPvY?+ETlk%{QzwM69-7@g9i_KGBYzv3JMBr(==`DT42GqWT)RW1>WJ7Wf3TU6S8pt z8mp+N_z}Uc7km{qpkiFAEC` z$@61C$VX`B1c+Ffo0~J6nwt2dN00cz!UBLgJS!`U2LeeFFTGC;rlh1809S-(gLm%S z8C8r#-Efy7uXJ|7SPF3lSm`M(EiHtzM&OLZ4AXrK3$WzmWF8C#d1K>$4}4-`d;`U$ zrDd>EQCV3fojni;P^4KyLqk*5)zu&4m1!keNXcdMI1*u<HJt}M#Q7$SueBlqw3vd!v$T3y`-h$P`qHm3P# zj-{m~2M$k6Gp)S1V0>#6!(cW&Jxz>6Mn*;=@E;55--K_NC;>)m>#v+-(68d+B4cW5 zTFSX=*Dg_3R&Kv~^~#3NL_?vFO`vw}+!>%vVuQ@5$THtTNjo8@Bd4W2f}KdJ!ITW& z?(VMGyN3_gi=#(>k2+~->BiNoKlAI?+gL-xX&X@!ee>px4Vh%BCf_7>$nR)=pPtB< z89^@-m6W_>wnKiQoI=qvGBO++TvJmEAfMP^(V3Zrs$j}Y zt^AE4AP5Xg)X%tGnKLyt)q#z?16rxZa6|$l-ysQ*KVk)c37M4&p?LlJHHEx@l%k+u zyLkEXr2vCezhqbw5ac6@LKE*JCr$KgeNSvY?$e>!r%s*vk)jBTn8=vKjs$`QNIHR} zB`1JGO4@N3*Z_fW2nhWRc_afgmOzoejgF3*6kSLMziHXm1thqtYQo#0fsx69fq?*a zZ<6FB9qkr>RahK3@{ypO_V(U$>nkH!0gB8ZCh0dxL_p|5Z88T32TlArr+S)oz1fmr zJTf^7@%rP(kIx|tjVDi@1a|D$VSyQjs4ze=8~klje&u`X+v^hm3?J2s^1a} zYMh01U_m0Iqod=JYO+?nZA3gU;pXP%KM~URQKKw>IHXlpR%VhUXa@u$g>r}8(C}5% zG%bhZQ<5-E8fmCc7B*q_^z;xb&)VAB?s=N5NUS&33ZZdj0e?!tu&pJC2f&D_2wBKu-bbLA!@ z+2JXFKshH)ocR64ix+wO_U&`fAlYziV{B|pI;q=;tC~eoBhYp*7)Pthy1Ke}NlD4v z<;#~pSDoIh)?h7bJ#oTLF9zt?v13ic!^7`lF;-Po53%+mVWTy!Q&YFp4)RmDI^fe86U zk?-js!MQ1@K&7dBQ0qtZ)1>V=z^!U$rnSw^O}>Rv6*fZ)^$lUKCQtUZ0NR;4q5)cC z*FtzhlH1aWGR|4s)Y?+Z+Zg$rvu&;Eek=9+owfhVR|xI_!F@i5I35#Q`3k}Q<@Xu3 y$u}AuOuTP2|L^-uf{#X?X delta 1773 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 A@Bjb+ From be79249c9cf81f9f08e81b9c7a8be8c0fc91f77f Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Thu, 27 Feb 2014 14:39:18 -0700 Subject: [PATCH 06/17] Added pre-draw event for tiles to allow applications to alter the image just prior to its rendering. This should enable invert, brightness, contrast, sharpen and other transformations to occur naturally through the 'tile-drawing' event listener. The listener is given the 'rendered' object which is the pre-drawn image on a canvas context object. By altering the 'rendered' object the listener can alter the display results. Since this event gets fired multiple times for the tile, it is wise for the handler to track what their desired modifications are and to tag the 'tile' element to keep track of the modifications already applied. --- src/drawer.js | 21 +++++++++++++++++++-- src/tile.js | 7 ++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/drawer.js b/src/drawer.js index a53d0d3b..3055feda 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -1228,6 +1228,23 @@ function drawTiles( drawer, lastDrawn ){ tileSource, collectionTileSource; + // We need a callback to give image manipulation a chance to happen + var drawingHandler = function(args) { + if (drawer.viewer) { + /** + * This event is fired just before the tile is drawn giving the application a chance to alter the image. + * + * @event tile-drawing + * @memberof OpenSeadragon.Viewer + * @type {object} + * @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised the event. + * @property {OpenSeadragon.Tile} tile + * @property {?Object} userData - 'context', 'tile' and 'rendered'. + */ + drawer.viewer.raiseEvent('tile-drawing', args); + } + }; + for ( i = lastDrawn.length - 1; i >= 0; i-- ) { tile = lastDrawn[ i ]; @@ -1299,10 +1316,10 @@ function drawTiles( drawer, lastDrawn ){ // specifically, don't save,rotate,restore every time we draw a tile if( drawer.viewport.degrees !== 0 ) { offsetForRotation( tile, drawer.canvas, drawer.context, drawer.viewport.degrees ); - tile.drawCanvas( drawer.context ); + tile.drawCanvas( drawer.context, drawingHandler ); restoreRotationChanges( tile, drawer.canvas, drawer.context ); } else { - tile.drawCanvas( drawer.context ); + tile.drawCanvas( drawer.context, drawingHandler ); } } else { tile.drawHTML( drawer.canvas ); diff --git a/src/tile.js b/src/tile.js index d818c010..9aa4bde4 100644 --- a/src/tile.js +++ b/src/tile.js @@ -231,8 +231,10 @@ $.Tile.prototype = /** @lends OpenSeadragon.Tile.prototype */{ * Renders the tile in a canvas-based context. * @function * @param {Canvas} context + * @param {Function} method for firing the drawing event. drawingHandler({context, tile, rendered}) + * where rendered is the context with the pre-drawn image. */ - drawCanvas: function( context ) { + drawCanvas: function( context, drawingHandler ) { var position = this.position, size = this.size, @@ -280,6 +282,9 @@ $.Tile.prototype = /** @lends OpenSeadragon.Tile.prototype */{ rendered = TILE_CACHE[ this.url ]; + // This gives the application a chance to make image manipulation changes as we are rendering the image + drawingHandler({context: context, tile: this, rendered: rendered}); + //rendered.save(); context.drawImage( rendered.canvas, From 60da75aede14cb6f6d12375dac20ffe5a2625a88 Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Mon, 3 Mar 2014 09:28:28 -0700 Subject: [PATCH 07/17] Added configuration around the rotate left/right buttons. The default for showRotationControls is false to preserve existing functionality. Also added default tooltip strings for the buttons. This version runts the tests fine locally using 'npm test'. It looks like the remote build was having a timeout issue which I couldn't reproduce. --- src/openseadragon.js | 6 +++++ src/strings.js | 4 +++- src/viewer.js | 55 +++++++++++++++++++++++--------------------- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/openseadragon.js b/src/openseadragon.js index 9ee18112..7e3c8366 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -336,6 +336,11 @@ * image and if the 'next' button will wrap to the first image when viewing * the last image. * + * @property {Boolean} [showRotationControl=false] + * If true then the rotate left/right controls will be displayed as part of the + * standard controls. This is also subject to the browser support for rotate + * (e.g. viewer.drawer.canRotate()). + * * @property {Boolean} [showSequenceControl=true] * If the viewer has been configured with a sequence of tile sources, then * provide buttons for navigating forward and backward through the images. @@ -807,6 +812,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ } }, navPrevNextWrap: false, + showRotationControl: false, //DEVELOPER SETTINGS debugMode: false, diff --git a/src/strings.js b/src/strings.js index e6cf8352..03f4ed42 100644 --- a/src/strings.js +++ b/src/strings.js @@ -55,7 +55,9 @@ var I18N = { ZoomIn: "Zoom in", ZoomOut: "Zoom out", NextPage: "Next page", - PreviousPage: "Previous page" + PreviousPage: "Previous page", + RotateLeft: "Rotate left", + RotateRight: "Rotate right" } }; diff --git a/src/viewer.js b/src/viewer.js index ca20ca98..56990624 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1234,33 +1234,36 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, onBlur: onBlurHandler })); - buttons.push( this.rotateLeft = new $.Button({ - element: this.rotateLeftButton ? $.getElement( this.rotateLeftButton ) : null, - clickTimeThreshold: this.clickTimeThreshold, - clickDistThreshold: this.clickDistThreshold, - tooltip: $.getString( "Tooltips.RotateLeft" ), - srcRest: resolveUrl( this.prefixUrl, navImages.rotateleft.REST ), - srcGroup: resolveUrl( this.prefixUrl, navImages.rotateleft.GROUP ), - srcHover: resolveUrl( this.prefixUrl, navImages.rotateleft.HOVER ), - srcDown: resolveUrl( this.prefixUrl, navImages.rotateleft.DOWN ), - onRelease: onRotateLeftHandler, - onFocus: onFocusHandler, - onBlur: onBlurHandler - })); + if (this.showRotationControl && this.drawer.canRotate()) { + buttons.push( this.rotateLeft = new $.Button({ + element: this.rotateLeftButton ? $.getElement( this.rotateLeftButton ) : null, + clickTimeThreshold: this.clickTimeThreshold, + clickDistThreshold: this.clickDistThreshold, + tooltip: $.getString( "Tooltips.RotateLeft" ), + srcRest: resolveUrl( this.prefixUrl, navImages.rotateleft.REST ), + srcGroup: resolveUrl( this.prefixUrl, navImages.rotateleft.GROUP ), + srcHover: resolveUrl( this.prefixUrl, navImages.rotateleft.HOVER ), + srcDown: resolveUrl( this.prefixUrl, navImages.rotateleft.DOWN ), + onRelease: onRotateLeftHandler, + onFocus: onFocusHandler, + onBlur: onBlurHandler + })); - buttons.push( this.rotateRight = new $.Button({ - element: this.rotateRightButton ? $.getElement( this.rotateRightButton ) : null, - clickTimeThreshold: this.clickTimeThreshold, - clickDistThreshold: this.clickDistThreshold, - tooltip: $.getString( "Tooltips.RotateRight" ), - srcRest: resolveUrl( this.prefixUrl, navImages.rotateright.REST ), - srcGroup: resolveUrl( this.prefixUrl, navImages.rotateright.GROUP ), - srcHover: resolveUrl( this.prefixUrl, navImages.rotateright.HOVER ), - srcDown: resolveUrl( this.prefixUrl, navImages.rotateright.DOWN ), - onRelease: onRotateRightHandler, - onFocus: onFocusHandler, - onBlur: onBlurHandler - })); + buttons.push( this.rotateRight = new $.Button({ + element: this.rotateRightButton ? $.getElement( this.rotateRightButton ) : null, + clickTimeThreshold: this.clickTimeThreshold, + clickDistThreshold: this.clickDistThreshold, + tooltip: $.getString( "Tooltips.RotateRight" ), + srcRest: resolveUrl( this.prefixUrl, navImages.rotateright.REST ), + srcGroup: resolveUrl( this.prefixUrl, navImages.rotateright.GROUP ), + srcHover: resolveUrl( this.prefixUrl, navImages.rotateright.HOVER ), + srcDown: resolveUrl( this.prefixUrl, navImages.rotateright.DOWN ), + onRelease: onRotateRightHandler, + onFocus: onFocusHandler, + onBlur: onBlurHandler + })); + + } if( useGroup ){ this.buttons = new $.ButtonGroup({ From 5e0e8005d67dba110f640c305163e6686494ecf9 Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Mon, 3 Mar 2014 11:14:09 -0700 Subject: [PATCH 08/17] Tuned the configuration around the rotate left/right to work when the drawer is instantiated. --- src/viewer.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/viewer.js b/src/viewer.js index 56990624..cd4b5614 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -1234,7 +1234,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype, onBlur: onBlurHandler })); - if (this.showRotationControl && this.drawer.canRotate()) { + if (this.showRotationControl) { buttons.push( this.rotateLeft = new $.Button({ element: this.rotateLeftButton ? $.getElement( this.rotateLeftButton ) : null, clickTimeThreshold: this.clickTimeThreshold, @@ -1503,6 +1503,21 @@ function openTileSource( viewer, source ) { debugGridColor: _this.debugGridColor }); + // Now that we have a drawer, see if it supports rotate. If not we need to remove the rotate buttons + if (!_this.drawer.canRotate()) { + // Disable/remove the rotate left/right buttons since they aren't supported + if (_this.rotateLeft) { + i = _this.buttons.buttons.indexOf(_this.rotateLeft); + _this.buttons.buttons.splice(i, 1); + _this.buttons.element.removeChild(_this.rotateLeft.element); + } + if (_this.rotateRight) { + i = _this.buttons.buttons.indexOf(_this.rotateRight); + _this.buttons.buttons.splice(i, 1); + _this.buttons.element.removeChild(_this.rotateRight.element); + } + } + //Instantiate a navigator if configured if ( _this.showNavigator && !_this.collectionMode ){ // Note: By passing the fully parsed source, the navigator doesn't From e368bd50aa79c77ac1417725e85e7520eaa682c0 Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Mon, 3 Mar 2014 14:45:30 -0700 Subject: [PATCH 09/17] Added tests for rotate control on/off setting. --- src/openseadragon.js | 12 ++++++++ test/rotate.js | 68 ++++++++++++++++++++++++++++++++++++++++++++ test/test.html | 1 + 3 files changed, 81 insertions(+) create mode 100644 test/rotate.js diff --git a/src/openseadragon.js b/src/openseadragon.js index 7e3c8366..611d1cd4 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -798,6 +798,18 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){ HOVER: 'fullpage_hover.png', DOWN: 'fullpage_pressed.png' }, + rotateleft: { + REST: 'rotateleft_rest.png', + GROUP: 'rotateleft_grouphover.png', + HOVER: 'rotateleft_hover.png', + DOWN: 'rotateleft_pressed.png' + }, + rotateright: { + REST: 'rotateright_rest.png', + GROUP: 'rotateright_grouphover.png', + HOVER: 'rotateright_hover.png', + DOWN: 'rotateright_pressed.png' + }, previous: { REST: 'previous_rest.png', GROUP: 'previous_grouphover.png', diff --git a/test/rotate.js b/test/rotate.js new file mode 100644 index 00000000..10b3f53a --- /dev/null +++ b/test/rotate.js @@ -0,0 +1,68 @@ +/* global module, asyncTest, $, ok, equal, notEqual, start, test, Util, testLog */ + +(function () { + var viewer; + + module('Basic', { + setup: function () { + var example = $('

').appendTo("#qunit-fixture"); + + testLog.reset(); + + }, + teardown: function () { + if (viewer && viewer.close) { + viewer.close(); + } + + viewer = null; + } + }); + + asyncTest('RotateControlOff', function () { + + var openHandler = function (event) { + viewer.removeHandler('open', openHandler); + ok(true, 'Open event was sent'); + ok(viewer.drawer, 'Drawer exists'); + ok(viewer.drawer.canRotate(), 'drawer.canRotate is true'); + ok(!viewer.showRotationControl, 'showRotationControl is on - default should be off'); + ok(!viewer.rotateLeft, "rotateLeft button should be null"); + ok(!viewer.rotateRight, "rotateRight button should be null"); + start(); + }; + + viewer = OpenSeadragon({ + id: 'rotateTests', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100, // Faster animation = faster tests + showRotationControl: false + }); + viewer.addHandler('open', openHandler); + viewer.open('/test/data/testpattern.dzi'); + }); + + asyncTest('RotateControlOn', function () { + + var openHandler = function (event) { + viewer.removeHandler('open', openHandler); + ok(true, 'Open event was sent'); + ok(viewer.drawer, 'Drawer exists'); + ok(viewer.drawer.canRotate(), 'drawer.canRotate is true'); + ok(viewer.showRotationControl, 'showRotationControl is on'); + ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateLeft), "rotateLeft not found"); + ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateRight), "rotateRight not found"); + start(); + }; + + viewer = OpenSeadragon({ + id: 'rotateTests', + prefixUrl: '/build/openseadragon/images/', + springStiffness: 100, // Faster animation = faster tests + showRotationControl: true + }); + viewer.addHandler('open', openHandler); + viewer.open('/test/data/testpattern.dzi'); + }); + +})(); diff --git a/test/test.html b/test/test.html index 0f46fa30..1d5c1ce6 100644 --- a/test/test.html +++ b/test/test.html @@ -27,5 +27,6 @@ + From 27424348f34fc57636aea04bf98416f0344bcceb Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Mon, 3 Mar 2014 16:19:40 -0700 Subject: [PATCH 10/17] Added test case for tile-drawing event. --- test/events.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/events.js b/test/events.js index 6fb7f23c..c5480837 100644 --- a/test/events.js +++ b/test/events.js @@ -280,4 +280,23 @@ viewer.open( '/test/data/testpattern.dzi' ); } ); + // ---------- + asyncTest( 'tile-drawing event', function () { + var tileDrawing = function ( event ) { + viewer.removeHandler( 'tile-drawing', tileDrawing ); + ok( event, 'Event handler received event data' ); + if ( event ) { + // Make sure we have the expected elements set + ok(event.context, "Context is not set"); + ok(event.tile, "Tile is not set"); + ok(event.rendered, "Rendered is not set"); + } + viewer.close(); + start(); + }; + + viewer.addHandler( 'tile-drawing', tileDrawing ); + viewer.open( '/test/data/testpattern.dzi' ); + } ); + } )(); From 0bfb83439326a6054167ddfb96471ec8940a3670 Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Tue, 4 Mar 2014 10:28:19 -0700 Subject: [PATCH 11/17] Fixed message context to be more correct. I believe the message is only displayed when a failure occurs, so it needs to be clear what was being tested. --- test/rotate.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/rotate.js b/test/rotate.js index 10b3f53a..ec66b1ac 100644 --- a/test/rotate.js +++ b/test/rotate.js @@ -25,8 +25,8 @@ viewer.removeHandler('open', openHandler); ok(true, 'Open event was sent'); ok(viewer.drawer, 'Drawer exists'); - ok(viewer.drawer.canRotate(), 'drawer.canRotate is true'); - ok(!viewer.showRotationControl, 'showRotationControl is on - default should be off'); + ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true'); + ok(!viewer.showRotationControl, 'showRotationControl should be off'); ok(!viewer.rotateLeft, "rotateLeft button should be null"); ok(!viewer.rotateRight, "rotateRight button should be null"); start(); @@ -48,10 +48,10 @@ viewer.removeHandler('open', openHandler); ok(true, 'Open event was sent'); ok(viewer.drawer, 'Drawer exists'); - ok(viewer.drawer.canRotate(), 'drawer.canRotate is true'); - ok(viewer.showRotationControl, 'showRotationControl is on'); - ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateLeft), "rotateLeft not found"); - ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateRight), "rotateRight not found"); + ok(viewer.drawer.canRotate(), 'drawer.canRotate needs to be true'); + ok(viewer.showRotationControl, 'showRotationControl should be true'); + ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateLeft), "rotateLeft should be found"); + ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateRight), "rotateRight should be found"); start(); }; From 95f059121037a440485925955b1417c2d3159e58 Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Tue, 4 Mar 2014 10:38:10 -0700 Subject: [PATCH 12/17] Added message to clarify that the event only fires when is being used. --- src/drawer.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/drawer.js b/src/drawer.js index 3055feda..2e100384 100644 --- a/src/drawer.js +++ b/src/drawer.js @@ -1234,6 +1234,8 @@ function drawTiles( drawer, lastDrawn ){ /** * This event is fired just before the tile is drawn giving the application a chance to alter the image. * + * NOTE: This event is only fired when the drawer is using a . + * * @event tile-drawing * @memberof OpenSeadragon.Viewer * @type {object} From 9f09951840fb7ba8b8e6ce93ab36e356c443373c Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Thu, 6 Mar 2014 08:58:56 -0700 Subject: [PATCH 13/17] Reworded the test messages to 'should be' form as per standard practice. --- test/events.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/events.js b/test/events.js index c5480837..86f007c1 100644 --- a/test/events.js +++ b/test/events.js @@ -284,12 +284,12 @@ asyncTest( 'tile-drawing event', function () { var tileDrawing = function ( event ) { viewer.removeHandler( 'tile-drawing', tileDrawing ); - ok( event, 'Event handler received event data' ); + ok( event, 'Event handler should be invoked' ); if ( event ) { // Make sure we have the expected elements set - ok(event.context, "Context is not set"); - ok(event.tile, "Tile is not set"); - ok(event.rendered, "Rendered is not set"); + ok(event.context, "Context should be set"); + ok(event.tile, "Tile should be set"); + ok(event.rendered, "Rendered should be set"); } viewer.close(); start(); From 3f095c71cf3887379376bf8fd2e5b25b6429d77f Mon Sep 17 00:00:00 2001 From: Grant Echols Date: Thu, 6 Mar 2014 10:06:58 -0700 Subject: [PATCH 14/17] Added simulated left/right rotate clicks to the test case. --- test/rotate.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/rotate.js b/test/rotate.js index ec66b1ac..c59bb91e 100644 --- a/test/rotate.js +++ b/test/rotate.js @@ -52,6 +52,15 @@ ok(viewer.showRotationControl, 'showRotationControl should be true'); ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateLeft), "rotateLeft should be found"); ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateRight), "rotateRight should be found"); + + // Now simulate the left/right button clicks. Security prevents us from simulating a click, + // so we will call the 'onRelease' handler for the button + ok(viewer.viewport.degrees === 0, "Image should start at 0 degrees rotation"); + viewer.rotateLeft.onRelease(); + ok(viewer.viewport.degrees === 270, "Image should be 270 degrees rotation (left)"); + viewer.rotateRight.onRelease(); + ok(viewer.viewport.degrees === 0, "Image should be 270 degrees rotation (right)"); + start(); }; From 214cda41e95bdddc84cca8b565e5be57d18f9f72 Mon Sep 17 00:00:00 2001 From: Ian Gilman Date: Thu, 6 Mar 2014 09:34:23 -0800 Subject: [PATCH 15/17] Changelog for #348 --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index a9f13430..f20cc33b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -13,6 +13,7 @@ OPENSEADRAGON CHANGELOG * Enhanced the navigatorTop, navigatorLeft, navigatorHeight, and navigatorWidth options to allow a number for pixel units or a string for other element units (%, em, etc.) (#310) * Additional enhancements for IIIF support (#315) * Fixed: Setting degrees in Viewer constructor has no effect (#336) +* Added pre-draw event for tiles to allow applications to alter the image (#348) 1.0.0: From 06065c3ab4de56f46fb7864c71e06529131552b5 Mon Sep 17 00:00:00 2001 From: Ian Gilman Date: Fri, 7 Mar 2014 10:08:47 -0800 Subject: [PATCH 16/17] Change log for #341 --- changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.txt b/changelog.txt index f20cc33b..551c5bf2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -14,6 +14,7 @@ OPENSEADRAGON CHANGELOG * Additional enhancements for IIIF support (#315) * Fixed: Setting degrees in Viewer constructor has no effect (#336) * Added pre-draw event for tiles to allow applications to alter the image (#348) +* Added optional Rotate Left/Right buttons to standard controls (#341) 1.0.0: From 13fa798e52d5455503f1c6e7955a14ca20a1bcea Mon Sep 17 00:00:00 2001 From: Ian Gilman Date: Fri, 7 Mar 2014 10:11:02 -0800 Subject: [PATCH 17/17] comment update on rotate test --- test/rotate.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/rotate.js b/test/rotate.js index c59bb91e..9128d7fa 100644 --- a/test/rotate.js +++ b/test/rotate.js @@ -53,8 +53,8 @@ ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateLeft), "rotateLeft should be found"); ok(-1 != viewer.buttons.buttons.indexOf(viewer.rotateRight), "rotateRight should be found"); - // Now simulate the left/right button clicks. Security prevents us from simulating a click, - // so we will call the 'onRelease' handler for the button + // Now simulate the left/right button clicks. + // TODO: re-factor simulateViewerClickWithDrag so it'll accept any element, and use that. ok(viewer.viewport.degrees === 0, "Image should start at 0 degrees rotation"); viewer.rotateLeft.onRelease(); ok(viewer.viewport.degrees === 270, "Image should be 270 degrees rotation (left)");