snap.svg.js学习------时间认知

  wallimn原创,欢迎转载,原文地址: http://wallimn.iteye.com/blog/2374931
  最近儿子学校教时间认知,动手做了这样一个小软件。功能很简单:在手机上使用,手指按住钮表针可以拖动表针,改变时间,点击下面按钮可显示时间,验证小朋友时间认知是否正确。
  界面如下图所示:




  用到的相关技术:snap.svg.js、hammer.js、jQuery.js。对于svg绘制、svg动画、触屏事件处理有一定的借鉴意义。
  代码没有仔细推敲与封装,随便玩玩而已。

  所有代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<!--
	作者: wallimn, http://wallimn.iteye.com
	时间:2017年1月7日
	功能:snap.svg.js学习之-时间认知
-->
<html lang="zh-cn">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
	<meta http-equiv="pragma" content="no-cache">  
	<meta http-equiv="cache-control" content="no-cache">  
	<meta http-equiv="expires" content="0">     
	<c:set var="ctx" value="${pageContext.request.contextPath}"></c:set>
    <title>时间认知-wallimn</title>

    <!-- Bootstrap -->
    <link href="${ctx}/css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script type="text/javascript" src="${ctx}/js/html5shiv.min.js"></script>
      <script type="text/javascript" src="${ctx}/js/respond.min.js"></script>
    <![endif]-->
    <style type="text/css">
    	html,body{
    		width:100%;
    		height:100%;
    	}
		#svg {
			margin:0;
			position:relative;
			top:50%;
			border-radius:5px;
			border:1px solid #efefef;
		}
		text{
			font-size:14px;
		}
    </style>
  </head>
  <body>
  
 
	<svg id='paper'></svg>
  
  
    <script type="text/javascript" src="${ctx}/js/jquery-1.11.1.min.js"></script>
	<script type="text/javascript" src="${pageContext.request.contextPath}/js/snap.svg.js"></script>
	<script type="text/javascript" src="${pageContext.request.contextPath}/js/hammer-2.0.8.js"></script>
    
	<script type="text/javascript">
	
	    $(function(){
	    	//阻止长按网页出现菜单
	    	window.ontouchstart = function(e) { e.preventDefault(); }
	    	var clientWidth=document.body.clientWidth;
	    	var clientHeight=document.body.clientHeight;
			$("#paper").css("width",clientWidth+"px").css("height",clientHeight+"px");
	    	var minsize = Math.min(clientWidth,clientHeight);
	    	var paper = Snap("#paper");
	    	
	    	var centerX=clientWidth/2, centerY=clientHeight/2 ;
	    	
	    	
	    	var radius =Math.round( minsize/2*0.8);
	    	var hourLen = Math.round(radius*0.65),hourDeta=6;//时针长度
	    	var minLen = Math.round(radius*0.8),minDeta=12;//分针长度
	    	var numLen =  Math.round(radius*0.86);//数字半径
	    	
	    	var clock = paper.circle(centerX,centerY,radius);
	    	clock.attr({fill:'#0000cc',stroke:'#0000ff',strokeWidth:6,'fill-opacity':0.6});
	    	
	    	var x,y,ang;
	    	for(var i=0; i<12; i++){
	    		ang = Math.PI/2-i*2*Math.PI/12-30*Math.PI/180;
	    		x = centerX+numLen*Math.cos(ang);
	    		y = centerY-numLen*Math.sin(ang);
	    		paper.text(x,y,i+1).attr({'text-anchor':'middle','dominant-baseline':'middle','font-size':32});
	    	}
	    	
	    	var hourHand = paper.polygon(centerX-hourDeta*2,centerY,centerX,centerY+hourDeta,centerX+hourLen,centerY,centerX,centerY-hourDeta,centerX-hourDeta*2,centerY).attr({stroke:'black',"data-id":'hourHand',"data-selected":'false',"data-angle":0,strokeWidth:2,strokeOpacity:0.8,'fill-opacity':0.5,fill:'black'});
	    	var minHand = paper.polygon(centerX-minDeta*2,centerY,centerX,centerY+minDeta,centerX+minLen,centerY,centerX,centerY-minDeta,centerX-minDeta*2,centerY).attr({stroke:'black',"data-id":'minHand',"data-selected":'false',"data-angle":0,strokeWidth:2,strokeOpacity:0.8,'fill-opacity':0.5,fill:'black'});
	    	
	    	window.hourHand = hourHand;
	    	window.minHand = minHand;
	    	
	    	//旋转表针的函数
	    	function rotateHand(hand,resultAng){
	    		var oldang = hand.attr("data-angle");
	    		if(resultAng<0)resultAng=360+resultAng;
	    		else if (resultAng>360)resultAng = resultAng-360;
	    		//console.log("初始角度:",oldang,",最终角度:",resultAng);
	    		//Snap.Matrix().rotate()函数中指定的角度是最终结果的角度。
	    		//hand.transform(new Snap.Matrix().rotate(resultAng,centerX,centerY));
	    		Snap.animate(oldang,resultAng,function(value){
	    			hand.transform(new Snap.Matrix().rotate(value,centerX,centerY));
	    		},100);
	    		hand.attr({"data-angle":resultAng});
	    	}
	    	
	    	//初始状态设置
	    	rotateHand(hourHand,-90);
	    	rotateHand(minHand,-90);
	    	
	    	
	    	var minHanmmer = new Hammer($('[data-id=minHand]')[0]);
	    	minHanmmer.add(new Hammer.Pan({direction:Hammer.DIRECTION_ALL,threshold:0}));
	    	minHanmmer.on("panstart",function(ev){
	    		var element = $(ev.target);
	    		element.attr("stroke","red");
	    		element.attr("data-selected",'true');
	    	});
	    	minHanmmer.on("panend",function(ev){
	    		$(ev.target).attr("stroke","black").attr("data-selected",'false');
	    	});
	    	minHanmmer.on("panmove",function(ev){
	    		if(minHand.attr("data-selected")=='true' && ev.pointers.length>=1){
	    			var px = ev.pointers[0].clientX;
	    			var py = ev.pointers[0].clientY;
	    			var ang = Math.atan2((py-centerY),(px-centerX))*180/Math.PI;
	    			if(ang<0)ang=360+ang;
	    			var deta =ang- parseFloat(minHand.attr("data-angle"));
	    			if(deta<-300)deta=deta+360;
	    			else if(deta>300)deta=deta-360;
	    			var hourAng = parseFloat(hourHand.attr("data-angle"))+deta/12.0;
	    			
	    			rotateHand(minHand,ang);
	    			rotateHand(hourHand,hourAng);
	    		}
	    	});

	    	
	    	var hourHanmmer = new Hammer($('[data-id=hourHand]')[0]);
	    	hourHanmmer.add(new Hammer.Pan({direction:Hammer.DIRECTION_ALL,threshold:0}));
	    	hourHanmmer.on("panstart",function(ev){
	    		var element = $(ev.target);
	    		element.attr("stroke","red");
	    		element.attr("data-selected",'true');
	    	});
	    	hourHanmmer.on("panend",function(ev){
	    		$(ev.target).attr("stroke","black").attr("data-selected",'false');
	    	});
	    	hourHanmmer.on("panmove",function(ev){
	    		if(hourHand.attr("data-selected")=='true'){
	    			var px = ev.pointers[0].clientX;
	    			var py = ev.pointers[0].clientY;
	    			var ang = Math.atan2((py-centerY),(px-centerX))*180/Math.PI;
	    			if(ang<0)ang=360+ang;
	    			var deta =ang- parseFloat(hourHand.attr("data-angle"));
	    			if(deta<-300)deta=deta+360;
	    			else if(deta>300)deta=deta-360;
	    			var hourAng = parseFloat(minHand.attr("data-angle"))+deta*12;
	    			
	    			rotateHand(hourHand,ang);
	    			rotateHand(minHand,hourAng);
	    		}
	    	});
	    	
	    	//输出提示文字
	    	var tipText = paper.text(centerX,centerY*2-8,"按住表针拖动可移动表针").attr({'text-anchor':'middle','dominant-baseline':'middle',fill:'red','font-size':12});
	    	//绘制按钮、并设置事件
	    	var textdeta=40;//文字中心跟底端的距离
	    	var whenText = paper.text(centerX,centerY*2-textdeta,"几点了?").attr({'text-anchor':'middle','dominant-baseline':'middle','font-size':24});
	    	var bbox = whenText.getBBox();
	    	var detax=5,detay=8;
	    	var whenRect = paper.rect(centerX-bbox.width/2-detax,centerY*2-textdeta-bbox.height/2-detay,
	    			bbox.width+detax*2,bbox.height+detay*2,3,3);
	    	whenRect.attr({fill:'#00ff00',stroke:'#00ff00',strokeWidth:1,'fill-opacity':0.1});
	    	var whenHanmmer = new Hammer(whenRect.node);
	    	//阻止了touchstart事件后,click事件就不好使用了。只能用tap事件了。
	    	whenHanmmer.on("tap",function(){
	    		var hourAng = hourHand.attr("data-angle");
	    		hourAng = hourAng-270;//与指针相匹配的角度
	    		if(hourAng<0)hourAng=hourAng+360;
	    		var hourNum = Math.floor(hourAng/30);
	    		if(hourNum==0)hourNum=12;
	    		
	    		
	    		var minAng = minHand.attr("data-angle");
	    		minAng = minAng-270;
	    		if(minAng<0)minAng=minAng+360;
	    		var minNum = Math.round(minAng/6);
	    		if(minNum==60)minNum=0;
	    		//console.log("时针角度:",hourAng,",分针角度:",minAng,",时间",hourNum+":"+minNum);
	    		alert("时间:"+hourNum+":"+minNum);
	    	});
		});
	</script>
  </body>
</html>


  代码上传到github.com,访问地址: https://github.com/wallimn/snapcat,猛戳下载全部程序。

  手机体验,请使用微信扫描下面二维码,不需关注、不需注册、不需下载:


猜你喜欢

转载自wallimn.iteye.com/blog/2374931
今日推荐