纯html+css+js高仿苹果手机时钟小组件

话不多数说,这是一款用html+css+js开发的高仿苹果手机时钟组件,
作者将苹果的小组件移植到浏览器插件中,可以在BdTab插件安装该组件

HTML

<div style="width: 100vw;height: 100vh;overflow: hidden;">
    <div class="fill">
        <div class="clock" id="utility-clock">
            <div class="centre">
                <div class="dynamic"></div>
                <div class="expand round circle-1"></div>
                <div class="anchor hour">
                    <div class="element thin-hand"></div>
                    <div class="element fat-hand"></div>
                </div>
                <div class="anchor minute">
                    <div class="element thin-hand"></div>
                    <div class="element fat-hand minute-hand"></div>
                </div>
                <div class="anchor second">
                    <div class="element second-hand"></div>
                </div>
                <div class="expand round circle-2"></div>
                <div class="expand round circle-3"></div>
            </div>
        </div>
    </div>
</div>

JS

var clock = document.querySelector('#utility-clock')
   utilityClock(clock)

   if (clock.parentNode.classList.contains('fill')) {
       autoResize(clock, 295 + 32)
   }

   function utilityClock (container) {
       var dynamic = container.querySelector('.dynamic')
       var hourElement = container.querySelector('.hour')
       var minuteElement = container.querySelector('.minute')
       var secondElement = container.querySelector('.second')
       var minute = function (n) {
           return 0 === n % 5 ? minuteText(n) : minuteLine(n)
       }
       var minuteText = function (n) {
           var anchor = document.createElement('div')
           anchor.className = 'anchor'
           var element = document.createElement('div')
           element.className = 'element minute-line-long'
           rotate(anchor, n)
           anchor.appendChild(element)
           dynamic.appendChild(anchor)
       }
       var minuteLine = function (n) {
           var anchor = document.createElement('div')
           anchor.className = 'anchor'
           var element = document.createElement('div')
           element.className = 'element minute-line'
           rotate(anchor, n)
           anchor.appendChild(element)
           dynamic.appendChild(anchor)
       }
       var hour = function (n) {
           var element = document.createElement('div')
           element.className = 'hour-text hour-' + n
           element.innerHTML = n
           position(element, n / 12, 105)
           dynamic.appendChild(element)
       }
       var position = function (element, phase, r) {
           var theta = phase * 2 * Math.PI
           element.style.top = (-r * Math.cos(theta)).toFixed(1) + 'px'
           element.style.left = (r * Math.sin(theta)).toFixed(1) + 'px'
       }
       var rotate = function (element, second) {
           element.style.transform = element.style.webkitTransform = 'rotate(' + (second * 6) + 'deg)'
       }
       var animate = function () {
           var now = new Date()
           var time = now.getHours() * 3600 + now.getMinutes() * 60 + now.getSeconds() + now.getMilliseconds() / 1000;
           rotate(secondElement, time);
           rotate(minuteElement, time / 60);
           rotate(hourElement, time / 60 / 12);
           requestAnimationFrame(animate);
       }
       for (var i = 1; i <= 60; i++) {
           minute(i);
       }
       for (var i = 1; i <= 12; i++) {
           hour(i);
       }
       animate();
   }

   function autoResize (element, nativeSize) {
       var update = function () {
           var scale = Math.min(window.innerWidth, window.innerHeight) / nativeSize
           element.style.transform = element.style.webkitTransform = 'scale(' + scale.toFixed(3) + ')'
       }
       update();
       window.addEventListener('resize', update)
   }

CSS

.fill {
        display: flex;
       justify-content: center;
       align-items: center;
       border-radius: 20px;
       width: 100%;
       height: 100%;
       background: black;
   }

   .clock {
       position: absolute;
       opacity: 1;
       background: #1C1C1D;
       width: 300px;
       height: 300px;
       border-radius: 50%;
       margin: 20px;
   }

   .centre {
       position: absolute;
       top: 50%;
       left: 50%;
       width: 0;
       height: 0;
   }

   .expand {
       position: absolute;
       top: 0;
       left: 0;
       -webkit-transform: translate(-50%, -50%);
       -ms-transform: translate(-50%, -50%);
       transform: translate(-50%, -50%);
   }

   .anchor {
       position: absolute;
       top: 0;
       left: 0;
       width: 0;
       height: 0;
   }

   .element {
       position: absolute;
       top: 0;
       left: 0;
   }

   .round {
       border-radius: 296px;
   }

   .circle-1 {
       background: white;
       width: 12px;
       height: 12px;
   }

   .circle-2 {
       background: #FA9F22;
       width: 8px;
       height: 8px;
   }

   .circle-3 {
       background: black;
       width: 4px;
       height: 4px;
   }

   .second {
       -webkit-transform: rotate(180deg);
       -ms-transform: rotate(180deg);
       transform: rotate(180deg);
   }

   .minute {
       -webkit-transform: rotate(54deg);
       -ms-transform: rotate(54deg);
       transform: rotate(54deg);
   }

   .second-hand {
       width: 2px;
       height: 164px;
       background: #FA9F22;
       -webkit-transform: translate(-50%, -100%) translateY(24px);
       -ms-transform: translate(-50%, -100%) translateY(24px);
       transform: translate(-50%, -100%) translateY(24px);
   }

   .hour {
       -webkit-transform: rotate(304.5deg);
       -ms-transform: rotate(304.5deg);
       transform: rotate(304.5deg);
   }

   .thin-hand {
       width: 4px;
       height: 50px;
       background: white;
       -webkit-transform: translate(-50%, -100%);
       -ms-transform: translate(-50%, -100%);
       transform: translate(-50%, -100%);
   }

   .fat-hand {
       width: 10px;
       height: 57px;
       border-radius: 10px;
       background: white;
       -webkit-transform: translate(-50%, -100%) translateY(-18px);
       -ms-transform: translate(-50%, -100%) translateY(-18px);
       transform: translate(-50%, -100%) translateY(-18px);
   }

   .minute-hand {
       height: 112px;
   }

   .hour-text {
       position: absolute;
       font: 40px Hei, Helvetica, Arial, sans-serif;
       color: white;
       -webkit-transform: translate(-50%, -50%);
       -ms-transform: translate(-50%, -50%);
       transform: translate(-50%, -50%);
   }

   .hour-10 {
       padding-left: 0.4ex;
   }

   .hour-11 {
       padding-left: 0.25ex;
   }

   .minute-text {
       position: absolute;
       font: 12px Avenir Next, Helvetica, Arial, sans-serif;
       color: white;
       -webkit-transform: translate(-50%, -50%);
       -ms-transform: translate(-50%, -50%);
       transform: translate(-50%, -50%);
   }

   .minute-line {
       background: white;
       width: 1px;
       height: 9px;
       -webkit-transform: translate(-50%, -100%) translateY(-131px);
       -ms-transform: translate(-50%, -100%) translateY(-131px);
       transform: translate(-50%, -100%) translateY(-131px);
       opacity: 0.34;
   }

   .minute-line-long {
       width: 2px;
       background: #fff;
       height: 12px;
       -webkit-transform: translate(-50%, -100%) translateY(-131px);
       -ms-transform: translate(-50%, -100%) translateY(-131px);
       transform: translate(-50%, -100%) translateY(-131px);
       /*opacity: 0.34;*/
   }

以上就是全部代码,
安装BdTab浏览器插件
可以查看更多其他小组件的源码,喜欢的支持一下吧

插件内的组件查看教程:

posted @   haiyuan4101  阅读(176)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
点击右上角即可分享
微信分享提示