多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > web前端 > jscript > 改進版:JavaScript 顏色梯度和漸變效果

改進版:JavaScript 顏色梯度和漸變效果

來源:程序員人生   發布時間:2013-11-09 13:18:37 閱讀次數:3735次

近來看了Dean的“Convert any colour value to hex in MSIE”,終于解決了根據關鍵字獲取顏色rgb值的問題。


提示:可修改后代碼再運行!

上一版《JavaScript 顏色梯度和漸變效果》

程序說明

【ColorGrads顏色梯度】

程序ColorGrads的作用是根據顏色集合和漸變級數生成顏色梯度集合。
漸變級數的意思是分多少步完成漸變。

網頁設計中的顏色是用RGB色彩模式呈現的。
在這個模式中每種顏色可以用三個代表紅(r)、綠(g)、藍(b)的顏色值(0到255)來表示。

從w3c的Colors部分看到標準中顏色的表示形式包括:
關鍵字形式:
em { color: red }
RGB形式:
em { color: #f00 }
em { color: #ff0000 }
em { color: rgb(255, 0, 0) }
em { color: rgb(100%, 0%, 0%) }
以上都是表示同一種顏色(紅色)。
關鍵字形式就是用關鍵字代表顏色值。
而RGB形式,前兩種用的比較多,都是一個"#"后面帶16進制表示的顏色值,第三種是用十進制的顏色值,第四種是實際值跟255的百分比形式。

各個瀏覽器對各種顏色表示形式的獲取并不相同:
"color: red"形式:
  ie opera ff chrome/safari
style red red #ff0000 red
currentStyle red "red"     
getComputedStyle   #ff0000 rgb(255, 0, 0) rgb(255, 0, 0)
"color: #ff0000"/"color: #f00"形式:
  ie opera ff chrome/safari
style #ff0000/#f00 #ff0000 rgb(255, 0, 0) rgb(255, 0, 0)
currentStyle #ff0000/#f00 #ff0000     
getComputedStyle   #ff0000 rgb(255, 0, 0) rgb(255, 0, 0)
"color: rgb(255, 0, 0)"/"color: rgb(100%, 0%, 0%)"形式:
  ie opera ff chrome/safari
style rgb(255,0,0) #ff0000 rgb(255, 0, 0) rgb(255, 0, 0)
currentStyle rgb(255,0,0) #ff0000     
getComputedStyle   #ff0000 rgb(255, 0, 0) rgb(255, 0, 0)

基本上得到的值還是按標準的形式顯示的,只是有些會自動轉換形式。
不過ie的rgb形式跟ff/chrome/safari的不同,數值之間并沒有空格。
要特別注意的是opera用currentStyle獲取關鍵字形式得到的顏色值是帶雙引號的,十分奇怪,要盡量避免使用。

要獲取兩種顏色的漸變梯度,先要把顏色轉化成能用來計算的數值。
GetColor和GetData程序就是用來把符合w3c標準表示的顏色值轉化成組合該顏色的紅(r)、綠(g)、藍(b)的顏色數值。
RGB形式的值本身就已經帶了rgb的具體數值,只要用正則把值提取出來再轉化就可以了。
這個過程在GetData中進行:
function GetData(color) {
       var re = RegExp;
       if (/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.test(color)) {
              //#rrggbb
              return $$A.map([ re.$1, re.$2, re.$3 ], function(x){
                            return parseInt(x, 16);
                     });
       } else if (/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.test(color)) {
              //#rgb
              return $$A.map([ re.$1, re.$2, re.$3 ], function(x){
                            return parseInt(x + x, 16);
                     });
       } else if (/^rgb((.*),(.*),(.*))$/i.test(color)) {
              //rgb(n,n,n) or rgb(n%,n%,n%)
              return $$A.map([ re.$1, re.$2, re.$3 ], function(x){
                            return x.indexOf("%") > 0 ? parseFloat(x, 10) * 2.55 : x | 0;
                     });
       }
}

注意#rrggbb/#rgb形式得到的是16進制的數值字符,把parseInt的第二個參數設為16就可以指定用16進制來處理字符串轉換。
對于rgb(n,n,n)/rgb(n%,n%,n%)的形式,直接取得數值,如果有%就根據百分比計算對應數值就行了。
使用這種形式設置顏色時也要注意,
ie6和ie7允許數字百分比混用,其他不可以(包括ie8);
ie6和ie7可以用空格或逗號分隔數值,其他必須用逗號(包括ie8);
當然我們使用時也應該是按照w3c的標準來設置了。
ps:那個DHTML 手冊上寫的 EM { color: rgb 1.0 0.0 0.0 } 是不能用的,不要被誤導了。

如果是關鍵字形式那就要另外想方法了,可以用一個字典對象來匹配顏色值,但這樣程序會變得很龐大。
ps:可以到這里看所有顏色名對應的數值。
近來dean發表了“Convert any colour value to hex in MSIE”,終于解決了這個難題。
其中的關鍵是利用queryCommandValue("ForeColor")來獲取顏色值(或許做過編輯器的會比較熟悉)。
queryCommandValue的作用是返回document、range或current selection對于給定命令的當前值。
而ForeColor命令是設置或獲取文本時的前景色。

具體的做法是先創建一個textarea:
if (!frag) {
       frag = document.createElement("textarea");
       frag.style.display = "none";
       document.body.insertBefore(frag, document.body.childNodes[0]);
};
然后設置color為要取值的顏色:
try { frag.style.color = color; } catch(e) { return [0, 0, 0]; }
在ie如果設置錯誤的顏色值會報錯,所以這里用try...catch來保證能返回值。

能使用queryCommandValue的包括document、range和current selection。
用createTextRange就可以建立一個range:
color = frag.createTextRange().queryCommandValue("ForeColor");

createTextRange可以用在Body,Button,Input和TextArea。
在dean的方法中是用createPopup().document.body的,好處是不用插入元素到dom。
但createPopup是ie的方法,而TextArea還可以用于getComputedStyle,后面會用到。

這樣得到的顏色值是一個數值,這個數字跟顏色的關系是這樣的:
例如紅色的16進制rgb是ff0000,先轉成bgr,即0000ff,然后轉成10進制,得到255。
同樣粉紅色pink是FFC0CB,轉成bgr是CBC0FF,10進制是13353215。
ps:使用時要注意queryCommandValue("ForeColor")得到的顏色是bgr排列的,跟一般的不一樣。

要得到rgb的值可以把轉換過程倒過來獲取,不過參考dean的文章有更巧妙的方法:
ret = [ color & 0x0000ff, (color & 0x00ff00) >>> 8, (color & 0xff0000) >>> 16 ];
先用與操作(&)把對應位的數值取出來,再用右移運算符(>>>)把數值移到正確的位置上。

例如粉紅色FFC0CB要取得綠(g)的顏色值,用與操作(&)取得對應值,FFC0CB & 0x00ff00得到C000,然后右移8個數位得到C0(16進制的一位相當于二進制的4位),即192。

其他支持document.defaultView的可以直接用getComputedStyle獲取color。
從上面各個瀏覽器獲取顏色值的結果可知獲取的值都是RGB形式的值,所以可以直接用GetData轉換:
ret = GetData(document.defaultView.getComputedStyle(frag, null).color);
注意除了ff,如果元素沒有插入dom,用getComputedStyle是獲取不了color的,所以元素創建時要順便插入到body中。

在GetStep用GetColor獲得顏色值之后,再根據step就可以獲得步長了:
var colors = [], start = GetColor(start), end = GetColor(end),
       stepR = (end[0] - start[0]) / step,
       stepG = (end[1] - start[1]) / step,
       stepB = (end[2] - start[2]) / step;
再根據步長生成集合:
for(var i = 0, r = start[0], g = start[1], b = start[2]; i < step; i++){
       colors[i] = [r, g, b]; r += stepR; g += stepG; b += stepB;
}
colors[i] = end;
正確的顏色值是在0到255之間的,而且是不帶小數的,需要修正一下:
return $$A.map(colors, function(x){ return $$A.map(x, function(x){
       return Math.min(Math.max(0, Math.floor(x)), 255);
});});

程序支持設置多個顏色的連續變換:
for(var i = 0, n = len - 1; i < n; i++){
       var steps = GetStep( colors[i], colors[i+1], step );
       i < n - 1 && steps.pop();
       ret = ret.concat(steps);
}
注意的是各次變換之間要去掉重復的顏色(steps.pop())。

【ColorTrans顏色漸變】

有了顏色梯度集合,只需要設個定時器把集合的值依次顯示就是一個漸變效果了。
這個漸變有兩種效果:顏色漸入(transIn)和顏色漸出(transOut)。
原理就是通過改變_index集合索引屬性,漸入時逐漸變大,漸出時逐漸變小:
  transIn: function() {
       this.stop(); this._index++; this._set();
       if(this._index < this._colors.length - 1){
              this._timer = setTimeout($$F.bind( this.transIn, this ), this.speed);
       }
  },
  transOut: function() {
       this.stop(); this._index--; this._set();
       if(this._index > 0){
              this._timer = setTimeout($$F.bind( this.transOut, this ), this.speed);
       }
  },

在_set設置樣式程序中修改樣式:
var color = this._colors[Math.min(Math.max(0, this._index), this._colors.length - 1)];
this._elem.style[this.style] = "rgb(" + color.join(",") + ")";
其中style屬性是要修改的樣式屬性名,例如顏色是"color",背景色是"backgroundColor"。

由于顏色集合是根據開始顏色、結束顏色和步數生成的,所以如果要修改這些屬性必須重新生成過集合。
reset程序就是用來重新生成集合的,同時索引也會設回0:
this._options = options = $$.extend(this._options, options || {});
this._colors = ColorGrads( [options.from, options.to], options.step );
this._index = 0;

程序初始化的時候也會reset一次:
this.reset({
       from: this.options.from || $$D.getStyle(this._elem, this.style),
       to: this.options.to,
       step: Math.abs(this.options.step)
});
如果沒有自定義from顏色的話會自動獲取當前顏色。

使用技巧

鏈接標簽a的偽類的顏色暫時沒有辦法直接用dom來修改(除非改class)。
所以在顏色漸變菜單中用了個小技巧,把a的內容和跳轉換到td的innerHTML和onclick上實現:
var a = x.getElementsByTagName("a")[0], href = a.href, txt = a.innerHTML;
x.onclick = function(){ location.href = href; }
x.innerHTML = txt;
這樣就可以在不影響可用性的情況下實現效果。

在測試過程中還發現一個數組的問題,運行alert([,,].length),在ie會返回3,其他會返回2。
在mozilla的Array_Literals部分查到:
If you include a trailing comma at the end of the list of elements, the comma is ignored.
即如果數組字面量元素集合的最后是逗號,逗號會被忽略掉。

使用說明

ColorGrads的第一個參數是顏色集合,第二個參數是漸變級數。

ColorTrans只要一個參數,要實現漸變的對象,可設置以下屬性:
from:       "",//開始顏色
to:       "#000",//結束顏色
step:       20,//漸變級數
speed:       20,//漸變速度
style:       "color"//設置屬性(Scripting屬性)
from默認是空值,方便判斷自動獲取。
其中from、to和step在實例化后要修改的話需要用reset來設置。
具體使用請參考實例。

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 欧美人一级淫片a免费播放 欧美人与z0z0xxxx | 日本成人在线免费 | 免费观看www | 妇欲欢公爽公妇高h欲 | a成人 | 综合五月网 | 欧美一级性视频 | 亚洲jizzjizz中文在线播放 | 67194在线午夜亚洲 | 久久艹免费视频 | 国产亚洲一区二区三区在线 | 成人乱码| 亚洲色图色 | 亚洲a级黄色 | 国产欧美日韩综合精品无毒 | 黄 色 免 费 网站在线观看 | 亚洲精品第一 | 国产精品亚洲欧美日韩区 | 亚洲专区一区 | 国产一区二区高清在线 | 亚洲欧美四级在线播放 | 中文字幕观看 | 欧美一欧美一区二三区性 | 久久精品一区二区三区日韩 | 国产在线不卡一区 | 国产午夜永久福利视频在线观看 | 国产第一页亚洲 | 欧美日韩乱码毛片免费观看 | 亚洲欧美一级视频 | 韩国午夜理伦三级2020宅男 | 自拍偷拍第 | 欧美老女人性视频 | 亚洲精品乱码久久久久久蜜桃欧美 | 午夜欧美性欧美 | 成人娱乐网 | 久久艹免费视频 | 校园春色亚洲色图 | 最近免费中文字幕大全免费 | 欧美一级毛片日本 | 成人性色生活片免费看爆迷你毛片 | 亚洲国产欧美目韩成人综合 |