欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中的canvas?實現(xiàn)一個圓環(huán)漸變倒計時效果

 更新時間:2022年09月14日 11:04:31   作者:用戶4811483110569???????  
這篇文章主要介紹了JavaScript中的canvas?實現(xiàn)一個圓環(huán)漸變倒計時效果,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

前言

內容:

  • 效果圖
  • 需求分析
  • 實現(xiàn)技術
  • 實現(xiàn)過程
  • 全部源碼

1、效果圖展示

(img-iSl2hFK6-1605966576712)(./images/1.png)]

隨著時間的減少, 圓環(huán)的紅黃色部分會慢慢的減少,圓環(huán)中的數(shù)字會變小,一直到0停止.

2、需求分析

  • 可以自定義倒計時結束的時間
  • 圓環(huán)的顏色是漸變的
  • 倒計時的動畫在視覺上是流暢運行, 而不是一格一格的減少

3、實現(xiàn)的技術

語言框架
HTML5
CSS3BootStrap SASS
JavaScript

4、實現(xiàn)的過程

1. HTML 部分

主要用到的是 HTML5 中的畫布元素 canvas, 一共4個 canvas 元素拍成一排, 每個元素都是高144px, 寬144px的正方形, 兩個圓環(huán)中的兩個小點部分可以使用偽元素 after 和 before 來實現(xiàn)

源碼如下:

<div class="count-down">
 <div class="container">
   <div class="row">
     <div class="days col-lg-3 col-md-3 col-sm-3 col-xs-6">
       <div class="colck">
         <canvas id="days" width="144" height="144"></canvas>
       </div>
     </div>
     <div class="hours col-lg-3 col-md-3 col-sm-3 col-xs-6">
       <div class="colck">
         <canvas id="hours" width="144" height="144"></canvas>
       </div>
     </div>
     <div class="minutes col-lg-3 col-md-3 col-sm-3 col-xs-6">
       <div class="colck">
         <canvas id="minutes" width="144" height="144"></canvas>
       </div>
     </div>
     <div class="seconds col-lg-3 col-md-3 col-sm-3 col-xs-6">
       <div class="colck">
         <canvas id="seconds" width="144" height="144"></canvas>
       </div>
     </div>
   </div>
 </div>
</div>

用 BootStrap 提供的柵格布局快速的把 canvas 元素排成一排 為每個 cnavas 元素設置對應的 id, 方便用 JavaScript 獲取到該元素.

2. SASS部分

css 的部分是用 Sass 來寫的, Sass 是一個 css 的 擴展語言, html 文件中引用的是寫好的 Sass 文件編譯生成 css 文件.

源碼如下:

.count-down {
  width: 100%;
  .row {
    padding: 0 145px;
  }
  .col-lg-3 {
    padding: 0;
    position: relative;
    .colck {
      width: 144px;
      height: 144px;
      background-color: #fff;
      margin: 0 auto;
    }
  }
  .days, .hours, .minutes {
    &:after, &:before {
      content: "";
      display: block;
      width: 12px;
      height: 12px;
      background-color: #fff;
      position: absolute;
      right: -6px;
    }
    &:after {
      bottom: 45px;
    }
    &:before {
      top: 45px;
    } 
  }
}

控制圓環(huán)的運動主要靠 JavaScript 代碼, 這里 sass 的作用是用來把把元素的位置排列好, 把兩個圓環(huán)中間的點畫出來,

因為背景色是黑色的 為了看的更加直觀, 我先把包裹 canvas 的元素背景色設為白色,

此時的效果: 

在這里插入圖片描述

3. JavaScript部分

最終的運動效果靠 js 代碼來實現(xiàn):

  • 我們先來獲取到這4個 canvas 元素
// 獲取4個 canvas 元素
var days_canvas = document.getElementById('days');
var hours_canvas = document.getElementById('hours');
var minutes_canvas = document.getElementById('minutes');
var seconds_canvas = document.getElementById('seconds');
  • 為了可以自定義指定倒計時結束時間, 寫一個設置結束時間的函數(shù), 返回值為一個 Date 對象.
