JavaScript 颜色梯度和渐变效果

cloudgamer 2009-03-11 10:36:56
加精
很久没写文章,太忙了。没什么时间写复杂的东西,重新把颜色渐变效果写一遍。
关于颜色的效果一般就两个,颜色梯度变化和样式的颜色渐变,前者在ie中一般用滤镜实现。

实例效果请到这里看

下载完整实例

程序说明

【ColorGrads颜色梯度】

程序ColorGrads的作用是通过StartColor和EndColor生成颜色梯度集合。
颜色都可以用红(r)、绿(g)、蓝(b)三个颜色来表示。
程序中先通过GetColor把一般的颜色表示形式转化成一个用红(r)、绿(g)、蓝(b)三个颜色值作元素的集合。
那就首先要知道有什么颜色表示形式,从w3c的Colors部分(http://www.w3.org/TR/CSS21/syndata.html#color-units)可以知道有以下形式:
关键词模式:
em { color: red }
RGB颜色模式:
em { color: #f00 }
em { color: #ff0000 }
em { color: rgb(255,0,0) }
em { color: rgb(100%, 0%, 0%) }
以上都是表示同一种颜色(红色)。
获取颜色属性的形式在ie和ff并不同,ff统一返回RGB颜色模式的第三种形式,ie则按照设置时的形式返回。

先说说RGB颜色模式,前两种比较常用应该都明白他们的区别吧,它用的是16进制表示形式,而我们想要10进制的。
把一个16进制表示的字符转成10进制数字,一般用parseInt,在substr截取字符之后就可以用parseInt转换。
对于#ff0000这个形式可以这样转换:
return Map([color.substr(1, 2), color.substr(3, 2), color.substr(5, 2)],
function(x){ return parseInt(x, 16); }
)
parseInt的第二个参数就是第一个参数的进制值。
对于#f00形式,跟上一个差不多,只是转换之前要先换成完整表示形式:
return Map([color.substr(1, 1), color.substr(2, 1), color.substr(3, 1)],
function(x){ return parseInt(x + x, 16); }
)

后面两种可能用的就比较少了,一个用10进制的rgb颜色值表示,另一个用百分比来表示。
ff严格按照那样的格式来表示,而ie就“放松”很多,例如:
ie可以允许数字百分比混用,ff不可以;
ff必须有逗号分隔,ie可以只用空格分隔;
当然我们使用时最好是按照w3c的标准来设置了。
ps:那个DHTML 手册上写的 EM { color: rgb 1.0 0.0 0.0 } 根本不能用的,不要被误导了。
对这个形式,程序用正则取得数值,如果有%就根据百分比计算出对应数值:
return Map(color.match(/\d+(\.\d+)?\%?/g),
function(x){ return parseInt(x.indexOf("%") > 0 ? parseFloat(x, 10) * 2.55 : x, 10); }
)

而关键词大家都很熟悉,要转化却很麻烦,因为没有一定规律只能一个一个对应:
var mapping = {"red":"#FF0000"};//略
color = mapping[color.toLowerCase()];
if(color){
return Map([color.substr(1, 2), color.substr(3, 2), color.substr(5, 2)],
function(x){ return parseInt(x, 16); }
)
}

在Create创建颜色集合程序中获得开始颜色和结束颜色的数据后,再根据Step(多少步)就可以获得步长了:
startColor = this.GetColor(this.StartColor),
endColor = this.GetColor(this.EndColor),
stepR = (endColor[0] - startColor[0]) / this.Step,
stepG = (endColor[1] - startColor[1]) / this.Step,
stepB = (endColor[2] - startColor[2]) / this.Step;
再根据步长生成集合:
for(var i = 0, n = this.Step, r = startColor[0], g = startColor[1], b = startColor[2]; i < n; i++){
colors.push([r, g, b]); r += stepR; g += stepG; b += stepB;
}
colors.push(endColor);

正确的颜色值是在0到255之间的,而且是不带小数的,所以最好修正一下:
return Map(colors, function(x){ return Map(x, function(x){
return Math.min(Math.max(0, Math.floor(x)), 255);
});});


【ColorTrans颜色渐变】

有了颜色梯度集合,只需要设个定时器把集合的值依次显示就是一个渐变效果了。
这个渐变一般是分两个步骤,分别是(FadeIn)和渐出(FadeOut)。
原理就是通过改变_index集合索引,渐入时逐渐变大,渐出时逐渐变小:
//颜色渐入
FadeIn: function() {
this.Stop(); this._index++; this.SetColor();
if(this._index < this._colors.length - 1){
this._timer = setTimeout(Bind(this, this.FadeIn), this.Speed);
}
},
//颜色渐出
FadeOut: function() {
this.Stop(); this._index--; this.SetColor();
if(this._index > 0){
this._timer = setTimeout(Bind(this, this.FadeOut), this.Speed);
}
},
在SetColor设置样式程序中,通过CssColor来设置要修改的样式属性,例如字体颜色是"color",背景色是"backgroundColor":
var color = this._colors[Math.min(Math.max(0, this._index), this._colors.length - 1)];
this._obj.style[this.CssColor] = "rgb(" + color[0] + "," + color[1] + "," + color[2] + ")";

由于颜色集合是根据开始颜色、结束颜色和步数生成的,所以如果要修改这些属性必须重新生成过集合。
Reset程序就是用来修改这些属性并重新生成集合的,集合重新生成后索引也要设回0:
//修改颜色后必须重新获取颜色集合
color = Extend({ StartColor: this._startColor, EndColor: this._endColor, Step: this._step }, color || {});
//设置属性
this._grads.StartColor = this._startColor = color.StartColor;
this._grads.EndColor = this._endColor = color.EndColor;
this._grads.Step = this._step = color.Step;
//获取颜色集合
this._colors = this._grads.Create();
this._index = 0;

使用技巧

在颜色渐变菜单中,并没有使用链接标签a,原因是a的伪类的颜色并不能直接用js来修改(除非改class)。
暂时没想到很好的方法,只好用onclick跳转代替了。

在测试过程中还发现一个关于数组的问题,在ie和ff运行alert([,,].length)会分别显示3和2。
最后一个元素不写的话ff就会忽略这个元素,只要写的话就不会忽略即使是undefined和null,看了下文档也找到原因。
所以这个情况还是插一个东西进去,觉得不好看就new Array好了。

使用说明

ColorGrads只有3个属性设置:
StartColor: "#fff",//开始颜色
EndColor: "#000",//结束颜色
Step: 20//渐变级数
设置好属性后用Create生成集合就行了。

ColorTrans只要一个参数,要实现渐变的对象,可设置以下属性:
StartColor: "",//开始颜色
EndColor: "#000",//结束颜色
Step: 20,//渐变级数
Speed: 20,//渐变速度
CssColor: "color"//设置属性(Scripting属性)
如果不设置StartColor会自动使用CurrentStyle获取的样式值。
其中StartColor、EndColor和Step在实例化后要重新设置的话需要用Reset来设置。

具体使用请参考实例。
...全文
5460 113 打赏 收藏 转发到动态 举报
写回复
用AI写文章
113 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhouxtry 2011-02-24
  • 打赏
  • 举报
回复
牛人.........................
20220510zhuce 2010-05-29
  • 打赏
  • 举报
回复
太强了
zendj 2009-11-27
  • 打赏
  • 举报
回复
C5662601 2009-11-06
  • 打赏
  • 举报
回复
收藏
wo554006164 2009-11-04
  • 打赏
  • 举报
回复
谢谢
Delta 2009-09-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 free_wind22 的回复:]
jf,,
[/Quote]太厉害了。
bestboy1 2009-09-15
  • 打赏
  • 举报
回复
好贴。楼主辛苦了,顶楼主.......
tantaiyizu 2009-09-15
  • 打赏
  • 举报
回复
i support
biannu 2009-09-14
  • 打赏
  • 举报
回复
等我做网站了,也许用的上
做鸡真好吃 2009-09-14
  • 打赏
  • 举报
回复
mark~
yutian_01261027 2009-09-14
  • 打赏
  • 举报
回复
UP
jooin2009 2009-09-13
  • 打赏
  • 举报
回复
收藏了~~现在正在研究这方面的知识~~谢谢楼主分享
dake53 2009-09-13
  • 打赏
  • 举报
回复
看看 学习
youjianbo_han_87 2009-09-12
  • 打赏
  • 举报
回复
长期关注博主
mengxj85 2009-09-12
  • 打赏
  • 举报
回复
继续关注博主
ljsheng 2009-09-11
  • 打赏
  • 举报
回复
牛人@@@@@@@
mlhm2 2009-09-11
  • 打赏
  • 举报
回复
收藏了~
coolcat9527 2009-09-10
  • 打赏
  • 举报
回复
效果很8错 谢谢LZ
cloudgamer 2009-04-20
  • 打赏
  • 举报
回复
[Quote=引用 90 楼 cuixiping 的回复:]
赞楼主的研究精神与共享精神。

关于颜色渐变,还有一个比较巧妙的方法,就是利用一个渐变透明度的PNG图片 <img>,当改变底下的背景颜色时,就会呈现对应色系的渐变色。
如果这个PNG图片有特定的alpha透明通道(PNG每个像素都可以有RGBA),能呈现更加丰富的颜色变化。
有一种流传很广的颜色选择控件就是利用PNG实现的。
[/Quote]

做背景当然是用图片比较好
我也没用过这个渐变来做背景
我这个主要还是用在一些颜色的动态变化上
CaoMei_Jenny 2009-04-17
  • 打赏
  • 举报
回复
谢谢楼主分享
加载更多回复(89)

87,922

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