原生JS、CSS实现的转盘效果(目前仅支持webkit)

       这是一个原生JS、CSS实现的转盘效果(题目在这:http://www.cnblogs.com/arfeizhang/p/turntable.html),花了半个小时左右,准备睡觉,所以先贴一段代码,预计会抽空优化,让它在手机上也能运行;另外,如果看代码的时候有什么问题,请留言。。。

 1 <!DOCTYPE html>
 2 <html>
 3 
 4 <head>
 5     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 6     <title>转盘</title>
 7     <style>
 8     .holder {
 9          550px;
10         display: block;
11         margin: 10px auto;
12         padding: 20px;
13         border: 3px solid black;
14         border-radius: 10px;
15         position: relative;
16     }
17     .rotate-pointer {
18         display: block;
19         position: absolute;
20          521px;
21         line-height: 10px;
22         top: 270.5px;
23         left: 37px;
24         -webkit-transition:all 4s ease-in-out;
25     }
26     #rules {
27          260.5px;
28         height: 10px;
29         display: inline-block;
30         background-color: black;
31     }
32     </style>
33 </head>
34 
35 <body>
36     <div class="holder">
37         <img src="//images0.cnblogs.com/i/636015/201406/151737329993303.jpg" alt="">
38         <div id="pointer" class="rotate-pointer">
39             <div id="rules"></div>
40         </div>
41     </div>
42     <script type="text/javascript">
43     window.onload = function() {
44         var table = document.getElementsByClassName('holder')[0],
45             tablePointer = document.getElementById('pointer'),
46             getRandom = function(min, max) {
47                 max = max || 1000;
48                 min = min || 0;
49                 return Math.floor(Math.random() * (max - min) + min);
50             },
51             degree = 0,
52             min_circle_times = 2,
53             max_circle_times = 6,
54             translate = function() {
55                 degree += getRandom(min_circle_times * 360, max_circle_times * 360);
56 
57                 requestAnimationFrame(function() {
58                     tablePointer.style.webkitTransform = 'rotate(' + degree + 'deg)';
59                 });
60             };
61         table.onclick = translate;
62 
63     };
64     </script>
65 </body>
66 
67 </html>
View Code

   


  昨天放出上述内容后,收到题目博主的评论,发现好像有些地方不符合需求,恩,又再试了一个版本,这个版本目前是支持手机的,不过还是只能在webkit内核下使用哦,源码如下:

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>转盘</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <style>
    body {
        margin:0px;
    }
    .holder {
        text-align: center;
        overflow: hidden;
        display: block;
        margin: 10px auto;
        border: 3px solid black;
        border-radius: 10px;
        position: relative;
    }
    #table {
        cursor: pointer;
        display: inline-block;
        max-width: 521px;
        width: 100%;
        -webkit-transition:all 4s ease-in-out;
    }
    </style>
</head>