// 設置倒計時時間:年 月 日 小時 分鐘 秒 毫秒
endTime = setEndTime(2020, 11, 30, 15, 0, 0);

// 設置到期時間
function setEndTime(year, month, day, hour, minute, millisecond) {
return new Date(year, month - 1, day, hour, minute, millisecond);
}

js 中創(chuàng)建 Date 對象的5種方式 new Date("month dd,yyyy hh:mm:ss"); new Date("month dd,yyyy"); new Date(yyyy,mth,dd,hh,mm,ss); new Date(yyyy,mth,dd); new Date(ms);

注意: Date 對象中的月份取值是 0 - 11, 0 就表示 1 月, 用變量 endTime 保存這個設置好的 Date 對象

  • 根據(jù)現(xiàn)在的時間和設置好的到期時間計算現(xiàn)在到到期時間還有多少秒,多少分鐘, 多少小時, 多少天.
// 計算距離到期時間還剩下多少 days, hours, minutes
 function getLeftTimeObj() {
   var date = new Date();
   var millisecond = date.getTime()
   var end_millisecond = endTime.getTime();

   if (end_millisecond < millisecond) {
     return {
       days: 0,
       hours: 0,
       minutes: 0,
       seconds: 0
     }
   }
   // 距離結束時間的秒數(shù)
   var left_seconds = (( end_millisecond - millisecond ) / 1000);
   var seconds = (left_seconds % 60);
   var left_minutes = (left_seconds - seconds) / 60;
   var minutes = (left_minutes % 60);
   var left_hours = (left_minutes - minutes) / 60;
   var hours = (left_hours % 24);
   var left_days = ((left_hours - hours) / 24);

   return {
     days: left_days,
     hours: hours,
     minutes: minutes,
     seconds: seconds
   }
 }
 var dateObj = getLeftTimeObj();

思路:

  • Date 對象中有一個方法 getTime(), 返回值是從 1970 年 1 月 1 日至今的毫秒數(shù)。
  • 用兩個 Date 對象的 getTime() 返回值相減值再 ÷ 1000 獲得兩者相差的秒數(shù)
  • 用兩者相差的秒數(shù)換算出兩者相差多少天,多少小時,多少分鐘,多少秒
  • 最后返回一個對象 { days: 還有多少天, hours: 還有多少個小時, minutes: 還有多少分鐘, secondsL: 還有多少秒 }

我們定義一個變量 dateObj 保存這個對象, 然后根據(jù)這個對象去在相應的 canvas 元素上畫圖

  • 繪圖

我們先不考慮怎么讓圓環(huán)動起來, 而是先考慮怎么把圖畫出來

觀察單個圖形的樣子如下圖所示:

在這里插入圖片描述

可以把這個圖形分成4個部分:

  • 灰色的整個圓環(huán)
  • 紅黃漸變的不完整圓環(huán)
  • 中間的數(shù)字 54
  • 下面的字符串 Seconds

我們可以為寫四個方法分別完成每一個步驟:

 // 畫整個圓
function drawCricle(canvas) {
  // 獲取 context 對象
  var context = canvas.getContext('2d');
  // 獲取 canvas 的中心點的 x 坐標
  var centerX = canvas.width / 2;
  // 獲取 canvas 的中心點的 y 坐標
  var centerY = canvas.height / 2;
  context.save();
  context.beginPath();
  context.lineWidth = 7;
  context.strokeStyle = "#636363";
  // 圓環(huán)的寬度為 7, canvas 元素的長和寬是 144, 所以圓半徑應為 (144 - 7) / 2, 也就是 canvas.width / 2 - 3.5
  context.arc(centerX, centerY, canvas.width / 2 - 3.5 , 0, Math.PI*2, false);
  context.stroke();
  context.closePath();
  context.restore();
}

// 畫數(shù)字下的字符
function drawStr(canvas, str) {
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;

  context.save();
  context.fillStyle = '#fff';
  context.font = "14px Arial"; //設置字體大小和字體
  context.textAlign = 'center';
  context.fillText(str, centerX, centerY+54);
  context.restore();
}

