embedded.html 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. <!DOCTYPE html>
  2. <meta name="apple-mobile-web-app-capable" content="yes" />
  3. <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1" />
  4. <html>
  5. <head>
  6. <meta charset="UTF-8">
  7. <meta name="theme-color" content="#4b75ff">
  8. <title>Photo Viewer</title>
  9. <script src="../script/jquery.min.js"></script>
  10. <script src="../script/ao_module.js"></script>
  11. <link rel="manifest" href="manifest.json">
  12. <style>
  13. body{
  14. margin: 0px !important;
  15. background:rgba(34,34,34,1);
  16. overflow: hidden;
  17. }
  18. .arrow{
  19. width: 2em;
  20. opacity: 0.5;
  21. position: fixed;
  22. top: calc(50% - 1em);
  23. cursor: pointer;
  24. }
  25. .left.arrow{
  26. left: 2em;
  27. }
  28. .right.arrow{
  29. right: 2em;
  30. }
  31. .zoom{
  32. width: 2em;
  33. opacity: 0.5;
  34. position: fixed;
  35. bottom: 1em;
  36. cursor: pointer;
  37. }
  38. .zoom.out{
  39. right: 1em;
  40. }
  41. .zoom.in{
  42. right: 3.2em;
  43. }
  44. </style>
  45. </head>
  46. <body>
  47. <img id="img" style="max-height: 100vh;max-width: 100%;">
  48. <img class="left arrow" onclick="previousImage();" src="embedded/arrow-left.svg">
  49. <img class="right arrow" onclick="nextImage();" src="embedded/arrow-right.svg">
  50. <img class="zoom in" onclick="zoomIn();" src="embedded/zoom-in.svg">
  51. <img class="zoom out" onclick="zoomOut();" src="embedded/zoom-out.svg">
  52. <script>
  53. //Get file playback info from hash
  54. var playbackFile = ao_module_loadInputFiles();
  55. var nearbyFileList = [];
  56. var currentViewingIndex = 0;
  57. var zoomLevel = 1;
  58. var initMargin = [];
  59. //Only handle one file
  60. playbackFile = playbackFile[0];
  61. loadImage(playbackFile.filename, playbackFile.filepath);
  62. $(window).on("resize ", function() {
  63. updateImgSize();
  64. });
  65. /*
  66. Zooming related functions
  67. */
  68. function zoomIn(){
  69. zoomLevel+= 0.5;
  70. applyZoom();
  71. }
  72. function zoomOut(){
  73. zoomLevel-= 0.5;
  74. applyZoom();
  75. }
  76. $(window).bind('mousewheel DOMMouseScroll', function(event){
  77. if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
  78. // scroll up
  79. zoomIn();
  80. }
  81. else {
  82. // scroll down
  83. zoomOut();
  84. }
  85. });
  86. function applyZoom(){
  87. if (zoomLevel < 1){
  88. zoomLevel = 1;
  89. }
  90. if (zoomLevel == 1){
  91. //Reset offsets
  92. updateImgSize();
  93. }
  94. $("#img").css("transform", `scale(${zoomLevel})`);
  95. }
  96. //Event binding for photo draging
  97. var isDragging = false;
  98. var initPositions = [];
  99. $("#img").mousedown(function(evt) {
  100. evt.preventDefault();
  101. handleZoomMousedown(evt.clientX, evt.clientY);
  102. });
  103. $("#img").mousemove(function(evt) {
  104. handleZoomMouseMove(evt.clientX, evt.clientY);
  105. });
  106. $("#img").mouseup(function() {
  107. handleZoomMouseUp();
  108. });
  109. function getCurrentImageMargins(){
  110. var accLeft = $("#img").css("margin-left").replace("px","");
  111. var accTop = $("#img").css("margin-top").replace("px","");
  112. return [parseFloat(accLeft), parseFloat(accTop)];
  113. }
  114. function handleZoomMousedown(x,y){
  115. if (zoomLevel > 1){
  116. //Only allow dragging when zoomlv > 1
  117. isDragging = true;
  118. var accLeft = $("#img").css("margin-left").replace("px","");
  119. var accTop = $("#img").css("margin-top").replace("px","");
  120. initPositions = [JSON.parse(JSON.stringify(x - accLeft)), JSON.parse(JSON.stringify(y - accTop))];
  121. }
  122. }
  123. function handleZoomMouseMove(x,y){
  124. if (isDragging){
  125. console.log("dragging");
  126. var offsetsToStartPoint = [initPositions[0] - x, initPositions[1] - y];
  127. MoveImage(-offsetsToStartPoint[0], -offsetsToStartPoint[1]);
  128. }
  129. }
  130. function MoveImage(x,y){
  131. $("#img").css("margin-left", x + "px");
  132. $("#img").css("margin-top", y + "px");
  133. }
  134. function handleZoomMouseUp(){
  135. isDragging = false;
  136. }
  137. //Load the nearby image files and allow swapping using <- and -> key
  138. function loadNearbyFiles(filepath){
  139. ao_module_agirun("Photo/embedded/listNearbyImage.js", {
  140. path: filepath
  141. }, function(data){
  142. if (data.error != undefined){
  143. alert(data.error);
  144. }else{
  145. nearbyFileList = data;
  146. //Track which index currently the user is viewing
  147. for (var i = 0; i < nearbyFileList.length; i++){
  148. var thisPath = nearbyFileList[i];
  149. if (thisPath == filepath.split("\\").join("/")){
  150. currentViewingIndex = i;
  151. }
  152. }
  153. }
  154. })
  155. }
  156. function nextImage(){
  157. nextPhoto = currentViewingIndex + 1;
  158. if (nextPhoto > nearbyFileList.length - 1){
  159. nextPhoto = nearbyFileList.length - 1;
  160. }
  161. var filepath = nearbyFileList[nextPhoto];
  162. var filename = filepath.split('/').pop();
  163. if (nextPhoto != currentViewingIndex){
  164. //Change in photo index
  165. loadImage(filename, filepath);
  166. currentViewingIndex = nextPhoto;
  167. }
  168. }
  169. function previousImage(){
  170. nextPhoto = currentViewingIndex - 1;
  171. if (nextPhoto < 0){
  172. nextPhoto = 0;
  173. }
  174. var filepath = nearbyFileList[nextPhoto];
  175. var filename = filepath.split('/').pop();
  176. if (nextPhoto != currentViewingIndex){
  177. //Change in photo index
  178. loadImage(filename, filepath);
  179. currentViewingIndex = nextPhoto;
  180. }
  181. }
  182. //Bind arrow key events
  183. $("body").on("keydown", function(e){
  184. var nextPhoto = currentViewingIndex;
  185. if (e.keyCode == 37){
  186. //<-
  187. previousImage();
  188. }else if (e.keyCode == 39){
  189. //->
  190. nextImage();
  191. }else{
  192. //Invalid keycode to operate
  193. return;
  194. }
  195. })
  196. loadNearbyFiles(playbackFile.filepath);
  197. function loadImage(filename, filepath){
  198. $("#img").hide();
  199. ao_module_setWindowTitle("Photo - " + filename);
  200. $("#img").attr("src", '../media?file=' + encodeURIComponent(filepath))
  201. //realigin to center
  202. $('#img').on('load', function() {
  203. zoomLevel = 1;
  204. applyZoom();
  205. updateImgSize();
  206. $("#img").show();
  207. });
  208. }
  209. function updateImgSize() {
  210. $('#img').css("margin-top", (window.innerHeight - $("#img").height()) / 2);
  211. $('#img').css("margin-left", (window.innerWidth - $("#img").width()) / 2);
  212. initMargin = [(window.innerWidth - $("#img").width()) / 2, (window.innerHeight - $("#img").height()) / 2];
  213. }
  214. //Touch gesture detections
  215. document.addEventListener('touchstart', handleTouchStart, false);
  216. document.addEventListener('touchmove', handleTouchMove, false);
  217. var xDown = null;
  218. var yDown = null;
  219. function getTouches(evt) {
  220. return evt.touches || // browser API
  221. evt.originalEvent.touches; // jQuery
  222. }
  223. function handleTouchStart(evt) {
  224. const firstTouch = getTouches(evt)[0];
  225. xDown = firstTouch.clientX;
  226. yDown = firstTouch.clientY;
  227. };
  228. function handleTouchMove(evt) {
  229. if ( ! xDown || ! yDown ) {
  230. return;
  231. }
  232. var xUp = evt.touches[0].clientX;
  233. var yUp = evt.touches[0].clientY;
  234. var imgmg = getCurrentImageMargins();
  235. var xDiff = xDown - xUp;
  236. var xDiffAcc = xDiff - imgmg[0];
  237. var yDiff = yDown - yUp;
  238. var yDiffAcc = yDiff - imgmg[1];
  239. if (zoomLevel == 1){
  240. if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
  241. if ( xDiff > 0 ) {
  242. /* right swipe */
  243. nextImage();
  244. } else {
  245. /* left swipe */
  246. previousImage();
  247. }
  248. } else {
  249. if ( yDiff > 0 ) {
  250. /* down swipe */
  251. } else {
  252. /* up swipe */
  253. }
  254. }
  255. }else{
  256. MoveImage(-xDiffAcc, -yDiffAcc);
  257. }
  258. /* reset values */
  259. if (zoomLevel == 1){
  260. xDown = null;
  261. yDown = null;
  262. }else{
  263. xDown = xUp;
  264. yDown = yUp;
  265. }
  266. };
  267. function isZoomed(){
  268. return window.matchMedia('(max--moz-device-pixel-ratio:0.99), (min--moz-device-pixel-ratio:1.01)').matches;
  269. }
  270. </script>
  271. </body>
  272. </html>