// Generated by CoffeeScript 2.0.0-beta4
(function() {
// ------------------------------------------------------------------------
// 變數與常數設置
// ------------------------------------------------------------------------
// 模組名稱。
var ClassName, EVENT_NAMESPACE, Error, Event, MODULE_NAMESPACE, Metadata, NAME, Selector, Settings;
NAME = 'comparison';
// 模組事件鍵名。
EVENT_NAMESPACE = `.${NAME}`;
// 模組命名空間。
MODULE_NAMESPACE = `module-${NAME}`;
// 模組設定。
Settings = {
// 消音所有提示,甚至是錯誤訊息。
silent: false,
// 顯示除錯訊息。
debug: true,
// 監聽 DOM 結構異動並自動重整快取。
observeChanges: true,
// 當尺寸正在變更時所呼叫的回呼函式。
onResize: function() {},
// 當圖片載入完畢後並顯示時所會呼叫的回呼函式。
onDisplay: function() {},
// 標籤上的文字。
labels: {
// 之前圖片的標籤文字。
before: 'Before',
// 之後圖片的標籤文字。
after: 'After'
},
// 更改大小拉桿的設置。
resizer: {
// 拉桿的樣式,可用為:divider、circular、dots、rounded。
style: 'rounded'
}
};
// 中繼資料名稱。
Metadata = {
CONTENT: 'content'
};
// 事件名稱。
Event = {
LOAD: `load${EVENT_NAMESPACE}`,
RESIZE: `resize${EVENT_NAMESPACE}`,
DISPLAY: `display${EVENT_NAMESPACE}`,
MOUSEDOWN: `mousedown${EVENT_NAMESPACE}`,
MOUSEMOVE: `mousemove${EVENT_NAMESPACE}`,
MOUSEUP: `mouseup${EVENT_NAMESPACE}`,
MOUSEOUT: `mouseout${EVENT_NAMESPACE}`,
TOUCHSTART: `touchstart${EVENT_NAMESPACE}`,
TOUCHMOVE: `touchmove${EVENT_NAMESPACE}`,
TOUCHEND: `touchend${EVENT_NAMESPACE}`
};
// 樣式名稱。
ClassName = {
ACTIVE: 'active',
ANIMATING: 'animating'
};
// 選擇器名稱。
Selector = {
AFTER: '.after',
BEFORE: '.before',
RESIZER: '.resizer',
IMG: 'img',
BODY: 'body'
};
// 錯誤訊息。
Error = {};
// ------------------------------------------------------------------------
// 模組註冊
// ------------------------------------------------------------------------
ts.register({NAME, MODULE_NAMESPACE, Error, Settings}, ({$allModules, $this, element, debug, settings}) => {
var $after, $before, $body, $comparison, $resizer, comparisonRect, module, resizerWidth;
// ------------------------------------------------------------------------
// 區域變數
// ------------------------------------------------------------------------
$comparison = $this;
$before = void 0;
$after = void 0;
$resizer = void 0;
$body = ts(Selector.BODY);
comparisonRect = void 0;
resizerWidth = 14;
// ------------------------------------------------------------------------
// 模組定義
// ------------------------------------------------------------------------
return module = {
show: {
after: () => {
return module.set.resizer(100);
},
before: () => {
return module.set.resizer(0);
}
},
create: {
template: () => {
var afterImg, beforeImg;
beforeImg = $this.find(Selector.BEFORE).attr('src');
afterImg = $this.find(Selector.AFTER).attr('src');
return `
\n

\n
\n
\n\n

\n
\n
\n`;
}
},
set: {
resizer: (percent) => {
percent = percent > 50 ? `calc(${percent}% - ${resizerWidth}px)` : `${percent}%`;
$after.css('width', percent);
$resizer.css('left', percent);
return module.trigger.resize();
},
after: {
url: (url) => {
return module.get.after.$img().prop('src', url);
}
},
before: {
url: (url) => {
return module.get.before.$img().prop('src', url);
}
},
html: (html) => {
return $this.html(html);
},
content: (content) => {
return $this.data(Metadata.CONTENT, content);
}
},
get: {
rect: () => {
return $this.get().getBoundingClientRect();
},
resizer: {
rect: () => {
return $resizer.get().getBoundingClientRect();
}
},
after: {
rect: () => {
return $after.get().getBoundingClientRect();
},
$img: () => {
return $after.find(Selector.IMG);
}
},
before: {
$img: () => {
return $before.find(Selector.IMG);
}
},
html: () => {
return $this.html();
},
content: () => {
return $this.data(Metadata.CONTENT);
},
clientX: (event) => {
if (event.type === 'touchstart' || event.type === 'touchmove') {
return event.touches[0].clientX;
} else {
return event.clientX;
}
}
},
trigger: {
resize: () => {
return $this.trigger(Event.RESIZE, element);
},
display: () => {
return $this.trigger(Event.DISPLAY, element);
}
},
move: {
resizer: (event) => {
var offset, rect;
rect = comparisonRect;
offset = module.get.clientX(event) - module.get.resizer.rect().left;
return $this.on(`${Event.MOUSEMOVE} ${Event.TOUCHMOVE}`, (event) => {
var clientX, left, reached;
clientX = module.get.clientX(event);
left = clientX - rect.left - offset;
reached = {
left: left < 0,
right: left > rect.right - rect.left - resizerWidth
};
if (reached.left || reached.right) {
return;
}
$resizer.css('left', `${left}px`);
$after.css('width', `${((module.get.resizer.rect().left - rect.left) / rect.width) * 100}%`);
return module.trigger.resize();
});
}
},
bind: {
events: () => {
$this.on(Event.RESIZE, (event, context) => {
debug('發生 RESIZE 事件', context);
return settings.onResize.call(context, event);
});
$this.on(Event.DISPLAY, (event, context) => {
debug('發生 DISPLAY 事件', context);
return settings.onDisplay.call(context, event);
});
$body.on(`${Event.MOUSEUP} ${Event.TOUCHEND}`, (event) => {
$this.off(`${Event.MOUSEDOWN} ${Event.MOUSEMOVE} ${Event.MOUSEUP} ${Event.TOUCHSTART} ${Event.TOUCHMOVE}`);
return module.bind.resizer.events();
});
module.get.after.$img().on(Event.LOAD, (event, context) => {
debug('發生 LOAD 事件', context);
return module.trigger.display();
});
return module.get.before.$img().on(Event.LOAD, (event, context) => {
debug('發生 LOAD 事件', context);
return module.trigger.display();
});
},
resizer: {
events: () => {
return $this.on(`${Event.MOUSEDOWN} ${Event.TOUCHSTART}`, Selector.RESIZER, (event) => {
return module.move.resizer(event);
});
}
}
},
// ------------------------------------------------------------------------
// 基礎方法
// ------------------------------------------------------------------------
initialize: () => {
debug('初始化圖片比較', element);
module.set.content(module.get.html());
module.set.html(module.create.template());
module.refresh();
module.bind.events();
return module.bind.resizer.events();
},
instantiate: () => {
return debug('實例化圖片比較', element);
},
refresh: () => {
$after = $this.find(Selector.AFTER);
$before = $this.find(Selector.BEFORE);
$resizer = $this.find(Selector.RESIZER);
comparisonRect = module.get.rect();
return $allModules;
},
destroy: () => {
debug('摧毀圖片比較', element);
$this.removeData(MODULE_NAMESPACE).off(EVENT_NAMESPACE);
module.set.html(module.get.content());
return $allModules;
}
};
});
}).call(this);