zoukankan      html  css  js  c++  java
  • 滑弯曲弧形效果的插件-arctext.js改造

     要实现以上效果  JQ插件 circletype  和  arctext都都可以

    1.为何这么进行改造? 

        1.  arctext.js  不可拓展及可调控性差

     2.  代码臃肿 ,未压缩源代码三百余行 , 剔除空行及注释后也有二百余行代码

    2.如何做?

     将 arctext.js源代码中的核心函数提取化为己用 , 重新封装  

    arctext.js剔除注释及空行后的源代码:

    (function( $, undefined ) {
        $.fn.fitText = function( kompressor, options ) {
            var settings = {
                'minFontSize' : Number.NEGATIVE_INFINITY,
                'maxFontSize' : Number.POSITIVE_INFINITY
            };
            return this.each(function() {
                var $this = $(this);              // store the object
                var compressor = kompressor || 1; // set the compressor
                if ( options ) { 
                  $.extend( settings, options );
                }
                var resizer = function () {
                    $this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize)));
                };
                resizer();
                $(window).resize(resizer);
            });
        };
        function injector(t, splitter, klass, after) {
            var a = t.text().split(splitter), inject = '', emptyclass;
            if (a.length) {
                $(a).each(function(i, item) {
                    emptyclass = '';
                    if(item === ' ') {
                        emptyclass = ' empty';
                        item=' ';
                    }   
                    inject += '<span class="'+klass+(i+1)+emptyclass+'">'+item+'</span>'+after;
                }); 
                t.empty().append(inject);
            }
        }
        var methods = {
            init : function() {
                return this.each(function() {
                    injector($(this), '', 'char', '');
                });
            },
            words : function() {
                return this.each(function() {
                    injector($(this), ' ', 'word', ' ');
                });
            },
            lines : function() {
                return this.each(function() {
                    var r = "eefec303079ad17405c889e092e105b0";
                    injector($(this).children("br").replaceWith(r).end(), r, 'line', '');
                });
            }
        };
        $.fn.lettering  = function( method ) {
            if ( method && methods[method] ) {
                return methods[ method ].apply( this, [].slice.call( arguments, 1 ));
            } else if ( method === 'letters' || ! method ) {
                return methods.init.apply( this, [].slice.call( arguments, 0 ) ); // always pass an array
            }
            $.error( 'Method ' +  method + ' does not exist on jQuery.lettering' );
            return this;
        };
        $.Arctext = function( options, element ) {
            this.$el= $( element );
            this._init( options );
        };
        $.Arctext.defaults  = {
            radius  : 0,    
            dir     : 1,    
            rotate  : true, 
            fitText : false 
        };
        $.Arctext.prototype     = {
            _init: function( options ) {
                this.options        = $.extend( true, {}, $.Arctext.defaults, options );
                this._applyLettering();
                this.$el.data( 'arctext', true );
                this._calc();
                this._rotateWord();
                this._loadEvents();
            },
            _applyLettering : function() {
                this.$el.lettering();
                if( this.options.fitText ) this.$el.fitText();
                this.$letters   = this.$el.find('span').css('display', 'inline-block');
            },
            _calc: function() {
                if( this.options.radius === -1 )return false;
                this._calcBase();
                this._calcLetters();
            },
            _calcBase  : function() {
                this.dtWord = 0;
                var _self= this;
                this.$letters.each( function(i) {
                    var $letter = $(this),
                        letterWidth = $letter.outerWidth( true );
                    _self.dtWord += letterWidth;
                    $letter.data( 'center', _self.dtWord - letterWidth / 2 );
                });
                var centerWord = this.dtWord / 2;
                if( this.options.radius < centerWord ) this.options.radius = centerWord;
                this.dtArcBase  = this.dtWord;
                var angle  = 2 * Math.asin( this.dtArcBase / ( 2 * this.options.radius ) );
                this.dtArc = this.options.radius * angle;
            },
            _calcLetters: function() {
                var _self = this,
                    iteratorX = 0;
                this.$letters.each( function(i) {
                    
                    var $letter = $(this),
                        dtArcLetter  = ( $letter.outerWidth( true ) / _self.dtWord ) * _self.dtArc,
                        beta= dtArcLetter / _self.options.radius,
                        h   = _self.options.radius * ( Math.cos( beta / 2 ) ),
                        alpha = Math.acos( ( _self.dtWord / 2 - iteratorX ) / _self.options.radius ),
                        theta   = alpha + beta / 2,
                        x    = Math.cos( theta ) * h,
                        y    = Math.sin( theta ) * h,
                        xpos = iteratorX + Math.abs( _self.dtWord / 2 - x - iteratorX ),
                        xval    = 0| xpos - $letter.data( 'center' ),
                        yval    = 0| _self.options.radius - y,
                        angle   = ( _self.options.rotate ) ? 0| -Math.asin( x / _self.options.radius ) * ( 180 / Math.PI ) : 0;
                    iteratorX = 2 * xpos - iteratorX;
                    $letter.data({
                        x   : xval,
                        y   : ( _self.options.dir === 1 ) ? yval : -yval,
                        a   : ( _self.options.dir === 1 ) ? angle : -angle
                    });
                });
            },
            _rotateWord : function( animation ) {
                if( !this.$el.data('arctext') ) return false;
                var _self = this;
                this.$letters.each( function(i) {
                    var $letter = $(this),
                        transformation= ( _self.options.radius === -1 ) ? 'none' : 'translateX(' + $letter.data('x') + 'px) translateY(' + $letter.data('y') + 'px) rotate(' + $letter.data('a') + 'deg)',
                        transition= ( animation ) ? 'all ' + ( animation.speed || 0 ) + 'ms ' + ( animation.easing || 'linear' ) : 'none';
                    $letter.css({
                        '-webkit-transition' : transition,
                        '-moz-transition' : transition,
                        '-o-transition' : transition,
                        '-ms-transition' : transition,
                        'transition' : transition
                    })
                    .css({
                        '-webkit-transform' : transformation,
                        '-moz-transform' : transformation,
                        '-o-transform' : transformation,
                        '-ms-transform' : transformation,
                        'transform' : transformation
                    });
                });
            },
            _loadEvents : function() {
                if( this.options.fitText ) {
                    var _self = this;
                    $(window).on( 'resize.arctext', function() {
                        _self._calc();
                        _self._rotateWord();
                    });
                }
            },
            set : function( opts ) {
                if( !opts.radius &&  
                    !opts.dir &&
                    opts.rotate === 'undefined' ) {return false;}
                this.options.radius = opts.radius || this.options.radius;
                this.options.dir    = opts.dir || this.options.dir;
                if( opts.rotate !== undefined ) {this.options.rotate = opts.rotate;}
                this._calc();
                this._rotateWord( opts.animation );
            },
            destroy : function() {
                this.options.radius = -1;
                this._rotateWord();
                this.$letters.removeData('x y a center');
                this.$el.removeData('arctext');
                $(window).off('.arctext');
            }
        };
        var logError = function( message ) {
            if ( this.console ) {console.error( message ); }
        };
        $.fn.arctext= function( options ) {
            if ( typeof options === 'string' ) {
                var args = Array.prototype.slice.call( arguments, 1 );
                this.each(function() {
                    var instance = $.data( this, 'arctext' );
                    if ( !instance ) {
                        logError( "cannot call methods on arctext prior to initialization; " +
                        "attempted to call method '" + options + "'" );
                        return;
                    }
                    if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
                        logError( "no such method '" + options + "' for arctext instance" );
                        return;
                    }
                    instance[ options ].apply( instance, args );
                });
            }  else {
                this.each(function() {
                    var instance = $.data( this, 'arctext' );
                    if ( !instance ) {
                        $.data( this, 'arctext', new $.Arctext( options, this ) );
                    }
                });
            }
            return this;
        };
    })( jQuery );

     

    提取核心算法函数(此版为测试逻辑算法是否走通 , 未处理全局声明)

    arcText('.big_tit1')
    function arcText(el){
        var a = $(el).text().split(''),emptyclass, after,inject;
        inject = ''
        if (a.length) {
            $(a).each(function(i, item) {
                emptyclass = '';
                after = '';
                if(item === ' ') {
                    emptyclass = ' empty';
                    item='&nbsp;';
                }   
                inject += '<span class="'+'char'+(i+1)+emptyclass+'">'+item+'</span>'+after;
            }); 
            $(el).empty().append(inject);
        }
        letters   = $(el).find('span').css('display', 'inline-block');
        rotate = true;
        calcBase();
        calcLetters();
        rotateWord();
    }
    function calcBase() {
        dtWord = 0;
        radius =1000;
        letters.each( function(i) {
            var $letter = $(this),
                letterWidth = $letter.outerWidth( true );
            dtWord += letterWidth;
            $letter.data( 'center', dtWord - letterWidth / 2 );
        });
        var centerWord = dtWord / 2;
        if( radius < centerWord ) radius = centerWord;
        dtArcBase  = dtWord;
        angle  = 2 * Math.asin( dtArcBase / ( 2 * radius ) );
        dtArc = radius * angle;
    }
    function calcLetters() {
        var _self = this,
            iteratorX = 0;
        letters.each( function(i) {
            $letter = $(this),
            dtArcLetter  = ( $letter.outerWidth( true ) /dtWord ) * dtArc,
            beta= dtArcLetter / radius,
            h   = radius * ( Math.cos( beta / 2 ) ),
            alpha = Math.acos( (dtWord / 2 - iteratorX ) / radius ),
            theta   = alpha + beta / 2,
            x    = Math.cos( theta ) * h,
            y    = Math.sin( theta ) * h,
            xpos = iteratorX + Math.abs( dtWord / 2 - x - iteratorX ),
            xval    = 0| xpos - $letter.data( 'center' ),
            yval    = 0| radius - y,
            angle   = ( rotate ) ? 0| -Math.asin( x / radius ) * ( 180 / Math.PI ) : 0;
            iteratorX = 2 * xpos - iteratorX;
            $letter.data({
                x   : xval,
                y   : yval,
                a   : angle
            });
        });
    }
    function rotateWord( animation ) {
       var _self = this;
       letters.each( function(i) {
            var $letter = $(this),
                transformation= (radius === -1 ) ? 'none' : 'translateX(' + $letter.data('x') + 'px) translateY(' + $letter.data('y') + 'px) rotate(' + $letter.data('a') + 'deg)',
                transition= ( animation ) ? 'all ' + ( animation.speed || 0 ) + 'ms ' + ( animation.easing || 'linear' ) : 'none';
            $letter.css({
                '-webkit-transition' : transition,
                '-moz-transition' : transition,
                '-o-transition' : transition,
                '-ms-transition' : transition,
                'transition' : transition
            })
            .css({
                '-webkit-transform' : transformation,
                '-moz-transform' : transformation,
                '-o-transform' : transformation,
                '-ms-transform' : transformation,
                'transform' : transformation
            });
        });
    }

    将核心代码换个包装 , 化为己用
    缺点:当多个dom同一个类名时会出现问题

    Arctext.prototype={
        init(options){
            this.initData(options);
            this.render();
            this.handle();
        },
        initData(options){
            var defaults  = {
                radius  : 0,    
                dir     : 1,    
                rotate  : true, 
                fitText : false 
            }
            this.options= $.extend( true, {}, defaults, options );
            this.dir = this.options.dir;
            this.rotate = this.options.rotate;
            this.$el =  $(this.options.el);
            this.radius = this.options.radius;
        },
        render(){
            let { $el, radius} = this;
            var a = $el.text().split(''),emptyclass, after,inject;
            inject = ''
            if (a.length) {
                $(a).each(function(i, item) {
                    emptyclass = '';
                    after = '';
                    if(item === ' ') {
                        emptyclass = ' empty';
                        item='&nbsp;';
                    }   
                    inject += '<span class="'+'char'+(i+1)+emptyclass+'">'+item+'</span>'+after;
                }); 
               $el.empty().append(inject);
            }
            this.letters   = $el.find('span').css('display', 'inline-block');
        },
        handle(){
            this.calcBase();
            this.calcLetters();
            this.rotateWord(this.animation)
        },
        calcBase() {
            var dtWord = 0;
            var self =this;
            self.letters.each( function(i) {
                var $letter = $(this),
                    letterWidth = $letter.outerWidth( true );
                dtWord += letterWidth;
                $letter.data( 'center', dtWord - letterWidth / 2 );
            });
            var centerWord = dtWord / 2;
            if( self.radius < centerWord ) self.radius = centerWord;
            var dtArcBase  = dtWord;
            var angle  = 2 * Math.asin( dtArcBase / ( 2 * self.radius ) );
            dtArc = self.radius * angle;
            self.dtArc = dtArc;
            self.dtWord = dtWord;
        },
        calcLetters() {
            let { radius , letters , dtWord ,dtArc,rotate ,dir } = this;
            var _self = this,iteratorX = 0;
            // var rotate  = true;
            letters.each( function(i) {
                $letter = $(this),
                dtArcLetter  = ( $letter.outerWidth( true ) /dtWord ) * dtArc,
                beta= dtArcLetter / radius,
                h   = radius * ( Math.cos( beta / 2 ) ),
                alpha = Math.acos( (dtWord / 2 - iteratorX ) / radius ),
                theta   = alpha + beta / 2,
                x    = Math.cos( theta ) * h,
                y    = Math.sin( theta ) * h,
                xpos = iteratorX + Math.abs( dtWord / 2 - x - iteratorX ),
                xval    = 0| xpos - $letter.data( 'center' ),
                yval    = 0| radius - y,
                angle   = ( rotate ) ? 0| -Math.asin( x / radius ) * ( 180 / Math.PI ) : 0;
                iteratorX = 2 * xpos - iteratorX;
                $letter.data({
                    x   : xval,
                    y   : ( dir === 1 ) ? yval : -yval,
                    a   : ( dir === 1 ) ? angle : -angle
                });
              
            });
        },
        rotateWord( animation ) {
           var _self = this;
           let { radius , letters } = this;
           letters.each( function(i) {
                 var $letter = $(this),
                  transformation= (radius === -1 ) ? 'none' : 'translateX(' + $letter.data('x') + 'px) translateY(' + $letter.data('y') + 'px) rotate(' + $letter.data('a') + 'deg)',
                transition= ( animation ) ? 'all ' + ( animation.speed || 0 ) + 'ms ' + ( animation.easing || 'linear' ) : 'none';
                $letter.css({
                    '-webkit-transition' : transition,
                    '-moz-transition' : transition,
                    '-o-transition' : transition,
                    '-ms-transition' : transition,
                    'transition' : transition
                })
                .css({
                    '-webkit-transform' : transformation,
                    '-moz-transform' : transformation,
                    '-o-transform' : transformation,
                    '-ms-transform' : transformation,
                    'transform' : transformation
                });
            });
        }    
    }
    function Arctext(options){
        this.init(options)
    }

    new Arctext({
        el:'.big_tit1',
        radius:370 , // 
       // rotate:false, //字体是否随拱形旋转
        dir:1 // 1 向下弯曲 非1 向上弯曲
    })

     

     改进版

    //文字拱形显示    
    Arctext.prototype={
        init(options){
            this.initData(options);
            this.render();
           
        },
        initData(options){
            var defaults  = {
                radius  : 0,    
                dir     : 1,    
                rotate  : true, 
                fitText : false 
            }
            this.options= $.extend( true, {}, defaults, options );
            this.dir = this.options.dir;
            this.rotate = this.options.rotate;
            this.$el =  $(this.options.el);
            this.radius = this.options.radius;
        },
        render(){
            let { $el, radius} = this;
            if($el.length){
                $el.each((i,dom)=>{
                    var a = $(dom).text().split(''),emptyclass, after,inject;
                    inject = '';
                    console.log($el.length)
                    if (a.length) {
                        $(a).each(function(i, item) {
                            emptyclass = '';
                            after = '';
                            if(item === ' ') {
                                emptyclass = ' empty';
                                item='&nbsp;';
                            }   
                            inject += '<span class="'+'char'+(i+1)+emptyclass+'">'+item+'</span>'+after;
                        }); 
                       $(dom).empty().append(inject);
                    }
                    this.letters   = $(dom).find('span').css('display', 'inline-block');
                    this.handle();
                })
            }
            
        },
        handle(){
            this.calcBase();
            this.calcLetters();
            this.rotateWord(this.animation)
        },
        calcBase() {
            var dtWord = 0;
            var self =this;
            self.letters.each( function(i) {
                var $letter = $(this),
                    letterWidth = $letter.outerWidth( true );
                dtWord += letterWidth;
                $letter.data( 'center', dtWord - letterWidth / 2 );
            });
            var centerWord = dtWord / 2;
            if( self.radius < centerWord ) self.radius = centerWord;
            var dtArcBase  = dtWord;
            var angle  = 2 * Math.asin( dtArcBase / ( 2 * self.radius ) ); // Math.asin 返回值-PI/2 到 PI/2  
            self.dtArc = self.radius * angle;
            self.dtWord = dtWord;
        },
        calcLetters() {
            let { radius , letters , dtWord ,dtArc,rotate ,dir } = this;
            var _self = this,iteratorX = 0;
            letters.each( function(i) {
                $letter = $(this),
                dtArcLetter  = ( $letter.outerWidth( true ) /dtWord ) * dtArc,
                beta= dtArcLetter / radius,
                h   = radius * ( Math.cos( beta / 2 ) ),
                alpha = Math.acos( (dtWord / 2 - iteratorX ) / radius ),
                theta   = alpha + beta / 2,
                x    = Math.cos( theta ) * h,
                y    = Math.sin( theta ) * h,
                xpos = iteratorX + Math.abs( dtWord / 2 - x - iteratorX ),
                xval    = 0| xpos - $letter.data( 'center' ),
                yval    = 0| radius - y,
                angle   = ( rotate ) ? 0| -Math.asin( x / radius ) * ( 180 / Math.PI ) : 0; //在角度和弧度之间转换
                iteratorX = 2 * xpos - iteratorX;
                $letter.data({
                    x   : xval,
                    y   : ( dir === 1 ) ? yval : -yval,  
                    a   : ( dir === 1 ) ? angle : -angle
                });
              
            });
        },
        rotateWord( animation ) {
           var _self = this;
           let { radius , letters } = this;
           letters.each( function(i) {
                 var $letter = $(this),
                  transformation= (radius === -1 ) ? 'none' : 'translateX(' + $letter.data('x') + 'px) translateY(' + $letter.data('y') + 'px) rotate(' + $letter.data('a') + 'deg)',
                transition= ( animation ) ? 'all ' + ( animation.speed || 0 ) + 'ms ' + ( animation.easing || 'linear' ) : 'none';
                $letter.css({
                    '-webkit-transition' : transition,
                    '-moz-transition' : transition,
                    '-o-transition' : transition,
                    '-ms-transition' : transition,
                    'transition' : transition
                })
                .css({
                    '-webkit-transform' : transformation,
                    '-moz-transform' : transformation,
                    '-o-transform' : transformation,
                    '-ms-transform' : transformation,
                    'transform' : transformation
                });
            });
        }    
    }
    function Arctext(options){
        this.init(options)
    }
       new Arctext({
            el:'.big_tit',
            radius:370 , //
            //   rotate:false,  //默认true,为false则不旋转文字
            //   dir:1        //默认1 (1:向下弯曲 非1(-1,0,2等):向上弯曲 )
        })

    解决多个dom同一个类名带来的bug

    ...

  • 相关阅读:
    Linux环境变量$PATH
    grep
    echo命令
    ip命令
    浅析Linux下的/etc/profile、/etc/bashrc、~/.bash_profile、~/.bashrc文件
    shell脚本4种执行方式
    /proc路径
    tr命令
    Linux命令cut
    前端论坛网站知识
  • 原文地址:https://www.cnblogs.com/wxyblog/p/13371057.html
Copyright © 2011-2022 走看看