comparison.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. // Generated by CoffeeScript 2.0.0-beta4
  2. (function() {
  3. // ------------------------------------------------------------------------
  4. // 變數與常數設置
  5. // ------------------------------------------------------------------------
  6. // 模組名稱。
  7. var ClassName, EVENT_NAMESPACE, Error, Event, MODULE_NAMESPACE, Metadata, NAME, Selector, Settings;
  8. NAME = 'comparison';
  9. // 模組事件鍵名。
  10. EVENT_NAMESPACE = `.${NAME}`;
  11. // 模組命名空間。
  12. MODULE_NAMESPACE = `module-${NAME}`;
  13. // 模組設定。
  14. Settings = {
  15. // 消音所有提示,甚至是錯誤訊息。
  16. silent: false,
  17. // 顯示除錯訊息。
  18. debug: true,
  19. // 監聽 DOM 結構異動並自動重整快取。
  20. observeChanges: true,
  21. // 當尺寸正在變更時所呼叫的回呼函式。
  22. onResize: function() {},
  23. // 當圖片載入完畢後並顯示時所會呼叫的回呼函式。
  24. onDisplay: function() {},
  25. // 標籤上的文字。
  26. labels: {
  27. // 之前圖片的標籤文字。
  28. before: 'Before',
  29. // 之後圖片的標籤文字。
  30. after: 'After'
  31. },
  32. // 更改大小拉桿的設置。
  33. resizer: {
  34. // 拉桿的樣式,可用為:divider、circular、dots、rounded。
  35. style: 'rounded'
  36. }
  37. };
  38. // 中繼資料名稱。
  39. Metadata = {
  40. CONTENT: 'content'
  41. };
  42. // 事件名稱。
  43. Event = {
  44. LOAD: `load${EVENT_NAMESPACE}`,
  45. RESIZE: `resize${EVENT_NAMESPACE}`,
  46. DISPLAY: `display${EVENT_NAMESPACE}`,
  47. MOUSEDOWN: `mousedown${EVENT_NAMESPACE}`,
  48. MOUSEMOVE: `mousemove${EVENT_NAMESPACE}`,
  49. MOUSEUP: `mouseup${EVENT_NAMESPACE}`,
  50. MOUSEOUT: `mouseout${EVENT_NAMESPACE}`,
  51. TOUCHSTART: `touchstart${EVENT_NAMESPACE}`,
  52. TOUCHMOVE: `touchmove${EVENT_NAMESPACE}`,
  53. TOUCHEND: `touchend${EVENT_NAMESPACE}`
  54. };
  55. // 樣式名稱。
  56. ClassName = {
  57. ACTIVE: 'active',
  58. ANIMATING: 'animating'
  59. };
  60. // 選擇器名稱。
  61. Selector = {
  62. AFTER: '.after',
  63. BEFORE: '.before',
  64. RESIZER: '.resizer',
  65. IMG: 'img',
  66. BODY: 'body'
  67. };
  68. // 錯誤訊息。
  69. Error = {};
  70. // ------------------------------------------------------------------------
  71. // 模組註冊
  72. // ------------------------------------------------------------------------
  73. ts.register({NAME, MODULE_NAMESPACE, Error, Settings}, ({$allModules, $this, element, debug, settings}) => {
  74. var $after, $before, $body, $comparison, $resizer, comparisonRect, module, resizerWidth;
  75. // ------------------------------------------------------------------------
  76. // 區域變數
  77. // ------------------------------------------------------------------------
  78. $comparison = $this;
  79. $before = void 0;
  80. $after = void 0;
  81. $resizer = void 0;
  82. $body = ts(Selector.BODY);
  83. comparisonRect = void 0;
  84. resizerWidth = 14;
  85. // ------------------------------------------------------------------------
  86. // 模組定義
  87. // ------------------------------------------------------------------------
  88. return module = {
  89. show: {
  90. after: () => {
  91. return module.set.resizer(100);
  92. },
  93. before: () => {
  94. return module.set.resizer(0);
  95. }
  96. },
  97. create: {
  98. template: () => {
  99. var afterImg, beforeImg;
  100. beforeImg = $this.find(Selector.BEFORE).attr('src');
  101. afterImg = $this.find(Selector.AFTER).attr('src');
  102. return `<div class=\"before\">\n <img src=\"${beforeImg}\" style=\"filter: blur(5px);\">\n <label>${settings.labels.before}</label>\n</div>\n<div class=\"after\">\n <img src=\"${afterImg}\">\n <label>${settings.labels.after}</label>\n</div>\n<div class=\"${settings.resizer.style} resizer\"></div>`;
  103. }
  104. },
  105. set: {
  106. resizer: (percent) => {
  107. percent = percent > 50 ? `calc(${percent}% - ${resizerWidth}px)` : `${percent}%`;
  108. $after.css('width', percent);
  109. $resizer.css('left', percent);
  110. return module.trigger.resize();
  111. },
  112. after: {
  113. url: (url) => {
  114. return module.get.after.$img().prop('src', url);
  115. }
  116. },
  117. before: {
  118. url: (url) => {
  119. return module.get.before.$img().prop('src', url);
  120. }
  121. },
  122. html: (html) => {
  123. return $this.html(html);
  124. },
  125. content: (content) => {
  126. return $this.data(Metadata.CONTENT, content);
  127. }
  128. },
  129. get: {
  130. rect: () => {
  131. return $this.get().getBoundingClientRect();
  132. },
  133. resizer: {
  134. rect: () => {
  135. return $resizer.get().getBoundingClientRect();
  136. }
  137. },
  138. after: {
  139. rect: () => {
  140. return $after.get().getBoundingClientRect();
  141. },
  142. $img: () => {
  143. return $after.find(Selector.IMG);
  144. }
  145. },
  146. before: {
  147. $img: () => {
  148. return $before.find(Selector.IMG);
  149. }
  150. },
  151. html: () => {
  152. return $this.html();
  153. },
  154. content: () => {
  155. return $this.data(Metadata.CONTENT);
  156. },
  157. clientX: (event) => {
  158. if (event.type === 'touchstart' || event.type === 'touchmove') {
  159. return event.touches[0].clientX;
  160. } else {
  161. return event.clientX;
  162. }
  163. }
  164. },
  165. trigger: {
  166. resize: () => {
  167. return $this.trigger(Event.RESIZE, element);
  168. },
  169. display: () => {
  170. return $this.trigger(Event.DISPLAY, element);
  171. }
  172. },
  173. move: {
  174. resizer: (event) => {
  175. var offset, rect;
  176. rect = comparisonRect;
  177. offset = module.get.clientX(event) - module.get.resizer.rect().left;
  178. return $this.on(`${Event.MOUSEMOVE} ${Event.TOUCHMOVE}`, (event) => {
  179. var clientX, left, reached;
  180. clientX = module.get.clientX(event);
  181. left = clientX - rect.left - offset;
  182. reached = {
  183. left: left < 0,
  184. right: left > rect.right - rect.left - resizerWidth
  185. };
  186. if (reached.left || reached.right) {
  187. return;
  188. }
  189. $resizer.css('left', `${left}px`);
  190. $after.css('width', `${((module.get.resizer.rect().left - rect.left) / rect.width) * 100}%`);
  191. return module.trigger.resize();
  192. });
  193. }
  194. },
  195. bind: {
  196. events: () => {
  197. $this.on(Event.RESIZE, (event, context) => {
  198. debug('發生 RESIZE 事件', context);
  199. return settings.onResize.call(context, event);
  200. });
  201. $this.on(Event.DISPLAY, (event, context) => {
  202. debug('發生 DISPLAY 事件', context);
  203. return settings.onDisplay.call(context, event);
  204. });
  205. $body.on(`${Event.MOUSEUP} ${Event.TOUCHEND}`, (event) => {
  206. $this.off(`${Event.MOUSEDOWN} ${Event.MOUSEMOVE} ${Event.MOUSEUP} ${Event.TOUCHSTART} ${Event.TOUCHMOVE}`);
  207. return module.bind.resizer.events();
  208. });
  209. module.get.after.$img().on(Event.LOAD, (event, context) => {
  210. debug('發生 LOAD 事件', context);
  211. return module.trigger.display();
  212. });
  213. return module.get.before.$img().on(Event.LOAD, (event, context) => {
  214. debug('發生 LOAD 事件', context);
  215. return module.trigger.display();
  216. });
  217. },
  218. resizer: {
  219. events: () => {
  220. return $this.on(`${Event.MOUSEDOWN} ${Event.TOUCHSTART}`, Selector.RESIZER, (event) => {
  221. return module.move.resizer(event);
  222. });
  223. }
  224. }
  225. },
  226. // ------------------------------------------------------------------------
  227. // 基礎方法
  228. // ------------------------------------------------------------------------
  229. initialize: () => {
  230. debug('初始化圖片比較', element);
  231. module.set.content(module.get.html());
  232. module.set.html(module.create.template());
  233. module.refresh();
  234. module.bind.events();
  235. return module.bind.resizer.events();
  236. },
  237. instantiate: () => {
  238. return debug('實例化圖片比較', element);
  239. },
  240. refresh: () => {
  241. $after = $this.find(Selector.AFTER);
  242. $before = $this.find(Selector.BEFORE);
  243. $resizer = $this.find(Selector.RESIZER);
  244. comparisonRect = module.get.rect();
  245. return $allModules;
  246. },
  247. destroy: () => {
  248. debug('摧毀圖片比較', element);
  249. $this.removeData(MODULE_NAMESPACE).off(EVENT_NAMESPACE);
  250. module.set.html(module.get.content());
  251. return $allModules;
  252. }
  253. };
  254. });
  255. }).call(this);