(jQuery,SVG)使用jQuery和svg仿QQ地图测距功能(抛砖引玉)

不久前看到了QQ地图的测距功能,觉得挺好玩的,就思考模仿一下。本来想通过canvas来画图,可惜对canvas不是很熟悉,就准备用svg了,其实我对svg也不是很熟,纯粹是学习。

代码只是简单的生成图线,没有删除点的功能,也没有拖动路线的功能,demo仅仅是抛砖引玉,大侠就不要拍砖了,我是个菜鸟。

DEMO截图:

素材:

资源:jQuery.js,Raphael.js

思考:

实现测距所需要获取的参数,最基本的两点:

1:比例尺,由于是虚拟的地图,比例尺可以手动设定。

2:路线的长度,可以通过path.getTotalLength()来获取像素长度。

基本知识:

1:svg的路径格式

 

<path d="M 100 100 L 300 200 L 200 300 z" />

说明:

M 表示移动到当前点 M 100 100 指将当前点移动到坐标(100, 100) 的地方
L 表示绘制直线 "L 300 200" 指从当前位置(100, 100) 绘制直线到 (300, 200) 处
z 表示闭合路径,首尾相连。更多

2:我们使用Raphael这个js操作SVG。其声明path的基本语法,更多

/*String id,divWidth,divHeight*/
var ploy = Raphael('mapPloy', datas.w, datas.h);
var pathslength=ploy.path(options)
实现:

获取鼠标发生事件的位置--->添加点--->更新包含svg的DIV的相关属性--->绘图

原理:

代码:

HTML与CSS

<style type="text/css">
			#maps{
				width:500px;
				height:300px;
				background:#f9f9f9;
				border:1px solid #c6c6c6;
				margin:10px auto;
				position:relative;
			}
			div.point{
				position:absolute;
				width:12px;
				height:12px;
				background:url(stone.gif) no-repeat;
			}
			div.svgCotainer{
				position:absolute;
			}
			#mapPloy{
				position:absolute;
			}
			#info{
				position:absolute;
				top:10px;
				right:10px;
				width:100px;
				height:25px;
				background:#ecf6fc;
				border:1px solid #8ad0fd;
				font-size:14px;
				font-family:Arial, Helvetica, sans-serif;
				color:#51a961;
				text-align:center;
				line-height:25px;
			}
		</style>
<div id="maps">
			<div id="info">
			</div>
			
		</div>

1首先写个获取数组中最大值,最小值的方法,主要是为了获取所有点Top与Left的最大值与最小值

//return array's max
        Array.prototype.max = function(){
            return Math.max.apply({}, this);
        }
		//return array's min
        Array.prototype.min = function(){
            return Math.min.apply({}, this);
}
2其次为了便于控制,声明一些属性

var options={
			cssClickClass:'point',//点击时生成点的类
			svgCtnCls:'svgContainer',//svg容器的类
			wapper:'#maps',//地图容器
			scale:'1'//比例尺
		};
3.代码实现

var Ploy={
			getData:function(){
				var arrayTop=[];
				var arrayLeft=[];
				var el=$('div.'+options.cssClickClass);
				$.each(el,function(i,n){
					var pointTop=$(n).position().top;
					var pointLeft=$(n).position().left;
					arrayTop.push(pointTop);
					arrayLeft.push(pointLeft);
				});
				var minTop=arrayTop.min();
				var maxTop=arrayTop.max();
				var minLeft=arrayLeft.min();
				var maxLeft=arrayLeft.max();
				var svgWidth=maxLeft-minLeft+el.width();
				var svgHeight=maxTop-minTop+el.height();
				return {
					w:svgWidth,
					h:svgHeight,
					minTop:minTop,
					minLeft:minLeft,
					elWidth:el.width(),
					elHeight:el.height()
				}
			},
			makeSvgContainer:function(){
				var s=this;
				var datas=s.getData();
				var div=$('#mapPloy').is('div');
				if(!div){
					var svgContainer=$('<div/>')
								 .attr('id','mapPloy')
								 .addClass(options.svgCtnCls)
								 .css({
								 	width:datas.w,
									height:datas.h,
									top:datas.minTop+datas.elHeight/2,
									left:datas.minLeft+datas.elWidth/2
					}).prependTo($(options.wapper));
				}else{
					$('#mapPloy').css({
						width:datas.w,
						height:datas.h,
						top:datas.minTop+datas.elHeight/2,
						left:datas.minLeft+datas.elWidth/2
					})
				}
			},
			//添加点在地图区域中
			addPoint:function(top,left){
				var wapper=$(options.wapper);
				var t=wapper.offset().top;
				var l=wapper.offset().left;
				var pt=top-t;
				var pl=left-l;
				var point=$('<div/>').addClass(options.cssClickClass)
									 .css({
									 	top:pt,
										left:pl,
										poisiton:'absolute'
									 })
									 .appendTo(wapper);
			},
			makePoly:function(el,o){
				var s=this;
				s.addPoint(o.top,o.left);
				s.makeSvgContainer();
				//清空svg,重新画图
				$(el).find('div.'+options.svgCtnCls).empty();
				//遍历已经有的点,做出路线
				var points=$('div.'+options.cssClickClass);
				var datas=s.getData();
				//生成路径
				var path=""
				$.each(points,function(i,n){
					if(i==0){
						path+="M";
					}else{
						path+="L";
					}
					var leftInSvg=$(n).position().left-datas.minLeft;
					var TopInSvg=$(n).position().top-datas.minTop;
                    path += leftInSvg;
                    path += ",";
                    path += TopInSvg;
                    path += " ";
				});
				var ploy = Raphael('mapPloy', datas.w, datas.h);
				var pathslength=ploy.path(path).attr({
					stroke:'#1791fc', 
					'stroke-width':3,
					opacity:.7, 
					fill:"none"});
				//计算距离
				return pathslength.getTotalLength()*options.scale;
			}	
		}
启动事件

$(document).ready(function(){
			$('#maps').click(function(e){
				var left=e.pageX;
				var top=e.pageY;
				var o={
					left:left,
					top:top
				}
			    var lengths=Ploy.makePoly('#maps',o);
				lengths=(Math.round(lengths*100))/100;
				$('#info').html(lengths+'Km');
			})
});

DEMO下载

posted @ 2010-10-09 11:42  FED@Web  阅读(7840)  评论(6编辑  收藏  举报