svg
突然要求做一个温度计效果,要能放大缩小,动态显示温度;
开始准备用jquery+css+图片做,发现很复杂,后来可以只兼容ie9+,firefox和chorme,所以决定用svg做,由于svg各主流浏览器dom支持差异,又折腾了一天,决定引入snap;
不废话,直接贴代码:
1.首先引入,jquery和snap
js代码:
(function ($) {
$.fn.Thermometer = function (options, value) {
var dft = {
parentid: '', //容器
px: 0, //相对与parentid x坐标
py: 0, //相对于parentid y坐标
//parentid,px,py全部有值才有效
width: 130, //面板宽度
height: 400, //面板高度
max: 50, //温度最大值
min: 0, //温度最小值
current: 0, //当前温度
isnormal: 1, //温度是否正常;1表示正常,0不正常
title: '温度'
}
this.SetTitle = function (title) {
var etitle = this.svg.getElementById("txttitle");
if (etitle != null && etitle != undefined) {
etitle.textContent = title;
}
}
this.SetRange = function (maxnum, minnum) {
var max = this.svg.getElementById("svg_max");
var min = this.svg.getElementById("svg_min");
this.Max = maxnum;
this.Min = minnum;
if (max != null && max != undefined)
max.textContent = maxnum;
if (min != null && min != undefined)
min.textContent = minnum;
}
this.SetCurrent = function (num, isnormal, callback) {
if (num < this.Min)
return;
var rct_panel = Snap("#rct_panel");
var rct_current = Snap("#rct_current");
var txt_current = Snap("#svg_current");
var heightsum = 275;
var value = this.Max - this.Min;
//当前温度文本隐藏
txt_current.attr('text', num);
txt_current.attr("opacity", 0);
//if (animate_height.beginElement) {
//温度水银柱高度变化动画
var fromheight = parseFloat(rct_panel.attr("height"));
var toheight = heightsum - num * 240 / value;
rct_panel.animate({ height: toheight }, 1000, mina.Linear, function () {
txt_current.attr("y", 305 - num * 240 / value);
txt_current.attr("opacity", 1);
})
var cIsnormal = txt_current.data("isnormal") == undefined ? 1 : txt_current.data("isnormal");
//显示状态变化
if (cIsnormal > isnormal) {
rct_current.animate({ fill: 'red' }, 2000, mina.Linear);
txt_current.attr("fill", "red");
} else if (cIsnormal < isnormal) {
rct_current.animate({ fill: '#00A600' }, 2000, mina.Linear);
txt_current.attr("fill", "#00A600");
}
else {
rct_current.animate({ opacity: 0.5 }, 1000, mina.linear, function () {
rct_current.animate({ opacity: 1 }, 1000, mina.linear);
});
}
txt_current.data("isnormal", isnormal);
}
if (typeof options == "string") {
var svg = document.getElementById(this.attr("id"));
this.svg = svg;
this.Max = parseFloat(svg.getElementById("svg_max").textContent);
this.Min = parseFloat(svg.getElementById("svg_min").textContent);
if (options == "setcurrent") {
this.SetCurrent(value);
}
} else {
var opts = $.extend(dft, options);
this.Opts = opts;
this.Isnormal = opts.isnormal;
var svg = document.getElementById(this.attr("id"));
if (svg != null && svg != undefined) {
this.svg = svg;
var w = parseFloat(opts.width);
svg.style.width = w + "px";
var h = parseFloat(opts.height);
svg.style.height = h + "px";
if (opts.title != "" && opts.title != undefined) {
this.SetTitle(opts.title);
}
this.SetRange(opts.max, opts.min);
var obj = this;
var timer = undefined;
if (opts.current.url != undefined && opts.current.delay != undefined) {
var loadRemote = function () {
$.post(opts.current.url, opts.current.param, function (data) {
data = eval(data)[0];
if (data != null && data != undefined && data.current != null && data.current != undefined)
obj.SetCurrent(data.current, data.isnormal, null)
})
}
timer = setInterval(loadRemote, opts.current.delay);
} else {
this.SetCurrent(opts.current, opts.isnormal, null);
}
}
}
}
})(jQuery);
$("#tem").Thermometer({
width: 130,
height: 300,
title: '室温',
current: 60,
isnormal: 0,
current: {
url: 'test.aspx',
delay: 3000
},
max: 100,
min: 0
});
html代码:
<svg id="tem" style="border:solid 2px black; width:130px;height:400px;" viewBox="0,0,130,400" preserveAspectRatio="xMidYMid meet"> <defs> <linearGradient id="bg" x1="1%" y1="20%" x2="100%" y2="20%"> <stop offset="10%" style="stop-color:#F0F0F0;stop-opacity:0.1" /> <stop offset="40%" style="stop-color:white;stop-opacity:0.4" /> <stop offset="50%" style="stop-color:white;stop-opacity:0.5" /> <stop offset="80%" style="stop-color:#F0F0F0;stop-opacity:0.1" /> </linearGradient> <clipPath id="temp"> <path d="M25 50 A25,25 180 1 1 75,50 L75 300 A25,25 180 1 1 25,300 z" stroke="black" stroke-width="2" fill="none" /> </clipPath> </defs> <rect id="rct_current" x="25" y="25" width="50" height="300" fill="#00A600" clip-path="url(#temp)" style=""> </rect> <rect id="rct_panel" x="25" y="25" height="275" width="50" fill="#2894FF" clip-path="url(#temp)"> </rect> <rect id="rct_white" x="25" y="25" height="300" width="50" fill="url(#bg)" clip-path="url(#temp)"></rect> <path d="M50 300 h25 M60 288 h15 M60 276 h15 M60 264 h15 M60 252 h15 M50 240 h25 M60 228 h15 M60 216 h15 M60 204 h15 M60 192 h15 M50 180 h25 M60 168 h15 M60 156 h15 M60 144 h15 M60 132 h15 M50 120 h25 M60 108 h15 M60 96 h15 M60 84 h15 M60 72 h15 M50 60 h25 " stroke="white" stroke-width="3"></path> <text id="txttitle" x="46" y="375" font-weight="900">温度</text> <text id="svg_max" x="85" y="65">100</text> <text id="svg_current" x="85" y="305" font-weight="900" font-size="20" fill="#00A600" opacity="0">50</text> <text id="svg_min" x="85" y="305">0</text> </svg>
效果图如下:

浙公网安备 33010602011771号