以下是 Canvas仿支付宝芝麻信用特效代码 的示例演示效果:
部分效果截图1:
部分效果截图2:
HTML代码(index.html):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Canvas仿支付宝芝麻信用特效</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<style>
#box {
width: 1000px;
text-align: center;
margin: 100px auto;
}
</style>
</head>
<body>
<div id="box">
<canvas id="meter" width="360" height="220"></canvas>
<canvas id="radar" width="538" height="370"></canvas>
</div>
<script src="chart.meter.js"></script>
<script src="chart.radar.js"></script>
<script>
window.onload = function(){
Meter.setOptions({
element: 'meter',
centerPoint: {
x: 180,
y: 180
},
radius: 180,
data: {
value: 710,
title: '职场竞争力{t}',
subTitle: '评估时间:2015.07.28',
area: [{
min: 350, max: 550, text: '较弱'
},{
min: 550, max: 600, text: '一般'
},{
min: 600, max: 650, text: '很强'
},{
min: 650, max: 700, text: '超强'
},{
min: 700, max: 950, text: '极强'
}]
}
}).init();
Radar.setOptions({
element: 'radar',
radius: 140,
polar: [
{ text: '简历信息', max: 190, icon: { sx: 0, sy: 0, w: 32, h: 33, l: -17, t: -60 } },
{ text: '职场身份', max: 190, icon: { sx: 32, sy: 0, w: 30, h: 33, l: 30, t: -30 } },
{ text: '九博成长', max: 190, icon: { sx: 61, sy: 0, w: 32, h: 33, l: 10, t: 0 } },
{ text: '职场活力', max: 190, icon: { sx: 93, sy: 0, w: 31, h: 33, l: -40, t: 0 } },
{ text: '人脉社交', max: 190, icon: { sx: 124, sy: 0, w: 29, h: 33, l: -60, t: -30 } }
],
title: '{v}',
data: [130, 130, 130, 148, 150],
styles: {
label: {
image: 'icon.png'
}
}
}).init();
}
</script>
</body>
</html>
JS代码(chart.pie.js):
/** * * @authors 王昱森 * @date 2015-09-02 12:57:00 * @version $Id$ */
Object.prototype.extend = function (obj){
for(var k in obj){
if(this.hasOwnProperty(k) && typeof this[k] == 'object'){
extend(this[k],obj[k]);
}
else{
this[k] = obj[k];
}
}
}
var Pie = function (element,opt){
this.opts ={
colors:['#CAF44A','#FFBD30','#FFF335','#FF6D4C'],valueStyle:{
formate:'{
v}
人',color:'#fff',font:'16px Microsoft YaHei'}
}
;
this.opts.extend(opt);
this.element = typeof element == 'string' ? document.getElementById(element):element;
this.r = this.element.width / 2;
this.context = this.element.getContext('2d');
}
Pie.prototype ={
calcLocation:function(r,end){
return{
x:this.r + r * Math.cos(Math.PI * end),y:this.r + r * Math.sin(Math.PI * end)}
;
}
,drawCircle:function(opts){
var s = opts.s || 0,e = opts.e || 2;
this.context.beginPath();
this.context.moveTo(this.r,this.r);
this.context.arc(this.r,this.r,this.r,Math.PI*s,Math.PI*e);
this.context.closePath();
this.context.fillStyle = opts.style;
this.context.fill();
}
,fillText:function(opts){
var style = this.opts.valueStyle,text = style.formate.replace('{
v}
',opts.text);
this.context.font = style.font;
this.context.fillStyle = style.color;
this.context.textAlign = style.align || 'center';
this.context.textBaseline = style.vertical || 'middle';
this.context.moveTo(opts.loc.x,opts.loc.y);
this.context.fillText(text,opts.loc.x,opts.loc.y);
}
,drawRange:function (sum,values){
var ends = [],txtEnds = [];
for (var i = 0,len = values.length;
i < len;
i++){
var s = i === 0 ? 1.5:ends[i-1],e = values[i] / sum * 2 + s,txtEnd = s + (e - s) / 2;
ends.push(e);
txtEnds.push(txtEnd);
this.drawCircle({
s:s,e:e,style:this.opts.colors[i]}
);
}
;
for (var i = 0,len = txtEnds.length;
i < len;
i++){
this.fillText({
loc:this.calcLocation(this.r * 0.6,txtEnds[i]),text:values[i]}
);
}
}
,draw:function (){
var sum = 0,values = [],data = this.opts.data;
for (var i = 0,len = data.length;
i < len;
i++){
var value = data[i].value;
values.push(value);
sum += value;
}
;
this.drawRange(sum,values);
}
}
JS代码(chart.radar.js):
/** * * @authors 王昱森 * @date 2015-08-14 11:31:44 * @version 1.0.3 */
var Radar = (function(){
var options ={
styles:{
offset:{
top:15,left:0}
,border:{
width:2,color:'#2EC8CA'}
,splitLine:{
color:'#ccc'}
,title:{
font:'bold 52px Microsoft YaHei',color:'#F56948'}
,valueRange:{
border:{
width:4,color:'#FF0101'}
,background:'#F56948',arrow:2}
,inner:{
radius:70,background:'#fff'}
,label:{
image:'',font:'16px Microsoft YaHei',color:'#666'}
}
}
;
var element,styles,borderStyle,splitLineStyle,titleStyle,valueRangeStyle,innerStyle,labelStyle;
var extend = function(obj1,obj2){
for(var k in obj2){
if(obj1.hasOwnProperty(k) && typeof obj1[k] == 'object'){
extend(obj1[k],obj2[k]);
}
else{
obj1[k] = obj2[k];
}
}
}
var calcLocation = function(cp,r,end){
return{
x:cp[0] + r * Math.cos(Math.PI * end),y:cp[1] + r * Math.sin(Math.PI * end)}
;
}
var drawLine = function(line){
var lines = line.lines;
context.beginPath();
context.moveTo(lines[0].x,lines[0].y);
for(var i = 1;
i < lines.length;
i++){
context.lineTo(lines[i].x,lines[i].y);
}
context.closePath();
if(line.style){
context.strokeStyle = line.style;
context.lineWidth = line.width || 1;
context.stroke();
}
if(line.fill){
context.fillStyle = line.fill;
context.fill();
}
}
var fillText = function(opts){
context.font = opts.font;
context.fillStyle = opts.color;
context.textAlign = opts.align || 'center';
context.textBaseline = opts.vertical || 'middle';
context.moveTo(opts.x,opts.y);
context.fillText(opts.text,opts.x,opts.y);
}
var drawIcon = function(borderLoc,polar){
var img = new Image();
img.src = labelStyle.image;
img.onload = function(){
for(var n = 0;
n < borderLoc.length;
n++){
var text = polar[n].text,icon = polar[n].icon,loc = borderLoc[n],x = loc.x + icon.l,y = loc.y + icon.t;
context.drawImage(img,icon.sx,icon.sy,icon.w,icon.h,x,y,icon.w,icon.h);
fillText({
font:labelStyle.font,color:labelStyle.color,text:text,x:x + icon.w/2,y:y + icon.h + 10}
);
}
}
}
var drawInner = function(cp,valueRangeLoc,borderLoc,innerLoc,valueSum){
drawLine({
lines:borderLoc,style:borderStyle.color,width:borderStyle.width}
);
drawLine({
lines:valueRangeLoc,style:valueRangeStyle.border.color,width:valueRangeStyle.border.width,fill:valueRangeStyle.background}
);
for(var j = 0;
j < borderLoc.length;
j++){
drawLine({
lines:[{
x:cp[0],y:cp[1]}
,borderLoc[j]],style:splitLineStyle.color}
);
}
drawLine({
lines:innerLoc,fill:innerStyle.background}
);
fillText({
font:titleStyle.font,color:titleStyle.color,text:options.title.replace('{
v}
',valueSum),x:cp[0],y:cp[1]}
);
for (var k = valueRangeLoc.length - 1;
k >= 0;
k--){
var x = valueRangeLoc[k].x,y = valueRangeLoc[k].y;
context.beginPath();
context.moveTo(x,y);
context.arc(x,y,valueRangeStyle.arrow,0,Math.PI*2);
context.closePath();
context.strokeStyle = valueRangeStyle.border.color;
context.lineWidth = valueRangeStyle.border.width;
context.stroke();
context.fillStyle = '#fff';
context.fill();
}
}
var calcRedrawPath = function(borderLoc){
var startLoc = borderLoc[0];
var minX = startLoc.x,minY = startLoc.y,maxX = startLoc.x,maxY = startLoc.y;
for(var i = 1;
i < borderLoc.length;
i ++){
var loc = borderLoc[i];
minX = loc.x < minX ? loc.x:minX;
minY = loc.y < minY ? loc.y:minY;
maxX = loc.x > maxX ? loc.x:maxX;
maxY = loc.y > maxY ? loc.y:maxY;
}
var borderW = borderStyle.width;
return{
x:minX - borderW,y:minY - borderW,w:maxX - minX + borderW * 2,h:maxY - minY + borderW * 2}
;
}
var drawing = function(cp,w,h){
var polar = options.polar,polarCount = polar.length,radius = options.radius,data = options.data;
angles = [],borderLoc = [];
var dataTemp = [];
for(var i = 0;
i < polarCount;
i++){
dataTemp.push(0);
var end = 1.5 + i * (2/polarCount);
angles.push(end);
borderLoc.push(calcLocation(cp,radius,end));
}
context.fillStyle = "#fff";
context.fillRect(0,0,w,h);
drawIcon(borderLoc,polar);
var redrawPath = calcRedrawPath(borderLoc);
var timer = setInterval(function(){
var eqCount = 0,valueSum = 0,valueRangeLoc = [],innerLoc = [];
for(var i = 0;
i < polarCount;
i++){
dataTemp[i] = dataTemp[i] + 5 > data[i] ? data[i]:dataTemp[i] + 5;
if(dataTemp[i] === data[i]){
++eqCount;
}
var end = angles[i];
// inner var ir = innerStyle.radius;
innerLoc.push(calcLocation(cp,innerStyle.radius,end));
// valueRange var vr = dataTemp[i]/polar[i].max * (radius - ir) + ir;
valueRangeLoc.push(calcLocation(cp,vr,end));
valueSum += dataTemp[i];
}
if(eqCount === polarCount){
clearInterval(timer);
}
context.clearRect(redrawPath.x,redrawPath.y,redrawPath.w,redrawPath.h);
context.fillStyle = "#fff";
context.fillRect(redrawPath.x,redrawPath.y,redrawPath.w,redrawPath.h);
drawInner(cp,valueRangeLoc,borderLoc,innerLoc,valueSum);
}
,10);
}
var exports ={
}
;
exports.setOptions = function(opts){
extend(options,opts);
styles = options.styles;
borderStyle = styles.border;
splitLineStyle = styles.splitLine;
titleStyle = styles.title,valueRangeStyle = styles.valueRange,innerStyle = styles.inner;
labelStyle = styles.label;
element = typeof options.element == 'string' ? document.getElementById(options.element):options.element;
context = element.getContext('2d');
return exports;
}
;
exports.init = function(){
var w = element.offsetWidth,h = element.offsetHeight;
var ofs = options.styles.offset;
drawing([w/2 + ofs.left,h/2 + ofs.top],w,h);
return exports;
}
return exports;
}
)();