jQuery文本效果不能用单个字母呈现

时间:2016-06-11 07:09:53

标签: jquery html css

我正在尝试使用h1表示" hello world",并使用lettering.js(见下文),将h1分解为一系列跨度,以便我可以单独更改字母的颜色制作彩虹效果。我还想使用这里找到的混乱文字效果:http://cozuya.github.io/TextEffect-jQuery-plugin/。以下是刻字插件的链接:https://github.com/davatron5000/Lettering.js

基本上会发生什么,颜色会发生变化,但字母不会混乱,一会儿之后颜色会恢复变白。
我在刻字调用之前尝试使用.delay(),在另一个之前将脚本放在脚本中,似乎没有任何东西让这两个插件一起工作。

这就是h1"你好世界"将看起来像.lettering被称为:

<h1 id = "letters">
  <span class="char1">"</span>
  <span class="char2">h</span>
  <span class="char3">e</span>
  <span class="char4">l</span>
  <span class="char5">l</span>
  <span class="char6">o</span>
  <span class="char7"> </span>
  <span class="char8">w</span>
  <span class="char9">o</span>
   ... and so on
</h1> 

我的jQuery:

$(document).ready(function() {
  $('#letters').textEffect({effect: 'jumble', 
    effectSpeed: 150, 
    completionSpeed: 6000 
  });   
  $("#letters").lettering();
});

CSS

#letters .char10 {
  color: #94C472;
}
#letters .char11 {
  color: #B33E92;
}
#letters .char12 {
  color: #D18D61;
}
#letters .char13 {
  color: #DA3C40;
}
#letters .char14 {
  color: #1AAAA2;
}
#letters .char15 {
  color: #1AAAA2;
}

1 个答案:

答案 0 :(得分:3)

