1.下载fabric.js文件http://fabricjs.com/
2.效果图
3.代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
width: 100%;
}
canvas {
display: block;
}
</style>
</head>
<body>
<div id="divcanvas">
<canvas id="canvas" width="974" height="715"></canvas>
</div>
</body>
<script src="fabric.min.js"></script>
<script src="jquery/jquery.min.js"></script>
<script>
var contrydata = {
name : "浙江省上城区上城区",
cenNum : 19,
color : '#D0D0D0',
childData : [ {
name : "杭州市",
color : '#0C64FC',
cenNum : 10,
childData : [ {
color : '#D0D0D0',
cenNum : 2,
name : "上城区上城区上城区上城区上城区"
}, {
color : '#D0D0D0',
cenNum : 2,
name : "下城区"
}, {
color : '#D0D0D0',
cenNum : 2,
name : "萧山区"
}, {
color : '#D0D0D0',
cenNum : 2,
name : "滨江区"
}, {
color : '#D0D0D0',
cenNum : 2,
name : "江干区"
} ]
}, {
name : "宁波市上城区上城区上城区上",
color : '#D0D0D0',
cenNum : 4,
childData : [ {
color : '#D0D0D0',
cenNum : 4,
name : "海曙区",
childData : [ {
color : '#D0D0D0',
cenNum : 2,
name : "上城区上城区上城区上城区上城区上城区"
}, {
color : '#D0D0D0',
cenNum : 2,
name : "下城区上城区上城区上城区上城区上区上城区上区上城区上区上城区"
}]
} ]
}, {
name : "丽水市",
color : '#D0D0D0',
cenNum : 5,
childData : [ {
color : '#D0D0D0',
cenNum : 5,
name : "丽水一区"
} ]
} ]
};
$(window).resize(resizeCanvas);
function resizeCanvas() {
var c=document.getElementById("canvas");
$(c).attr("width", $(window).get(0).innerWidth);
$(c).attr("height", $(window).get(0).innerHeight);
c.getContext("2d").fillRect(0, 0, $(c).width(), $(c).height());
};
resizeCanvas();
var w_h = $(window).get(0).innerHeight;
var w_w = $(window).get(0).innerWidth;
var LINE_LENGTH = 30/974*w_w;//线长度
var FONT_SIZE = 10/974*w_w;//字体大小
var RECT_WIDTH = 100/974*w_w;
var RECT_HEIGHT = 30/715*w_h;
var RECT_BCOLOR_NO = '#D0D0D0';//不可选城市颜色
var RECT_BCOLOR_YES = '#0C64FC';//可选城市颜色
var dataposition= [];
window.onload = function() {
var rootl = 150;
var roott = 50;
var citys = contrydata.citys;
var canvas = new fabric.Canvas('canvas');
drawRectAndTextGroup(canvas, rootl, roott, contrydata.color,
contrydata.name);
dataposition.push({left:rootl,top:roott,name:contrydata.name});
drawData(canvas, rootl, roott, contrydata);
canvas.on({
'mouse:down' : function(options) {
console.log(options.e.clientX + "," + options.e.clientY);
var oleft = options.e.clientX;
var otop = options.e.clientY;
for(var i=0;i<dataposition.length;i++){
var dp = dataposition[i];
if(oleft>=dp.left && oleft<=dp.left+RECT_WIDTH && otop>=dp.top&&otop<=dp.top+RECT_HEIGHT){
alert(dp.name);
}
}
}
});
}
function drawData(canvas, rootleft, rootTop, rootData) {
var childData = rootData.childData;
if (childData == undefined || childData == null)
return;
var childlen = childData.length;
var yuanheght = 0;
for (var i = 0; i < childlen; i++) {
var child = childData[i];
var cen = child.cenNum;
var childLeft = rootleft + LINE_LENGTH * 2 + RECT_WIDTH;
var childTop = rootTop + yuanheght;
yuanheght += cen * LINE_LENGTH;
dataposition.push({left:childLeft,top:childTop,name:child.name});
drawRectAndTextGroup(canvas, childLeft, childTop, child.color,
child.name);
/*var r_w = RECT_WIDTH;
if(r_w<FONT_SIZE*(tc.length)){
r_w = FONT_SIZE*(tc.length);
}*/
//横线
if (i == 0) {
drawLateralLine(canvas, childLeft - LINE_LENGTH * 2, childTop
+ RECT_HEIGHT / 2);
}
drawLateralLine(canvas, childLeft - LINE_LENGTH * 1, childTop
+ RECT_HEIGHT / 2);
if (i == childlen - 1) {
for (var k = 0; k < rootData.cenNum - cen; k++)
drawHorrentLine(canvas,
rootleft + LINE_LENGTH + RECT_WIDTH, rootTop
+ RECT_HEIGHT / 2 + k * LINE_LENGTH);
}
var cchild = child.childData;
if (cchild != undefined && cchild != null && cchild.length > 0) {
drawData(canvas, childLeft, childTop, child);
}
}
}
/**
1:left
t:top
bcolor:方形背景颜色
tc:文本内容
*/
function drawRectAndTextGroup(canvas, l, t, bcolor, tc) {
var r_w = RECT_WIDTH;
if(r_w<FONT_SIZE*(tc.length)){
r_w = FONT_SIZE*(tc.length);
}
var rect = new fabric.Rect({
width : r_w,
height : RECT_HEIGHT,
fill : bcolor,
originX : 'center',//调整中心点的X轴坐标
originY : 'center',//调整中心点的Y轴坐标
});
var text = new fabric.Text(tc, {
hasControls : false,
fill : "black",
fontFamily : 'pokeText',
fontSize : FONT_SIZE,
originX : 'center',
originY : 'center'
});
//进行组合
var group = new fabric.Group([ rect, text ], {
left : l,
top : t,
hasControls : false, //选中时是否可以放大缩小
hasRotatingPoint : false,//选中时是否可以旋转
hasBorders : false,//选中时是否有边框
transparentCorners : true,
perPixelTargetFind : true,//默认false。当设置为true,对象的检测会以像互点为基础,而不是以边界的盒模型为基础。
selectable : true,//是否可被选中
lockMovementX : true,//X轴是否可被移动(true为不可,因为前缀是lock)
lockMovementY : true
//Y轴是否可被移动(true为不可,因为前缀是lock)
})
canvas.add(group);//方块文字组合块
}
/**
横线
*/
function drawLateralLine(canvas, l, t) {
var line = new fabric.Line([ l, t, l + LINE_LENGTH, t ], {//横线
//终止位置,线长,起始位置,top,这里是从项目中截下来的我用了变量代替,你要用的话lineheight和lineleft用自己的变量或者数字代替。如果两个终止位置和起始位置的数值一样那么这个线条会垂直,这个应该很好理解。
fill : '#5E2300',//填充颜色
stroke : '#5E2300',//笔触颜色
strokeWidth : 1,//笔触宽度
hasControls : false, //选中时是否可以放大缩小
hasRotatingPoint : false,//选中时是否可以旋转
hasBorders : false,//选中时是否有边框
transparentCorners : true,
perPixelTargetFind : true,//默认false。当设置为true,对象的检测会以像互点为基础,而不是以边界的盒模型为基础。
selectable : true,//是否可被选中
lockMovementX : true,//X轴是否可被移动(true为不可,因为前缀是lock)
lockMovementY : true
//Y轴是否可被移动(true为不可,因为前缀是lock)
});
canvas.add(line);
}
function drawHorrentLine(canvas, l, t) {
var line = new fabric.Line([ l, t, l, t + LINE_LENGTH ], {//竖线
//终止位置,线长,起始位置,top,这里是从项目中截下来的我用了变量代替,你要用的话lineheight和lineleft用自己的变量或者数字代替。如果两个终止位置和起始位置的数值一样那么这个线条会垂直,这个应该很好理解。
fill : '#5E2300',//填充颜色
stroke : '#5E2300',//笔触颜色
strokeWidth : 1,//笔触宽度
hasControls : false, //选中时是否可以放大缩小
hasRotatingPoint : false,//选中时是否可以旋转
hasBorders : false,//选中时是否有边框
transparentCorners : true,
perPixelTargetFind : true,//默认false。当设置为true,对象的检测会以像互点为基础,而不是以边界的盒模型为基础。
selectable : true,//是否可被选中
lockMovementX : true,//X轴是否可被移动(true为不可,因为前缀是lock)
lockMovementY : true
//Y轴是否可被移动(true为不可,因为前缀是lock)
});
canvas.add(line);
}
</script>
</html>