/**
* Copyright (c) 2015 NAVER Corp.
* egjs projects are licensed under the MIT license
*/
import Plugin from "../Plugin";
/**
* A plugin to add opacity effect attached with flicking interaction.
* - Should be targeted only one element(or a wrapper element having child nodes) per panel.
* @ko 플리킹 인터렉션에 따른 투명도 조절 효과 플러그인.
* - 각 패널당 한 개의 요소(또는 자식노드를 포함하는 한 개의 래퍼요소)만 지정되어야 한다.
* @alias eg.Flicking.plugin.OpacityEffect
* @memberof eg.Flicking.plugin
* @see eg.Flicking#plugin
* @see eg.Flicking#plugins
* @example
* ```html
* <div id="flick">
* <div><p>panel 0 <span class="text">abc</span></p></div>
* <div><p>panel 1 <span class="text">abc</span></p></div>
* <div><p>panel 2 <span class="text">abc</span></p></div>
* </div>
* ```
* ```js
* // as namespace usage
* new eg.Flicking("#some")
* .plugin([
* // Apply opacity effect to '<span>' selector matched elements
* new eg.Flicking.plugin.OpacityEffect("span")
* ]);
*
* // as ESM import usage
* import Flicking from "@egjs/flicking";
* import {OpacityEffect} from "@egjs/flicking-plugins";
*
* new Flicking("#some")
* .plugin([
* new OpacityEffect("span")
* ]);
* ```
*/
export default class OpacityEffect extends Plugin {
/**
* Constructor
* @param {String} selector Target element selector string <ko>대상 요소 셀렉터 문자열</ko>
*/
constructor(selector) {
super({selector});
}
$componentMount() {
this.details = Plugin.utils.toArray(
this.$$.$wrapper.querySelectorAll(this.options.selector)
);
this._build();
this.resize();
return this;
}
_build() {
this.details = [this.details.pop()].concat(this.details);
}
_setSelected(index, setClass) {
const utils = Plugin.utils;
utils.classList(utils.css(this.details[index], {opacity: ""}), "selected", setClass);
}
resize() {
this.size = this.getInstanceConf().panel.size;
this.onRestore("resize");
}
arrange(type) {
if (type !== "resize") {
this.details = (type === "next") ?
this.details.concat(this.details.shift()) :
[this.details.pop()].concat(this.details);
}
this._setSelected(1, true);
/next|resize/.test(type) && this._setSelected(0, false);
/prev|resize/.test(type) && this._setSelected(2, false);
}
onFlick(e, distance) {
const pos = e.pos;
const per = (pos % this.size) / this.size;
const utils = Plugin.utils;
if (Math.abs(distance) >= this.size) {
return;
}
const opacity = (distance > 0 && per <= 0.5 && 1 - (2 * per)) ||
(distance < 0 && per > 0.5 && 2 * (per - 0.5));
opacity !== undefined && utils.css(this.details[1], {opacity});
}
onRestore() {
this.arrange("resize");
}
get() {
return this.details[1];
}
}