这些插件不兼容。你的行为的原因是:

  1. $('#letters').textEffect(...)由于动画超时而延迟
  2. $("#letters").lettering()textEffect完成渲染之前执行。 lettering插件正在修改它导致问题的元素你注意到jumble不工作的问题(它将带有文本节点的元素转换为具有多个span元素的元素,但textEffect插件是只是期望一串文本,它会对span元素进行自己的操作。)
  3. 要实现此功能,需要对textEffect插件进行一些简单的修改。我更改了jumblerunJumble函数。

    <强> jumble

    删除了对self.reset()的调用,这就是为什么颜色在延迟后会改变回来的原因,就像你指出的那样。这会将单个span标记更改回常规文本节点。 (我评论它显示它的位置;见下文)

    使用您的示例颜色创建colorArray。这可以是您想要的任何内容,并且可以轻松修改为与options一起传递。对于混乱的字母颜色,colorArray传递给runJumble,并且还用于在混乱动画完成后设置正确的字母颜色。

    runJumble

    使用colorArray设置混乱字母的颜色。这取代了选项options.jumbleColor,因此有效地改变了函数的工作方式(从数组中随机选择一种颜色,而不是使用选项定义的单一颜色)。

    这只是为了举例 - 您可能希望更进一步,创建不同的方法,可能称为rainbowJumble,而不是弄乱原始的jumble,或者您可以添加一个选项{rainbow:true}并分支不同的颜色行为。然后你可以做一个pull请求并将它合并到GitHub中的插件中。 WIZ!

    $(document).ready(function() {
      $('#letters').textEffect({effect: 'jumble', 
        effectSpeed: 150, 
        completionSpeed: 6000 
      });   
    });
    
    // from http://cozuya.github.io/TextEffect-jQuery-plugin/javascripts/textEffect.jquery.js
    // jQuery text effect plugin created by Chris Ozols copywrite MIT license 2013
    // v0.1.6
    
    if ( typeof Object.create !== 'function' ) {
    	Object.create = function( obj ) {
    		function F() {}
    		F.prototype = obj;
    		return new F();
    	};
    }
    
    (function( $, window, document, undefined ) {
    
    	var TextEffect = {
    		init: function (options, elem) {
    			var _options = {};
    			this.$elem = $(elem);
    			this.oldText = this.$elem.html();
    			typeof options === 'string' ? _options.effect = options : _options = options;
    			this.options = $.extend( {}, $.fn.textEffect.options, _options );
    			this[this.options.effect]();
    		},
    
    		setup: function (effectOption) {
    			this.textArray = [];
    			this.$elem.html('');  // oddly jQuery.empty() doesn't work as well here.
    			for (var i = 0; i < this.oldText.length; i++) {
    				this.textArray[i] = "<span class='text-effect' style='" + effectOption + "'>" + this.oldText.substr(i, 1) + "</span>";
    				this.$elem.append(this.textArray[i]);
    			}
    		},
    
    		random: function () {
    			var effects = ['grow', 'fade', 'jumble', 'slide', 'dropdown'];
    			var effect = effects[(Math.floor(Math.random() * effects.length))];
    			this[effect]();
    		},
    
    		slide: function () {
    			var startPosition = (this.$elem.offset().left + this.$elem.width());
    			this.setup('visibility: hidden; position: relative; left: ' + startPosition + 'px;');
    			this.run('left', 0);
    		},
    
    		dropdown: function () {
    			var offscreen = this.$elem.offset().top + this.$elem.height() * 1.1;  // little extra padding
    			this.setup('position: relative; bottom: ' + offscreen + 'px;');
    			this.run('bottom', 0);			
    		},
    
    		grow: function () {
    			this.setup('font-size: 0px;');
    			this.run('fontSize', this.$elem.css('fontSize'));
    		},
    
    		fade: function () {
    			this.$elem[0].style.opacity !== undefined ? this.setup('opacity: 0;') : this.setup('filter: alpha(opacity=0); display: inline-block;');  // IE8 and below. jQuery handles animating opacity natively.
    			this.run('opacity', this.$elem.css('opacity'));
    		},
    
    		jumble: function () {
    			var self = this;
                var colorArray = ["#94C472","#B33E92","#D18D61","#DA3C40","#1AAAA2","#1AAAA2"];
    			var letterArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    			var i = 0;
    			this.setup();
    			var jumbleEffectInterval = setInterval(function () {
    				if (self.jumbleInterval) {
    					clearInterval(self.jumbleInterval);
    				}
    				self.runJumble(letterArray, colorArray, i);
    
    				self.$elem.children('span.text-effect').eq(i).html(self.oldText.substr(i, 1)).css('color', colorArray[Math.floor(Math.random() * (colorArray.length - 1))]);
    				if (i === (self.oldText.length - 1)) {
    					clearInterval(jumbleEffectInterval);
    					//self.reset(); // omit reset. this was changing the charcter spans back to plain text
    				} else {
    					i++;
    				}
    			}, self.options.effectSpeed);
    		},
    
    		runJumble: function (letterArray, colorArray, jumbleLength) {
    			var self = this;
    			this.jumbleInterval = setInterval(function () {
    				for (var i = (self.textArray.length - 1); i > jumbleLength; i--) {
    					if (self.oldText.substr(i, 1) !== ' ') {
    						self.$elem.children('span.text-effect').eq(i).html(letterArray[Math.floor(Math.random() * (letterArray.length - 1))]).css('color', colorArray[Math.floor(Math.random() * (colorArray.length - 1))]);
    					} else {
    						self.$elem.children('span.text-effect').eq(i).html(' ');
    					}
    				}
    			}, 70);
    		},
    
    		run: function (effect, oldEffect) {
    			var self = this;
    			var obj = {};
    			var i;
    			obj[effect] = oldEffect;
    			this.options.reverse ? i = this.textArray.length - 1 : i = 0;
    			var $spans = self.$elem.children('span.text-effect');
    			var effectInterval = setInterval(function () {
    				$spans.eq(i).css('visibility', 'visible').animate(obj, self.options.completionSpeed / self.textArray.length, function () {
    						if ($(this).index() === self.textArray.length - 1 && !self.options.reverse || self.options.reverse && $(this).index() === 0) {
    							clearInterval(effectInterval);
    							self.reset();
    						}
    					});
    				self.options.reverse ? i-- : i++;
    			}, self.options.effectSpeed);
    		},
    
    		reset: function () {
    			this.$elem.html(this.oldText);
    		}
    	};
    
    	$.fn.textEffect = function(options) {
    		return this.each(function() {
    			var texteffect = Object.create(TextEffect);
    			texteffect.init(options, this);
    		});
    	};
    
    	$.fn.textEffect.options = {
    		effect: 'random',
    		effectSpeed: 150,
    		completionSpeed: 6000,
    		jumbleColor: '#7f7f7f',
    		reverse: false
    	};
    })( jQuery, window, document );
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <h1 id = "letters">goodbye cruel world</h1>