[Tencent Cloud Studio Practical Training Camp] Silky Experience: Using Cloud Studio to Realize a Clock with Precise Timing

Today's cloud computing technology has become more and more mature, and cloud development based on cloud computing technology has become the latest trend. Cloud Studio is a cloud-based web-side development microservice platform that provides various functions such as code editors, debuggers, code libraries, and automatic build and deployment tools to help developers develop applications in the cloud.

Although I have been exposed to cloud IDEs for a long time, the development experience that can make me feel so smooth should belong to this time!

Among many IDEs, Cloud Studio is definitely the one you can choose. Because choosing a cloud IDE depends not only on its user experience, but also on the resources it can provide. Cloud Studio is backed by Tencent Cloud and has abundant cloud resources for developers to call. This is equivalent to opening a hardware store. When you are decorating your own house, you can get the tools you want in time.

And why did I experience the silky feeling this time? Because when I was trying to create a web clock animation through front-end technology, I found that Cloud Studio could help me realize a series of functions such as project application preview, code saving, code hosting and so on as quickly as possible and without frustration. The background processing process of the browser is running "arrogantly". So, without further ado, let me share how I quickly created a web clock animation on Cloud Studio.

This project is derived from the entry of "Tencent Cloud Studio Practical Training Camp" , which runs correctly in Tencent Cloud Studio .

start to experience

First, you need to create your account.

Since CODING and Cloud Studio have achieved account interoperability, if you have a CODING account, you can log in with the CODING account to complete account authorization. In addition, you can also log in through WeChat or GitHub.
insert image description here
After logging in, you will see a menu such as " Space Template " in the left navigation bar of Cloud Studio. Click this menu, and there will be many commonly used templates and frame templates on the right for you to choose. Of course, you can also select the upper right corner and click the "New Template" button to manually create a template.

insert image description here

So, to be special, this project chooses the method of " new template " to create:
insert image description here
only need to fill in the above necessary information.

After the creation is successful, click to open the template you just created:
insert image description here

start programming

After entering the template we just created, a workspace will be loaded for you (note that in work mode, only one workspace is running. ps: this is not very friendly).

If you are a front-end developer, do you feel familiar when you see the open workspace screen? That's right! This is a VSCode editor interface. Well, for a developer who uses VSCode as the main editor for daily development, such a workspace can be said to have zero threshold to get started.

Next, we create two folders and three files, the project structure is as follows:

insert image description here
To start creating a clock, you still need some basic knowledge. For example, let's learn about it first Web Animations API.

Web Animations API

The Web Animations API introduces the concept of a timeline. By default, all animations are associated with the document's timeline. This means that animations share the same "internal clock" - the clock that starts from page load.

A shared clock allows us to coordinate animations. Whether it's a certain rhythm or a pattern, you don't have to worry about something being delayed or happening ahead of time. Among them, it also has an startTimeattribute that we need to know.

  • startTime property

To make the animation start at a certain moment, use startTimethe property. startTimeThe value is in milliseconds since the page load. 1000.5An animation with a start time set to will start playing when the document timeline's currentTimeproperty is equal to 1000.5.

Did you notice the decimal point in the start time value? Yes, you can use fractions of milliseconds for precise times. However, the accuracy depends on browser settings.

Another interesting thing is that the start time can also be negative . You are free to set it to a time in the future or a time in the past . Set this value to -1000, and your animation will state as if it had played for a second when the page loaded. To the user, the animation will appear to start playing before they even think about visiting your page .

After understanding the basic knowledge above, let's take a look at how to use Web Animations API to realize Web clock animation.

Web clock animation

First, open it index.htmland fill in the following code in the file. This code is mainly used to create the layout of the clock:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>时钟动画</title>
  <link rel="stylesheet" href="/css/index.css">
</head>
<body>
  <template id="tick">
    <div class="tick"><span></span></div>        
  </template>
  
  <template id="digit"><span class="digit" style="--len: 10;"><span></span></span></template>
  
  <div id="analog-clock">
    <div class="hour-ticks"></div>
    <div class="minute-ticks"></div>
    
    <div class="day"></div>
    
    <div class="hand second"><div class="shadow"></div><div class="body"></div></div>
    <div class="hand minute"><div class="shadow"></div><div class="body"></div></div>
    <div class="hand hour"><div class="shadow"></div><div class="body"></div></div>
  
    <div class="dot"></div>
  </div>
  
  <div id="digital-clock">
    <span class="hours"></span><span>:</span><span class="minutes"></span><span>:</span><span class="seconds"></span><span>.</span><span class="milliseconds"></span>
  </div>
  <script src="./js/index.js"></script>
