img-check.js 4.49 KB
/**
 *  Plugin: 图片旋转验证;
 *  @example
 *  pc:
 *  var ImgCheck = require('path/to/img-check')
 *  var imgCheck = new ImgCheck('#js-img-check', {
 *       template: require('path/to/hbs'),
 *       refreshURI: 'path/to/refresh/src'
 *  })
 *
 *  imgCheck.init()
 *
 *  imgCheck.getResult() // '1230'
 *- ----------------------------------------
 *  @example
 *  wap:
 *  var imgCheck = new ImgCheck('#js-img-check', {
 *       useREM: {
 *           rootFontSize: 40,
 *           picWidth: 150
 *       }
 *  })
 * imgCheck.init()
 *
 *  imgCheck.getResult() // '1112'
 */



/**
 *  @param selector|jQuery|Element container
 *  @param object options 配置选项
 *      pc:
 *          {
 *              template,
 *              refreshURI
 *          }
 *
 *      wap:
 *          {
 *              useREM: {
 *                  rootFontSize,  // 设计稿基准字体大小
 *                  picWidth    // 设计稿的验证图片宽度
 *              },
 *              template,
 *              refreshURI
 *          }
 *
 *  @param object data 初始值
 *  {
 *      imgSrc: '图片src'
 *  }
 *
 */
const ImgCheck = function(container, options) {
    let optionDefault = {
        useREM: null,
        template: require('common/img-check.hbs'),
        refreshURI: '/passport/captcha/get',
        imgProcess: '',
    };

    $.extend(this, optionDefault, options);

    this.$container = $(container);
    this.$imgCheck = null;
    this.$imgPics = null;
    this.picWidth = null;

    this.atWorking = false;

    return this;
};

ImgCheck.prototype = {
    init: function() {
        if (this.atWorking) {
            return;
        }

        var self = this;

        if (this.useREM) {
            this.picWidth = this.useREM.picWidth / this.useREM.rootFontSize;
        }

        this.refresh().done(function() {
            self.bindEvents();
        });

        this.atWorking = true;
    },

    /**
     *  method: 绑定事件
     */
    bindEvents: function() {
        this.$container
            .on('click.refresh', '.img-check-refresh', $.proxy(this.refresh, this))
            .on('click.rotate', '.img-check-pic', $.proxy(this.rotateImg, this));
    },

    /**
     *  method: 渲染 dom
     *  @param obj data 渲染数据
     *  {
     *      imgSrc: 'src'  //图片src
     *  }
     */
    render: function(data) {
        var self = this;

        this.$container.html(this.template(data));
        this.$imgPics = this.$container.find('.img-check-pic');

        if (!this.useREM && !this.picWidth) {
            this.picWidth = this.$imgPics.width();
        }

        this.$imgPics.each(function(index, elem) {
            var $elem = $(elem);
            var position = self.calcPosition($elem);

            $elem.css('backgroundPosition', position);
        });
    },

    /**
     *  method: 计算 background-position
     *  @param num index img-check-pic 的index
     *  @param num count img-check-pic
     */
    calcPosition: function($elem) {
        var positionX, positionY;
        var index = $elem.index();
        var count = parseInt($elem.attr('data-val'), 10);
        var unit = this.useREM ? 'rem' : 'px';

        count = count % 4;

        positionX = -index * this.picWidth + unit;
        positionY = -count * this.picWidth + unit;


        return [positionX, positionY].join(' ');
    },

    /**
     *  Handler method: 刷新验证码
     */
    refresh: function() {
        const self = this;
        let uri = this.refreshURI;

        return $.get(uri)
            .done(function(data) {
                let src = data.src;

                self.render({
                    imgSrc: src
                });
            })
            .fail($.noop);
    },


    /**
     * Handler method: 旋转图片
     */
    rotateImg: function(event) {
        var $pic = $(event.target);
        var prevRotateCount = parseInt($pic.attr('data-val'), 10);

        $pic.attr('data-val', prevRotateCount + 1);

        $pic.css({
            backgroundPosition: this.calcPosition($pic)
        });
    },

    /**
     * method: 获取结果
     * @return string '0123'
     */
    getResults: function() {
        var result = [];

        this.$container.find('.img-check-pic')
            .each(function() {
                var $elem = $(this);
                var val = $elem.attr('data-val');

                val = parseInt(val, 10);

                result.push(val % 4);
            });

        return result.join('');
    }
};

ImgCheck.prototype.construct = ImgCheck;


module.exports = ImgCheck;