zoukankan      html  css  js  c++  java
  • 大公司移动前端开发面试题——做转盘[参考代码]

    题目在此

    http://www.cnblogs.com/arfeizhang/p/turntable.html

    这几天一直在忙,终于找到时间把参考代码放出来了。大家参考一下。

    参考代码考虑到让入行不久的前端也看得懂,没有进行封装。变量名也没有进行简写,尽量一看就明白。

    图片随手在网上截的,也许没有对准圆心。这段代码只考虑了webkit内核的浏览器,没做兼容。重在让大家弄懂原理。 :P

    如果感到有些卡帧,可能是转盘图片带来的效果。在调试器上试过,能维持50-60帧,流畅度还是让人满意的。在LG G2和IPHONE 5上感觉很流畅,低配置手机上还没试过。

    建议在手机上转着试下(PC上可以使用调试工具来模拟触摸屏进行测试)。

    示例链接:http://codepen.io/arfeizhang/full/qdxEe/

    手机扫二维码访问:

    代码如下:

      1 <!DOCTYPE HTML>
      2 <html manifest="" lang="en-US">
      3 <head>
      4     <meta charset="UTF-8">
      5     <!-- 用户两指操作时,防止放大 -->
      6     <meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no,minimal-ui">
      7        <title>Turnable</title>
      8     <style>
      9     #centerCircle{
     10     border-radius: 125px;
     11     background: url('//images0.cnblogs.com/i/636015/201406/151737329993303.jpg') no-repeat; 
     12   background-size: 270px 260px;
     13   background-position:-10px -4px;
     14   width: 250px;
     15     height: 250px;
     16     position: absolute;
     17     top: 126px;
     18     left: 36px;
     19     color: white;
     20     z-index: 11;
     21     -webkit-transform: rotateZ(0deg);
     22     border: 1px solid #f60;
     23     }
     24     </style>
     25 </head>
     26 <body>
     27   <div id="centerCircle">
     28 
     29 </div>
     30 
     31 Rotate me on mobile device!
     32 <script type="text/javascript">
     33 //先把DOM存起来,以后就不用再重新请求了,节省资源。
     34 var eleCircle = document.querySelector("#centerCircle");
     35 //获取圆心。注意,这里读的是CSS样式表中定义的样式
     36 var centerX = GetCircleStyle("left") + GetCircleStyle("width") / 2;
     37 var centerY = GetCircleStyle("top") + GetCircleStyle("height") / 2;
     38 //触摸事件,有些人会用鼠标事件,但鼠标事件比触摸事件慢,大概是300毫秒。300毫秒的延迟的原因,是因为浏览器需要判断你是否需要双击缩放网页。在后期的chrome版本中,如果在META信息中规定网页满屏展示(如viewport的宽度小于或等于物理设备的宽度),并不允许放大,可以消除鼠标300毫秒的延时,这点我没验证过。
     39 eleCircle.addEventListener('touchstart', Start, false);
     40 eleCircle.addEventListener('touchmove', Move, false);
     41 eleCircle.addEventListener('touchend', End, false);
     42 
     43 var touchStartX = touchStartY = 0,
     44   touchMoveX = touchMoveY = 0;
     45 // 这里定义两个向量,用于计算角度和顺逆时针
     46 var vectorStart = {
     47   x: 0,
     48   y: 0
     49 }, vectorEnd = {
     50     x: 0,
     51     y: 0
     52   };
     53 
     54 function Start(e) {
     55   e.preventDefault();
     56   touchStartX = e.touches[0].pageX;
     57   touchStartY = e.touches[0].pageY;
     58   vectorStart.x = touchStartX - centerX;
     59   vectorStart.y = touchStartY - centerY;
     60 }
     61 var rotateDeg = 0;
     62 var startDeg = 0;
     63 
     64 function Move(e) {
     65   // 阻止浏览器默认行为。不然在滚动转盘时,会让整个页面滚动。
     66   e.preventDefault();
     67   touchMoveX = e.touches[0].pageX;
     68   touchMoveY = e.touches[0].pageY;
     69   vectorEnd.x = touchMoveX - centerX;
     70   vectorEnd.y = touchMoveY - centerY;
     71   //旋转角度=(开始向量和当前向量的夹角)*(是否是顺时针转)
     72   rotateDeg = (RadianToDeg(CalcDeg(vectorStart, vectorEnd))) * (((vectorStart.x * vectorEnd.y - vectorStart.y * vectorEnd.x) < 0) ? -1 : 1);
     73   //使用CSS3来进行旋转
     74   eleCircle.style.webkitTransform = "rotateZ(" + (startDeg + rotateDeg) + "deg)";
     75 }
     76 
     77 function End(e) {
     78   // 存入当前角度
     79   startDeg = startDeg + rotateDeg;
     80   rotateDeg = 0;
     81 }
     82 // 依据向量计算弧度
     83 function CalcDeg(vectorStart, vectorEnd) {
     84   var cosDeg = (vectorStart.x * vectorEnd.x + vectorStart.y * vectorEnd.y) / (Math.sqrt(Math.pow(vectorStart.x, 2) + Math.pow(vectorStart.y, 2)) * Math.sqrt(Math.pow(vectorEnd.x, 2) + Math.pow(vectorEnd.y, 2)));
     85   return Math.acos(cosDeg);
     86 }
     87 
     88 function GetCircleStyle(attr) {
     89   return GetNum(GetStyle(eleCircle, attr))
     90 }
     91 // 取得对象的最终CSS属性,这个最终是指浏览器自动计算的结果。
     92 function GetStyle(obj, prop) {
     93   if (obj.currentStyle) //IE
     94   {
     95     return obj.currentStyle[prop];
     96   } else if (window.getComputedStyle) //非IE
     97   {
     98     propprop = prop.replace(/([A-Z])/g, "-$1");
     99     propprop = prop.toLowerCase();
    100     return document.defaultView.getComputedStyle(obj, null)[propprop];
    101   }
    102   return null;
    103 }
    104 // 从CSS属性值(如10px)中取到数值(如10),以便计算
    105 function GetNum(str) {
    106   return parseInt(str.replace("px", ""));
    107 }
    108 // 弧度转换为角度。因为Math.acos得到的是弧度,但CSS3 rotate需要角度
    109 function RadianToDeg(radian) {
    110 
    111   return 180 / Math.PI * radian;
    112 }
    113 </script>
    114     
    115     </body>
    116     </html>

    本文是博主Arfei Zhang原创,欢迎转载。转载请注明转自博客园,并附上本文链接http://www.cnblogs.com/arfeizhang/p/turntable_demo.html  ,谢谢!

  • 相关阅读:
    计数器应用-数据清洗案例
    Map Join实战案例
    Reduce Join实战案例
    自定义OutputFormat代码实现
    Golang的序列化-RPC和GRPC
    jetty服务器的安装和部署、新增到开机启动服务
    myeclipse不编译解决方法
    MyEclipse从数据库反向生成实体类之Hibernate方式 反向工程
    MyEclipse自动生成hibernate实体类和配置文件攻略
    eclipse从数据库逆向生成Hibernate实体类
  • 原文地址:https://www.cnblogs.com/arfeizhang/p/turntable_demo.html
Copyright © 2011-2022 走看看