iOS抽奖大转盘的二种实现方法,js跟手转动的罗盘指针

顺手扶拖拉机拽,转盘旋转,都不是难事,然则跟手转动一个转盘或许转盘上的指针,确是个值得沉思的难点查看效果(请用手提式有线电话机张开,或许用chrome的无绳电话机情势张开)

有个对象必要写个抽取奖品大转盘的功效,就让小编援救写了下。我用了2种艺术实现了职能,在那边和豪门一齐分享下。

一、
跟手扶拖拉机拽的做法是:touchstart的时候记录下本来地点,touchmove的时候得到岗位的变迁,动态更新地方就足以了二、转盘转动的做法是:设定圆心为转动原点,动态的改变旋转角度三、
以往大家须要在手发生位移的时候,映射到角度依旧弧度的变型,此时经过x轴方向和y轴方向的离开变化来映射将会是一片困顿,是时候表明您的想象力了,请拿起你的纸和笔。这里就不卖关子了,直接上海教室:

一、一键转动大转盘
本人一初阶获得手的是一堆的图样,然后本身花了点时间,搭建出美术专门的学问须要的UI,接下去就开端分析哪些让它转动了。如下图:

图片 1wheel.png

demo1没转此前

只顾到图片影青的点是圆心,青莲的点是touchstart时候记录下的初叶点,浅青的点是touchmove的进程中连连变动的靶子点。大家的对象很刚烈,总括指针变化的角度,用本身唯有的初级中学数学知识思索得知,知道三角形的每一个终端,是足以求出每一个顶角的角度。运用三角形的余弦定理,求弧度值:

demo1转动之后

 //获得point2顶角的弧度值 //point1传入起始点,point2传入圆心,point3传入结束点,可求得指针运动的夹角弧度 function getAngle(point1, point2, point3) { var bb = (point2.y - point1.y)*(point2.y - point1.y) + (point2.x - point1.x)*(point2.x - point1.x); var aa = (point3.y - point1.y)*(point3.y - point1.y) + (point3.x - point1.x)*(point3.x - point1.x); var cc = (point3.y - point2.y)*(point3.y - point2.y) + (point3.x - point2.x)*(point3.x - point2.x); var cosa = (bb + cc - aa)/(2*Math.sqrt*Math.sqrt; return Math.acos; }

率先,咱们先到做旋转的动画,鲜明是用到系统自带的CABasicAnimation框架下边包车型大巴点子,确实用那几个做特别的有益,只需求我们设置相关属性就足以化解的。
能够看来上海教室中,全部的褒奖是把大圆给八等分了,而中奖的指针是平昔停留在正上边不改变的,大家所改动的是转盘和相应的嘉勉的地方。
那思路接下去是比较相对清晰了,我们只须求把角度也八等分,让指针指向每三个记功区域的宗旨就能够。要是让转盘顺时针旋转,那么首先个“500”对应的是0°要么360°,右边“一束鲜花”对应的则是45°,就那样推算。大家事先能够把奖赏按那样的依次放到数组中,0°对应的是数组中第一个的奖励,45°对应的是第三个的奖赏……好了,思路有了,就足以一向写代码,边写边调节了,上边作者附上点击“Go”之后的动画片效果代码

四、 刚才只思量了顺时针的事态,并从未设想逆时针的大方向

-(void)startAnimaition
{
    NSInteger turnAngle;//8个奖励分别对应的角度
    NSInteger randomNum = arc4random()%100;//控制概率
    NSInteger turnsNum = arc4random()%5+1;//控制圈数

    if (randomNum>=0 && randomNum<20) {//80%的概率 就是0-80

        if (randomNum < 10) {
            turnAngle = 0;
        }else{
            turnAngle = 135;
        }
        self.labelText = self.turntable.numberArray[0];
        NSLog(@"抽中了500");

    } else if (randomNum>=20 && randomNum<40) {

        if (randomNum < 35) {
            turnAngle = 45;
        }else{
            turnAngle = 225;
        }
        self.labelText = self.turntable.numberArray[3];
        NSLog(@"抽中了鲜花");

    } else if (randomNum >=40 && randomNum<60) {

        turnAngle = 315;
        self.labelText = self.turntable.numberArray[1];
        NSLog(@"抽中了2000");

    } else if(randomNum >=60 && randomNum<80){

        if (randomNum < 75) {
            turnAngle = 90;
        }else{
            turnAngle = 270;
        }
        self.labelText = self.turntable.numberArray[2];
        NSLog(@"抽中了5000");

    }else{

        turnAngle = 180;
        self.labelText = self.turntable.numberArray[4];
        NSLog(@"抽中了20000");
    }

    CGFloat perAngle = M_PI/180.0;

    CABasicAnimation* rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimation.toValue = [NSNumber numberWithFloat:turnAngle * perAngle + 360 * perAngle * turnsNum];
    rotationAnimation.duration = 3.0f;
    rotationAnimation.cumulative = YES;
    rotationAnimation.delegate = self;
    //由快变慢
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    rotationAnimation.fillMode=kCAFillModeForwards;
    rotationAnimation.removedOnCompletion = NO;
    [self.turntable.rotateWheel.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];

    // 转盘结束后调用,显示获得的对应奖励
    self.label.text = [NSString stringWithFormat:@"恭喜您抽中%@",self.labelText];

}

图片 2wheel2.png

