Your IP : 216.73.216.79


Current Path : /var/www/html/reddsis/node_modules/grapick/src/
Upload File :
Current File : /var/www/html/reddsis/node_modules/grapick/src/Handler.js

import {on, off, isFunction, isDef, getPointerEvent } from './utils'

/**
 * Handler is the color stop of the gradient
 */
export default class Handler {

  constructor(Grapick, position = 0, color = 'black', select = 1, opts = {}) {
    Grapick.getHandlers().push(this);
    this.gp = Grapick;
    this.position = position;
    this.color = color;
    this.selected = 0;
    this.render();
    select && this.select(opts);
  }

  toJSON() {
    return {
      position: this.position,
      selected: this.selected,
      color: this.color,
    };
  }

  /**
   * Set color
   * @param {string} color Color string, eg. red, #123, 'rgba(30,87,153,1)', etc..
   * @param {Boolean} complete Indicates if the action is complete
   * @example
   * handler.setColor('red');
   */
  setColor(color, complete = 1) {
    this.color = color;
    this.emit('handler:color:change', this, complete);
  }

  /**
   * Set color
   * @param {integer} position Position integer in percentage, eg. 20, 50, 100
   * @param {Boolean} complete Indicates if the action is complete
   * @example
   * handler.setPosition(55);
   */
  setPosition(position, complete = 1) {
    const el = this.getEl();
    this.position = position;
    el && (el.style.left = `${position}%`);
    this.emit('handler:position:change', this, complete);
  }

  /**
   * Get color of the handler
   * @return {string} Color string
   */
  getColor() {
    return this.color;
  }

  /**
   * Get position of the handler
   * @return {integer} Position integer
   */
  getPosition() {
    const { position, gp } = this;
    const { onValuePos } = gp.options;
    return isFunction(onValuePos) ? onValuePos(position) : position;
  }

  /**
   * Indicates if the handler is the selected one
   * @return {Boolean}
   */
  isSelected() {
    return !!this.selected;
  }

  /**
   * Get value of the handler
   * @return {string}
   * @example
   * handler.getValue(); // -> `black 0%`
   */
  getValue() {
    return `${this.getColor()} ${this.getPosition()}%`;
  }

  /**
   * Select the current handler and deselect others
   * @param {Object} [options={}] Options
   * @param {Boolean} [options.keepSelect=false] Avoid deselecting other handlers
   */
  select(opts = {}) {
    const el = this.getEl();
    const handlers = this.gp.getHandlers();
    !opts.keepSelect && handlers.forEach(handler => handler.deselect());
    this.selected = 1;
    const clsNameSel = this.getSelectedCls();
    el && (el.className += ` ${clsNameSel}`);
    this.emit('handler:select', this);
  }

  /**
   * Deselect the current handler
   */
  deselect() {
    const el = this.getEl();
    this.selected = 0;
    const clsNameSel = this.getSelectedCls();
    el && (el.className = el.className.replace(clsNameSel, '').trim());
    this.emit('handler:deselect', this);
  }

  getSelectedCls() {
    const pfx = this.gp.options.pfx;
    return `${pfx}-handler-selected`;
  }

  /**
   * Remove the current handler
   * @param {Object} [options={}] Options
   * @param {Boolean} [options.silent] Don't trigger events
   * @return {Handler} Removed handler (itself)
   */
  remove(options = {}) {
    const { cpFn } = this;
    const el = this.getEl();
    const handlers = this.gp.getHandlers();
    const removed = handlers.splice(handlers.indexOf(this), 1)[0];
    el && el.parentNode.removeChild(el);
    !options.silent && this.emit('handler:remove', removed);
    isFunction(cpFn) && cpFn(this);
    ['el', 'gp'].forEach(i => this[i] = 0);
    return removed;
  }

  /**
   * Get handler element
   * @return {HTMLElement}
   */
  getEl() {
    return this.el;
  }

