Yahoo! UI Library

codecola-color  1.0.0

Yahoo! UI Library > codecola-color > codecola-degree.js (source view)
Search:
 
Filters
/*
Copyright (c) 2011, ZHOUQICF.COM. All rights reserved.
Code licensed under the MIT License:
version: 1.0.0
*/
/**
 * a degree control for css3 property
 * @module codecola-degree
 */
YUI().add('codecola-degree', function(Y) {
    /**
     * a degree control for css3 property
     * @param config {Object} Object literal specifying codecolaDegree configuration properties.
     * @class codecolaDegree
     * @constructor
     * @namespace Y
     * @extends Widget
     * @requires node widget codecola-degree-css
     */
    Y.codecolaDegree = Y.Base.create('codecola-degree', Y.Widget, [], {
        initializer: function() {
        },

        renderUI: function() {
            var that = this;
            that.vars = {
                degreeWrap : Y.Node.create('<div class="codecola-degree-wrap"></div>'),
                degree : Y.Node.create('<div class="codecola-degree"></div>'),
                line : Y.Node.create('<i class="codecola-degree-line"></i>'),
                dot : Y.Node.create('<b class="codecola-degree-dot"></b>'),
                label : Y.Node.create('<label class="codecola-degree-label"></label>'),
                input : Y.Node.create('<input type="number" class="codecola-degree-input" step="1" max="180" min="-180">'),
                disable: false
            };
            var val = that.vars,
                degreeWrap = val.degreeWrap,
                degree = val.degree,
                line = val.line,
                dot = val.dot,
                label = val.label,
                input = val.input;

            degree.append(line).append(dot);
            label.append(input);
            degreeWrap.append(degree).append(label);
            Y.one(that.get('wrap')).append(degreeWrap);

            return that;
        },

        bindUI: function() {
            var that = this,
                drag = false,
                vars = that.vars,
                doc = Y.one('html');
            vars.degree.on('click', function(e) {
                if(vars.disable){
                    return;
                }
                that.setDegree({
                    degree: that._calculateDegree(e)
                });
            });
            vars.degree.on('mousedown', function(e) {
                if(vars.disable){
                    return;
                }
                drag = true;
                doc.setStyle('webkitUserSelect', 'none');
            });
            doc.on('mouseup', function() {
                if(vars.disable){
                    return;
                }
                drag = false;
                doc.setStyle('webkitUserSelect', '');
            });
            doc.on('mousemove', function(e) {
                if (!drag || vars.disable) {
                    return;
                }
                that.setDegree({
                    degree: that._calculateDegree(e)
                });
            });
            vars.input.on('change', function() {
                that.setDegree({
                    degree: this.get('value')
                });
            });
            return that;
        },

        syncUI: function() {
            this._initControls();
            return this;
        },

        renderer: function(){
            this.renderUI().bindUI().syncUI().get('onInit')();
            return this;
        },

        /**
         * Calculate degree
         * @method _calculateDegree
         * @private
         * @param {Event}
         * @return {Number}
         */
        _calculateDegree: function(e) {
            var dot = this.vars.dot,
                dotXY = dot.getXY(),
                offset = {};

            offset.x = e.clientX + window.pageXOffset - dotXY[0];
            offset.y = e.clientY + window.pageYOffset - dotXY[1];

            return - Math.ceil(Math.atan2(offset.y, offset.x) * (360 / (2 * Math.PI)));
        },

        /**
         * init all controls
         * @method _initControls
         * @private
         * @chainable
         */
        _initControls: function() {
            var that = this,
                degree = that.get('degree'),
                value = 'rotate(' + (-degree) + 'deg)';

            that.vars.line.setStyles({
                'MozTransform': value,
                'webkitTransform': value,
                'OTransform': value,
                'transform': value
            });

            that.vars.input.set('value', degree);
            return that;
        },

        /**
         * update the attribute 'degree', init all the controls, fire the onChange event
         * @method setDegree
         * @param {Object} param.degree for update the attribute 'degree'
         * @chainable
         */
        setDegree: function(param) {
            this.set('degree', param.degree)._initControls()._fireCallback();
            return this;
        },

        /**
         * return the current degree
         * @method getDegree
         * @return {Number}
         */
        getDegree: function() {
            return this.get('degree');
        },

        /**
         * reset all, degree is 0, will not run onChange
         * @method reset
         * @chainable
         */
        reset: function(param) {
            this.set('degree', 0)._initControls();
            return this;
        },

        //TODO: add able and disable method
        /**
         * disable all controls
         * @method disable
         * @chainable
         */
        disable: function() {
            var vars = this.vars;
            vars.input.set('disable', true);
            vars.disable = true;
            return this;
        },

        /**
         * able all controls
         * @method able
         * @chainable
         */
        able: function() {
            var vars = this.vars;
            vars.input.set('disable', false);
            vars.disable = false;
            return this;
        },


        /**
         * fire the onChange event
         * @method _fireCallback
         * @private
         * @chainable
         */
        _fireCallback: function() {
            this.get('onChange')(this.get('degree'));
            return this;
        }
    }, {
        ATTRS:{
            /**
             * @attribute wrap
             * @type String
             * @default 'body'
             * @description a css selector for <code>Y.one()</code>,controls will insert into the wrap
             */
            wrap: {
                value: 'body',
                validator: Y.Lang.isString
            },
            /**
             * @attribute degree
             * @type Number
             * @default 0
             * @description degree for init, degree is a number from -180 to 180
             */
            degree: {
                value: 0,
                validator: function(v){
                    if(/^-?1[0-7]\d$|^-?180$|^-?[1-9]\d$|^\d$|^-[1-9]$/.test(v)){
                        return true;
                    }else{
                        Y.log('"' + v + '" is not a valid degree!');
                        return false;
                    }
                }
            },
            /**
             * @attribute onInit
             * @type Function
             * @default function(){}
             * @description callback when widget init
             */
            onInit: {
                value: function() {
                },
                validator: Y.Lang.isFunction
            },
            /**
             * @attribute onChange
             * @type Function
             * @default function(){}
             * @description callback when degree change
             */
            onChange: {
                value: function() {
                },
                validator: Y.Lang.isFunction
            }
        }
    });
}, '1.0.0', {requires:['node', 'widget-base','codecola-degree-css']});

Copyright © 2011 Yahoo! Inc. All rights reserved.