</body>
</html>

Next, you need to style the layout. Open css/index.cssthe file and fill in the following code:

:root {
    
    
    --face-size: 15rem;
}

body {
    
    
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-family: sans-serif;
}

body > * {
    
    
    margin: 1rem;
}

#analog-clock {
    
    
    width: var(--face-size);
    height: var(--face-size);
    position: relative;
    border: 3px solid #555;
    border-radius: 50%;
    font-weight: 400;
}

.dot {
    
    
    --size: 9px;
    position: absolute;
    left: calc(50% - calc(var(--size) / 2));
    top: calc(50% - calc(var(--size) / 2));
    width: var(--size);
    height: var(--size);
    background-color: #333;
    border-radius: 50%;
    filter: drop-shadow(1px 1px 1px #333);
}

.hand {
    
    
    position: absolute;
    bottom: 50%;
    left: calc(50% - calc(var(--width) / 2));
    width: var(--width);
    transform-origin: center bottom;
}

.hand > * {
    
    
    position: absolute;
    height: 100%;
    width: 100%;
    border-radius: 4px;
}

.hand .body {
    
    
    background-color: #333;
}

.hand .shadow {
    
    
    background-color: black;
    opacity: 0.2;
    filter: drop-shadow(0 0 1px black);
}

.second {
    
    
    --width: 1px;
    height: 50%;
    transform-origin: center 80%;
    margin-bottom: calc(var(--face-size) * -0.1)
}

.second .body {
    
    
    background-color: black;
}

.minute {
    
    
    --width: 3px;
    height: 35%;
}

.hour {
    
    
    --width: 5px;
    height: 25%;
}

.day {
    
    
    --size: 2ch;
    position: absolute;
    left: calc(50% - calc(var(--size) / 2));
    top: calc(50% - calc(var(--size) / 2));
    width: var(--size);
    height: var(--size);
    transform: translate(calc(var(--face-size) * 0.2));
}

.tick {
    
    
    --width: 2px;
    --height: 29px;
    --shift: translateY(calc(var(--face-size) / -2));
    position: absolute;
    width: var(--width);
    height: var(--height);
    background-color: #666;
    top: 50%;
    left: calc(50% - calc(var(--width) / 2));
    transform-origin: top center;
}

.tick > span {
    
    
    --width: calc(calc(var(--face-size) * 3.141592653589793) / 24);
    position: absolute;
    width: var(--width);
    top: 3px;
    left: calc(var(--width) / -2);
    text-align: center;
}

.hour-ticks .tick:nth-child(even) > span {
    
    
    display: none;
}

.hour-ticks .tick:nth-child(odd) {
    
    
    background: none;
}

.hour-ticks .tick {
    
    
    transform: rotate(calc(var(--index) * 15deg)) var(--shift);
}

.minute-ticks .tick {
    
    
    --width: 1px;
    --height: 5px;
    --shift: translateY(calc(var(--face-size) / -2.5));
    background-color: black;
    transform: rotate(calc(var(--index) * 6deg)) var(--shift);
}

.minute-ticks .tick:nth-child(5n+1) {
    
    
    display: none;
}

#digital-clock {
    
    
    font-size: 1.5rem;
    line-height: 1;
}

#digital-clock > span {
    
    
    display: inline-block;
    vertical-align: top;
}

.digit {
    
    
    display: inline-block;
    overflow: hidden;
    max-width: 1ch;
}

.digit.wide {
    
    
    max-width: 2ch;
}

.digit > span {
    
    
    display: inline-flex;
    align-items: flex-start;
}

.digit.wide > span > span {
    
    
    min-width: 2ch;
    text-align: right;
}

.day .digit > span > span {
    
    
    text-align: center;
}

At this point, our clock is drawn, click the button in the upper right corner of the editor to preview:

insert image description here
insert image description here
Does the clock in the picture above have a stick figure feeling?

But to make the clock go, script processing is still required. It is the Web Animation API we mentioned earlier.

Next, we open js/index.jsthe file and add the following code:

const ms = 1;
const s = ms * 1000;
const m = s * 60;
const h = m * 60;
const d = h * 24;

