【Tencent Cloud Studio 実践合宿】Silky Experience: Cloud Studio を使って正確なタイミングの時計を実現

今日のクラウド コンピューティング テクノロジーはますます成熟しており、クラウド コンピューティング テクノロジーに基づくクラウド開発が最新のトレンドになっています。Cloud Studio は、開発者がクラウドでアプリケーションを開発するのを支援する、コード エディター、デバッガー、コード ライブラリ、自動ビルドおよびデプロイメント ツールなどのさまざまな機能を提供する、クラウド ベースの Web サイド開発マイクロサービス プラットフォームです。

私は長い間クラウド IDE に触れてきましたが、これほどスムーズに感じられる開発経験は今回のものです。

数多くの IDE の中で、間違いなく Cloud Studio を選択できます。クラウド IDE の選択は、そのユーザー エクスペリエンスだけでなく、クラウド IDE が提供できるリソースにも依存するためです。Cloud Studio は Tencent Cloud によってサポートされており、開発者が呼び出すための豊富なクラウド リソースがあり、これは金物店を開くのと同じであり、自分の家を装飾するときに必要なツールをすぐに入手できます。

そしてなぜ今回私はシルキーな感触を体験したのでしょうか?フロントエンド テクノロジーを使用して Web 時計アニメーションを作成しようとしたときに、Cloud Studio を使用すると、プロジェクト アプリケーションのプレビュー、コード保存、コード ホスティングなどの一連の機能をできるだけ早く、手間をかけずに実現できることがわかりました。ブラウザのバックグラウンド処理プロセスが「傲慢に」実行されています。それでは、早速、Cloud Studio でウェブ時計アニメーションをすばやく作成した方法を共有しましょう。

このプロジェクトは、「Tencent Cloud Studio 実践トレーニング キャンプ」のエントリーから派生したもので、Tencent Cloud Studioで正しく動作します。

体験を始める

まず、アカウントを作成する必要があります。

CODINGとCloud Studioはアカウントの相互運用を実現しているため、CODINGアカウントをお持ちの場合は、CODINGアカウントでログインすることでアカウント認証が完了します。さらに、WeChat または GitHub を通じてログインすることもできます。
ここに画像の説明を挿入
ログイン後、 Cloud Studio の左側のナビゲーション バーに「スペース テンプレート」などのメニューが表示され、このメニューをクリックすると、右側によく使用されるテンプレートやフレーム テンプレートが多数表示されます。もちろん、右上隅を選択して「新しいテンプレート」ボタンをクリックして、テンプレートを手動で作成することもできます。

ここに画像の説明を挿入

そこで、このプロジェクトでは特別に、上記の必要事項を入力するだけで済む「新規テンプレート」を作成する方法を選択します。
ここに画像の説明を挿入

作成が成功したら、作成したばかりのテンプレートをクリックして開きます。
ここに画像の説明を挿入

プログラミングを始める

作成したばかりのテンプレートを入力すると、ワークスペースがロードされます (作業モードでは、1 つのワークスペースのみが実行されることに注意してください。ps: これはあまりフレンドリーではありません)。

フロントエンド開発者であれば、開いているワークスペース画面を見たときに見慣れたものを感じませんか? それは正しい!これは VSCode エディター インターフェイスです。まあ、VSCode を日常の開発のメイン エディタとして使用する開発者にとって、このようなワークスペースは始めるのに敷居がゼロであると言えます。

次に、2 つのフォルダーと 3 つのファイルを作成します。プロジェクト構造は次のとおりです。

ここに画像の説明を挿入
時計の作成を始めるには、いくつかの基本的な知識が必要です。たとえば、まずそれについて学びましょうWeb Animations API

ウェブアニメーションAPI

Web アニメーション API では、タイムラインの概念が導入されています。デフォルトでは、すべてのアニメーションはドキュメントのタイムラインに関連付けられます。これは、アニメーションが同じ「内部クロック」、つまりページの読み込みから開始するクロックを共有することを意味します。

共有時計を使用すると、アニメーションを調整できます。特定のリズムであれ、パターンであれ、何かが遅れたり、先に起こったりすることを心配する必要はありません。startTimeその中には、私たちが知っておくべき属性もあります。

  • startTime プロパティ

アニメーションを特定の瞬間に開始するには、startTimeプロパティを使用します。startTime値は、ページが読み込まれてからのミリ秒単位です。開始時間が に設定された1000.5アニメーションは、ドキュメント タイムラインのcurrentTimeプロパティが に等しいときに再生を開始します1000.5