// 畫數(shù)字
function drawNumber(canvas, num) {
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;
  num = num.toFixed();
  num = num < 10 ? '0' + num : num;

  context.save();
  context.fillStyle = '#fff';
  context.font = "bolder 60px Arial"; //設置字體大小和字體
  context.textAlign = 'center';
  // context.fontWeight = 'bold';
  context.fillText(num, centerX, centerY+10);
  context.restore();
}
// 畫進度條 -0.5為起點
// percentage 為進度條的百分比(0<percentage<1), 1 表示整個圓
function drawProgress(canvas, percentage) {
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;

  var end_cricle = (percentage * 2) - 0.5;
  end_cricle = Number(end_cricle.toFixed(4))

  // 設置垂直漸變
  var linearGrad = context.createLinearGradient(canvas.width / 2, 0, canvas.width / 2, canvas.height);
  linearGrad.addColorStop(0, '#ff0503');
  linearGrad.addColorStop(1, '#ff8200');

  context.save();
  context.strokeStyle = linearGrad; //設置描邊樣式
  context.lineWidth = 7; //設置線寬
  context.beginPath(); //路徑開始
  context.arc(centerX, centerY, canvas.width / 2 -3.5 , -0.5 * Math.PI, end_cricle * Math.PI, false); //用于繪制圓弧context.arc(x坐標,y坐標,半徑,起始角度,終止角度,順時針/逆時針)
  context.stroke(); //繪制
  context.closePath(); //路徑結束
  context.restore();
}
// 為秒計數(shù)的 canvas 繪圖, 畫圖依賴 dateObj.seconds
drawCricle(seconds_canvas);
drawStr(seconds_canvas, 'Seconds');
// 每一分鐘有60秒, 用 dateObj.seconds / 60 獲得 當前進度
drawProgress(seconds_canvas, (dateObj.seconds / 60).toFixed(4));
drawNumber(seconds_canvas, dateObj.seconds);

寫一個繪制 4 個 canvas 的方法 draw(); 然后執(zhí)行

// 繪圖
function draw() {
  drawCricle(days_canvas);
  drawStr(days_canvas, 'Days');
  drawProgress(days_canvas, dateObj.days / 10);
  drawNumber(days_canvas, dateObj.days);

  drawCricle(hours_canvas);
  drawStr(hours_canvas, 'Hours');
  drawProgress(hours_canvas, (dateObj.hours / 24).toFixed(4));
  drawNumber(hours_canvas, dateObj.hours);

  drawCricle(minutes_canvas);
  drawStr(minutes_canvas, 'Minutes');
  drawProgress(minutes_canvas, (dateObj.minutes / 60).toFixed(4));
  drawNumber(minutes_canvas, dateObj.minutes);

  drawCricle(seconds_canvas);
  drawStr(seconds_canvas, 'Seconds');
  drawProgress(seconds_canvas, (dateObj.seconds / 60).toFixed(4));
  drawNumber(seconds_canvas, dateObj.seconds);
}

drwa();

然后先記得把之前設置的白色背景色去掉

執(zhí)行了 draw() 之后效果如下圖: 

在這里插入圖片描述

但是現(xiàn)在還沒有實現(xiàn)讓他動起來,

  • 讓倒計時動起來

先明白動起來的邏輯:

  • 用定時器每過 16ms 清除一次所有 canvas 畫的圖像
  • 重新獲取所剩下的時間的對象 dateObj
  • 再次繪圖 draw();
// 清除 canvas 內容
function clear() {
  var days_ctx = days_canvas.getContext('2d');
  var hours_ctx = hours_canvas.getContext('2d');
  var minutes_ctx = minutes_canvas.getContext('2d');
  var seconds_ctx = seconds_canvas.getContext('2d');

  days_ctx.clearRect(0, 0, days_canvas.width, days_canvas.height);
  hours_ctx.clearRect(0, 0, hours_canvas.width, hours_canvas.height);
  minutes_ctx.clearRect(0, 0, minutes_canvas.width, minutes_canvas.height);
  seconds_ctx.clearRect(0, 0, seconds_canvas.width, seconds_canvas.height);
}
// 讓倒計時動起來
// 可以直接用定時器
setInterval(function() {
  clear();
  dateObj = getLeftTimeObj();
  draw();
}, 16)

