javascript 线性渐变三

  作者:bea

IE还有一个利器至今没有被使用过,那就是VML。虽然比不上SVG,但它还是非常强大的。在实现渐变上,其fill还比IE的Gragient滤镜强悍得多了。不过VML出现得比较早,只支持很少的颜色名,如red,blue,yellow,其他如orange就可以搞死它了。因此要使用VML做线性渐变,我们得对这些颜色名做一下转换。 HTML4的颜色值 black = #000000 green = #008000 silver = #c0c0c0 l
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


我们可以在火狐官网以及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需刷新才能执行]



有用  |  无用

猜你喜欢