写点什么

三步教你编写一个 Neumorphism 风格的小时钟

用户头像
空城机
关注
发布于: 2021 年 06 月 12 日
三步教你编写一个Neumorphism风格的小时钟

目录

  • 序 Neumorphism

  • 正文开始

  • 一、时钟表盘编写

  • 二、时钟指针编写

  • 、时钟组件的调用

  • 完整组件代码

又到了自己编写组件的时节了



作为一名前端开发者,平时也是阔以没事可以写写自定义的组件,增加一下自己的阅历,实际开发中用到也可以 通过 CV 大法去快速开发




先提前来看一下最终的效果:




先问一个小问题,现在大家现在更习惯于看哪种样式的时间,是钟表类型还是数字类型?(虽然你们的回答影响不了我做一个钟表啦


钟表时间:


数字时间:


Neumorphism

目前网上的一些时钟风格不太喜欢,之前偶然看到一款新拟物风格Neumorphism的设计,让我眼前不禁一亮所以本次时钟组件的风格就决定是你啦---新拟物

Neumorphism 风格页面




<br>


正文开始

上面又水了一堆话,增加了一下文字的数量,真是太开森了


下面正式开始组件的制作流程

一、时钟表盘编写

因为本人使用的是 vue,所以编写的也是.vue 组件


先搭建一个clock.vue的组件,设定好props可能会接收的宽高,还有阴影颜色。阴影部分使用box-shadow进行设置


其中像 Compute 中的 styleVar 内容类似于 CSS 中的:root 也可以去此文章中查看相关方法:自己动手丰衣足食系列の自定义下拉框 vue 组件


在主页面 app.vue 中设置全局颜色为#EBE6DA


在 CSS 样式编写中,计算位置等值可以使用 calc 加 var 的方式计算


代码:

<template>    <!-- 时钟 -->    <div class="clock" :style="styleVar">        <!-- 内圈 -->        <div class="innerBorder">            <!-- 时钟刻度 -->            <div class="scale mark1"></div>            <div class="scale mark2"></div>            <div class="scale mark3"></div>            <div class="scale mark4"></div>            <div class="scale mark5"></div>            <div class="scale mark6"></div>            <div class="scale mark7"></div>            <div class="scale mark8"></div>        </div>        <!-- 内圈波浪 -->        <div class="wave"></div>    </div></template><script>export default {    name: 'clock',    components: {},    props: {        bgsize: {            type: Number,            default: 180        },        bgcolor: {            type: String,            default: '#D1CCC0'        }    },    data() {        return {        };    },    created() {},    mounted() {},    watch: {},    computed: {        styleVar() {            return {                '--clock-size': this.bgsize + 'px',                '--clock-bgcolor': this.bgcolor,                '--length-log2E': ((this.bgsize - 10) / 2) / Math.LOG2E + 'px',            }        }    },    methods: {            },};</script><style scoped>    /* 外部大小和阴影 */    .clock {        width: var(--clock-size);        height: var(--clock-size);        border-radius: 50%;        box-shadow: 5px 5px 10px var(--clock-bgcolor), -4px -4px 8px #fff;    }    /* 内阴影 */    .innerBorder {        /* calc加var计算 */        width: calc(var(--clock-size) - 10px);        height: calc(var(--clock-size) - 10px);        position: relative;        left: 5px;        top: 5px;        box-shadow: -3px -3px 6px #fff inset, 3px 3px 6px var(--clock-bgcolor) inset;        border-radius: 50%;    }    /* 时钟刻度 */    .scale {        width: 2px;        height: 8px;        position: absolute;        box-shadow: 1px 1px 1px #9D958F inset, -1px -1px 1px var(--clock-bgcolor) inset;        border-radius: 1px;    }    /* 设置小刻度位置 */    .mark1 {        left: calc(50% - 1px);        top: 2px;    }    .mark2 {        transform: rotate(45deg);        left: calc(50% + var(--length-log2E) );        top: calc(50% - var(--length-log2E) );    }    .mark3 {        transform: rotate(90deg);        left: calc(100% - 7px);        top: calc(50% - 1px);    }    .mark4 {        transform: rotate(135deg);        left: calc(50% + var(--length-log2E) - 5px);        top: calc(50% + var(--length-log2E) - 5px);    }    .mark5 {        left: calc(50% - 1px);        bottom: 2px;    }    .mark6 {        transform: rotate(45deg);        left: calc(50% - var(--length-log2E) + 5px);        top: calc(50% + var(--length-log2E) - 5px);    }    .mark7 {        transform: rotate(90deg);        left: 2px;        top: calc(50% - 1px);    }    .mark8 {        transform: rotate(135deg);        left: calc(50% - var(--length-log2E) );        top: calc(50% - var(--length-log2E) );    }    /* 中间波浪 */    .wave {        width: 30%;        height: 30%;        position: absolute;        left: 35%;        top: 35%;        box-shadow: 3px 3px 9px var(--clock-bgcolor), -3px -3px 9px #fff;        border-radius: 50%;        filter: blur(1px);        animation: wavemove 4s infinite linear;    }    @keyframes wavemove {        0% {            transform: scale(0.5);        }        50% {            transform: scale(1);            opacity: 1;        }        100% {            transform: scale(1.7);            opacity: 0;        }    }</style>
复制代码


效果:



二、时钟指针编写

在编写指针时需要注意,指针的旋转运动是围绕圆心进行的,使用 transform 来改变旋转


所以需要使用transform-origin: bottom来设置选择的基准点,之后旋转rotate改变



在样式编写完成之后,就可以将当前的北京时间与指针、分针、秒针的转动相结合起来了


这里的原理其实更加简单,使用new Date()获取到当前的时分秒,然后再将时分秒按比例转换成度数deg

// 校准时钟指针方法currentTime:function(){    let date = new Date();    this.hour = date.getHours();    this.minute = date.getMinutes();    this.second = date.getSeconds();    document.getElementsByClassName('hourhand')[0].style.transform = 'rotate(' + this.hour / 24 * 360 + 'deg)';    document.getElementsByClassName('minhand')[0].style.transform = 'rotate(' + this.minute / 60 * 360 + 'deg)';    document.getElementsByClassName('sechand')[0].style.transform = 'rotate(' + this.second / 60 * 360 + 'deg)';}
复制代码


使用 setInterval 定时器定时 1000 毫秒执行一次


这样就可以达到最终想要的效果了


三、时钟组件的调用

编写好时钟组件后,接下来就可以在页面上进行调用了

import clock from './components/clock'
export default { name: 'App', components: { clock }}
复制代码


调用<clock></clock>就能够将时钟放置到你想要的位置因为之前设置了 props 的原因,所以可以通过简单的设置调整时钟的大小和颜色风格<clock :bgsize="150" :bgcolor=color></clock>color为#bec8e4


现在的时钟样式:




完整组件代码

<template>    <!-- 时钟 -->    <div class="clock" :style="styleVar">        <!-- 内圈 -->        <div class="innerBorder">            <!-- 时钟刻度 -->            <div class="scale mark1"></div>            <div class="scale mark2"></div>            <div class="scale mark3"></div>            <div class="scale mark4"></div>            <div class="scale mark5"></div>            <div class="scale mark6"></div>            <div class="scale mark7"></div>            <div class="scale mark8"></div>        </div>        <!-- 内圈波浪 -->        <div class="wave"></div>        <!-- 时针、分针、秒针 -->        <div class="hands hourhand"></div>        <div class="hands minhand"></div>        <div class="hands sechand"></div>    </div></template>
<script>export default { name: 'clock', components: {}, props: { bgsize: { type: Number, default: 180 }, bgcolor: { type: String, default: '#D1CCC0' } }, data() { return { hour: 0, //小时 minute: 0, //分钟 second: 0, //秒 }; }, created() {}, mounted() { this.currentTime(); // 定时校准 setInterval(this.currentTime, 1000); }, watch: {}, computed: { styleVar() { return { '--clock-size': this.bgsize + 'px', '--clock-bgcolor': this.bgcolor, '--length-log2E': ((this.bgsize - 10) / 2) / Math.LOG2E + 'px', } } }, methods: { // 校准时钟指针方法 currentTime:function(){ let date = new Date(); this.hour = date.getHours(); this.minute = date.getMinutes(); this.second = date.getSeconds();
document.getElementsByClassName('hourhand')[0].style.transform = 'rotate(' + this.hour / 24 * 360 + 'deg)'; document.getElementsByClassName('minhand')[0].style.transform = 'rotate(' + this.minute / 60 * 360 + 'deg)'; document.getElementsByClassName('sechand')[0].style.transform = 'rotate(' + this.second / 60 * 360 + 'deg)'; } },};</script><style scoped> /* 外部大小和阴影 */ .clock { width: var(--clock-size); height: var(--clock-size); border-radius: 50%; box-shadow: 5px 5px 10px var(--clock-bgcolor), -4px -4px 8px #fff; } /* 内阴影 */ .innerBorder { /* calc加var计算 */ width: calc(var(--clock-size) - 10px); height: calc(var(--clock-size) - 10px); position: relative; left: 5px; top: 5px; box-shadow: -3px -3px 6px #fff inset, 3px 3px 6px var(--clock-bgcolor) inset; border-radius: 50%; } /* 时钟刻度 */ .scale { width: 2px; height: 8px; position: absolute; box-shadow: 1px 1px 1px #9D958F inset, -1px -1px 1px var(--clock-bgcolor) inset; border-radius: 1px; } /* 设置小刻度位置 */ .mark1 { left: calc(50% - 1px); top: 2px; } .mark2 { transform: rotate(45deg); left: calc(50% + var(--length-log2E) ); top: calc(50% - var(--length-log2E) ); } .mark3 { transform: rotate(90deg); left: calc(100% - 7px); top: calc(50% - 3px); } .mark4 { transform: rotate(135deg); left: calc(50% + var(--length-log2E) - 5px); top: calc(50% + var(--length-log2E) - 5px); } .mark5 { left: calc(50% - 1px); bottom: 2px; } .mark6 { transform: rotate(45deg); left: calc(50% - var(--length-log2E) + 5px); top: calc(50% + var(--length-log2E) - 5px); } .mark7 { transform: rotate(90deg); left: 2px; top: calc(50% - 3px); } .mark8 { transform: rotate(135deg); left: calc(50% - var(--length-log2E) ); top: calc(50% - var(--length-log2E) ); } /* 中间波浪 */ .wave { width: 30%; height: 30%; position: absolute; left: 35%; top: 35%; box-shadow: 3px 3px 9px var(--clock-bgcolor), -3px -3px 9px #fff; border-radius: 50%; filter: blur(1px); /* 模糊处理 */ animation: wavemove 4s infinite linear; } @keyframes wavemove { 0% { transform: scale(0.5); } 50% { transform: scale(1); opacity: 1; } 100% { transform: scale(1.7); opacity: 0; } } /*************************** 时针、分针、秒针 ****************************/ .hands { position: absolute; transform-origin: bottom; border-radius: 10px; z-index: 300; bottom: 50%; left: calc(50% - 1px); } .sechand { width: 2px; height: 42%; background-image: linear-gradient( #CD69C9, #1CA6F3); } .minhand { width: 4px; height: 33%; background-color: #9BA5AA; left: calc(50% - 2px); } .hourhand { width: 6px; height: 21%; background-color: #BEC8E4; left: calc(50% - 3px); }</style>
复制代码


发布于: 2021 年 06 月 12 日阅读数: 10
用户头像

空城机

关注

曾经沧海难为水,只是当时已惘然 2021.03.22 加入

业余作者,在线水文 主要干前端的活,业余会学学python 欢迎各位关注,互相学习,互相进步

评论

发布
暂无评论
三步教你编写一个Neumorphism风格的小时钟