Javascript和tween.js实现钟表

最近在从新学习JS的一些基础的方法,发现了Tween.js写了一点东西,直接上代码。

时钟代码:

<!DOCTYPE html>
<html lang="en">

<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">
    <title>时钟</title>
    <script src="tween.js"></script>
    <script src="moveTw.js"></script>

    <style>
        ul {
            padding: 0;
            margin: 0;
            list-style: none;
        }
        
        #clock-wrap {
            width: 120px;
            height: 120px;
            border: 2px solid #fff;
            background: #eeeded;
            border-radius: 50%;
            box-shadow: 0 0 5px #000;
            padding: 10px;
            margin: 200px auto;
        }
        
        #clock {
            width: 110px;
            height: 110px;
            background: url(./imgs/圆盘.png) no-repeat center center;
            border: 5px solid #e15671;
            border-radius: 50%;
        }
        
        #box {
            position: relative;
        }
        
        .dot {
            width: 7px;
            height: 7px;
            border-radius: 3px;
            background: #fff;
            position: absolute;
            left: 52px;
            top: 52px;
        }
        
        .hour {
            width: 7px;
            height: 35px;
            background-color: #fff;
            border-radius: 3px;
            position: absolute;
            left: 52px;
            top: 21px;
            transform-origin: center 33px;
        }
        
        .min {
            width: 4px;
            height: 44px;
            background: #fff;
            border-radius: 3px;
            position: absolute;
            left: 53px;
            top: 15px;
            transform-origin: center 42px;
        }
        
        .sec {
            width: 40px;
            height: 40px;
            background: url(./imgs/指针1.png) no-repeat center center;
            position: absolute;
            left: 18px;
            top: 15px;
            transform-origin: 37px 39px;
            z-index: 999;
        }
        
        #lattice-list {
            position: relative;
        }
        
        .lattice {
            width: 2px;
            height: 6px;
            background: #fff;
            position: absolute;
            left: 55px;
            transform-origin: left 55px;
        }
    </style>
</head>

<body>
    <div id="clock-wrap">
        <div id="clock">
            <ul id="lattice-list"></ul>
            <div id="box">
                <div class="dot"></div>
                <div class="hour"></div>
                <div class="min"></div>
                <div class="sec"></div>
            </div>
        </div>
    </div>
    <script>
        var latticeList = document.querySelector('#lattice-list')
        var hourEle = document.querySelector('.hour')
        var minEle = document.querySelector('.min')
        var secEle = document.querySelector('.sec')

        var html = ''
        for (var i = 0; i < 12; i++) {
            html += '<li class="lattice" style="transform:rotate(' + i * 30 + 'deg)"></li>'
        }
        latticeList.innerHTML = html
        clock()

        function clock() {
            var date = new Date()
            var H = date.getHours()
            var M = date.getMinutes()
            var S = date.getSeconds()
            var Ms = date.getMilliseconds() //毫秒
            console.log(H, M, S, Ms);

            var Hdeg = H * 30 + M / 60 * 30 //不足一小时的度数
            var Mdeg = M * 6 + S / 60 * 6 //不足一分钟
            var Msdeg = S * 6 + 45 + Ms / 1000 * 6 //每一毫秒的度数


            // hourEle.style.transform = 'rotate(' + H * 30 + 'deg)' //只指向整小时
            // minEle.style.transform = 'rotate(' + M * 6 + 'deg)' //只指向整分
            // secEle.style.transform = 'rotate(' + (S * 6 + 45) + 'deg)'//每一秒走的度数
            hourEle.style.transform = 'rotate(' + Hdeg + 'deg)'
            minEle.style.transform = 'rotate(' + Mdeg + 'deg)'
            secEle.style.transform = 'rotate(' + Msdeg + 'deg)'
        }
        //定时器
        setInterval(clock, 30)
    </script>
</body>

</html>

封装函数:

 // css方法
 function css(el, attr, val) {
     if (arguments.length == 2) {
         return parseFloat(getComputedStyle(el)[attr])
     } else {
         el.style[attr] = val + 'px'
     }
 }

 //调用Tween 方法
 function moveFn(op) {
     if (!op.el) {
         alert('请传入运动元素')
         return;
     }
     if (!op.attrs) {
         alert('请传入运动属性')
         return;
     }
     var el = op.el
     var attrs = op.attrs
     var duration = op.duration || 1000
     var type = op.type || 'linear'


     var delay = 1000 / 60
     var t = 0
     var b = {}
     var c = {}
     for (var attr in attrs) {
         b[attr] = css(el, attr)
         c[attr] = attrs[attr] - b[attr]
     }

     var d = Math.ceil(duration / delay)
     var _this = this
     clearInterval(this.timer)
     this.timer = setInterval(function() {
         t++
         for (var item in b) {
             var value = Tween[type](t, b[item], c[item], d)
             console.log(value);
             css(el, item, value)
         }

         if (t == d) {
             clearInterval(_this.timer)
             op.cb && op.cb()
         }
     }, delay)
 }

Tween.js方法