// 也可以考慮使用 requestAnimationFrame 這個方法
(function count() {
  requestAnimationFrame(count);
  clear();
  dateObj = getLeftTimeObj();
  draw();
})();

到現(xiàn)在為止整個完整的功能全部實現(xiàn)了。

5、全部源碼

1.index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./bootstrap.min.css" rel="external nofollow" >
  <link rel="stylesheet" href="./style.css" rel="external nofollow" >
  <style>
    .count-down {
      background: #000;
    }
  </style>
</head>
<body>
  <div class="count-down">
    <div class="container">
      <div class="row">
        <div class="days col-lg-3 col-md-3 col-sm-3 col-xs-6">
          <div class="colck">
            <canvas id="days" width="144" height="144"></canvas>
          </div>
        </div>
        <div class="hours col-lg-3 col-md-3 col-sm-3 col-xs-6">
          <div class="colck">
            <canvas id="hours" width="144" height="144"></canvas>
          </div>
        </div>
        <div class="minutes col-lg-3 col-md-3 col-sm-3 col-xs-6">
          <div class="colck">
            <canvas id="minutes" width="144" height="144"></canvas>
          </div>
        </div>
        <div class="seconds col-lg-3 col-md-3 col-sm-3 col-xs-6">
          <div class="colck">
            <canvas id="seconds" width="144" height="144"></canvas>
          </div>
        </div>
      </div>
    </div>
  </div>
  <script src="./index.js"></script>
</body>
</html>

2. style.scss

.count-down {
  position: absolute;
  bottom: 90px;
  left: 0;
  width: 100%;
  .row {
    padding: 0 145px;
  }
  .col-lg-3 {
    padding: 0;
    position: relative;
    .colck {
      width: 144px;
      height: 144px;
      // background-color: #fff;
      margin: 0 auto;
    }
  }
  .days, .hours, .minutes {
    &:after, &:before {
      content: "";
      display: block;
      width: 12px;
      height: 12px;
      background-color: #fff;
      position: absolute;
      right: -6px;
    }
    &:after {
      bottom: 45px;
    }
    &:before {
      top: 45px;
    } 
  }
}

3. index.js

// 倒計時
// 到期時間
// 設置倒計時時間:年 月 日 小時 分鐘 秒 毫秒
endTime = setEndTime(2020, 11, 30, 15, 0, 0);

// 設置到期時間
function setEndTime(year, month, day, hour, minute, millisecond) {
  return new Date(year, month - 1, day, hour, minute, millisecond);
}

// 獲取4個 canvas 元素
var days_canvas = document.getElementById('days');
var hours_canvas = document.getElementById('hours');
var minutes_canvas = document.getElementById('minutes');
var seconds_canvas = document.getElementById('seconds');

// 計算距離到期時間還剩下多少 days, hours, minutes
function getLeftTimeObj() {
  var date = new Date();
  var millisecond = date.getTime()
  var end_millisecond = endTime.getTime();

  if (end_millisecond < millisecond) {
    return {
      days: 0,
      hours: 0,
      minutes: 0,
      seconds: 0
    }
  }

  // 距離結束時間的秒數(shù)
  var left_seconds = (( end_millisecond - millisecond ) / 1000);

  var seconds = (left_seconds % 60);
  var left_minutes = (left_seconds - seconds) / 60;
  var minutes = (left_minutes % 60);
  var left_hours = (left_minutes - minutes) / 60;
  var hours = (left_hours % 24);
  var left_days = ((left_hours - hours) / 24);

  return {
    days: left_days,
    hours: hours,
    minutes: minutes,
    seconds: seconds
  }
}

var dateObj = getLeftTimeObj();

