"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _kit_utils = require("kit_utils");

var _index = _interopRequireDefault(require("./index.less"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

var SlideVerify =
/*#__PURE__*/
function () {
  function SlideVerify() {
    _classCallCheck(this, SlideVerify);
  }

  _createClass(SlideVerify, [{
    key: "init",
    value: function init() {
      this.initDOM();
      this.initImg();
      this.bindEvents();
    }
  }, {
    key: "render",
    value: function render(_ref) {
      var container = _ref.container,
          onSuccess = _ref.onSuccess,
          onFail = _ref.onFail,
          onRefresh = _ref.onRefresh;
      container.style.position = container.style.position || 'relative';
      this.slideLong = 42; // 拼图边长

      this.slideRadius = 9; // 拼图缺口半径

      this.canvasWidth = 310; // canvas宽度

      this.canvasHeight = 155; // canvas高度

      this.slideTotalWidth = this.slideLong + this.slideRadius * 2 + 3; // 拼图实际边长

      this.container = container;
      this.onSuccess = onSuccess;
      this.onFail = onFail;
      this.onRefresh = onRefresh;
      this.init();
    }
  }, {
    key: "destroy",
    value: function destroy() {
      var childs = this.container.childNodes;

      for (var i = childs.length - 1; i >= 0; i--) {
        this.container.removeChild(childs[i]);
      }
    }
  }, {
    key: "initDOM",
    value: function initDOM() {
      var canvas = this.createCanvas(this.canvasWidth, this.canvasHeight); // 画布

      var block = canvas.cloneNode(true); // 拼图

      var sliderContainer = this.createElement('div', _index["default"].sliderContainer);
      var refreshIcon = this.createElement('div', _index["default"].refreshIcon);
      var sliderMask = this.createElement('div', _index["default"].sliderMask);
      var slider = this.createElement('div', _index["default"].slider);
      var sliderIcon = this.createElement('span', _index["default"].sliderIcon);
      var text = this.createElement('span', _index["default"].sliderText);
      block.className = _index["default"].sliderBlock;
      text.innerHTML = '向右滑动填充拼图';
      var el = this.container;
      el.appendChild(canvas);
      el.appendChild(refreshIcon);
      el.appendChild(block);
      slider.appendChild(sliderIcon);
      sliderMask.appendChild(slider);
      sliderContainer.appendChild(sliderMask);
      sliderContainer.appendChild(text);
      el.appendChild(sliderContainer);
      Object.assign(this, {
        canvas: canvas,
        block: block,
        sliderContainer: sliderContainer,
        refreshIcon: refreshIcon,
        slider: slider,
        sliderMask: sliderMask,
        sliderIcon: sliderIcon,
        text: text,
        canvasCtx: canvas.getContext('2d'),
        blockCtx: block.getContext('2d')
      });
    }
  }, {
    key: "initImg",
    value: function initImg() {
      var _this = this;

      var img = this.createImg(function () {
        _this.startDraw();

        _this.canvasCtx.drawImage(img, 0, 0, _this.canvasWidth, _this.canvasHeight);

        _this.blockCtx.drawImage(img, 0, 0, _this.canvasWidth, _this.canvasHeight);

        var y = _this.slideY - _this.slideRadius * 2 - 2;

        var ImageData = _this.blockCtx.getImageData(_this.slideX - 3, y, _this.slideTotalWidth, _this.slideTotalWidth);

        _this.block.width = _this.slideTotalWidth;

        _this.blockCtx.putImageData(ImageData, 0, y);
      });
      this.img = img;
    }
  }, {
    key: "startDraw",
    value: function startDraw() {
      // 随机创建拼图的位置(矩形拼图左上顶点位置)
      this.slideX = this.getRandomNumberByRange(this.slideTotalWidth + 10, this.canvasWidth - (this.slideTotalWidth + 10));
      this.slideY = this.getRandomNumberByRange(10 + this.slideRadius * 2, this.canvasHeight - (this.slideTotalWidth + 10));
      this.draw(this.canvasCtx, this.slideX, this.slideY, 'fill');
      this.draw(this.blockCtx, this.slideX, this.slideY, 'clip');
    }
  }, {
    key: "clean",
    value: function clean() {
      this.canvasCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
      this.blockCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
      this.block.width = this.canvasWidth;
    }
  }, {
    key: "bindEvents",
    value: function bindEvents() {
      var _this2 = this;

      this.container.onselectstart = function () {
        return false;
      };

      this.refreshIcon.onclick = function () {
        _this2.reset();

        typeof _this2.onRefresh === 'function' && _this2.onRefresh();
      };

      var originX,
          originY,
          trail = [],
          isMouseDown = false;

      var handleDragStart = function handleDragStart(e) {
        originX = e.clientX || e.touches[0].clientX;
        originY = e.clientY || e.touches[0].clientY;
        isMouseDown = true;
      };

      var handleDragMove = function handleDragMove(e) {
        if (!isMouseDown) return false;
        var eventX = e.clientX || e.touches[0].clientX;
        var eventY = e.clientY || e.touches[0].clientY;
        var moveX = eventX - originX;
        var moveY = eventY - originY;
        if (moveX < 0 || moveX + 38 >= _this2.canvasWidth) return false;
        _this2.slider.style.left = moveX + 'px'; //按钮的滑动距离

        var blockLeft = (_this2.canvasWidth - 40 - 20) / (_this2.canvasWidth - 40) * moveX; //按钮与滑块的移动比例相同

        _this2.block.style.left = blockLeft + 'px';

        _kit_utils.dom.addClass(_this2.sliderContainer, _index["default"]['sliderContainer_active']);

        _this2.sliderMask.style.width = moveX + 'px';
        trail.push(moveY);
      };

      var handleDragEnd = function handleDragEnd(e) {
        if (!isMouseDown) return false;
        isMouseDown = false;
        var eventX = e.clientX || e.changedTouches[0].clientX;
        if (eventX == originX) return false;

        _kit_utils.dom.removeClass(_this2.sliderContainer, _index["default"]['sliderContainer_active']);

        _this2.trail = trail;

        var _this2$verify = _this2.verify(),
            spliced = _this2$verify.spliced,
            verified = _this2$verify.verified;

        if (spliced) {
          if (verified) {
            _kit_utils.dom.addClass(_this2.sliderContainer, _index["default"]['sliderContainer_success']);

            typeof _this2.onSuccess === 'function' && _this2.onSuccess();
          } else {
            _kit_utils.dom.addClass(_this2.sliderContainer, _index["default"]['sliderContainer_fail']);

            _this2.text.innerHTML = '再试一次';

            _this2.reset();
          }
        } else {
          _kit_utils.dom.addClass(_this2.sliderContainer, _index["default"]['sliderContainer_fail']);

          typeof _this2.onFail === 'function' && _this2.onFail();
          setTimeout(function () {
            _this2.reset();
          }, 1000);
        }
      };

      this.slider.addEventListener('mousedown', handleDragStart);
      this.slider.addEventListener('touchstart', handleDragStart);
      document.addEventListener('mousemove', handleDragMove);
      document.addEventListener('touchmove', handleDragMove);
      document.addEventListener('mouseup', handleDragEnd);
      document.addEventListener('touchend', handleDragEnd);
    }
  }, {
    key: "verify",
    value: function verify() {
      var arr = this.trail; // 拖动时y轴的移动距离

      var average = arr.reduce(this.sum) / arr.length;
      var deviations = arr.map(function (x) {
        return x - average;
      });
      var stddev = Math.sqrt(deviations.map(this.square).reduce(this.sum) / arr.length); //总体标准差

      var left = parseInt(this.block.style.left);
      return {
        spliced: Math.abs(left - this.slideX) < 10,
        verified: stddev !== 0 // 简单验证下拖动轨迹，为零时表示Y轴上下没有波动，可能非人为操作

      };
    }
  }, {
    key: "reset",
    value: function reset() {
      this.sliderContainer.className = _index["default"].sliderContainer;
      this.slider.style.left = 0;
      this.block.style.left = 0;
      this.sliderMask.style.width = 0;
      this.clean();
      this.img.src = this.getRandomImg();
    }
  }, {
    key: "createCanvas",
    value: function createCanvas(width, height) {
      var canvas = this.createElement('canvas');
      canvas.width = width;
      canvas.height = height;
      return canvas;
    }
  }, {
    key: "createElement",
    value: function createElement(tagName, className) {
      var element = document.createElement(tagName);
      element.className = className;
      return element;
    }
  }, {
    key: "getRandomNumberByRange",
    value: function getRandomNumberByRange(start, end) {
      return Math.round(Math.random() * (end - start) + start);
    }
  }, {
    key: "getRandomImg",
    value: function getRandomImg() {
      return require("../../assets/SlideVerify/" + [this.getRandomNumberByRange(1, 8) + '.jpg']);
    }
  }, {
    key: "createImg",
    value: function createImg(onload) {
      var _this3 = this;

      var img = new Image();
      img.setAttribute('crossOrigin', 'Anonymous');
      img.src = this.getRandomImg();
      img.onload = onload;

      img.onerror = function () {
        img.src = _this3.getRandomImg();
      };

      return img;
    }
  }, {
    key: "draw",
    value: function draw(ctx, x, y, operation) {
      var l = this.slideLong; // 滑块边长

      var r = this.slideRadius;
      var PI = Math.PI;
      var borderGap = 2;
      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.arc(x + l / 2, y - r + borderGap, r, 0.72 * PI, 2.26 * PI); //上圆

      ctx.lineTo(x + l, y);
      ctx.arc(x + l + r - borderGap, y + l / 2, r, 1.21 * PI, 2.78 * PI); //右圆

      ctx.lineTo(x + l, y + l);
      ctx.lineTo(x, y + l);
      ctx.arc(x + r - borderGap, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true); //左圆

      ctx.lineTo(x, y);
      ctx.lineWidth = borderGap;
      ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
      ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';
      ctx.stroke();
      ctx[operation]();
      ctx.globalCompositeOperation = 'overlay';
    }
  }, {
    key: "sum",
    value: function sum(x, y) {
      return x + y;
    }
  }, {
    key: "square",
    value: function square(x) {
      return x * x;
    }
  }]);

  return SlideVerify;
}();

var _default = SlideVerify;
exports["default"] = _default;