const start_time = (function () {
    
    
    const time = new Date();
    const document_time = document.timeline.currentTime;
    const hour_diff = time.getHours() - time.getUTCHours();
    const current_time = (Number(time) % d) + (hour_diff * h);

    return document_time - current_time;
}());

const single_digit_keyframes = [
    {
    
    transform: "translateX(0)"},
    {
    
    transform: "translateX(calc(var(--len, 10) * -1ch)"}
];
const double_digit_keyframes = [
    {
    
    transform: "translateX(0)"},
    {
    
    transform: "translateX(calc(var(--len) * -2ch)"}
];

function range(len) {
    
    
    return new Array(len).fill(true);
}

function digits(len = 10, zero_based = true) {
    
    
    const digit = document.getElementById("digit").content.cloneNode(true);
    digit.firstElementChild.style.setProperty("--len", len);

    digit.firstElementChild.firstElementChild.append(
        ...range(len).map(function (ignore, index) {
    
    
            const span = document.createElement("span");
            span.textContent = zero_based ? index : index + 1;
            return span;
        })
    );

    if (len > 10) {
    
    
        digit.firstElementChild.classList.add("wide");
    }

    return digit;
}

(function build_analog_clock() {
    
    
    const clock = document.getElementById("analog-clock");
    const tick_template = document.getElementById("tick");
    const hour_marks_container = clock.querySelector(".hour-ticks");
    const minute_marks_container = clock.querySelector(".minute-ticks");
    const day = clock.querySelector(".day");

    hour_marks_container.append(...range(24).map(function (ignore, index) {
    
    
        const tick = tick_template.content.cloneNode(true);
        const shifted = index + 1;
        tick.firstElementChild.style.setProperty("--index", shifted);
        tick.firstElementChild.firstElementChild.textContent = shifted;
        return tick;
    }));

    minute_marks_container.append(...range(60).map(function (ignore, index) {
    
    
        const tick = tick_template.content.cloneNode(true);
        tick.firstElementChild.style.setProperty("--index", index);
        tick.firstElementChild.firstElementChild.remove();
        return tick;
    }));
}());

(function build_digital_clock() {
    
    
    const clock = document.getElementById("digital-clock");
    const hours = clock.querySelector(".hours");
    const minutes = clock.querySelector(".minutes");
    const seconds = clock.querySelector(".seconds");
    const milliseconds = clock.querySelector(".milliseconds");

    hours.append(digits(24));
    minutes.append(digits(6), digits());
    seconds.append(digits(6), digits());
    milliseconds.append(digits(), digits(), digits());
}());

(function start_analog_clock() {
    
    
    const clock = document.getElementById("analog-clock");
    if (clock === null) {
    
    
        return;
    }

    const second = clock.querySelector(".second");
    const minute = clock.querySelector(".minute");
    const hour = clock.querySelector(".hour");

    const hands = [second, minute, hour];
    const hand_durations = [m, h, d];
    const steps = [60, 60, 120];

    const movement = [];

    hands.forEach(function (hand, index) {
    
    
        const duration = hand_durations[index];
        const easing = `steps(${
      
      steps[index]}, end)`;
        movement.push(hand.animate(
            [
                {
    
    transform: "rotate(0turn)"},
                {
    
    transform: "rotate(1turn)"}
            ],
            {
    
    duration, iterations: Infinity, easing}
        ));
        
        const shadow = hand.querySelector(".shadow");
        if (shadow) {
    
    
            movement.push(shadow.animate(
                [
                    {
    
    transform: "rotate(1turn) translate(3px) rotate(0turn)"},
                    {
    
    transform: "rotate(0turn) translate(3px) rotate(1turn)"}
                ],
                {
    
    duration, iterations: Infinity, iterationStart: 0.9, easing}
            ));
        }
    });

    movement.forEach(function (move) {
    
    
        move.startTime = start_time;
    });
}());