// 畫整個圓
function drawCricle(canvas) {
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;

  context.save();
  context.beginPath();
  context.lineWidth = 7;
  context.strokeStyle = "#636363";
  context.arc(centerX, centerY, canvas.width / 2 - 3.5 , 0, Math.PI*2, false);
  context.stroke();
  context.closePath();
  context.restore();
}

// 畫數(shù)字下的字符
function drawStr(canvas, str) {
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;

  context.save();
  context.fillStyle = '#fff';
  context.font = "14px Arial"; //設置字體大小和字體
  context.textAlign = 'center';
  context.fillText(str, centerX, centerY+54);
  context.restore();
}

// 畫數(shù)字
function drawNumber(canvas, num) {
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;
  num = num.toFixed();
  num = num < 10 ? '0' + num : num;

  context.save();
  context.fillStyle = '#fff';
  context.font = "bolder 60px Arial"; //設置字體大小和字體
  context.textAlign = 'center';
  // context.fontWeight = 'bold';
  context.fillText(num, centerX, centerY+10);
  context.restore();
}

// 畫進度條 -0.5為起點
// percentage 為進度條的百分比(0<percentage<1), 1 表示整個圓
function drawProgress(canvas, percentage) {
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;

  var end_cricle = (percentage * 2) - 0.5;
  end_cricle = Number(end_cricle.toFixed(4))

  // 設置垂直漸變
  var linearGrad = context.createLinearGradient(canvas.width / 2, 0, canvas.width / 2, canvas.height);
  linearGrad.addColorStop(0, '#ff0503');
  linearGrad.addColorStop(1, '#ff8200');

  context.save();
  context.strokeStyle = linearGrad; //設置描邊樣式
  context.lineWidth = 7; //設置線寬
  context.beginPath(); //路徑開始
  context.arc(centerX, centerY, canvas.width / 2 -3.5 , -0.5 * Math.PI, end_cricle * Math.PI, false); //用于繪制圓弧context.arc(x坐標,y坐標,半徑,起始角度,終止角度,順時針/逆時針)
  context.stroke(); //繪制
  context.closePath(); //路徑結束
  context.restore();
}

// 清除 canvas 內容
function clear() {
  var days_ctx = days_canvas.getContext('2d');
  var hours_ctx = hours_canvas.getContext('2d');
  var minutes_ctx = minutes_canvas.getContext('2d');
  var seconds_ctx = seconds_canvas.getContext('2d');

  days_ctx.clearRect(0, 0, days_canvas.width, days_canvas.height);
  hours_ctx.clearRect(0, 0, hours_canvas.width, hours_canvas.height);
  minutes_ctx.clearRect(0, 0, minutes_canvas.width, minutes_canvas.height);
  seconds_ctx.clearRect(0, 0, seconds_canvas.width, seconds_canvas.height);
}

// 繪圖
function draw() {
  drawCricle(days_canvas);
  drawCricle(hours_canvas);
  drawCricle(minutes_canvas);
  drawCricle(seconds_canvas);
  drawStr(days_canvas, 'Days');
  drawStr(hours_canvas, 'Hours');
  drawStr(minutes_canvas, 'Minutes');
  drawStr(seconds_canvas, 'Seconds');

  drawProgress(days_canvas, dateObj.days / 10 >= 1 ? 1 : dateObj.days / 10);
  drawNumber(days_canvas, dateObj.days);
  drawProgress(hours_canvas, (dateObj.hours / 24).toFixed(4));
  drawNumber(hours_canvas, dateObj.hours);
  drawProgress(minutes_canvas, (dateObj.minutes / 60).toFixed(4));
  drawNumber(minutes_canvas, dateObj.minutes);
  drawProgress(seconds_canvas, (dateObj.seconds / 60).toFixed(4));
  drawNumber(seconds_canvas, dateObj.seconds);
}

draw();

(function count() {
  requestAnimationFrame(count);
  clear();
  dateObj = getLeftTimeObj();
  draw();
})();

到此這篇關于JavaScript中的canvas 實現(xiàn)一個圓環(huán)漸變倒計時效果的文章就介紹到這了,更多相關JavaScript canvas 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論