embedded.html 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  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. #img{
  45. transition: transform 0.5s;
  46. }
  47. .print{
  48. width: 2em;
  49. opacity: 0.5;
  50. position: fixed;
  51. bottom: 1em;
  52. cursor: pointer;
  53. left: 1em;
  54. }
  55. </style>
  56. </head>
  57. <body>
  58. <img id="img" style="max-height: 100vh;max-width: 100%;">
  59. <img class="left arrow" style="display:none;" onclick="previousImage();" src="embedded/arrow-left.svg">
  60. <img class="right arrow" style="display:none;" onclick="nextImage();" src="embedded/arrow-right.svg">
  61. <img class="zoom in" onclick="zoomIn();" src="embedded/zoom-in.svg">
  62. <img class="zoom out" onclick="zoomOut();" src="embedded/zoom-out.svg">
  63. <img class="print" onclick="PrintImage();" src="embedded/print.svg">
  64. <script>
  65. //Get file playback info from hash
  66. var playbackFile = ao_module_loadInputFiles();
  67. var nearbyFileList = [];
  68. var currentImageURL = "";
  69. var currentImageFilename = "";
  70. var currentViewingIndex = 0;
  71. var zoomLevel = 1;
  72. var initMargin = [];
  73. var currentMargin = [];
  74. //Only handle one file
  75. playbackFile = playbackFile[0];
  76. loadImage(playbackFile.filename, playbackFile.filepath);
  77. $(window).on("resize ", function() {
  78. updateImgSize();
  79. });
  80. /*
  81. Zooming related functions
  82. */
  83. function zoomIn(){
  84. zoomLevel+= 0.5;
  85. if (zoomLevel >=3){
  86. zoomLevel = 3;
  87. }
  88. applyZoom();
  89. }
  90. function zoomOut(){
  91. zoomLevel-= 0.5;
  92. applyZoom();
  93. }
  94. $(window).bind('mousewheel DOMMouseScroll', function(event){
  95. //Get the percentage of offsets from the cursor position to the photo edge
  96. if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
  97. // scroll up
  98. zoomIn();
  99. }
  100. else {
  101. // scroll down
  102. zoomOut();
  103. }
  104. });
  105. function applyZoom(){
  106. if (zoomLevel < 1){
  107. zoomLevel = 1;
  108. }
  109. if (zoomLevel == 1){
  110. //Reset offsets
  111. updateImgSize();
  112. }
  113. $("#img").css("transform", `scale(${zoomLevel})`);
  114. }
  115. //Event binding for photo draging
  116. var isDragging = false;
  117. var initPositions = [];
  118. $(window).mousedown(function(evt) {
  119. evt.preventDefault();
  120. handleZoomMousedown(evt.clientX, evt.clientY);
  121. });
  122. $(window).mousemove(function(evt) {
  123. handleZoomMouseMove(evt.clientX, evt.clientY);
  124. });
  125. $(window).mouseup(function() {
  126. handleZoomMouseUp();
  127. });
  128. function getCurrentImageMargins(){
  129. var accLeft = $("#img").css("margin-left").replace("px","");
  130. var accTop = $("#img").css("margin-top").replace("px","");
  131. return [parseFloat(accLeft), parseFloat(accTop)];
  132. }
  133. function handleZoomMousedown(x,y){
  134. if (zoomLevel > 1){
  135. //Only allow dragging when zoomlv > 1
  136. isDragging = true;
  137. var accLeft = $("#img").css("margin-left").replace("px","");
  138. var accTop = $("#img").css("margin-top").replace("px","");
  139. initPositions = [JSON.parse(JSON.stringify(x - accLeft)), JSON.parse(JSON.stringify(y - accTop))];
  140. }
  141. }
  142. function handleZoomMouseMove(x,y){
  143. if (isDragging){
  144. console.log("dragging");
  145. var offsetsToStartPoint = [initPositions[0] - x, initPositions[1] - y];
  146. MoveImage(-offsetsToStartPoint[0], -offsetsToStartPoint[1]);
  147. }
  148. }
  149. function MoveImage(x,y){
  150. $("#img").css("margin-left", x + "px");
  151. $("#img").css("margin-top", y + "px");
  152. }
  153. function handleZoomMouseUp(){
  154. isDragging = false;
  155. }
  156. /*
  157. Printing related
  158. */
  159. function ImagetoPrint(source, title=""){
  160. return `<html>
  161. <head>
  162. <title>${title}</title>
  163. <${"script"}>
  164. function pre(){
  165. setTimeout('startprint()', 10);
  166. }
  167. function startprint(){
  168. window.print();
  169. window.close();
  170. }
  171. </${"script"}>
  172. </head>
  173. <body onload="pre()">
  174. <img style="max-width: 100%; max-height: 100%;" src='${source}' />
  175. </body>
  176. </html>`;
  177. }
  178. function PrintImage(){
  179. var Pagelink = "about:blank";
  180. var pwa = window.open(Pagelink, "_new");
  181. pwa.document.open();
  182. pwa.document.write(ImagetoPrint(currentImageURL, currentImageFilename));
  183. pwa.document.close();
  184. }
  185. //Load the nearby image files and allow swapping using <- and -> key
  186. function loadNearbyFiles(filepath){
  187. ao_module_agirun("Photo/embedded/listNearbyImage.js", {
  188. path: filepath
  189. }, function(data){
  190. if (data.error != undefined){
  191. alert(data.error);
  192. }else{
  193. nearbyFileList = data;
  194. $(".arrow").css("display", "");
  195. //Track which index currently the user is viewing
  196. for (var i = 0; i < nearbyFileList.length; i++){
  197. var thisPath = nearbyFileList[i];
  198. if (thisPath == filepath.split("\\").join("/")){
  199. currentViewingIndex = i;
  200. }
  201. }
  202. }
  203. })
  204. }
  205. function nextImage(){
  206. nextPhoto = currentViewingIndex + 1;
  207. if (nextPhoto > nearbyFileList.length - 1){
  208. nextPhoto = nearbyFileList.length - 1;
  209. }
  210. var filepath = nearbyFileList[nextPhoto];
  211. var filename = filepath.split('/').pop();
  212. if (nextPhoto != currentViewingIndex){
  213. //Change in photo index
  214. loadImage(filename, filepath);
  215. currentViewingIndex = nextPhoto;
  216. }
  217. }
  218. function previousImage(){
  219. nextPhoto = currentViewingIndex - 1;
  220. if (nextPhoto < 0){
  221. nextPhoto = 0;
  222. }
  223. var filepath = nearbyFileList[nextPhoto];
  224. var filename = filepath.split('/').pop();
  225. if (nextPhoto != currentViewingIndex){
  226. //Change in photo index
  227. loadImage(filename, filepath);
  228. currentViewingIndex = nextPhoto;
  229. }
  230. }
  231. //Bind arrow key events
  232. $("body").on("keydown", function(e){
  233. var nextPhoto = currentViewingIndex;
  234. if (e.keyCode == 37){
  235. //<-
  236. if (nearbyFileList.length > 0){
  237. previousImage();
  238. }
  239. }else if (e.keyCode == 39){
  240. //->
  241. if (nearbyFileList.length > 0){
  242. nextImage();
  243. }
  244. }else{
  245. //Invalid keycode to operate
  246. return;
  247. }
  248. })
  249. loadNearbyFiles(playbackFile.filepath);
  250. function loadImage(filename, filepath){
  251. $("#img").hide();
  252. ao_module_setWindowTitle("Photo - " + filename);
  253. $("#img").attr("src", '../media?file=' + encodeURIComponent(filepath))
  254. currentImageURL = '../media?file=' + encodeURIComponent(filepath);
  255. currentImageFilename = filename;
  256. //realigin to center
  257. $('#img').on('load', function() {
  258. zoomLevel = 1;
  259. applyZoom();
  260. updateImgSize();
  261. $("#img").show();
  262. });
  263. }
  264. function updateImgSize() {
  265. $('#img').css("margin-top", (window.innerHeight - $("#img").height()) / 2);
  266. $('#img').css("margin-left", (window.innerWidth - $("#img").width()) / 2);
  267. initMargin = [(window.innerWidth - $("#img").width()) / 2, (window.innerHeight - $("#img").height()) / 2];
  268. currentMargin = initMargin;
  269. }
  270. //Touch gesture detections
  271. document.addEventListener('touchstart', handleTouchStart, false);
  272. document.addEventListener('touchmove', handleTouchMove, false);
  273. var xDown = null;
  274. var yDown = null;
  275. function getTouches(evt) {
  276. return evt.touches || // browser API
  277. evt.originalEvent.touches; // jQuery
  278. }
  279. function handleTouchStart(evt) {
  280. const firstTouch = getTouches(evt)[0];
  281. xDown = firstTouch.clientX;
  282. yDown = firstTouch.clientY;
  283. };
  284. function handleTouchMove(evt) {
  285. if ( ! xDown || ! yDown ) {
  286. return;
  287. }
  288. var xUp = evt.touches[0].clientX;
  289. var yUp = evt.touches[0].clientY;
  290. var imgmg = getCurrentImageMargins();
  291. var xDiff = xDown - xUp;
  292. var xDiffAcc = xDiff - imgmg[0];
  293. var yDiff = yDown - yUp;
  294. var yDiffAcc = yDiff - imgmg[1];
  295. if (zoomLevel == 1){
  296. if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
  297. if ( xDiff > 0 ) {
  298. /* right swipe */
  299. nextImage();
  300. } else {
  301. /* left swipe */
  302. previousImage();
  303. }
  304. } else {
  305. if ( yDiff > 0 ) {
  306. /* down swipe */
  307. } else {
  308. /* up swipe */
  309. }
  310. }
  311. }else{
  312. MoveImage(-xDiffAcc, -yDiffAcc);
  313. }
  314. /* reset values */
  315. if (zoomLevel == 1){
  316. xDown = null;
  317. yDown = null;
  318. }else{
  319. xDown = xUp;
  320. yDown = yUp;
  321. }
  322. };
  323. function isZoomed(){
  324. return window.matchMedia('(max--moz-device-pixel-ratio:0.99), (min--moz-device-pixel-ratio:1.01)').matches;
  325. }
  326. </script>
  327. </body>
  328. </html>