<body>
    <div class="holder">
        <img id="table" src="//images0.cnblogs.com/i/631009/201406/181334125825974.png" alt="">
    </div>
    <script type="text/javascript">
    window.onload = function() {
        var degreeCount = 0,
            table = document.getElementById('table'),
            table_rect = table.getBoundingClientRect(),
            circle_center = {
                x: table_rect.width / 2 + table_rect.left,
                y: table_rect.height / 2 + table_rect.top
            },
            min_circle_times = 2,
            max_circle_times = 6,
            getRandom = function(min, max) {
                max = max || 1000;
                min = min || 0;
                return Math.floor(Math.random() * (max - min) + min);
            },

            // 根据两点求角度
            getDegreeByPoint = function(start, enb) {
                var tan1 = (start.y - circle_center.y) / (start.x - circle_center.x),
                    degree1 = Math.round(360 * Math.atan(tan1) / Math.PI),
                    tan2 = (enb.y - circle_center.y) / (enb.x - circle_center.x),
                    degree2 = Math.round(360 * Math.atan(tan2) / Math.PI);
                return -(degree1 - degree2);
            },
            rotate_rings = 0,
            rotate = function(degree) {
                degree = degree - 0;
                if (Number.isNaN(degree)) {
                    degree = degreeCount += getRandom(min_circle_times * 360, max_circle_times * 360);
                } else {
                    degree += degreeCount;
                }
                requestAnimationFrame(function() {
                    table.style.webkitTransform = 'rotate(' + degree + 'deg)';
                });
            };

        // 事件监听器
        var InputListener = function(tableId) {
            this.tableId = tableId;
            this.events = {};

            if (window.navigator.msPointerEnabled) {
                //Internet Explorer 10 style
                this.eventTouchstart = "MSPointerDown";
                this.eventTouchmove = "MSPointerMove";
                this.eventTouchend = "MSPointerUp";
            } else {
                this.eventTouchstart = "touchstart";
                this.eventTouchmove = "touchmove";
                this.eventTouchend = "touchend";
            }

            this._beginListen();
        };
        InputListener.prototype = {
            on: function(event, callback) {
                if (!this.events[event]) {
                    this.events[event] = [];
                }
                this.events[event].push(callback);
            },
            emit: function(event, data) {
                var callbacks = this.events[event];
                if (callbacks) {
                    callbacks.forEach(function(callback) {
                        callback(data);
                    });
                }
            },
            _start: function(event) {
                this.emit("start", event);
            },
            _rotate: function(event) {
                this.emit("rotate", event);
            },
            _stop: function(event) {
                this.emit("stop", event);
            },
            _celebrate: function(event) {
                this.emit("celebrate", event);
            },
            _click: function(event) {
                this.emit("click", event);
            },
            _getPointByEvent: function(event, toucherName) {
                toucherName = toucherName || 'touches';
                var point = null;
                if (window.navigator.msPointerEnabled) {
                    point = {
                        x: event.pageX,
                        y: event.pageY,
                        time: Date.now()
                    };
                } else {
                    point = {
                        x: event[toucherName][0].clientX,
                        y: event[toucherName][0].clientY,
                        time: Date.now()
                    };
                }
                return point;
            },
            _beginListen: function() {
                var self = this,
                    table = document.getElementById(this.tableId),
                    startPoint = null,
                    movePath = [];

                // Respond to direction keys
                table.addEventListener('click', function(event) {
                    self._click();
                });

                table.addEventListener(this.eventTouchstart, function(event) {
                    if ((!window.navigator.msPointerEnabled && event.touches.length > 1) ||
                        event.targetTouches > 1) {
                        return; // Ignore if touching with more than 1 finger
                    }
                    startPoint = self._getPointByEvent(event);

                    movePath = [startPoint];
                    self._start({
                        start: startPoint
                    });

                    event.preventDefault();
                });

                table.addEventListener(this.eventTouchmove, function(event) {
                    var endpoint = self._getPointByEvent(event);
                    if ( !! endpoint) {
                        movePath.push(endpoint);
                        self._rotate({
                            degree: getDegreeByPoint(startPoint, endpoint),
                            start: startPoint,
                            end: endpoint
                        });
                    }
                    event.preventDefault();
                });

                table.addEventListener(this.eventTouchend, function(event) {
                    if ((!window.navigator.msPointerEnabled && event.touches.length > 0) ||
                        event.targetTouches > 0) {
                        return; // Ignore if still touching with one or more fingers
                    }
                    var endpoint = self._getPointByEvent(event, 'changedTouches'),
                        countToCal = 3,
                        len = movePath.length;

                    self._stop({
                        degree: getDegreeByPoint(startPoint, endpoint),
                        start: startPoint,
                        end: endpoint
                    });
                    movePath.push(endpoint);
                    if (len <= 3) {
                        self._click({
                            start: startPoint
                        });
                    } else {
                        var p1 = movePath[len - 1],
                            p2 = movePath[len - 1 - 3],
                            // 转动的弧度
                            degree = getDegreeByPoint(p2, p1),
                            time = p1.time - p2.time,
                            speed = degree / time * 1000,
                            // 速度转换为期望的周数,4指的是CSS动画时间
                            expectDegree = (speed * 4) + min_circle_times;
                        self._celebrate({
                            start: p2,
                            end: p1,
                            degree: expectDegree
                        });
                    }
                    event.preventDefault();
                });
            }
        };

        var listener = new InputListener('table');
        listener.on('start', function(e) {
            table.style.webkitTransition = 'all 0s';
        });

        listener.on('rotate', function(e) {
            console.log(e.degree);
            rotate(e.degree);
        });

        listener.on('stop', function(e) {
            degreeCount += e.degree;
            //degreeCount = degreeCount % 360;
            table.style.webkitTransition = 'all 4s ease-in-out';
        });

        listener.on('celebrate', function(e) {
            rotate(e.degree);
        });

        listener.on('click', rotate);
    };
    </script>
</body>

</html>

一个可以在线运行的地址:http://www.w3cfuns.com/home.php?mod=space&uid=5446932&do=blog&quickforward=1&id=5398670

 

原文地址:https://www.cnblogs.com/vans/p/3792592.html