Recently, my son's school taught time cognition, and he made such a small software. The function is very simple: use it on the mobile phone, press and hold the button pointer with your finger to drag the pointer to change the time, click the button below to display the time, and verify whether the children's time cognition is correct.
The interface is as shown below:
Related technologies used: snap.svg.js, hammer.js, jQuery.js. It has certain reference significance for svg drawing, svg animation, and touch screen event processing.
The code is not carefully scrutinized and packaged, just play around.
All codes are as follows:
<%@ 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> <!-- Author: wallimn, http://wallimn.iteye.com Time: January 7, 2017 Function: snap.svg.js learning - time cognition --> <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>Time Cognition-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(){ // Prevent the menu from appearing by long-pressing the webpage 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;//Length of hour hand var minLen = Math.round(radius*0.8),minDeta=12;//Length of minute hand var numLen = Math.round(radius*0.86);//Number radius 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 to rotate the needle 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("Initial Angle: ",oldang,", Final Angle: ",resultAng); //The angle specified in the Snap.Matrix().rotate() function is the angle of the final result. //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}); } // initial state setting 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, the); 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, the); rotateHand(minHand,hourAng); } }); // output prompt text var tipText = paper.text(centerX,centerY*2-8,"Hold down the needle and drag to move the needle").attr({'text-anchor':'middle','dominant-baseline':'middle', fill:'red','font-size':12}); //Draw the button and set the event var textdeta=40;//The distance between the text center and the bottom var whenText = paper.text(centerX,centerY*2-textdeta,"几点了?").attr({'text-anchor':'middle','dominant-baseline':'middle','font-size':24}); var bbox = whenText.getBBox (); var detail=5,detail=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); //After blocking the touchstart event, the click event is not easy to use. You can only use tap events. whenHanmmer.on("tap",function(){ var hourAng = hourHand.attr("data-angle"); hourAng = hourAng-270;//The angle that matches the pointer 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("Hour hand angle:",hourAng,",minute hand angle:",minAng,",time",hourNum+":"+minNum); alert("Time: "+hourNum+":"+minNum); }); }); </script> </body> </html>
Upload the code to github.com, visit the address: https://github.com/wallimn/snapcat , click to download all the programs.
For mobile phone experience, please use WeChat to scan the following QR code, no attention, no registration, and no download required: