Source: src/AutoPlay.ts

  1. import Flicking, { FlickingEvent, Plugin, Direction } from "@egjs/flicking";
  2. interface AutoPlayOptions {
  3. duration: number;
  4. direction: Direction[keyof Direction];
  5. stopOnHover: boolean;
  6. }
  7. // tslint:disable-next-line naming-convention
  8. const DEFAULT_OPTION: AutoPlayOptions = {
  9. duration: 2000,
  10. direction: "NEXT",
  11. stopOnHover: false,
  12. };
  13. /**
  14. * Plugin that allow you to automatically move to the next/previous panel, on a specific time basis
  15. * @ko 일정 시간마다, 자동으로 다음/이전 패널로 넘어가도록 할 수 있는 플러그인
  16. * @memberof eg.Flicking.plugins
  17. */
  18. class AutoPlay implements Plugin {
  19. /* Options */
  20. private duration: AutoPlayOptions["duration"];
  21. private direction: AutoPlayOptions["direction"];
  22. private stopOnHover: AutoPlayOptions["stopOnHover"];
  23. /* Internal Values */
  24. private flicking: Flicking | null = null;
  25. private timerId = 0;
  26. private mouseEntered = false;
  27. /**
  28. * @param options Options for the AutoPlay instance.<ko>AutoPlay 옵션</ko>
  29. * @param options.duration Time to wait before moving on to the next panel.<ko>다음 패널로 움직이기까지 대기 시간</ko>
  30. * @param options.direction The direction in which the panel moves.<ko>패널이 움직이는 방향</ko>
  31. * @param options.stopOnHover Whether to stop when mouse hover upon the element.<ko>엘리먼트에 마우스를 올렸을 때 AutoPlay를 정지할지 여부</ko>
  32. * @example
  33. * flicking.addPlugins(new eg.Flicking.plugins.AutoPlay(2000, "NEXT"));
  34. */
  35. constructor(options: Partial<AutoPlayOptions> = DEFAULT_OPTION, direction: AutoPlayOptions["direction"] = DEFAULT_OPTION.direction) {
  36. if (typeof options === "number") {
  37. // Fallback for previous interface
  38. this.duration = options as number;
  39. this.direction = direction;
  40. this.stopOnHover = DEFAULT_OPTION.stopOnHover;
  41. return;
  42. }
  43. const mergedOptions = {
  44. ...DEFAULT_OPTION,
  45. ...options,
  46. } as AutoPlayOptions;
  47. const { duration, direction: dir, stopOnHover } = mergedOptions;
  48. this.duration = duration;
  49. this.direction = dir;
  50. this.stopOnHover = stopOnHover;
  51. }
  52. public init(flicking: Flicking): void {
  53. flicking.on({
  54. moveStart: this.stop,
  55. holdStart: this.stop,
  56. moveEnd: this.play,
  57. select: this.play,
  58. });
  59. this.flicking = flicking;
  60. if (this.stopOnHover) {
  61. const targetEl = this.flicking.getElement();
  62. targetEl.addEventListener("mouseenter", this.onMouseEnter, false);
  63. targetEl.addEventListener("mouseleave", this.onMouseLeave, false);
  64. }
  65. this.play();
  66. }
  67. public destroy(): void {
  68. const flicking = this.flicking;
  69. this.mouseEntered = false;
  70. this.stop();
  71. if (!flicking) return;
  72. flicking.off("moveStart", this.stop);
  73. flicking.off("holdStart", this.stop);
  74. flicking.off("moveEnd", this.play);
  75. flicking.off("select", this.play);
  76. const targetEl = flicking.getElement();
  77. targetEl.removeEventListener("mouseenter", this.onMouseEnter, false);
  78. targetEl.removeEventListener("mouseleave", this.onMouseLeave, false);
  79. this.flicking = null;
  80. }
  81. public play = () => {
  82. const flicking = this.flicking;
  83. if (!flicking) return;
  84. this.stop();
  85. if (this.mouseEntered || flicking.isPlaying()) return;
  86. this.timerId = window.setTimeout(() => {
  87. flicking[this.direction === "NEXT" ? "next" : "prev"]();
  88. this.play();
  89. }, this.duration);
  90. }
  91. public stop = () => {
  92. clearTimeout(this.timerId);
  93. }
  94. private onMouseEnter = () => {
  95. this.mouseEntered = true;
  96. this.stop();
  97. }
  98. private onMouseLeave = () => {
  99. this.mouseEntered = false;
  100. this.play();
  101. }
  102. }
  103. export default AutoPlay;
comments powered by Disqus