IE還有一個利器至今沒有被使用過,那就是VML。雖然比不上SVG,但它還是非常強大的。在實現漸層上,其fill還比IE的Gragient濾鏡強悍得多了。不過VML出現得比較早,只支援很少的顏色名,如red,blue,yellow,其他如orange就可以搞死它了。因此要使用VML做線性漸層,我們得對這些顏色名做一下轉換。
HTML4的顏色值
black = #000000 |
green = #008000 |
silver = #c0c0c0 |
lime = #00ff00 |
gray = #808080 |
olive = #808000 |
white = #ffffff |
yellow = #ffff00 |
maroon = #800000 |
navy = #000080 |
red = #ff0000 |
blue = #0000ff |
purple = #800080 |
teal = #008080 |
fuchsia = #ff00ff |
aqua = #00ffff |
我們可以在Firefox官網以及W3C瞭解到更多的顏色值。
複製代碼 代碼如下:
var htmlcolor={ black :"#000",green :"#008000",silver :"#c0c0c0",lime :"#0f0",
gray :"#808080",olive :"#808000",white :"#fff",yellow :"#ff0",
maroon :"#800000",navy :"#000080",red :"#f00",blue :"#00f",
purple :"#800080",teal :"#008080",fuchsia :"#f0f",aqua :"#0ff",
indigo :"#4b0082",orange : "#ffa500",sienna :"#a0522d",plum :"#dda0dd",
gold :"#ffd700", tan :"#d2b48c", snow :"#fffafa",violet :"#ee82ee"
}
接著我們在需要線性漸層的那個元素內部建立一個同樣大小的rect元素,然后里面再添加一個fill元素,用來設定漸層。偽碼如下:
複製代碼 代碼如下:
<div class="gradient" style="position:relative;width:width;height:height">
javascript線性漸層 by 司徒正美 實現多重水平漸層效果
<vml:rect style="position:absolute;width:width;height;top:0;left:0" stroked="f" >
<vml:fill colors="與SVG相對應的color-stop" focus="100%" type="gradient" method="linear"/>
</vml:rect>
</div>
<!doctype html> <title>javascript線性漸層 by 司徒正美</title> <meta charset="utf-8"/> <meta name="keywords" content="javascript線性漸層 by 司徒正美" /> <meta name="description" content="javascript線性漸層 by 司徒正美" /> <style type="text/css"> .gradient{ width:800px; height:100px; } </style> <script type="text/javascript"> var Gradient = function(id){ var entity = document.getElementById(id), options = arguments[1] || {}, width = options.width, height = options.height, type = options.type , stops = options["color-stop"]; this.init(entity,stops,width,height,type); } Gradient.prototype ={ constructor: Gradient, init: function(entity,stops,width,height,type) { this.css(entity,{position:"relative"}); var content = entity.innerHTML; entity.innerHTML = ""; !+"\v1"? this.IEgradient(entity,stops,width,height,type): this.SVGgradient(entity,stops,width,height,type) var contentDiv = document.createElement("div"); this.css(contentDiv,{position:"absolute",top:0,left:0}) contentDiv.innerHTML = content; entity.appendChild(contentDiv); }, css: function(node,bag){ var str = ";" for(var i in bag){ if(bag.hasOwnProperty(i)) str += i == "opacity" ? ("filter:alpha(opacity="+ bag[i] * 100+");"):(i+":"+bag[i]+";") } node.style.cssText = str; }, attr: function(node,bag){ for(var i in bag){ if(bag.hasOwnProperty(i)) node.setAttribute(i,bag[i]) } }, createSVG:function(tag){ return document.createElementNS("http://www.w3.org/2000/svg",tag); }, IEgradient:function(entity,stops,width,height,type){ if(!document.namespaces.vml){ document.namespaces.add('vml', 'urn:schemas-microsoft-com:vml'); var vmlobj = document.createElement("<object classid=CLSID:10072CEC-8CC1-11D1-986E-00A0C955B42E id=VMLRender>"), head = document.getElementsByTagName("head")[0]; head.appendChild(vmlobj) document.createStyleSheet().addRule(".vml", "behavior: url(#VMLRender); display:inline-block;"); } var rect = document.createElement('<vml:rect class="vml">'); entity.appendChild(rect); this.css(rect,{width:width+"px",height:height+"px"}); this.attr(rect,{stroked:"f"}); var fill = document.createElement('<vml:fill class="vml">'); var colors =""; for(var i=0,l=stops.length;i<l;i++){ var offset = stops[i].split(",")[0] + "%", color = this.hex(stops[i].split(",")[1]); colors += offset +" "+color +","; } rect.appendChild(fill); var angle = type ? 90 : 0; this.attr(fill,{type:"gradient",colors:colors,method:"sigma",focus:"100%",angle:angle}); }, SVGgradient:function(entity,stops,width,height,type){ var svg = this.createSVG("svg"), id = "id" + (new Date().getTime()* Math.random()).toFixed(0); this.attr(svg,{width:width+"px",height:height+"px"}) entity.appendChild(svg); var defs = this.createSVG("defs"); svg.appendChild(defs); var linearGradient = this.createSVG("linearGradient"); defs.appendChild(linearGradient); this.attr(linearGradient,{id:id,x1:"0%",y1:"0%"}) if(type){ this.attr(linearGradient,{x2:"100%",y2:"0%"}) }else{ this.attr(linearGradient,{x2:"0%",y2:"100%"}) } for(var i=0,l=stops.length;i<l;i++){ var offset = stops[i].split(",")[0] + "%", color = this.hex(stops[i].split(",")[1]), stop = this.createSVG("stop"); this.attr(stop,{offset:offset,"stop-color":color}); linearGradient.appendChild(stop); } var rect = this.createSVG("rect"); svg.appendChild(rect); this.attr(rect,{x:"0px",y:"0px",width:width+"px",height:height+"px", fill:"url(#"+linearGradient.getAttribute("id")+")"}); }, hex:function(value){ var color={ black :"#000",green :"#008000",silver :"#c0c0c0",lime :"#0f0", gray :"#808080",olive :"#808000",white :"#fff",yellow :"#ff0", maroon :"#800000",navy :"#000080",red :"#f00",blue :"#00f", purple :"#800080",teal :"#008080",fuchsia :"#f0f",aqua :"#0ff", indigo :"#4b0082",orange :"#ffa500",sienna :"#a0522d",plum :"#dda0dd", gold :"#ffd700", tan :"#d2b48c", snow :"#fffafa",violet :"#ee82ee" } if(!!color[value]){ value = color[value] } if(/^#/.test(value)){ value = value.replace('#', ''); return "#" + (value.length == 3 ? value.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : value); } return value; } } window.onload = function(){ new Gradient("text1",{width:800,height:100,type:1,"color-stop":["0,red","16,orange","32,yellow","48,green","64,blue","80,indigo","100,violet"]}) new Gradient("text2",{width:800,height:100,type:0,"color-stop":["0,red","16,orange","32,yellow","48,green","64,blue","80,indigo","100,violet"]}) } </script> <div id="text1" class="gradient">javascript線性漸層 by 司徒正美 實現多重水平漸層效果</div> <div id="text2" class="gradient">javascript線性漸層 by 司徒正美 實現多重垂直漸層效果</div>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]
利用VML實現IE的線性漸層後整個類的長度減少一半。
我們再來看如何?角度漸層,IE那邊好辦,直接傳入一個角就行了(0—360,也可以為負數)。SVG比較麻煩,它由linearGradient 的四個屬性來控制傾斜度,x1,x2,y2,y2,實質就是兩個點。假設第一個點為(0,0),第二個點為(100,0),它就是水平漸層。假設第一個點為(0,0),第二個點為(0,100),它就是垂直漸層。要實現傾斜就必須讓第二個點的座標與第一個點的座標完全不相等,無論是X軸還是Y軸。這就要用到三角函數了。
複製代碼 代碼如下:
var x = (Math.sin(angle*Math.PI/180) * 100).toFixed(2)+"%";
var y = (Math.cos(angle*Math.PI/180)* 100).toFixed(2)+"%";
this.attr(linearGradient,{x2:x,y2:y});
我們也應該看得出水平漸層與垂直漸層其實只是一個特例,我們大可以廢除type這個屬性,改成angle,傳入一個0至360的數。
<!doctype html> <title>javascript線性漸層 by 司徒正美</title> <meta charset="utf-8"/> <meta name="keywords" content="javascript線性漸層 by 司徒正美" /> <meta name="description" content="javascript線性漸層 by 司徒正美" /> <style type="text/css"> .gradient{ width:800px; height:100px; } </style> <script type="text/javascript"> var Gradient = function(id){ var entity = document.getElementById(id), options = arguments[1] || {}, width = options.width, height = options.height, angle = options.angle , stops = options["color-stop"]; this.init(entity,stops,width,height,angle); } Gradient.prototype ={ constructor: Gradient, init: function(entity,stops,width,height,angle) { this.css(entity,{position:"relative"}); var content = entity.innerHTML; entity.innerHTML = ""; !+"\v1"? this.IEgradient(entity,stops,width,height,angle): this.SVGgradient(entity,stops,width,height,angle) var contentDiv = document.createElement("div"); this.css(contentDiv,{position:"absolute",top:0,left:0}) contentDiv.innerHTML = content; entity.appendChild(contentDiv); }, css: function(node,bag){ var str = ";" for(var i in bag){ if(bag.hasOwnProperty(i)) str += i == "opacity" ? ("filter:alpha(opacity="+ bag[i] * 100+");"):(i+":"+bag[i]+";") } node.style.cssText = str; }, attr: function(node,bag){ for(var i in bag){ if(bag.hasOwnProperty(i)) node.setAttribute(i,bag[i]) } }, createSVG:function(tag){ return document.createElementNS("http://www.w3.org/2000/svg",tag); }, IEgradient:function(entity,stops,width,height,angle){ if(!document.namespaces.vml){ document.namespaces.add('vml', 'urn:schemas-microsoft-com:vml'); var vmlobj = document.createElement("<object classid=CLSID:10072CEC-8CC1-11D1-986E-00A0C955B42E id=VMLRender>"), head = document.getElementsByTagName("head")[0]; head.appendChild(vmlobj) document.createStyleSheet().addRule(".vml", "behavior: url(#VMLRender); display:inline-block;"); } var rect = document.createElement('<vml:rect class="vml">'); entity.appendChild(rect); this.css(rect,{width:width+"px",height:height+"px"}); this.attr(rect,{stroked:"f"}); var fill = document.createElement('<vml:fill class="vml">'); var colors =""; for(var i=0,l=stops.length;i<l;i++){ var offset = stops[i].split(",")[0] + "%", color = this.hex(stops[i].split(",")[1]); colors += offset +" "+color +","; } rect.appendChild(fill); this.attr(fill,{type:"gradient",colors:colors,method:"sigma",focus:"100%",angle:angle}); }, SVGgradient:function(entity,stops,width,height,angle){ var svg = this.createSVG("svg"), id = "id" + (new Date().getTime()* Math.random()).toFixed(0); this.attr(svg,{width:width+"px",height:height+"px"}) entity.appendChild(svg); var defs = this.createSVG("defs"); svg.appendChild(defs); var linearGradient = this.createSVG("linearGradient"); defs.appendChild(linearGradient); this.attr(linearGradient,{id:id,x1:"0%",y1:"0%"}) var x = (Math.sin(angle*Math.PI/180) * 100).toFixed(2)+"%"; var y = (Math.cos(angle*Math.PI/180)* 100).toFixed(2)+"%"; this.attr(linearGradient,{x2:x,y2:y}); for(var i=0,l=stops.length;i<l;i++){ var offset = stops[i].split(",")[0] + "%", color = this.hex(stops[i].split(",")[1]), stop = this.createSVG("stop"); this.attr(stop,{offset:offset,"stop-color":color}); linearGradient.appendChild(stop); } var rect = this.createSVG("rect"); svg.appendChild(rect); this.attr(rect,{x:"0px",y:"0px",width:width+"px",height:height+"px", fill:"url(#"+linearGradient.getAttribute("id")+")"}); }, hex:function(value){ var color={ black :"#000",green :"#008000",silver :"#c0c0c0",lime :"#0f0", gray :"#808080",olive :"#808000",white :"#fff",yellow :"#ff0", maroon :"#800000",navy :"#000080",red :"#f00",blue :"#00f", purple :"#800080",teal :"#008080",fuchsia :"#f0f",aqua :"#0ff", indigo :"#4b0082",orange :"#ffa500",sienna :"#a0522d",plum :"#dda0dd", gold :"#ffd700", tan :"#d2b48c", snow :"#fffafa",violet :"#ee82ee" } if(!!color[value]){ value = color[value] } if(/^#/.test(value)){ value = value.replace('#', ''); return "#" + (value.length == 3 ? value.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : value); } return value; } } window.onload = function(){ new Gradient("text1",{width:800,height:100,angle:90,"color-stop":["0,red","16,orange","32,yellow","48,green","64,blue","80,indigo","100,violet"]}) new Gradient("text2",{width:800,height:100,angle:0,"color-stop":["0,red","16,orange","32,yellow","48,green","64,blue","80,indigo","100,violet"]}) new Gradient("text3",{width:800,height:100,angle:45,"color-stop":["0,red","16,orange","32,yellow","48,green","64,blue","80,indigo","100,violet"]}) } </script> <div id="text1" class="gradient">javascript線性漸層 by 司徒正美 實現多重水平漸層效果</div> <div id="text2" class="gradient">javascript線性漸層 by 司徒正美 實現多重垂直漸層效果</div> <div id="text3" class="gradient">javascript線性漸層 by 司徒正美 實現多重角度漸層效果</div>
[Ctrl+A 全選 注:如需引入外部Js需重新整理才能執行]