(function start_digital_clock() {
    
    
    const clock = document.getElementById("digital-clock");
    if (clock === null) {
    
    
        return;
    }
    const milliseconds = clock.querySelector(".milliseconds");
    const seconds = clock.querySelector(".seconds");
    const minutes = clock.querySelector(".minutes");
    const hours = clock.querySelector(".hours");
    const sections = [seconds, minutes];

    const durations = [s, m, h];
    const animations = [];

    Array.from(
        milliseconds.children
    ).reverse().forEach(function (digit, index) {
    
    
        animations.push(digit.firstElementChild.animate(
            single_digit_keyframes,
            {
    
    
                duration: ms * (10 ** (index + 1)),
                iterations: Infinity,
                easing: "steps(10, end)"
            }
        ));
    });

    sections.forEach(function (section, index) {
    
    
        Array.from(
            section.children
        ).forEach(function (digit) {
    
    
            const nr_digits = digit.firstElementChild.children.length;
            animations.push(digit.firstElementChild.animate(
                single_digit_keyframes,
                {
    
    
                    duration: (
                        nr_digits === 10
                        ? durations[index] * 10
                        : durations[index + 1]
                    ),
                    iterations: Infinity,
                    easing: `steps(${
      
      nr_digits}, end)`
                }
            ));
        });
    });

    Array.from(hours.children).forEach(function (digit) {
    
    
        const nr_digits = digit.firstElementChild.children.length;
        animations.push(
            digit.firstElementChild.animate(
                double_digit_keyframes,
                {
    
    
                    duration: d,
                    iterations: Infinity,
                    easing: `steps(${
      
      nr_digits}, end)`
                }
            )
        );
    });

    animations.forEach(function (animation) {
    
    
        animation.startTime = start_time;
    });
}());

(function set_up_date_complication() {
    
    
    const day = document.querySelector(".day");
    if (day === null) {
    
    
        return;
    }

    function month() {
    
    
        const now = new Date();
        return digits(
            (new Date(now.getFullYear(), now.getMonth() + 1, 0)).getDate(),
            false
        );
    }

    function create_animation(digit) {
    
    
        const nr_digits = digit.firstElementChild.children.length;
        const duration = d * nr_digits;
        return digit.firstElementChild.animate(
            double_digit_keyframes,
            {
    
    
                duration,
                easing: `steps(${
      
      nr_digits}, end)`,
                iterationStart: (d * ((new Date()).getDate() - 1)) / duration
            }
        );
    }

    const new_day = day.cloneNode();
    new_day.append(month());
    day.replaceWith(new_day);

    Array.from(new_day.children).forEach(function (digit) {
    
    
        const complication = create_animation(digit);
        complication.startTime = start_time;
        complication.finished.then(set_up_date_complication);
    });
}());

At this time, the preview screen on the right will be updated in real time, and we will see the clock move magically.

Please add a picture description
At this point, our Web clock animation is complete~

Finally, we publish the application to a Git repository.

Publish Git

Cloud Studio supports associating the code with the warehouse address of the project, and supports multiple platforms such as github/Coding/gitee. Currently, the code of the Web clock has been published in the Coding warehouse , you can click the link to view it.
insert image description here

After such a series of operations, I feel that it seems that I use VSCode to develop myself in my daily development, which is much lighter and faster. It saves me a lot of steps to save files, configuration information, etc. Finally, let's summarize the experience.

Summarize

The feeling of using Cloud Studio, an online IDE, is very good, and its advantages are very rich. I have summarized some things that I think are worthy of appreciation:

  1. Based on the Web, it greatly facilitates developers to write code anywhere and on any device without installing any software.
  2. The interface of Cloud Studio is designed to be simple and intuitive, making it easy for beginners to get started without affecting the efficiency of developers.
  3. It supports multiple programming languages, such as Java, Python, JavaScript, etc., and some common frameworks, such as Node.js, Spring Boot, etc., so that it can meet various development needs.
  4. It can be seamlessly integrated with code hosting platforms such as GitHub to facilitate code submission and version control of code.
  5. Cloud Studio also provides many powerful development tools, such as code auto-completion, debugging, breakpoints and other functions, which can greatly improve development efficiency.
  6. Automatic build and deployment, Cloud Studio provides automated build and deployment tools that can deploy code to the cloud or other places for testing and production use.

While Cloud Studio performs well, it has some drawbacks:

  1. Since it is web-based, it may affect the developer experience on unstable or slow networks. Especially when creating/opening a workspace, it takes a while.
  2. Only one workspace can be opened : I don’t know if this shortcoming is caused by ordinary users. It is very inconvenient when I have multiple projects under development. I need to stop one workspace before opening another.

However, compared to other IDEs, the advantages of Cloud Studio lie in its portability, ease of use, scalability, and cloud storage. But there are some differences, such as it does not run offline and may be affected by network delays. Overall, Cloud Studio is a very convenient online IDE that allows us to develop easily anywhere.

Guess you like

Origin blog.csdn.net/ImagineCode/article/details/131843632