開始時間の値の小数点に気づきましたか? はい、ミリ秒単位の端数を使用して正確な時間を表現できます。ただし、精度はブラウザの設定によって異なります。

もう 1 つの興味深い点は、開始時刻が負の値になることもあることです。将来の時間または過去の時間に自由に設定できますこの値を に設定する-1000と、アニメーションは、ページが読み込まれたときに 1 秒間再生されたかのように表示されます。ユーザーにとっては、ページにアクセスしようと考える前にアニメーションの再生が始まっているように見えます

上記の基礎知識を理解した上で、Web アニメーション API を使用して Web 時計アニメーションを実現する方法を見てみましょう。

ウェブ時計のアニメーション

まず、それを開いてindex.html、ファイル内に次のコードを入力します。このコードは主に時計のレイアウトを作成するために使用されます。

<!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>

次に、レイアウトのスタイルを設定する必要があります。css/index.cssファイルを開き、次のコードを入力します。

: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;
}

この時点で、時計が描画されます。エディターの右上隅にあるボタンをクリックしてプレビューします。

ここに画像の説明を挿入
ここに画像の説明を挿入
上の写真の時計はスティックフィギュア的な感じでしょうか?

ただし、時計を進めるには、やはりスクリプト処理が必要です。先ほど紹介した Web アニメーション API です。

次に、js/index.jsファイルを開いて次のコードを追加します。

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);
    });
}());

このとき、右側のプレビュー画面がリアルタイムに更新され、時計が魔法のように動くのがわかります。

画像の説明を追加してください
この時点で、Web 時計のアニメーションが完成しました~

最後に、アプリケーションを Git リポジトリに公開します。

Git を公開する

Cloud Studio は、コードとプロジェクトのウェアハウス アドレスの関連付けをサポートし、github/Coding/gitee などの複数のプラットフォームをサポートします。現在、Web クロックのコードはコーディング ウェアハウス に公開されており、リンクをクリックして表示できます。
ここに画像の説明を挿入

このような一連の作業を経て、日々の開発ではVSCodeを使って開発しているようで、とても軽くて速いと感じています。ファイルや構成情報などを保存するための多くの手順を節約できます。最後に体験談をまとめてみましょう。

要約する

オンライン IDE である Cloud Studio の使用感は非常に良く、その利点は非常に豊富です。

  1. Web に基づいているため、開発者はソフトウェアをインストールすることなく、どこでも、どのデバイスでもコードを書くことが非常に容易になります。
  2. Cloud Studio のインターフェースはシンプルかつ直感的に設計されており、開発者の効率に影響を与えることなく初心者でも簡単に始めることができます。
  3. Java、Python、JavaScript などの複数のプログラミング言語と、Node.js、Spring Boot などの一般的なフレームワークをサポートしているため、さまざまな開発ニーズに対応できます。
  4. GitHub などのコード ホスティング プラットフォームとシームレスに統合して、コードの送信とコードのバージョン管理を容易にすることができます。
  5. Cloud Studio は、コードの自動補完、デバッグ、ブレークポイント、その他の機能など、開発効率を大幅に向上させる強力な開発ツールを多数提供します。
  6. 自動ビルドとデプロイメントの Cloud Studio は、テストや本番環境で使用するためにコードをクラウドまたは他の場所にデプロイできる自動ビルドおよびデプロイメント ツールを提供します。

Cloud Studio は優れたパフォーマンスを発揮しますが、いくつかの欠点があります。

  1. Web ベースであるため、不安定なネットワークや遅いネットワークでは開発者のエクスペリエンスに影響を与える可能性があります。特にワークスペースを作成・開くときは時間がかかります。
  2. ワークスペースを 1 つしか開くことができない: この欠点が一般ユーザーにあるのかはわかりませんが、複数のプロジェクトを開発中である場合、別のワークスペースを開く前に 1 つのワークスペースを停止する必要があり、非常に不便です。

ただし、他の IDE と比較した場合、Cloud Studio の利点は、移植性、使いやすさ、拡張性、クラウド ストレージにあります。ただし、オフラインでは実行されない、ネットワーク遅延の影響を受ける可能性があるなど、いくつかの違いがあります。全体として、Cloud Studio は、どこでも簡単に開発できる非常に便利なオンライン IDE です。

おすすめ

転載: blog.csdn.net/ImagineCode/article/details/131843632