let Tween = {
    linear: function(t, b, c, d) { //匀速
        return c * t / d + b;
    },
    easeIn: function(t, b, c, d) { //加速曲线
        return c * (t /= d) * t + b;
    },
    easeOut: function(t, b, c, d) { //减速曲线
        return -c * (t /= d) * (t - 2) + b;
    },
    easeBoth: function(t, b, c, d) { //加速减速曲线
        if ((t /= d / 2) < 1) {
            return c / 2 * t * t + b;
        }
        return -c / 2 * ((--t) * (t - 2) - 1) + b;
    },
    easeInStrong: function(t, b, c, d) { //加加速曲线
        return c * (t /= d) * t * t * t + b;
    },
    easeOutStrong: function(t, b, c, d) { //减减速曲线
        return -c * ((t = t / d - 1) * t * t * t - 1) + b;
    },
    easeBothStrong: function(t, b, c, d) { //加加速减减速曲线
        if ((t /= d / 2) < 1) {
            return c / 2 * t * t * t * t + b;
        }
        return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
    },
    elasticIn: function(t, b, c, d, a, p) { //正弦衰减曲线(弹动渐入)
        if (t === 0) {
            return b;
        }
        if ((t /= d) == 1) {
            return b + c;
        }
        if (!p) {
            p = d * 0.3;
        }
        if (!a || a < Math.abs(c)) {
            a = c;
            var s = p / 4;
        } else {
            var s = p / (2 * Math.PI) * Math.asin(c / a);
        }
        return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
    },
    elasticOut: function(t, b, c, d, a, p) { //正弦增强曲线(弹动渐出)
        if (t === 0) {
            return b;
        }
        if ((t /= d) == 1) {
            return b + c;
        }
        if (!p) {
            p = d * 0.3;
        }
        if (!a || a < Math.abs(c)) {
            a = c;
            var s = p / 4;
        } else {
            var s = p / (2 * Math.PI) * Math.asin(c / a);
        }
        return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
    },
    elasticBoth: function(t, b, c, d, a, p) {
        if (t === 0) {
            return b;
        }
        if ((t /= d / 2) == 2) {
            return b + c;
        }
        if (!p) {
            p = d * (0.3 * 1.5);
        }
        if (!a || a < Math.abs(c)) {
            a = c;
            var s = p / 4;
        } else {
            var s = p / (2 * Math.PI) * Math.asin(c / a);
        }
        if (t < 1) {
            return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) *
                Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
        }
        return a * Math.pow(2, -10 * (t -= 1)) *
            Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + c + b;
    },
    backIn: function(t, b, c, d, s) { //回退加速(回退渐入)
        if (typeof s == 'undefined') {
            s = 1.70158;
        }
        return c * (t /= d) * t * ((s + 1) * t - s) + b;
    },
    backOut: function(t, b, c, d, s) {
        if (typeof s == 'undefined') {
            s = 3.70158; //回缩的距离
        }
        return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
    },
    backBoth: function(t, b, c, d, s) {
        if (typeof s == 'undefined') {
            s = 1.70158;
        }
        if ((t /= d / 2) < 1) {
            return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
        }
        return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
    },
    bounceIn: function(t, b, c, d) { //弹球减振(弹球渐出)
        return c - Tween['bounceOut'](d - t, 0, c, d) + b;
    },
    bounceOut: function(t, b, c, d) {
        if ((t /= d) < (1 / 2.75)) {
            return c * (7.5625 * t * t) + b;
        } else if (t < (2 / 2.75)) {
            return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;
        } else if (t < (2.5 / 2.75)) {
            return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;
        }
        return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;
    },
    bounceBoth: function(t, b, c, d) {
        if (t < d / 2) {
            return Tween['bounceIn'](t * 2, 0, c, d) * 0.5 + b;
        }
        return Tween['bounceOut'](t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
    }
}

最后结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,three.jstween.js可以一起使用,实现复杂的动画效果,包括飞线动画。以下是一个简单的例子,演示了如何使用three.jstween.js创建一条飞线动画: ```javascript // 创建three.js场景 var scene = new THREE.Scene(); // 创建相机 var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // 创建渲染器 var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建飞线路径 var curve = new THREE.CatmullRomCurve3([ new THREE.Vector3(-10, 0, 0), new THREE.Vector3(-5, 5, 0), new THREE.Vector3(0, 0, 0), new THREE.Vector3(5, -5, 0), new THREE.Vector3(10, 0, 0) ]); // 创建飞线材质 var material = new THREE.LineBasicMaterial({ color: 0xffffff }); // 将飞线路径转换为几何体 var geometry = new THREE.Geometry(); geometry.vertices = curve.getPoints(50); // 创建飞线网格 var line = new THREE.Line(geometry, material); scene.add(line); // 创建飞线动画 var tween = new TWEEN.Tween({t:0}) .to({t:1}, 5000) // 5秒钟 .onUpdate(function() { // 根据tween的进度计算飞线的位置 var position = curve.getPoint(this.t); // 更新飞线网格的位置 line.position.copy(position); }) .start(); // 渲染场景 function render() { requestAnimationFrame(render); TWEEN.update(); // 更新tween动画 renderer.render(scene, camera); } render(); ``` 在这段代码中,我们首先创建了一个three.js场景、相机和渲染器。然后,我们创建了一个CatmullRomCurve3曲线,用于定义飞线路径,并将其转换为three.js几何体。接下来,我们创建了一个TWEEN.Tween对象,将其起始值设置为0,结束值设置为1,表示飞线动画的进度。在Tween对象的 onUpdate 回调函数中,我们根据飞线路径计算当前进度对应的位置,并将飞线网格的位置更新为该位置。最后,我们创建了一个渲染函数,用于在每帧更新Tween动画和渲染场景。 希望这个例子可以帮助你了解如何使用three.jstween.js创建飞线动画。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值