1.预先算好8个区域,区域基本种种对应的角度(比如,“500”对应的是0°和135°;“3000”对应了135°)
2.用随机数 NSInteger randomNum = arc4random()%100;
来调控转动事件的可能率,借使您想让“一束鲜花”的概率有三成,那么你可以给它设置随机数20-40都停留在鲜花的区域(当然也能够是30-50的数字啦)
3.因为鲜花有2个区域,为了都能够有机会停留,那么久20-30的时候,停留在率先块鲜花的区域;30-40的时候,停留在第二块鲜花的区域
4.您能够用一个狂妄数调控转动的圈数 NSInteger turnsNum
,也能够定死多少圈
5.接下来间接上旋转动画的代码,这里要求注意的是,我们在思量问题还是看得时候,都以用角度来算的。而实际动画中的属性,是用弧度来算的。
1弧度=180/π度;1度=π/180弧度,自个儿能够换算下。

这种场合包车型客车弧度值为-getAngle(point1, point2,
point3),那并轻便理解,难点在于怎么样判断终究是逆时针依然顺时针,能够由此如下的面积量的措施来决断顺时针依然逆时针

二、手动旋转大转盘

 //通过面积量的方法来判断顺时针还是逆时针 //point1传入圆心,point2传入起始点,point3传入终点 function duration(point1, point2, point3) { var sp = (point1.x-point3.x)*(point2.y-point3.y)-(point1.y-point3.y)*(point2.x-point3.x); console.log; if {//顺时针 return 1 } else if {//逆时针 return -1 } else { return 0; } }

手指滑动旋转荧屏

完整的程序代码

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>跟手转动罗盘指针</title> <meta name="viewport" content="width=device-width,initial-scale=0.5,minimum-scale=1.0,user-scalable=0"> <style type="text/css"> + { padding: 0; margin: 0; } html, body, .container { width: 100%; height: 100%; background-color: rgb(5, 15, 77); position: relative; } .circle { width: 320px; height: 262px; position: absolute; top: 50%; margin-top: -131px; background-image: url(img/circle.png); background-size: 100% 100%; } .line { width: 72px; height: 138px; background-image: url(img/line.png); background-size: 100% 100%; top: 0; left: 123px; position: absolute; transform: rotate; transform-origin: 36px 138px; -webkit-transform: rotate; -webkit-transform-origin: 36px 138px; } </style> </head> <body> <script type="text/javascript"> var clientWidth = document.documentElement.clientWidth, viewport = null, viewportWidth = 'device-width', viewportScale = 1; if (clientWidth > 320) { viewport = document.querySelector('meta[name="viewport"]'); viewportScale = clientWidth / 320; viewportWidth = 320; viewport.setAttribute('content', 'width=' + viewportWidth + ', initial-scale=' + viewportScale + ', maximum-scale=' + viewportScale + ', user-scalable=0'); } </script> <div > <div > <div id='line'></div> </div> </div> <script type="text/javascript" src="js/zepto.js"></script> <script type="text/javascript"> //获得point2顶角的弧度值 function getAngle(point1, point2, point3) { var bb = (point2.y - point1.y) * (point2.y - point1.y) + (point2.x - point1.x) * (point2.x - point1.x); var aa = (point3.y - point1.y) * (point3.y - point1.y) + (point3.x - point1.x) * (point3.x - point1.x); var cc = (point3.y - point2.y) * (point3.y - point2.y) + (point3.x - point2.x) * (point3.x - point2.x); var cosa = (bb + cc - aa) / (2 * Math.sqrt * Math.sqrt; return Math.acos; } //通过面积量的方法来判断顺时针还是逆时针 //point1传入圆心,point2传入起始点,point3传入终点 function duration(point1, point2, point3) { var sp = (point1.x-point3.x)*(point2.y-point3.y)-(point1.y-point3.y)*(point2.x-point3.x); console.log; if { return 1 } else if { return -1 } else { return 0; } } var line = document.getElementById; var oX = 0; var oY = 0; //全局记录 var rolate = 0; //圆心 var pointCenter = { x: 159, y: 187 } //初始移动点 var pointO = false; var ro = 0; //在手机浏览器中打开页面拖动的时候页面会漏底 //禁掉默认事件,不然影响咱们的更手转动 $.on('touchstart', function { e.preventDefault.on('touchmove', function { e.preventDefault; line.addEventListener('touchstart', function { var touche = e.touches[0]; oX = touche.clientX; oY = touche.clientY; pointO = { x: oX, y: oY } }); line.addEventListener('touchmove', function { var mx = e.touches[0].clientX; var my = e.touches[0].clientY; ro = getAngle(pointO, pointCenter, { x: mx, y: my }); ro = ro * duration(pointCenter, pointO, { x: mx, y: my }); ro = rolate + ro; $.css({ '-webkit-transform': 'rotate(' + ro + 'rad)', 'transform': 'rotate(' + ro + 'rad)' }); }); line.addEventListener('touchend', function() { rolate = ro; }); </script> </body> </html>

那类效果,代码无需多多,但是找到个中的规律再转车为机械认知的言语绝非易事,难就难在那几个数学建模的历程,供给一些想象力,能够赋予的阅历便是,拿起你的笔和纸,去画,灵感自来。源码在这里招待一同调换

那几个动画,是捕捉到手指在显示屏上的早先点和注重,然后总结让转盘跟着转动。主要措施如下:

发表评论

电子邮件地址不会被公开。 必填项已用*标注