  initEvents() {
    const eventDown = 'touchstart mousedown';
    const eventMove = 'touchmove mousemove';
    const eventUp = 'touchend mouseup';
    const el = this.getEl();
    const previewEl = this.gp.previewEl;
    const options = this.gp.options;
    const min = options.min;
    const max = options.max;
    const closeEl = el.querySelector('[data-toggle=handler-close]');
    const colorContEl = el.querySelector('[data-toggle=handler-color-c]');
    const colorWrapEl = el.querySelector('[data-toggle=handler-color-wrap]');
    const colorEl = el.querySelector('[data-toggle=handler-color]');
    const dragEl = el.querySelector('[data-toggle=handler-drag]');
    const upColor = (ev, complete = 1)  => {
      const { value } = ev.target;
      this.setColor(value, complete);
      colorWrapEl && (colorWrapEl.style.backgroundColor = value);
    }
    colorContEl && on(colorContEl, 'click', e => e.stopPropagation());
    closeEl && on(closeEl, 'click', e => {
      e.stopPropagation();
      this.remove()
    });
    if (colorEl) {
      on(colorEl, 'change', upColor);
      on(colorEl, 'input', ev => upColor(ev, 0));
    }

    if (dragEl) {
      let pos = 0;
      let posInit = 0;
      let dragged = 0;
      const elDim = {};
      const startPos = {};
      const deltaPos = {};
      const axis = 'x';
      const drag = e => {
        const evP = getPointerEvent(e);
        dragged = 1;
        deltaPos.x = evP.clientX - startPos.x;
        deltaPos.y = evP.clientY - startPos.y;
        pos = (axis == 'x' ? deltaPos.x : deltaPos.y) * 100;
        pos = pos / (axis == 'x' ? elDim.w : elDim.h);
        pos = posInit + pos;
        pos = pos < min ? min : pos;
        pos = pos > max ? max : pos;
        this.setPosition(pos, 0);
        this.emit('handler:drag', this, pos);
        // In case the mouse button was released outside of the window
        isDef(e.button) && e.which === 0 && stopDrag(e);
      };
      const stopDrag = e => {
        off(document, eventMove, drag);
        off(document, eventUp, stopDrag);
        if (!dragged) {
          return;
        }
        dragged = 0;
        this.setPosition(pos);
        this.emit('handler:drag:end', this, pos);
      };
      const initDrag = e => {
        //Right or middel click
        if (isDef(e.button) && e.button !== 0) {
          return;
        }
        this.select();
        const evP = getPointerEvent(e);
        posInit = this.position;
        elDim.w = previewEl.clientWidth;
        elDim.h = previewEl.clientHeight;
        startPos.x = evP.clientX;
        startPos.y = evP.clientY;
        on(document, eventMove, drag);
        on(document, eventUp, stopDrag);
        this.emit('handler:drag:start', this);
      };

      on(dragEl, eventDown, initDrag);
      on(dragEl, 'click', e => e.stopPropagation());
    }
  }

  emit() {
    this.gp.emit(...arguments);
  }

  /**
   * Render the handler
   * @return {HTMLElement} Rendered element
   */
  render() {
    const gp = this.gp;
    const opt = gp.options;
    const previewEl = gp.previewEl;
    const colorPicker = gp.colorPicker;
    const pfx = opt.pfx;
    const colorEl = opt.colorEl;
    const color = this.getColor();

    if (!previewEl) {
      return;
    }

    const hEl = document.createElement('div');
    const style = hEl.style;
    const baseCls = `${pfx}-handler`;
    hEl.className = baseCls;
    hEl.innerHTML = `
      <div class="${baseCls}-close-c">
        <div class="${baseCls}-close" data-toggle="handler-close">&Cross;</div>
      </div>
      <div class="${baseCls}-drag" data-toggle="handler-drag"></div>
      <div class="${baseCls}-cp-c" data-toggle="handler-color-c">
        ${colorEl || `
          <div class="${baseCls}-cp-wrap" data-toggle="handler-color-wrap" style="background-color: ${color}">
            <input type="color" data-toggle="handler-color" value="${color}">
          </div>`}
      </div>
    `;
    style.position = 'absolute';
    style.top = 0;
    style.left = `${this.position}%`;
    previewEl.appendChild(hEl);
    this.el = hEl;
    this.initEvents();
    this.cpFn = colorPicker && colorPicker(this);
    return hEl;
  }
}