Tạo đồng hồ thời gian thực với mặt chuyển màu Conic

Nút nguồn: 1670563

Gradients đã là một phần của phổ CSS từ khá lâu rồi. Chúng tôi thấy rất nhiều gradient xuyên tâm và tuyến tính trong rất nhiều dự án, nhưng có một loại gradient có vẻ hơi đơn độc: gradient conic. Chúng ta sẽ tạo một mặt đồng hồ bằng cách sử dụng loại gradient này.

Làm việc với các gradient conic

Những gì chúng tôi đang tạo ra bao gồm một gradient với các chuyển đổi màu được xoay quanh một điểm trung tâm và có thể có nhiều giá trị màu. Để đồng hồ này hoạt động, chúng tôi cũng sẽ sử dụng giá trị góc của một gradient hình nón để xác định chuyển động quay hoặc điểm bắt đầu. Góc được xác định bằng cách sử dụng from giá trị.

background-image: conic-gradient(from 45deg, #6e7dab, #5762d5);

Điều thú vị về điều này là góc bắt đầu có thể có giá trị âm trong CSS, điều này sẽ có ích về sau.

Một ví dụ thanh lịch đơn giản về gradient hình nón:

Xây dựng đồng hồ cơ bản của chúng tôi

Hãy bắt đầu bằng cách thêm một số HTML cho đồng hồ và kim:

Hãy tạo một số kiểu dáng mặc định cho đồng hồ của chúng ta. Để điều này hoạt động bình thường, chúng tôi sẽ cập nhật các biến CSS bằng JavaScript sau này, vì vậy hãy phân bổ các biến này bên trong .clock bộ chọn. Để dễ dàng điều chỉnh, hãy thêm cả màu sắc của bàn tay.

.clock {
  /* general clock vars */
  --hour-hand-color: #000;
  --hour-hand-degrees: 0deg;
  --minute-hand-color: #000;
  --minute-hand-degrees: 0deg;
  --second-hand-color: hotpink;
  --second-hand-degrees: 0deg;

  position: relative;
  min-width: 320px;
  width: 25vw;
  height: 25vw;
  min-height: 320px;
  border-radius: 50%;
  margin: 0 auto;
  border: 7px solid #000;
}

/* clock hands */
.hand {
  position: absolute;
  left: 50%;
  bottom: 50%;
  height: 45%;
  width: 4px;
  margin-left: -2px;
  background: var(--second-hand-color);
  border-radius: 6px;
  transform-origin: bottom center;
  transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
}
.second-hand {
  transform: rotate(var(--second-hand-degrees));
}
.hour-hand {
  height: 35%;
  border-radius: 40px;
  background-color: var(--hour-hand-color);
  transform: rotate(var(--hour-hand-degrees));
}
.minute-hand {
  height: 50%;
  background: var(--minute-hand-color);
  transform: rotate(var(--minute-hand-degrees));
}

Điều này thiết lập cho chúng tôi kiểu dáng chung mà chúng tôi cần cho đồng hồ. Chúng tôi đã thiết lập transform-origin trên kim đồng hồ để chúng xoay đúng cách xung quanh mặt đồng hồ. Ngoài ra còn có một số thuộc tính tùy chỉnh trong đó để đặt góc trên kim mà chúng tôi sẽ cập nhật bằng JavaScript để có thời gian phù hợp sao cho mỗi kim ánh xạ thành giây, phút và giờ cho phù hợp.

Đây là những gì chúng tôi có cho đến nay:

Được rồi, hãy chuyển sang cập nhật các thuộc tính tùy chỉnh đó!

Thêm JavaScript cho đồng hồ cơ bản của chúng tôi

Trước hết, chúng tôi sẽ nhắm mục tiêu đồng hồ của mình và tạo một hàm:

const clock = document.getElementById("clock");
function setDate() {
  // Code to set the current time and hand angles.
}
setDate();

Bên trong hàm của chúng tôi, chúng tôi sẽ tìm nạp thời gian hiện tại bằng cách sử dụng Date() chức năng để tính toán góc chính xác của bàn tay:

const now = new Date();
const secondsAngle = now.getSeconds() * 6; 
const minsAngle = now.getMinutes() * 6 + secondsAngle / 60;
const hourAngle = ((now.getHours() % 12) / 12) * 360 + minsAngle / 12;

Đây là cách tính toán này hoạt động:

  • Giây: Chúng tôi mất 60 giây và nhân nó với 6, điều đó xảy ra 360, số góc hoàn hảo trong một đường tròn đầy đủ.
  • Phút: Tương tự như giây, nhưng bây giờ chúng ta thêm góc giây và chia nó cho 60 để tăng góc một chút trong vòng một phút để có kết quả chính xác hơn.
  • Giờ Mở Cửa: Đầu tiên, chúng tôi tính thời gian còn lại của giờ và chia nó cho 12. Sau đó, chúng tôi chia phần còn lại đó cho 12 một lần nữa để nhận giá trị thập phân, chúng ta có thể nhân với 360. Ví dụ: khi chúng ta đang ở giờ thứ 23, 23 / 12 = remain 11. Chia điều này cho 12 và chúng tôi nhận được 0.916 sau đó được nhân với 360 với tổng số 330. Ở đây, chúng tôi sẽ làm điều tương tự như chúng tôi đã làm với phút và thêm góc phút, chia cho 12, để có kết quả chính xác hơn.

Bây giờ chúng ta đã có các góc của mình, điều duy nhất còn lại cần làm là cập nhật các biến của đồng hồ của chúng ta bằng cách thêm phần sau vào cuối hàm của chúng ta:

clock.style.setProperty("--second-hand-degrees", secondsAngle + "deg");
clock.style.setProperty("--minute-hand-degrees", minsAngle + "deg");
clock.style.setProperty("--hour-hand-degrees", hourAngle + "deg");

Cuối cùng, nhưng không kém phần quan trọng, chúng tôi sẽ kích hoạt hàm với khoảng thời gian là một giây để có được đồng hồ hoạt động:

const clock = document.getElementById("clock");
function setDate() {
  // etc.
}
// Tick tick tick
setInterval(setDate, 1000);
setDate();

Xem bản demo hoạt động của đồng hồ cơ bản của chúng tôi:

Áp dụng điều này cho một gradient hình nón

OK, vậy là kim đồng hồ của chúng ta đang hoạt động. Những gì chúng tôi thực sự muốn là ánh xạ chúng thành một gradient hình nón cập nhật khi thời gian thay đổi. Bạn có thể đã thấy hiệu ứng tương tự nếu bạn có Apple Watch với mặt “Gradient” đang hoạt động:

Tín dụng: Macworld

Để làm điều này, hãy bắt đầu bằng cách cập nhật .clock phần tử có gradient hình nón và hai thuộc tính tùy chỉnh kiểm soát góc bắt đầu và góc kết thúc:

.clock {
  /* same as before */

  /* conic gradient vars */
  --start: 0deg;
  --end: 0deg;

  /* same as before */

  background: 
    conic-gradient(
      from var(--start),
      rgb(255 255 255) 2deg,
      rgb(0 0 0 / 0.5) var(--end),
      rgb(255 255 255) 2deg,
      rgb(0 0 0 / 0.7)
  );
}

Bạn có thể nghịch ngợm cái này một chút để tạo kiểu theo cách bạn thích. Tôi đã thêm một số màu bổ sung trong gradient theo ý thích của mình, nhưng miễn là bạn có điểm bắt đầu và điểm kết thúc, thì bạn đã sẵn sàng.

Tiếp theo, chúng tôi sẽ cập nhật setDate() hàm để nó cập nhật các biến cho điểm bắt đầu và điểm kết thúc của chúng ta trên gradient conic. Điểm bắt đầu sẽ là kim giây của chúng ta, rất dễ tìm vì nó sẽ giống với góc của phút của chúng ta. Để kết thúc điều này ở kim giờ, chúng ta nên đặt điểm kết thúc giống với hourAngle biến trong script, nhưng trừ điểm bắt đầu của chúng ta khỏi nó.

let startPosition = minsAngle;
let endPosition = hourAngle - minsAngle;

Bây giờ chúng ta có thể cập nhật lại các biến của mình bằng JavaScript:

clock.style.setProperty("--start", startPosition + "deg");
clock.style.setProperty("--end", endPosition + "deg");

Có vẻ như chúng tôi có thể hoàn thành vào thời điểm này, nhưng có một điểm khó khăn! Tính toán này hoạt động tốt miễn là kim phút có góc nhỏ hơn kim giờ. Gradient conic của chúng ta sẽ lộn xộn khi kim phút di chuyển qua nó. Để khắc phục điều này, chúng tôi sẽ sử dụng một giá trị âm làm điểm bắt đầu. May mắn thay, thật dễ dàng phát hiện khi điều này xảy ra. Trước khi cập nhật các biến của chúng tôi, chúng tôi sẽ thêm những điều sau:

if (minsAngle > hourAngle) {
  startPosition = minsAngle - 360;
  endPosition = hourAngle - startPosition;
}

Bằng cách trừ đi 360 từ góc độ phút của chúng tôi, chúng tôi có thể đặt giá trị âm cho startposition Biến đổi. Do điểm bắt đầu âm này, vị trí kết thúc của chúng ta phải được cập nhật theo góc giờ, trừ đi vị trí bắt đầu.

Chúng ta bắt đầu - bây giờ kim giờ và kim phút được đặt thành các góc nghiêng:

Đó là nó! Nhưng đừng để điều đó ngăn cản bạn tiến xa hơn nữa. Tạo phong cách của riêng bạn và chia sẻ chúng với tôi trong phần nhận xét để tôi có thể kiểm tra chúng .. Đây là một chút cảm hứng để giúp bạn tiếp tục:

Dấu thời gian:

Thêm từ Thủ thuật CSS