带有纯 jQuery 动画的特殊颜色过渡效果 // 在 ui 或其他库上
Posted
技术标签:
【中文标题】带有纯 jQuery 动画的特殊颜色过渡效果 // 在 ui 或其他库上【英文标题】:Special color transition effect with pure jQuery animation // no ui or other libary 【发布时间】:2012-09-03 05:13:14 【问题描述】:我正在尝试在没有任何外部插件的情况下创建 jQuery 彩色动画。到目前为止,我可以用 jQuery-ui 做到这一点,但我想用 pure jQuery animate()
学习这种方式@
在 1.8 上用更少的代码和没有任何外部 jQuery 插件是否可以做到这一点?
Here is jsFiddle sample with jQuery 1.7.2 and ui
jQuery:
var Text = $('h1');
var Box = $('.box');
Text.click(function()
Text.animate('color':'#f00',600)
.delay(200).animate('color':'#ff0',600)
.delay(200).animate('color':'#000',600);
);
Box.click(function()
Box.animate('background-color':'#f00',600)
.delay(200).animate('background-color':'#ff0',600)
.delay(200).animate('background-color':'#000',600);
);
【问题讨论】:
我想在没有 jQuery ui 的情况下完成 this jsFiddle 示例。它不适用于纯 jQuery 1.8. jQuery 不支持没有 UI 的动画颜色。您必须编写自己的插件或使用 UI 核心。 @FabrícioMatté 感谢您的关注,我想知道是否有一个 代码块可以用更少的代码做到这一点? 我来看看,jQuery UI github 是分成几部分的,所以核心部分应该只有 1 或 2 个块。 呃,彩色动画的代码slightly比我预想的要大,没关系。 【参考方案1】:您要求的代码更少,所以这是我用Google Closure Compiler 缩小的relevant code:
(function(h,m)function n(a,b,c)var d=r[b.type]||;if(null==a)return c||!b.def?null:b.def;a=d.floor?~~a:parseFloat(a);return isNaN(a)?b.def:d.mod?(a+d.mod)%d.mod:0>a?0:d.max<a?d.max:afunction s(a)var b=f(),c=b._rgba=[],a=a.toLowerCase();j(v,function(d,g)var e,i=g.re.exec(a);e=i&&g.parse(i);i=g.space||"rgba";if(e)return e=b[i](e),b[k[i].cache]=e[k[i].cache],c=b._rgba=e._rgba,!1);return c.length?("0,0,0,0"===c.join()&&h.extend(c,o.transparent),b):o[a]function p(a,b,c)c=(c+1)%1;return 1>6*c?
a+6*(b-a)*c:1>2*c?b:2>3*c?a+6*(b-a)*(2/3-c):avar w=/^([\-+])=\s*(\d+\.?\d*)/,v=[re:/rgba?\(\s*(\d1,3)\s*,\s*(\d1,3)\s*,\s*(\d1,3)\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(a)return[a[1],a[2],a[3],a[4]],re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,parse:function(a)return[2.55*a[1],2.55*a[2],2.55*a[3],a[4]],re:/#([a-f0-9]2)([a-f0-9]2)([a-f0-9]2)/,parse:function(a)return[parseInt(a[1],16),parseInt(a[2],16),
parseInt(a[3],16)],re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(a)return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)],re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(a)return[a[1],a[2]/100,a[3]/100,a[4]]],f=h.Color=function(a,b,c,d)return new h.Color.fn.parse(a,b,c,d),k=rgba:props:red:idx:0,type:"byte",green:idx:1,type:"byte",blue:idx:2,type:"byte",hsla:props:hue:idx:0,
type:"degrees",saturation:idx:1,type:"percent",lightness:idx:2,type:"percent",r="byte":floor:!0,max:255,percent:max:1,degrees:mod:360,floor:!0,t=f.support=,u=h("<p>")[0],o,j=h.each;u.style.cssText="background-color:rgba(1,1,1,.5)";t.rgba=-1<u.style.backgroundColor.indexOf("rgba");j(k,function(a,b)b.cache="_"+a;b.props.alpha=idx:3,type:"percent",def:1);f.fn=h.extend(f.prototype,parse:function(a,b,c,d)if(a===m)return this._rgba=[null,null,null,null],this;if(a.jquery||a.nodeType)a=
h(a).css(b),b=m;var g=this,e=h.type(a),i=this._rgba=[];b!==m&&(a=[a,b,c,d],e="array");if("string"===e)return this.parse(s(a)||o._default);if("array"===e)return j(k.rgba.props,function(d,c)i[c.idx]=n(a[c.idx],c)),this;if("object"===e)return a instanceof f?j(k,function(c,d)a[d.cache]&&(g[d.cache]=a[d.cache].slice())):j(k,function(d,c)var b=c.cache;j(c.props,function(d,e)if(!g[b]&&c.to)if(d==="alpha"||a[d]==null)return;g[b]=c.to(g._rgba)g[b][e.idx]=n(a[d],e,true));if(g[b]&&h.inArray(null,g[b].slice(0,
3))<0)g[b][3]=1;if(c.from)g._rgba=c.from(g[b])),this,is:function(a)var b=f(a),c=!0,d=this;j(k,function(a,e)var i,h=b[e.cache];h&&(i=d[e.cache]||e.to&&e.to(d._rgba)||[],j(e.props,function(a,d)if(null!=h[d.idx])return c=h[d.idx]===i[d.idx]));return c);return c,_space:function()var a=[],b=this;j(k,function(c,d)b[d.cache]&&a.push(c));return a.pop(),transition:function(a,b)var c=f(a),d=c._space(),g=k[d],e=0===this.alpha()?f("transparent"):this,i=e[g.cache]||g.to(e._rgba),h=i.slice(),c=c[g.cache];
j(g.props,function(a,d)var g=d.idx,e=i[g],f=c[g],j=r[d.type]||;null!==f&&(null===e?h[g]=f:(j.mod&&(f-e>j.mod/2?e+=j.mod:e-f>j.mod/2&&(e-=j.mod)),h[g]=n((f-e)*b+e,d))));return this[d](h),blend:function(a)if(1===this._rgba[3])return this;var b=this._rgba.slice(),c=b.pop(),d=f(a)._rgba;return f(h.map(b,function(a,b)return(1-c)*d[b]+c*a)),toRgbaString:function()var a="rgba(",b=h.map(this._rgba,function(a,d)return null==a?2<d?1:0:a);1===b[3]&&(b.pop(),a="rgb(");return a+b.join()+")",toHslaString:function()var a=
"hsla(",b=h.map(this.hsla(),function(a,d)null==a&&(a=2<d?1:0);d&&3>d&&(a=Math.round(100*a)+"%");return a);1===b[3]&&(b.pop(),a="hsl(");return a+b.join()+")",toHexString:function(a)var b=this._rgba.slice(),c=b.pop();a&&b.push(~~(255*c));return"#"+h.map(b,function(a)a=(a||0).toString(16);return 1===a.length?"0"+a:a).join(""),toString:function()return 0===this._rgba[3]?"transparent":this.toRgbaString());f.fn.parse.prototype=f.fn;k.hsla.to=function(a)if(null==a[0]||null==a[1]||null==a[2])return[null,
null,null,a[3]];var b=a[0]/255,c=a[1]/255,d=a[2]/255,a=a[3],g=Math.max(b,c,d),e=Math.min(b,c,d),i=g-e,h=g+e,f=0.5*h;return[Math.round(e===g?0:b===g?60*(c-d)/i+360:c===g?60*(d-b)/i+120:60*(b-c)/i+240)%360,0===f||1===f?f:0.5>=f?i/h:i/(2-h),f,null==a?1:a];k.hsla.from=function(a)if(null==a[0]||null==a[1]||null==a[2])return[null,null,null,a[3]];var b=a[0]/360,c=a[1],d=a[2],a=a[3],c=0.5>=d?d*(1+c):d+c-d*c,d=2*d-c;return[Math.round(255*p(d,c,b+1/3)),Math.round(255*p(d,c,b)),Math.round(255*p(d,c,b-1/3)),
a];j(k,function(a,b)var c=b.props,d=b.cache,g=b.to,e=b.from;f.fn[a]=function(a)g&&!this[d]&&(this[d]=g(this._rgba));if(a===m)return this[d].slice();var b,q=h.type(a),k="array"===q||"object"===q?a:arguments,l=this[d].slice();j(c,function(a,d)var b=k["object"===q?a:d.idx];null==b&&(b=l[d.idx]);l[d.idx]=n(b,d));return e?(b=f(e(l)),b[d]=l,b):f(l);j(c,function(d,b)f.fn[d]||(f.fn[d]=function(c)var e=h.type(c),g="alpha"===d?this._hsla?"hsla":"rgba":a,f=this[g](),j=f[b.idx];if("undefined"===e)return j;
"function"===e&&(c=c.call(this,j),e=h.type(c));if(null==c&&b.empty)return this;"string"===e&&(e=w.exec(c))&&(c=j+parseFloat(e[2])*("+"===e[1]?1:-1));f[b.idx]=c;return this[g](f))));f.hook=function(a)a=a.split(" ");j(a,function(a,c)h.cssHooks[c]=set:function(a,b)var e,i="";if("string"!==h.type(b)||(e=s(b)))b=f(e||b);if(!t.rgba&&1!==b._rgba[3])for(e="backgroundColor"===c?a.parentNode:a;(""===i||"transparent"===i)&&e&&e.style;)tryi=h.css(e,"backgroundColor"),e=e.parentNodecatch(j)b=b.blend(i&&
"transparent"!==i?i:"_default")b=b.toRgbaString()trya.style[c]=bcatch(k);h.fx.step[c]=function(a)a.colorInit||(a.start=f(a.elem,c),a.end=f(a.end),a.colorInit=!0);h.cssHooks[c].set(a.elem,a.start.transition(a.end,a.pos)));f.hook("backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor");h.cssHooks.borderColor=expand:function(a)var b=;j(["Top","Right","Bottom","Left"],function(c,d)b["border"+
d+"Color"]=a);return b;o=h.Color.names=aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff")(jQuery);
它在 UTF8 中大约 7kb,没有 gzip 或其他压缩,它允许您像以前使用 jQuery UI 一样为颜色设置动画。这意味着,它允许您在保留相同代码的同时删除 jQuery UI。
Fiddle
我还建议您优先考虑开发时间。第一次加载 7kb 对任何最终用户来说都不会是一个明显的变化,即使是拨号用户也不会。这就是为什么我认为重构这是浪费时间。无需花费数小时/数天重新发明***。 =]
【讨论】:
感谢您的好评,稍后我会仔细检查此方法。 +1 来自我【参考方案2】:据我所知,没有插件或 jquery ui 就无法做到这一点,当然准确度也不一样。当然,除非您愿意使用需要大量编码但会产生与插件相同的结果但需要更多努力和工作的大型自定义编写函数。
有很多插件可以使用,我很喜欢jquery-color。
我个人会说 jquery ui 是实现这一目标的最佳方式。
抱歉,这不是您希望得到的答案
编辑:
正如 gautamdharmapuri 所说,您可以简单地使用 css 函数和时间延迟或超时来更改颜色,但为了实现动画效果,您需要计算出所有颜色之间的颜色,并制作它看起来很流畅,你需要很多过渡。
这里有一个工作演示,我把这个想法放在一起http://jsfiddle.net/2EECN/21/ 它表明实际实现将是相当密集的代码。
jQuery:
$(function()
var textElem = $('h1');
var box = $('.box');
//Set up colour array
colors = ["#000000", "#080000", "#100000", "#180000", "#200000", "#280000", "#300000", "#380000", "#400000", "#480000", "#500000", "#580000", "#600000", "#680000", "#700000", "#780000", "#800000", "#880000", "#900000", "#980000", "#A00000", "#A80000", "#B00000", "#B80000", "#C00000", "#C80000", "#D00000", "#D80000", "#E00000", "#E80000", "#F00000", "#F80000", "#FF0000"];
//Click event for text color
textElem.click(function()
$.each(colors, function(index, color)
setTimeout(function()
textElem.css("color", color);
, 20 * index);
);
);
//Click event for background color.
box.click(function()
colors = ["#000000", "#080000", "#100000", "#180000", "#200000", "#280000", "#300000", "#380000", "#400000", "#480000", "#500000", "#580000", "#600000", "#680000", "#700000", "#780000", "#800000", "#880000", "#900000", "#980000", "#A00000", "#A80000", "#B00000", "#B80000", "#C00000", "#C80000", "#D00000", "#D80000", "#E00000", "#E80000", "#F00000", "#F80000", "#FF0000"];
$.each(colors, function(index, color)
setTimeout(function()
box.css("backgroundColor", color);
, 20 * index);
);
);
);
在本例中,这些颜色仅用于 w3schools 的十六进制颜色图表。 http://www.w3schools.com/cs-s-ref/css_colors.asp
改进的答案:
好的,所以这实际上让我对它是如何完成的很感兴趣,并且您实际上可以通过以下示例看到,如果您明确设置,您可以更好地控制动画可以通过的周期它。 http://jsfiddle.net/2EECN/21/。
看起来也不错!所以我现在要说的是,这肯定是可能的并且是可以实现的,但是你最好将它打包到一个扩展动画功能的小插件中。
【讨论】:
有趣的方法,我猜也可以使用 jQuery animatestep:
方法而不是 setTimeout
可能使用更少的代码(:
当然可以,而且它还可以使用十六进制颜色方程(或简单的正则表达式)来自动计算出需要逐步通过的颜色,但即便如此,我也不会能够证明不仅仅是构建/使用现有插件是合理的。
我从 OP 的示例中获取了布局 html 和 CSS,并添加了基本的 jquery 来说明这一点,尽管它开始更像是一个实验。
@Jai 我需要用这种方法定义每个颜色步骤吗?
别担心,这对我来说是一个有趣的学习经验;但是没有必要定义每一个颜色步长,你需要做的就是在 rgba 值中添加 sub 并编写一个小函数来将初始值更改为最终指定值,我将整理一个示例。然而,这是一种有限的方法,因为所有内容都需要自定义编写以添加额外的功能以上是关于带有纯 jQuery 动画的特殊颜色过渡效果 // 在 ui 或其他库上的主要内容,如果未能解决你的问题,请参考以下文章
text 使用此Transition SCSS Mixin将CSS过渡添加到元素。轻松设置颜色,宽度和填充等属性的动画,以创建淡入淡出效果