Want to share your CSS expertise with others? Apply to the MDN Fellowship by April 1! http://mzl.la/MDNFellowship

mozilla

Compare Revisions

Linear-gradient Generator

Change Revisions

Revision 472625:

Revision 472625 by teoli on

Revision 472627:

Revision 472627 by teoli on

Title:
Linear-gradient Generator
Linear-gradient Generator
Slug:
Web/CSS/Tools/Linear-gradient_Generator
Web/CSS/Tools/Linear-gradient_Generator
Content:

Revision 472625
Revision 472627
tt2607window.addEventListener("load", function() {
2608        LinearGradientTool.init();
2609});
2610 
2611var LinearGradientTool = (function LinearGradientTool() {
2612        'use strict';
2613 
2614        var radian = 180 / Math.PI;
2615        var inv_radian = Math.PI / 180;
2616        var units = {'%': 1, 'px' : 0};
2617 
2618        /*========== DOM Methods ==========*/
2619 
2620        function getElemById(id) {
2621                return document.getElementById(id);
2622        }
2623 
2624        function allowDropEvent(e) {
2625                e.preventDefault();
2626        }
2627 
2628        function createClassElement(tag, className, parent) {
2629                var elem = document.createElement(tag);
2630                elem.className = className;
2631                if (parent) parent.appendChild(elem);
2632                return elem;
2633        };
2634 
2635        function trackMouse(elem, callback, startFunc, endFunc) {
2636                startFunc = startFunc || function(e) {};
2637                endFunc = endFunc || function(e) {};
2638 
2639                elem.addEventListener('mousedown', function(e) {
2640                        e.preventDefault();
2641                        startFunc(e);
2642 
2643                        document.addEventListener('mousemove', ca
 >llback);
2644 
2645                        document.addEventListener('mouseup', func
 >tion up(e) {
2646                                document.removeEventListener('mou
 >semove', callback);
2647                                document.removeEventListener('mou
 >seup', up);
2648                                endFunc(e);
2649                        });
2650                });
2651 
2652                elem.addEventListener('click', function(e) {
2653                        e.stopPropagation();
2654                });
2655        }
2656 
2657        var Color = UIColorPicker.Color;
2658        var HSVColor = UIColorPicker.HSVColor;
2659 
2660        var UIComponent = (function UIComponent() {
2661 
2662                function makeResizable(elem, axis, callback, endF
 >unc) {
2663                        var valueX = 0;
2664                        var valueY = 0;
2665                        var action = 0;
2666                        var callback = typeof callback === "funct
 >ion" ? callback : null;
2667 
2668                        endFunc = endFunc || function(e) {};
2669 
2670                        var resizeStart = function resizeStart(e)
 > {
2671                                e.stopPropagation();
2672                                e.preventDefault();
2673                                if (e.button !== 0)
2674                                        return;
2675 
2676                                valueX = e.clientX - elem.clientW
 >idth;
2677                                valueY = e.clientY - elem.clientH
 >eight;
2678 
2679                                document.body.setAttribute('data-
 >resize', axis);
2680                                document.addEventListener('mousem
 >ove', mouseMove);
2681                                document.addEventListener('mouseu
 >p', resizeEnd);
2682                        };
2683 
2684                        var mouseMove = function mouseMove(e) {
2685                                if (action >= 0)
2686                                        elem.style.width = e.clie
 >ntX - valueX + 'px';
2687                                if (action <= 0)
2688                                        elem.style.height = e.cli
 >entY - valueY + 'px';
2689                                if (callback)
2690                                        callback();
2691                        };
2692 
2693                        var resizeEnd = function resizeEnd(e) {
2694                                if (e.button !== 0)
2695                                        return;
2696 
2697                                document.body.removeAttribute('da
 >ta-resize', axis);
2698                                document.removeEventListener('mou
 >semove', mouseMove);
2699                                document.removeEventListener('mou
 >seup', resizeEnd);
2700                                endFunc();
2701                        };
2702 
2703                        var handle = document.createElement('div'
 >);
2704                        handle.className = 'resize-handle';
2705 
2706                        if (axis === 'width') action = 1;
2707                        else if (axis === 'height') action = -1;
2708                        else axis = 'both';
2709 
2710                        handle.className = 'resize-handle';
2711                        handle.setAttribute('data-resize', axis);
2712                        handle.addEventListener('mousedown', resi
 >zeStart);
2713                        elem.appendChild(handle);
2714                };
2715 
2716                return {
2717                        makeResizable : makeResizable
2718                };
2719        })();
2720 
2721 
2722        /**
2723         * Gradient Point
2724         */
2725        var GradientPoint = function GradientPoint(Axis) {
2726                var point = document.createElement('div');
2727 
2728                point.className = 'gradient-point';
2729 
2730                this.position = 0;
2731                this.node = point;
2732                this.Axis = Axis;
2733                this.color = new HSVColor(0, 0, 100);
2734                this.CSScolor = this.color.getColor();
2735                this.CSSposition = 0;
2736                this.PrevPoint = null;
2737                this.NextPoint = null;
2738 
2739                this.Axis.num_points++;
2740 
2741                point.addEventListener('click', this.activate.bin
 >d(this));
2742                trackMouse(point, this.updatePositionM.bind(this)
 >, this.startMove.bind(this),
2743                        this.endMove.bind(this));
2744 
2745                Axis.line.appendChild(point);
2746                return this;
2747        };
2748 
2749        GradientPoint.prototype.deletePoint = function deletePoin
 >t() {
2750                this.Axis.line.removeChild(this.node);
2751        };
2752 
2753        GradientPoint.prototype.activate = function activate() {
2754                if (this.Axis.state === false)
2755                        return;
2756 
2757                this.Axis.setActivePoint(this);
2758                this.node.setAttribute('data-active', 'true');
2759                UIColorPicker.setColor('picker', this.color);
2760                InputSliderManager.setValue('point-position', thi
 >s.CSSposition);
2761                if (this.Axis.num_points > 2)
2762                        AxesManager.setDeleteButtonState('active'
 >);
2763        };
2764 
2765        GradientPoint.prototype.deactivate = function deactivate(
 >) {
2766                this.node.removeAttribute('data-active');
2767        };
2768 
2769        GradientPoint.prototype.startMove = function startMove(e)
 > {
2770                this.Axis.updateCenterPointPos();
2771                this.node.setAttribute('data-active', 'true');
2772                document.body.setAttribute('data-dragging', 'true
 >');
2773        };
2774 
2775        GradientPoint.prototype.endMove = function endMove(e) {
2776                this.node.removeAttribute('data-active', 'true');
2777                document.body.removeAttribute('data-dragging');
2778        };
2779 
2780        GradientPoint.prototype.updatePositionM = function update
 >PositionM(e) {
2781                var A = this.Axis;
2782                var Qx = e.clientX - A.centerX;
2783                var Qy = e.clientY - A.centerY;
2784                this.position = (A.Px * Qx + A.Py * Qy) / A.Pmod 
 >+ A.lsize;
2785                this.updateCSSPosition();
2786                this.Axis.reorderPoint(this);
2787                this.Axis.updateGradient();
2788                this.updateSlider();
2789        };
2790 
2791        GradientPoint.prototype.setPositionM = function setPositi
 >onM(posX, posY) {
2792                var A = this.Axis;
2793                var Qx = posX - A.centerX;
2794                var Qy = posY - A.centerY;
2795                this.position = (A.Px * Qx + A.Py * Qy) / A.Pmod 
 >+ A.lsize;
2796                this.updateCSSPosition();
2797                this.Axis.reorderPoint(this);
2798                this.Axis.updateGradient();
2799                this.updateSlider();
2800        };
2801 
2802        GradientPoint.prototype.updateAbsolutePosition = function
 > updateAbsolutePosition() {
2803                if (this.Axis.unit ='%')
2804                        this.position = parseFloat(((this.CSSposi
 >tion / 100) * (2 * this.Axis.lsize)).toFixed(1));;
2805        };
2806 
2807        GradientPoint.prototype.setPosition = function setPositio
 >n(pos) {
2808                this.position = pos;
2809                if (this.Axis.unit === '%')
2810                        this.position = parseFloat(((this.positio
 >n / 100) * (2 * this.Axis.lsize)).toFixed(1));;
2811                this.updateCSSPosition();
2812                this.Axis.reorderPoint(this);
2813                this.Axis.updateGradient();
2814        };
2815 
2816        GradientPoint.prototype.updateSlider = function updateSli
 >der() {
2817                if (this.Axis.ActivePoint === this && thi
 >s.Axis.state === true)
2818                        InputSliderManager.setValue('point-positi
 >on', this.CSSposition, false);
2819        };
2820 
2821        GradientPoint.prototype.updateColor = function updateColo
 >r(color) {
2822                this.color.copy(color);
2823                this.CSScolor = color.getColor();
2824                this.updateCSSvalue();
2825        };
2826 
2827        GradientPoint.prototype.updateCSSPosition = function upda
 >teCSSPosition() {
2828                this.CSSposition = this.position | 0;
2829                if (this.Axis.unit === '%')
2830                        this.CSSposition = parseFloat((100 * this
 >.position / (2 * this.Axis.lsize)).toFixed(1));
2831 
2832                this.node.style.left = this.CSSposition + this.Ax
 >is.unit;
2833                this.updateCSSvalue();
2834        };
2835 
2836        GradientPoint.prototype.updateCSSvalue = function updateC
 >SSvalue() {
2837                this.CSSvalue = this.CSScolor + ' ' + this.CSSpos
 >ition + this.Axis.unit;
2838        };
2839 
2840        GradientPoint.prototype.insertBefore = function insertBef
 >ore(point) {
2841                this.NextPoint = point;
2842                this.PrevPoint = point.PrevPoint;
2843                point.PrevPoint = this;
2844                if (this.PrevPoint)
2845                        this.PrevPoint.NextPoint = this;
2846        };
2847 
2848        GradientPoint.prototype.insertAfter = function insertAfte
 >r(point) {
2849                this.NextPoint = point.NextPoint;
2850                this.PrevPoint = point;
2851                point.NextPoint = this;
2852                if (this.NextPoint)
2853                        this.NextPoint.PrevPoint = this;
2854        };
2855 
2856 
2857        /**
2858         * Gradient Axis
2859         */
2860        function GradientAxis(container, id) {
2861                var axis = createClassElement('div', 'gradient-ax
 >is', null);
2862                var line = createClassElement('div', 'gradient-li
 >ne', axis);
2863                var rotate_point = createClassElement('div', 'rot
 >ate-point', axis);
2864 
2865                axis.setAttribute('axisID', id);
2866 
2867                var svg = this.createSVGArrow(id);
2868                rotate_point.appendChild(svg);
2869 
2870                this.id         = id;
2871                this.axis       = axis;
2872                this.unit       = '%';
2873                this.line       = line;
2874                this.container = container;
2875                this.lsize = container.clientWidth / 2;
2876                this.FirstPoint = null;
2877                this.ActivePoint = null;
2878                this.gradient = '';
2879                this.num_points = 0;
2880 
2881                this.size = 0;
2882                this.angle = 0;
2883                this.state = false;
2884                this.updateOnResize();
2885 
2886                trackMouse(rotate_point, this.updateAxisAngle.bin
 >d(this),
2887                                                this.startRotatio
 >n.bind(this));
2888 
2889                container.appendChild(axis);
2890                line.addEventListener('click', this.placeGradient
 >Point.bind(this));
2891        };
2892 
2893 
2894        GradientAxis.prototype.createSVGArrow = function createSV
 >GArrow(id) {
2895                var xmlns = 'http://www.w3.org/2000/svg';
2896                var svg = document.createElementNS(xmlns, 'svg');
2897                var path = document.createElementNS(xmlns, 'path'
 >);
2898 
2899                svg.setAttribute('class', 'gradient-arrow');
2900 
2901                svg.setAttribute('width', '25');
2902                svg.setAttribute('height', '25');
2903 
2904                path.setAttribute('fill', '#CCC');
2905                path.setAttribute('d', 'M 25,12.5 L 0,0 L 7.5,12.
 >5 L 0,25');
2906                svg.appendChild(path);
2907 
2908                return svg;
2909        };
2910 
2911        GradientAxis.prototype.placeGradientPoint = function plac
 >eGradientPoint(e) {
2912                this.updateCenterPointPos();
2913                var point = new GradientPoint(this);
2914                point.setPositionM(e.clientX, e.clientY);
2915                point.activate();
2916                this.attachPoint(point);
2917                this.updateGradient();
2918        };
2919 
2920        GradientAxis.prototype.newGradientPoint = function newGra
 >dientPoint(pos) {
2921                var point = new GradientPoint(this);
2922                point.setPosition(pos);
2923                point.activate();
2924                this.attachPoint(point);
2925                this.updateGradient();
2926        };
2927 
2928        GradientAxis.prototype.attachPoint = function attachPoint
 >(point) {
2929 
2930                // add the first point
2931                if (this.FirstPoint === null) {
2932                        this.FirstPoint = point;
2933                        return;
2934                }
2935 
2936                // insert the point into the list
2937                var p = this.FirstPoint;
2938                while (p.NextPoint) {
2939                        if (point.CSSposition < p.CSSposition)
 > {
2940                                point.insertBefore(p);
2941                                if (point.PrevPoint === null)
2942                                        this.FirstPoint = point;
2943                                return;
2944                        }
2945                        p = p.NextPoint;
2946                };
2947 
2948                // test the last point
2949                if (point.CSSposition < p.CSSposition)
2950                        point.insertBefore(p);
2951                else
2952                        point.insertAfter(p);
2953 
2954                if (point.PrevPoint === null)
2955                        this.FirstPoint = point;
2956 
2957                return;
2958        };
2959 
2960        GradientAxis.prototype.detachPoint = function detachPoint
 >(point) {
2961                if (this.FirstPoint === point)
2962                        this.FirstPoint = point.NextPoint;
2963                if (point.PrevPoint)
2964                        point.PrevPoint.NextPoint = point.NextPoi
 >nt;
2965                if (point.NextPoint)
2966                        point.NextPoint.PrevPoint = point.PrevPoi
 >nt;
2967                point.NextPoint = null;
2968                point.PrevPoint = null;
2969        };
2970 
2971        GradientAxis.prototype.deleteActivePoint = function delet
 >eActivePoint() {
2972                // return if only 2 points left on the axis
2973                if (this.num_points === 2)
2974                        return;
2975 
2976                if (this.ActivePoint) {
2977                        this.ActivePoint.deletePoint();
2978                        this.detachPoint(this.ActivePoint);
2979                        this.updateGradient();
2980                        this.num_points--;
2981                }
2982        };
2983 
2984        GradientAxis.prototype.reorderPoint = function reorderPoi
 >nt(point) {
2985                if (point.NextPoint && point.NextPoint.CS
 >Sposition > point.CSSposition &&
2986                        point.PrevPoint && point.PrevPoin
 >t.CSSposition < point.CSSposition)
2987                        return;
2988                if (point.NextPoint === point.PrevPoint)
2989                        return;
2990 
2991                this.detachPoint(point);
2992                this.attachPoint(point);
2993        };
2994 
2995        GradientAxis.prototype.setActivePoint = function setActiv
 >ePoint(point) {
2996                if (this.ActivePoint)
2997                        this.ActivePoint.deactivate();
2998                this.ActivePoint = point;
2999        };
3000 
3001        GradientAxis.prototype.activate = function activate() {
3002                this.state = true;
3003                this.axis.setAttribute('data-active', this.state)
 >;
3004                InputSliderManager.setUnit('point-position', this
 >.unit, false);
3005                SliderManager.setValue('axis-rotation', this.angl
 >e | 0, false);
3006                DropDownManager.setValue('axis-unit', units[this.
 >unit], false);
3007 
3008                if (this.ActivePoint)
3009                        this.ActivePoint.activate();
3010        };
3011 
3012        GradientAxis.prototype.deactivate = function deactivate()
 > {
3013                this.state = false;
3014                this.axis.removeAttribute('data-active', this.sta
 >te);
3015                if (this.ActivePoint)
3016                        this.ActivePoint.deactivate();
3017        };
3018 
3019        GradientAxis.prototype.deleteAxis = function deleteAxis()
 > {
3020                this.deactivate();
3021                this.container.removeChild(this.axis);
3022        };
3023 
3024        GradientAxis.prototype.updatePointColor = function update
 >PointColor(color) {
3025                if (this.ActivePoint)
3026                        this.ActivePoint.updateColor(color);
3027                this.updateGradient();
3028        };
3029 
3030        GradientAxis.prototype.updatePointPosition = function upd
 >atePointPosition(value) {
3031                if (this.ActivePoint)
3032                        this.ActivePoint.setPosition(value);
3033        };
3034 
3035        GradientAxis.prototype.setUnit = function setUnit(unit) {
3036                this.unit = unit;
3037                this.updateAllPoints();
3038                InputSliderManager.setUnit('point-position', unit
 >, false);
3039 
3040                if (this.ActivePoint)
3041                        this.ActivePoint.updateSlider();
3042 
3043                this.updateGradient();
3044        };
3045 
3046        GradientAxis.prototype.updateAllPoints = function updateA
 >llPoints() {
3047                var p = this.FirstPoint;
3048                while(p) {
3049                        p.updateCSSPosition();
3050                        p = p.NextPoint;
3051                }
3052        };
3053 
3054        /* Axis events */
3055        GradientAxis.prototype.startRotation = function startRota
 >tion(e) {
3056                this.updateCenterPointPos();
3057                this.updateAxisAngle(e);
3058        };
3059 
3060        GradientAxis.prototype.updateOnResize = function updateOn
 >Resize() {
3061                this.updateContainer();
3062                this.updateCenterPointPos();
3063                this.setAxisAngle(this.angle);
3064        };
3065 
3066        GradientAxis.prototype.updateCenterPointPos = function up
 >dateCenterPointPos() {
3067                var pos = this.container.getBoundingClientRect();
3068                this.centerX = (pos.left + pos.right) / 2;
3069                this.centerY = (pos.top + pos.bottom) / 2;
3070        };
3071 
3072        GradientAxis.prototype.updateContainer = function updateC
 >ontainer() {
3073                var W = this.container.clientWidth;
3074                var H = this.container.clientHeight;
3075 
3076                var max_size = Math.sqrt(W * W + H * H) + 50;
3077 
3078                this.axis.style.width = max_size + 'px';
3079                this.axis.style.left = (W - max_size)/2 - 1 + 'px
 >';
3080 
3081                this.mW = W / 2;
3082                this.mH = H / 2;
3083        };
3084 
3085        GradientAxis.prototype.updateAxisAngle = function updateA
 >xisAngle(e) {
3086 
3087                var Px = e.clientX - this.centerX;
3088                var Py = e.clientY - this.centerY;
3089                var deg = -Math.atan2(Py, Px) * radian;
3090                var Pmod = Math.sqrt(Px * Px + Py * Py);
3091                this.lsize = (this.mW * Math.abs(Px) + this.mH * 
 >Math.abs(Py)) / Pmod;
3092 
3093                if (this.state === true)
3094                        SliderManager.setValue('axis-rotation', d
 >eg | 0, false);
3095 
3096                this.angle = deg;
3097                this.updateCSS();
3098                AxesManager.updateCSSGradient();
3099 
3100                this.Px = Px;
3101                this.Py = Py;
3102                this.Pmod = Pmod;
3103        };
3104 
3105        GradientAxis.prototype.setAxisAngle = function setAxisAng
 >le(deg) {
3106                var rad = -deg * inv_radian;
3107                var Px = Math.cos(rad);
3108                var Py = Math.sin(rad);
3109                this.lsize = this.mW * Math.abs(Px) + this.mH * M
 >ath.abs(Py);
3110 
3111                this.angle = deg;
3112                this.updateCSS();
3113                AxesManager.updateCSSGradient();
3114 
3115                this.Px = Px;
3116                this.Py = Py;
3117                this.Pmod = 1;
3118        };
3119 
3120        /* UI Methods - apply CSS */
3121 
3122        GradientAxis.prototype.updateCSS = function updateCSS() {
3123                this.line.style.width = 2 * this.lsize + 'px';
3124                this.axis.style.transform = 'rotate('+ -this.angl
 >e +'deg)';
3125                this.axis.style.webkitTransform = 'rotate('+ -thi
 >s.angle +'deg)';
3126        };
3127 
3128        GradientAxis.prototype.updateGradient = function updateGr
 >adient() {
3129                var p = this.FirstPoint;
3130                if (p === null)
3131                        return;
3132 
3133                this.gradient = p.CSSvalue;
3134                p = p.NextPoint;
3135                while(p) {
3136                        this.gradient += ', ' + p.CSSvalue;
3137                        p = p.NextPoint;
3138                };
3139                AxesManager.updateCSSGradient();
3140        };
3141 
3142        // this is the standard syntax
3143        GradientAxis.prototype.getCSSGradient = function getCSSGr
 >adient() {
3144                return 'linear-gradient('+ (-this.angle + 90 | 0)
 > +'deg, ' + this.gradient + ')';
3145        };
3146 
3147        /**
3148         * AxesManager
3149         */
3150        var AxesManager = (function AxesManager() {
3151 
3152                var lg_axes = [];
3153                var ActiveAxis = null;
3154                var ActiveShortcut = null;
3155                var axes_menu = null;
3156                var gradient_container = null;
3157                var add_axis_btn;
3158                var delete_axis_btn;
3159                var delete_point_btn;
3160                var update_output;
3161                var dragElem;
3162 
3163                var createStartAxis = function createStartAxis(an
 >gle) {
3164 
3165                        if (ActiveAxis)
3166                                ActiveAxis.deactivate();
3167 
3168                        var axisID = getNextAxisID();
3169                        var axis = new GradientAxis(gradient_cont
 >ainer, axisID);
3170                        var color = new HSVColor(210, 90, 90);
3171                        ActiveAxis = axis;
3172 
3173                        axis.activate();
3174                        axis.setAxisAngle(angle);
3175                        axis.newGradientPoint(10);
3176                        axis.updatePointColor(color);
3177 
3178                        color.setAlpha(0.5);
3179                        axis.newGradientPoint(50);
3180                        axis.updatePointColor(color);
3181 
3182                        color.setHue(275);
3183                        axis.newGradientPoint(50);
3184                        axis.updatePointColor(color);
3185 
3186                        color.setAlpha(1);
3187                        axis.newGradientPoint(90);
3188                        axis.updatePointColor(color);
3189 
3190                        UIColorPicker.setColor('picker', color);
3191                        lg_axes.push(axis);
3192 
3193                        axis.Shortcut = createAxisShortcut(axisID
 >);
3194                        axis.activate();
3195                };
3196 
3197                var createAxis = function createAxis(angle) {
3198 
3199                        if (ActiveAxis)
3200                                ActiveAxis.deactivate();
3201 
3202                        var axisID = getNextAxisID();
3203                        var axis = new GradientAxis(gradient_cont
 >ainer, axisID);
3204                        var color = new HSVColor(0, 0, 50);
3205                        ActiveAxis = axis;
3206 
3207                        axis.activate();
3208                        axis.setAxisAngle(angle);
3209                        axis.newGradientPoint(10);
3210                        axis.updatePointColor(color);
3211 
3212                        color.setValue(90);
3213                        axis.newGradientPoint(90);
3214                        axis.updatePointColor(color);
3215 
3216                        UIColorPicker.setColor('picker', color);
3217                        lg_axes.push(axis);
3218 
3219                        axis.Shortcut = createAxisShortcut(axisID
 >);
3220                        axis.activate();
3221                };
3222 
3223                var createAxisShortcut = function createAxisShort
 >cut(axisID) {
3224                        var axis = createClassElement('div', 'axi
 >s', axes_menu);
3225 
3226                        axis.setAttribute('axisID', axisID);
3227                        axis.setAttribute('draggable', 'true');
3228                        axis.style.left = (lg_axes.length - 1) * 
 >60 + 'px';
3229 
3230                        axis.addEventListener('click', function()
 > {
3231                                activateAxisShortcut(axis);
3232                                var axisID = this.getAttribute('a
 >xisID') | 0;
3233                                activateAxis(axisID);
3234                        });
3235 
3236                        axis.addEventListener('dragstart', functi
 >on (e) {
3237                                dragElem = this;
3238                                e.dataTransfer.setData('axisID', 
 >this.getAttribute('axisID'));
3239                        });
3240                        axis.addEventListener('dragover', allowDr
 >opEvent);
3241                        axis.addEventListener('drop', function sw
 >ap(e) {
3242                                if (dragElem === this)
3243                                        return;
3244 
3245                                var from = getOrderID(e.dataTrans
 >fer.getData('axisID'));
3246                                var to = getOrderID(this.getAttri
 >bute('axisID'));
3247 
3248                                var swap = lg_axes[from];
3249                                lg_axes[from] = lg_axes[to];
3250                                lg_axes[to] = swap;
3251 
3252                                var left = dragElem.offsetLeft;
3253                                dragElem.style.left = this.offset
 >Left + 'px';
3254                                this.style.left = left + 'px';
3255 
3256                                updateCSSGradient();
3257                        });
3258 
3259                        activateAxisShortcut(axis);
3260                        return axis;
3261                };
3262 
3263                var activateAxisShortcut = function activateAxisS
 >hortcut(node) {
3264                        if (ActiveShortcut)
3265                                ActiveShortcut.removeAttribute('d
 >ata-state');
3266                        node.setAttribute('data-state', 'active')
 >;
3267                        ActiveShortcut = node;
3268                };
3269 
3270                var getNextAxisID = function getNextAxisID() {
3271                        var ids = [];
3272                        var idx = 0;
3273                        var len = lg_axes.length;
3274 
3275                        for (var i=0; i< lg_axes.length) {
3276                                if (ids[idx] !== true)
3277                                        return idx;
3278                                idx++;
3279                        }
3280 
3281                        return idx;
3282                };
3283 
3284                var getOrderID = function getOrderID(axisID) {
3285                        var len = lg_axes.length;
3286                        for (var i=0; i 1)
3287                                delete_axis_btn.removeAttribute('
 >data-state');
3288                };
3289 
3290                /* Axis functions */
3291 
3292                var updateAxisRotation = function updateAxisRotat
 >ion(value) {
3293                        ActiveAxis.setAxisAngle(value);
3294                };
3295 
3296                var setAxisUnit = function setAxisUnit(obj) {
3297                        ActiveAxis.setUnit(obj.value);
3298                };
3299 
3300                var setAddAxisButton = function setAddAxisButton(
 >) {
3301                        add_axis_btn = getElemById('add-axis');
3302                        add_axis_btn.addEventListener('click', fu
 >nction() {
3303                                if (lg_axes.length === 4)
3304                                        return;
3305 
3306                                createAxis(0);
3307 
3308                                if (lg_axes.length > 1)
3309                                        delete_axis_btn.removeAtt
 >ribute('data-state');
3310                                if (lg_axes.length === 4)
3311                                        this.setAttribute('data-s
 >tate', 'disabled');
3312                        });
3313                };
3314 
3315                var setDeleteAxisButton = function setDeleteAxisB
 >utton() {
3316                        delete_axis_btn = getElemById('delete-axi
 >s');
3317                        delete_axis_btn.addEventListener('click',
 > function () {
3318                                if (this.hasAttribute('data-state
 >'))
3319                                        return;
3320                                if (lg_axes.length === 1)
3321                                        return;
3322 
3323                                axes_menu.removeChild(ActiveAxis.
 >Shortcut);
3324                                ActiveAxis.deleteAxis();
3325                                lg_axes.splice(getOrderID(ActiveA
 >xis.id), 1);
3326 
3327                                ActiveAxis = null;
3328                                updateCSSGradient();
3329 
3330                                var len = lg_axes.length;
3331                                for (var i=0; i< 4)
3332                                        add_axis_btn.removeAttrib
 >ute('data-state');
3333                        });
3334                };
3335 
3336                /* Point methods */
3337 
3338                var updatePointColor = function updatePointColor(
 >color) {
3339                        ActiveAxis.updatePointColor(color);
3340                };
3341 
3342                var updatePointPosition = function updatePointPos
 >ition(color) {
3343                        ActiveAxis.updatePointPosition(color);
3344                };
3345 
3346                var setDeletePointButton = function setDeletePoin
 >tButton() {
3347                        delete_point_btn = getElemById('delete-po
 >int');
3348                        delete_point_btn.addEventListener('click'
 >, function () {
3349                                if (this.getAttribute('data-state
 >') === 'disabled')
3350                                        return;
3351 
3352                                ActiveAxis.deleteActivePoint();
3353                                updateCSSGradient();
3354                                setDeleteButtonState('disabled');
3355                        });
3356                };
3357 
3358                var setDeleteButtonState = function setDeleteButt
 >onState(state) {
3359                        if (delete_point_btn)
3360                                delete_point_btn.setAttribute('da
 >ta-state', state);
3361                };
3362 
3363                /* Container box functions */
3364 
3365                var resizeContainer = function resizeContainer() 
 >{
3366                        var len = lg_axes.length;
3367                        for(var i = 0; i < len; i++)
3368                                lg_axes[i].updateOnResize();
3369                };
3370 
3371                var resizeEnd = function resizeEnd() {
3372                        var len = lg_axes.length;
3373                        for(var i = 0; i < len; i++)
3374                                lg_axes[i].updateAbsolutePosition
 >();
3375                };
3376 
3377                /* General functions */
3378 
3379                var updateCSSGradient = function () {
3380                        var gradient = [];
3381                        var k = 0;
3382                        var len = lg_axes.length;
3383                        for(var i = 0; i < len; i++) {
3384                                gradient.push(lg_axes[i].getCSSGr
 >adient());
3385                        }
3386 
3387                        gradient_container.style.background = gra
 >dient.join(', ');
3388 
3389                        if (update_output)
3390                                window.clearTimeout(update_output
 >);
3391 
3392                        update_output = setTimeout( function() {
3393                                Tool.updateOutputCSSCode(gradient
 >);
3394                        }, 500);
3395                };
3396 
3397                var init = function init() {
3398                        gradient_container = getElemById('gradien
 >t-container');
3399                        axes_menu = getElemById('gradient-axes');
3400 
3401                        setDeletePointButton();
3402                        setDeleteAxisButton();
3403                        setAddAxisButton();
3404 
3405                        createStartAxis(18);
3406                        createStartAxis(-18);
3407 
3408                        updateCSSGradient();
3409 
3410                        UIColorPicker.subscribe('picker', updateP
 >ointColor);
3411                        InputSliderManager.subscribe('point-posit
 >ion', updatePointPosition);
3412 
3413                        DropDownManager.subscribe('axis-unit', se
 >tAxisUnit);
3414                        SliderManager.subscribe('axis-rotation', 
 >updateAxisRotation);
3415 
3416                        UIComponent.makeResizable(gradient_contai
 >ner, 'both', resizeContainer, resizeEnd);
3417                        window.addEventListener('resize', resizeC
 >ontainer);
3418                };
3419 
3420                return {
3421                        init : init,
3422                        updateCSSGradient : updateCSSGradient,
3423                        setDeleteButtonState : setDeleteButtonSta
 >te
3424                };
3425 
3426        })();
3427 
3428 
3429        /**
3430         * Tool
3431         */
3432        var Tool = (function Tool() {
3433 
3434                var container;
3435                var output;
3436 
3437                var setToggleAlphaBackground = function setToggle
 >AlphaBackground() {
3438                        var button = getElemById('canvas-bg');
3439                        var state = true;
3440                        button.addEventListener('click', function
 >() {
3441                                state = !state;
3442                                container.setAttribute('data-alph
 >a', state);
3443                                this.setAttribute('data-alpha', s
 >tate);
3444                        });
3445                };
3446 
3447                var updateOutputCSSCode = function updateOutputCS
 >SCode(gradient) {
3448 
3449                        var updateOutputElem = function updateOut
 >putElem(index, prefix) {
3450                                var code = prefix + gradient.join
 >(',\n ' + prefix) + ';';
3451                                output.children[index].children[1
 >].textContent = code;
3452                                output.children[index].style.heig
 >ht = output.children[index].children[1].scrollHeight + 'px';
3453                        };
3454 
3455                        updateOutputElem(0, '');
3456                };
3457 
3458 
3459                var init = function init() {
3460                        output = getElemById('output');
3461                        container = getElemById('gradient-contain
 >er');
3462 
3463                        setToggleAlphaBackground();
3464                };
3465 
3466                return {
3467                        init : init,
3468                        updateOutputCSSCode: updateOutputCSSCode
3469                };
3470 
3471        })();
3472 
3473        var init = function init() {
3474                UIColorPicker.init();
3475                InputSliderManager.init();
3476                DropDownManager.init();
3477                SliderManager.init();
3478                AxesManager.init();
3479                Tool.init();
3480        };
3481 
3482        return {
3483                init : init
3484        };
3485 

Back to History