大公司移动前端开发面试题——做转盘[参考代码]

题目在此

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(‘http://images.cnitblog.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  ,谢谢!

大公司移动前端开发面试题——做转盘[参考代码]

时间: 2024-12-13 16:17:37

大公司移动前端开发面试题——做转盘[参考代码]的相关文章

大公司移动前端开发面试题——做转盘

"如果有个做转盘的需求,你准备怎么做?设计师只会提供一个转盘的图片,其余都需要你完成,不能用框架和类库." "这个转盘没有惯性的需求,只要求在手机上,用手指拖转盘,能让转盘跟随手指转起来即可." 这是我在面试前端开发人员时,经常会问到的一道题.转盘是类似上图的样子. 博主之前在M公司和C公司的时候,经常用这题面试移动前端开发工程师.M公司的产品和设计是美国团队,在个别项目上UI设计比较大胆脱俗,对前端开发人员有较高的要求.C公司的只会JS的前端开发人员占比较大,产品

各大公司 Java 后端开发面试题总结

ThreadLocal(线程变量副本) Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量. 采用空间换时间,它用于线程间的数据隔离,为每一个使用该变量的线程提供一个副本,每个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突. ThreadLocal类中维护一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值为对应线程的变量副本. ThreadLocal在Spring中发挥着巨大的作用,在管理Request作用域中的Bean.事

面试题:各大公司Java后端开发面试题总结 !=!未看

ThreadLocal(线程变量副本) Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量. 采用空间换时间,它用于线程间的数据隔离,为每一个使用该变量的线程提供一个副本,每个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突. ThreadLocal类中维护一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值为对应线程的变量副本. ThreadLocal在Spring中发挥着巨大的作用,在管理Request作用域中的Bean.事

前端开发面试题收集 JS

前端开发面试题收集-JS篇 收集经典的前端开发面试题 setTimeout的时间定义为0有什么用? javascript引擎是单线程处理任务的,它把任务放在队列中,不会同步执行,必须在完成一个任务后才开始另一个任务. 由于setTimeout可以把任务从某个队列中跳出成为新队列,因此能够得到期望的结果. 怎么理解this this指向的总是调用函数的那个对象. this一般情况下,是全局对象Global. 什么是闭包 闭包是一个概念,我的理解是函数里的函数,能够读取函数内部变量的函数. 就是将函

20K前端开发面试题:关于如何回答ajax跨域问题

在接触前端开发起,跨域这个词就一直以很高的频率在我们学习工作中重复出现,最近在工作中遇到了跨域的相关问题,这里我把它总结记录一下. 关于跨域,有N种类型,现在我只专注于ajax请求跨域(ajax跨域只是属于浏览器"同源策略"中的一部分,其它的这里不做介绍),内容大概如下:什么是ajax跨域?如何解决ajax跨域?如何分析ajax跨域? 一.什么是Ajax跨域 Ajax跨域的原理 ajax出现请求跨域错误问题,主要原因就是因为浏览器的"同源策略". CORS请求原理

前端开发面试题收集(css部分)

http://davidshariff.com/quiz/ 做了下这里面前端开发面试的题,发现有些不会,所以在此做个整理以供自己学习,参考,总结. 1.问: CSS属性是否区分大小写? ul { MaRGin: 10px; } 答:不区分.(HTML, CSS都不区分,但为了更好的可读性和团队协作,一般都小写,而在XHTML 中元素名称和属性是必须小写的.) 2.问:对行内元素设置margin-top 和margin-bottom是否起作用 答:不起作用.(需要注意行内元素的替换元素img.in

入我新美大的Java后台开发面试题总结

静儿最近在总结一些面试题,那是因为做什么事情都要认真.面试也一样,静儿作为新美大金融部门的面试官,负责任的告诉大家,下面的问题回答不上来,面试是过不了的.不过以下绝不是原题,你会发现自己实力不过硬,最终肯定是被问出来的. 1>如何定位线上服务OOM问题 2>JVM的GC ROOTS存在于那些地方 3>mysql innodb怎样做查询优化 4>java cas的概念 下面静儿就以自己面试的标准简单回答一下这些题怎样回答算过关. 1>如何定位线上服务OOM问题 因为面试主要是看

(转)Web前端开发面试题集锦(附答案)

1, 判断字符串是否是这样组成的,第一个必须是字母,后面可以是字母.数字.下划线,总长度为5-20 var reg = /^[a-zA-Z][a-zA-Z_0-9]{4,19}$/; reg.test(“a1a__a1a__a1a__a1a__”); 2,截取字符串abcdefg的efg var str = “abcdefg”; if (/efg/.test(str)) { var efg = str.substr(str.indexOf(“efg”), 3); alert(efg); } 3,

淘宝网前端开发面试题(一)--HTML &amp; CSS 面试题

转载请注明文章来源http://www.cnblogs.com/muqiangwei/p/5569783.html 1.DOCTYPE? 严格模式不混杂模式-如何触发这两种模式,区分它们有何意义? 分析: DOCTYPE(是DOCument TYPE的缩写,即文档类型)是一组机器可读的规则,它们指示(X)HTML文档中允许有什么,不允许有什么.DOCTYPE正是用来告诉浏览器使用哪种DTD,一般放在(X)HTML文档开头表示声明,用以告诉别人这个文档的类型风格. 触发:根据不同的DTD触发,如果