`

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,猛戳下载全部程序。

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


  • 大小: 27.9 KB
  • 大小: 8.3 KB
1
1
分享到:
评论

相关推荐

    snap.svg 中文参考手册 离线php版

    Snap.svg 是一个强大的JavaScript库,专门用于在Web上创建SVG(可缩放矢量图形)动画和交互。这个中文参考手册是为那些希望在PHP环境中使用Snap.svg的开发者准备的,即使你对PHP不感兴趣,也可以通过提供的链接访问...

    前端项目-snap.svg.zpd.zip

    Snap.svg 是一个强大的JavaScript库,专门用于在Web上创建、操作和动画SVG(Scalable Vector Graphics)元素。这个“前端项目-snap.svg.zpd.zip”包含了一个使用Snap.svg库实现的缩放、平移和拖动功能的插件。在深入...

    snap.svg.zip

    Snap.SVG 是一个强大的JavaScript库,专为在Web上创建SVG(可缩放矢量图形)动画和交互式设计而设计。这个库以其简洁的API和广泛的文档支持,深受前端开发者的喜爱。"snap.svg.zip" 文件包含了 Snap.SVG 库的两个...

    snap.svg.zpd:Snap.svg的zoompandragrotate插件(仅用于查看)

    Snap.svg的缩放/平移/拖动插件 这是对Andrea Leofreddi的(版本1.2.2)的改编,用作插件。...在snap.svg.zpd.js之后包含snap.svg.js &lt; script src =" snap.svg.js " &gt; &lt;/ script &gt; &lt; scri

    snap-svg js库

    Snap.svg 是一个强大的JavaScript库,专门用于在Web页面上创建、操作和动画化SVG(Scalable Vector Graphics)元素。SVG是一种矢量图形格式,它允许网页内容在不同分辨率和尺寸的设备上清晰显示,而不会失真。Snap....

    开发工具 fontawesome-webfont.svg

    开发工具 fontawesome-webfont.svg开发工具 fontawesome-webfont.svg开发工具 fontawesome-webfont.svg开发工具 fontawesome-webfont.svg开发工具 fontawesome-webfont.svg开发工具 fontawesome-webfont.svg开发工具...

    svg加snap.svg.js能做出饼状图,柱状图,折线图,svg事件和js事件的结合,svg坐标

    Snap.svg.js是一个强大的JavaScript库,专为SVG设计,使得用JavaScript操作SVG元素变得更加简单。 首先,SVG的优势在于它的矢量特性,这意味着无论放大多少倍,图像都不会失真,这对于需要高质量图形的项目尤其重要...

    Snap.svg-0.5.1.zip

    Snap.svg-0.5.1.zip 操作svg的js框架,Snap.svg-0.5.1.zip 操作svg的js框架,Snap.svg-0.5.1.zip 操作svg的js框架,Snap.svg-0.5.1.zip 操作svg的js框架

    基于Html5 svg+snap.svg实现带日期的天气预报特效源码.zip

    Snap.svg是基于SVG的JavaScript库,它简化了在浏览器中创建、操作和动画SVG元素的过程。这个库提供了丰富的API,包括选择、创建、操作和动画化SVG图形。在天气预报特效中,Snap.svg可能被用来创建天气图标、动态效果...

    Snabric.js:使用 Snap.svg 将 SVG 操作添加到 Fabric.js

    Snabric.js 使用 Snap.svg 将 SVG 操作添加到 Fabric.js 织物画布将 SVG 作为图像对象导入,因此失去了专用 SVG 库(如 Snap.svg)的操作级别。 Snap 提供了更详细的 SVG 界面,但缺少任何画布控件。 这个包引入了一...

    svg:受 raphaeljs、svgjs 和 snap.svg 启发的小型简单 SVG Javascript 库

    介绍一个简单的 SVG javascript 库建造安装依赖npm install 该库使用 gulp 来运行所有任务: 要构建运行gulp 。 文件将输出到 dist 文件夹。教程不。 可能也不会发生。去做对动画方法进行更广泛的测试创建更好的界面...

    Snap.svg-playground:我用 Snap.svg 制作的一些东西

    Snap.svg 是一个强大的 JavaScript 库,专为在 Web 上创建和操作 SVG(可缩放矢量图形)而设计。SVG 是一种矢量图形格式,它允许网页内容在不同分辨率和尺寸的设备上清晰显示,而不会失真。Snap.svg-playground 是一...

    jQuery插件Snap.svg.zip

    Snap.svg 是一款显示现代 SVG 图像的 Javascript 库。SVG 是一款能创建完美显示在各种尺寸的屏幕上的交互式,各种分辨率的向量图像。 标签:Snapsvg

    snappy-diagrams:使用 Snap.SVG 的箭头框图构建器

    script src =" /vendor/snap.svg.js " &gt; &lt;/ script &gt;&lt; script src =" /dist/snappy-diagram.js " &gt; &lt;/ script &gt;&lt; link href =" /dist/snappy-diagram.css " media =" all " rel =" ...

    前端项目-svg.pan-zoom.js.zip

    `svg.pan-zoom.js` 是一个专门针对SVG图形的JavaScript库,它的主要功能是实现SVG对象的平移和缩放操作,从而增强用户交互体验。 这个库的使用非常简单,开发者可以轻松地将其集成到自己的项目中。首先,你需要将`...

    一个实验性滑块,使用SVG剪切路径功能和Snap.svg驱动的动画-JavaScript开发

    Elastic Slider一种实验性滑块,它使用SVG剪切路径功能和Snap.svg驱动的动画。 演示文章的用法首先,您需要包括弹性滑块样式和脚本,以及外部Snap.svg弹性滑块。一个实验性滑块,它使用SVG剪切路径功能以及由Snap....

    cd-top-arrow.svg

    返回页面顶部符号。cd-top-arrow.svg

    clocks:一些使用snap.svg构建的时钟

    6. **动画与时间函数**:学习Snap.svg的动画方法,如`.animate()`,并理解时间函数(如linear, ease-in, ease-out)对动画速度的影响。 7. **事件监听**:掌握如何添加事件监听器,例如当用户点击时钟时,显示或...

    svg.min.js+svg.filter.min.js 好用2021新版

    官方地址 https://svgjs.dev/docs/3.1/ 资源版本: @svgdotjs/svg.js v3.1.1 MIT BUILT: Fri Jun 25 2021 15:37:54 GMT+0200 @svgdotjs/svg.filter.js BUILT: Mon Oct 18 2021 15:55:55 GMT+0200

Global site tag (gtag.js) - Google Analytics