Write in front:

Some time ago when I was watching Douyin, some people used time roulette as a dynamic desktop wallpaper, which became the most popular screen saver on the whole Internet. Later, Millet and other application markets also appeared [Time Roulette], which is a bit like five aspects of the eight diagrams. It feels very fun.

Online experience



Achieve this effect, of course, the front-end point of view, there are many, here are the most simple, reach the effect element is purely a circular layout, if it is just so sure dear brother psychological needs, so since, made sure is to do a small sparrow is small all-sided demo, so he took vue buckets used set of small projects. I’m going to take you step by step and build this little thing from zero to one.

I. Project Requirements:

Implement a mobile time compass with Settings (Settings include: multi-language switch, vertical and horizontal position, zoom size, rotation Angle, text color, background color, etc.)

Two, preparation of basic knowledge:

1. Circular layout, as shown below

The center of the circle is O point and the radius is r. 2. Central Angle: Angle BOM; 3. Elements to be laid out: A, B, C, D, E, F, G, and H are absolutely positioned elements; 4. The transform: Rotate value can be used to control the position of each element in the center of the circle based on equal rotation angles of seconds, minutes, hours, afternoons, weeks, dates, and months



With this information in hand, we started writing code (omitted here for the VUE build project), simply using VUE-CLI3

Basic information of development environment: NPM: V6.4.1; Node: v10.8.0; Vue – cli 3.5.3

Code style specification: ESLint + Prettier

Iii. Development of project layout effect

3.1 the layout

First of all, we see that the time wheel is composed of seconds, minutes, hours, afternoons, weeks, dates, and months, so they are encapsulated in a small module component

<template>
  <div class="home">
    <Second :second="second" />
    <Minute :minute="minute" />
    <Hour :hour="hour" />
    <Apm :apm="apm" />
    <Week :week="week" />
    <Day :day="day" />
    <Month :month="month" />
  </div>
</template>Copy the code

And it’s the same center, so the styles of the common parts can be shared

<style lang="scss">
.home {
  ul {
    list-style-type: none;
    padding: 0;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    height: 60px;
    width: 60px;
    li {
      position: absolute;
      height: 60px;
      width: 60px;
      color: #fff;
      text-align: center;
      font-size: 14px;
      line-height: 20px;
    }
  }
}
</style>Copy the code

Here is a circular layout, let’s take a week as an example to look at the following code

Week.vue

<template>
  <ul>
    <li
      v-for="(item, index) in weekList"
      :key="index"
    >
      {{ item }}
    </li>
  </ul>
</template>

<style scoped lang="scss">
ul {
  z-index: 5;
  @for $i from 1 through 7 {
    li:nth-child(#{$i}) {
      transform: rotate(#{$i * 360/7 * 1deg}) translateX(180px);
    }
  }
}
</style>
Copy the code

Let’s take a look at the layout. Ul Li label V-for runs from Monday to Sunday, seven days in total, so the following li style, for those who are familiar with SCSS grammar, the corners of the mouth are slightly raised, the use of @for, 360 degrees divided into 7 equal parts, MMM, really delicious. Let’s take a look at this. It’s good



Then, the same operation on the second, minute, hour, complete all afternoon, week, date, month, patient adjust translateX () the second, minute, hour, week, date, month, on the afternoon of radius will not overlap each other, see the effect, begun to take



Note that each module requires a z-index setting layer because of the same center and absolute positioning

3.2JS Time synchronization

We just need to use JavaScript Date object new a Date(), and then through the Date object method, get the specific second, minute, hour, change the afternoon, week, Date, month. The following code

<script>
export default {
  name: "home",
  methods: {
    start() {
      setInterval(() => {
        let data = new Date();
        this.second = data.getSeconds();
        this.minute = data.getMinutes();
        this.hour = data.getHours();
        this.week = data.getDay();
        this.day = data.getDate();
        this.month = data.getMonth() + 1;
        if (this.hour > 12) {
          this.apm = 2;
        } else{ this.apm = 1; }}, 1000); }},created() { this.start(); }}; </script>Copy the code


3.2 the rotation

Rotate: rotate: ul controls the Angle based on the values of the second, minute, hour, last afternoon, week, date, and month. The current value is highlighted. Again, take the Week as an example. Week.vue

<template>
  <ul :style="{ transform: `rotate(${((rotates * 360) / 7) * 1}deg)` }">
    <li
      v-for="(item, index) in weekList"
      :key="index"
      :class="{ hover: index == rotates - 1 || index == rotates + 6 }"
    >
      {{ item }}
    </li>
  </ul>
</template>
<script>
export default {
  name: "Week",
  props: ["week"].data() {
    return {
      rotates: "",
      weekList: [
        "Monday"."Tuesday"."Wednesday"."Thursday"."Friday"."Saturday"."Sunday"]}; }, watch: { week(val) { this.rotates = val; }}}; </script>Copy the code


Hover (); hover (); hover (); hover ()

    li {
      position: absolute;
      height: 60px;
      width: 60px;
      color: #fff;text-align: center; font-size: 14px; line-height: 20px; Hover {text-shadow: rgb(255, 255, 255) 0px 0px 10px, rgb(255, 255, 255) 0px 0px 20px, rgb(255, 0, 222) 0px 0px 30px, rgb(255, 0, 222) 0px 0px 40px, rgb(255, 0, 222) 0px 0px 70px, rgb(255, 0, 222) 0px 0px 80px, rgb(255, 0, 222) 0px 0px 100px; }}Copy the code

“Class =” {hover: index = = rotates – 1 | | index = = rotates + 6} “, highlighting the current week, other seconds, minutes, hours, the afternoon, date, month, week as well. Then the magic of love goes round and round



At this point, we have developed the basic effects

Iv. Setup and development

4.1 Full screen, screenfull.js is directly used here

4.2 Switching languages, i18N and jS-cookie third-party plug-ins are used here, and the specific implementation is to imitate vue-element-admin implementation

import Vue from "vue";
import VueI18n from "vue-i18n";
import Cookies from "js-cookie";
import enLocale from "./en";
import zhLocale from "./zh";
import esLocale from "./zw"; Vue.use(VueI18n); const messages = { en: { ... enLocale }, zh: { ... zhLocale }, zw: { ... esLocale } };export function getLanguage() {
  const chooseLanguage = Cookies.get("language");
  if (chooseLanguage) return chooseLanguage;

  const language = (
    navigator.language || navigator.browserLanguage
  ).toLowerCase();
  const locales = Object.keys(messages);
  for (const locale of locales) {
    if (language.indexOf(locale) > -1) {
      returnlocale; }}return "en";
}
const i18n = new VueI18n({
  locale: getLanguage(),
  messages
});

export default i18n;Copy the code

Note that we include seconds, minutes, hours, afternoons, days, days, and months in the multilingual switch, so we need to calculate the value of the language change at all times. Take the week for example, here computed, weekList, calculates its changes in real time, and then renders the page

<script>

export default {
  name: "week",
  props: ["week"].data() {
    return {
      rotates: ""
    };
  },
  computed: {
    weekList: {
      get() {
        return this.$t("week"); } } }, watch: { week(val) { this.rotates = val; }}}; </script>Copy the code

Look at the effect, in order to beautiful simple added a little Settings of the small effect, currently support simplified Chinese, traditional Chinese, English



4.3 Other Settings to be developed…


Of the pit

Of course, the layout with canvas to write, is certainly more elegant, in general, it is not very difficult to achieve, if you want to achieve other Settings, some logic needs to be reconstructed, other Settings will be updated and released in the near future, the project source code learning to move

Project source code address