This article introduces the sample code of the canvas ring countdown component and shares it with everyone. The details are as follows:
The effect is as shown in Figure 1:
Canvas ring countdown componentCanvas ring countdown is a countdown implemented based on Canvas and is recommended for use on mobile devices.
Canvas ring countdown download address
1. How to use1. html code
The ID attribute can be named arbitrarily
<canvas id=canvas></canvas>
2. Introduce process.js file
Page reference
<script src=js/process.js></script>
3. Initialization parameters
Just instantiate
<script> window.onload = function () { let ctd = new Countdown(); ctd.init(); };</script> 2. Description of settings parametersThe following parameters are not required and can be configured according to specific needs.
window.onload = function () { let ctd = new Countdown(); ctd.init({ id: canvas, // ID, canvas must have ID attribute size: 130, // The maximum size for drawing a circle, width = High borderWidth: 4, // Border width borderColor: #fff, // Border color outerColor: #fff, // Outermost bottom circle color scheduleColor: #fff, // Progress bar animation color fontColor: #fff, // Font color ringColor: #ffc720, // Progress bar ring color innerColor: #4e84e5, // Innermost circle background color fontSize: 50, time: 5 }); }; 3. Sample codehtml
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <title>Title</title> <style> body { background: #c2c1ce; } .container { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 130px; height: 130px; text-align: center; } </style></head><body><div class=container> <canvas class=canvas id=canvas></canvas></div><script src=js/process.js></script ><script> window.onload = function () { let ctd = new Countdown(); ctd.init(); };</script></body></html>js
/** * Created by Tan Xi on 2018/3/15. */function Countdown() { // Set the default parameters this.settings = { id: canvas, // ID, canvas must have ID attribute size: 130, // The maximum size for drawing a circle, width = height borderWidth: 4, // Border width borderColor: #fff, // Border color outerColor: #fff, // Outermost bottom circle color scheduleColor: #fff, // progress bar animation color fontColor: #fff, // font color ringColor: #ffc720, // progress bar ring color innerColor: #4e84e5, // innermost circle background color fontSize : 50, time: 5 }}Countdown.prototype.init = function (opt) { this.obj = document.getElementById(this.settings.id); this.obj.width = this.settings.size; this.obj.height = this.settings.size; this.ctx = this.obj.getContext(2d); extend( this.settings, opt); this.countdown();};//Draw the background color Countdown.prototype.drawBackground = function () { this.drawCircle(0, 360, 0, this.settings.outerColor);};// Draw progress bar animation background Countdown.prototype.drawProcess = function () { this.drawCircle(0, 360, 4, this.settings.ringColor);};/ / Draw countdown Countdown.prototype.drawInner = function () { this.drawCircle(0, 360, 23, this.settings.innerColor); this.strokeBorder(this.settings.borderWidth);};// Draw progress bar animation Countdown.prototype.drawAnimate = function () { // Rotation angle let deg = Math.PI / 180; let v = schedule * 360, startAng = -90, endAng = -90 + v; this.ctx.beginPath(); this.ctx.moveTo(this.settings.size / 2, this.settings.size / 2); this.ctx.arc(this.settings.size / 2, this.settings.size / 2, this.settings.size / 2 -3, startAng * deg, endAng * deg, false); this.ctx.fillStyle = this.settings.scheduleColor; this.ctx.fill(); this.ctx.closePath();};// Draw the border Countdown.prototype.strokeBorder = function (borderWidth) { this.ctx.lineWidth = borderWidth; this.ctx.strokeStyle = this.settings.borderColor; this.ctx.stroke ();};// Draw text Countdown.prototype.strokeText = function (text) { this.ctx.textAlign = center; this.ctx.textBaseline = middle; this.ctx.font = this.settings.fontSize+px+ microsoft yahei; this.ctx.fillStyle = this.settings.fontColor; this.ctx.fillText(text, this.settings.size / 2, this.settings.size / 2);};// Draw a circle Countdown.prototype.drawCircle = function (startAng, endAng, border, fillColor) { let deg = Math.PI / 180; this.ctx.beginPath(); this.ctx.arc(this.settings.size / 2, this.settings.size / 2, this.settings.size / 2 -border, startAng * deg, endAng * deg, false); this.ctx.fillStyle = fillColor; this.ctx.fill(); this.ctx.closePath();};//Progress bar animation Countdown.prototype.countdown = function () { let oldTime = +new Date(); timer = setInterval(() => { let allMs = this.settings. time * 1000,// For example, 30*1000=30 000ms currentTime = +new Date(); // Step size = (current time - past time) / total number of seconds schedule = (currentTime - oldTime) / allMs; this.schedule = schedule; this.drawAll(schedule); if (currentTime - oldTime >= allMs) { / / Redraw this.drawBackground(); this.drawProcess(); this.drawAnimate(); this.drawInner(); this.strokeText(0); clearInterval(timer); } }, 100);};// Draw all Countdown.prototype.drawAll = function (schedule) { schedule = schedule >= 1 ? 1 : schedule; let text = parseInt(this.settings.time * (1 - schedule)) + 1; // Clear the canvas this.ctx.clearRect(0, 0, this.settings.size, this.settings.size); this.drawBackground(); this.drawProcess(); this.drawAnimate(); this.drawInner(); this.strokeText(text);};//Object copy function extend(obj1,obj2){ for(let attr in obj2){ obj1[attr] = obj2[attr]; }} 4. Additional-canvas preparation workIn fact, canvas is not that mysterious. It is nothing more than an H5 tag, just like other HTML tags:
<canvas id=canvas></canvas>
Note that it is best to set the width and height of the canvas at the beginning (if you do not set the width and height, the browser will default to setting the canvas size to 300 pixels wide and 100 pixels high), and it cannot be set using css (it will be pulled extension), it is recommended to write directly inside the canvas tag:
<canvas id=canvas width=130 height=130></canvas>
Canvas itself does not have any drawing capabilities, and all drawing work is implemented through js. Usually we use getElementById in js to get the canvas to be operated on (this means that we have to set an id for the canvas):
var c = document.getElementById(canvas);var ctx = c.getContext(2d);
1. After preparing the brush, you can start drawing. Rings are actually concentric circles with different radii. The center coordinates are (size/2, size/2). First draw the largest white background bottom circle with a radius of size/2.
let deg = Math.PI / 180; // beginPath() can isolate the path drawing effect and prevent previous effects from being contaminated. ctx.beginPath();// tcx.arc(circle center deg, 360 * deg, false);ctx.fillStyle = #fff;ctx.fill();ctx.closePath();
2. Start drawing the second yellow bottom circle, the center of the circle is also (size/2, size/2), but the radius is 4px smaller than the white bottom circle, so the radius of the yellow bottom circle is (size/2-4)
let deg = Math.PI / 180; // beginPath() can isolate the path drawing effect and prevent previous effects from being contaminated. ctx.beginPath();//tcx.arc(circle center 0* deg, 360 * deg, false);ctx.fillStyle = #fff;ctx.fill();ctx.closePath();
3. Start drawing a blue inner circle, with the center of the circle being (size/2,size/2) and the radius being (size-23), and then add a 4px white border to it.
let deg = Math.PI / 180; // beginPath() can isolate the path drawing effect and prevent previous effects from being contaminated. ctx.beginPath();// tcx.arc(circle center 0* deg, 360 * deg, false);ctx.fillStyle = #fff;ctx.fill();ctx.closePath();// White border ctx.lineWidth = 4;ctx.strokeStyle = #fff;ctx.stroke();
4. Draw text and center it vertically
ctx.textAlign = center;ctx.textBaseline = middle;ctx.fillStyle = #fff;// ctx.fillText (text, X coordinate relative to the canvas, Y coordinate relative to the canvas) ctx.fillText(30, size / 2, size / 2);
5. How to create animation? In fact, it is also a process of drawing a white circle, a process of slowly covering the yellow progress bar. Then draw the white circle first. At this time, the blue circle will be covered by the white animated circle. At this time, the last blue circle will be drawn. alright.
let deg = Math.PI / 180;ctx.beginPath();// tcx.arc(circle center X, circle center Y, radius, starting angle, ending angle, clockwise and counterclockwise);ctx.arc(size / 2, size / 2, size / 2-4, 0* deg, 360 * deg, false);ctx.fillStyle = #fff;ctx.fill();ctx.closePath();
6. The relatively simple painting process is completed. Next, we need to associate the animation with the numbers. Using the current latest time - the earliest time, and then dividing the total time, we can get a key percentage. This percentage determines the change of the numbers. and the angle at which the white animated circle is drawn.
Countdown.prototype.countdown = function () { let oldTime = +new Date(); // Past time: 1522136419291 timer = setInterval(() => { let currentTime = +new Date(); // Current time: 1522136419393 let allMs = this.settings.time * 1000;// Total time in seconds: such as 30*1000=30 000ms schedule = (currentTime - oldTime) / allMs;// Drawing percentage: (1522136419393-1522136419291)/30000=0.0204 this.schedule = schedule; this.drawAll(schedule); if (currentTime - oldTime >= allMs) { // Redraw this.drawBackground(); this.drawProcess(); this.drawAnimate(); this.drawInner(); this.strokeText(0); clearInterval(timer); } }, 10);}; // Draw all Countdown.prototype.drawAll = function (schedule) { schedule = schedule >= 1 ? 1 : schedule; let text = parseInt(this.settings.time * (1 - schedule)) + 1; // Clear the canvas this.ctx.clearRect(0, 0, this.settings.size, this.settings.size); this.drawBackground(); this.drawProcess(); this.drawAnimate( ); this.drawInner(); this.strokeText(text);};// Draw progress bar animation Countdown.prototype.drawAnimate = function () { // Rotation angle let deg = Math.PI / 180; let v = schedule * 360, startAng = -90,//Start angle endAng = -90 + v;//End angle this.ctx.beginPath(); this.ctx.moveTo(this.settings .size / 2, this.settings.size / 2); this.ctx.arc(this.settings.size / 2, this.settings.size / 2, this.settings.size / 2 - 3, startAng * deg, endAng * deg, false); this.ctx.fillStyle = this.settings.scheduleColor; this.ctx.fill(); this.ctx.closePath();} ;Process-oriented version
/** * Progress bar animation*/ countdown: function () { this.getSystemInfo().then(v => { // Adaptive let width = v.windowWidth, size = width >= 414 ? 66 : 400 / 414 * 66; size = parseInt(size); size = size % 2 ? size + 1 : size; let maxtime =30, sTime = +new Date, temp = setInterval(() => { let time = maxtime * 1000, currentTime = +new Date, schedule = (currentTime - sTime) / time; this.drew(schedule, maxtime, size); if (currentTime - sTime >= time ) { // Draw text this.setData({ schedule: 0 }); clearInterval(temp); }; }, 100); }); }, /** * draw*/ drew: function (schedule, val, size) { size = size || 66; const _ts = this; schedule = schedule >= 1 ? 1 : schedule; let text = parseInt(val - val * schedule), r = size / 2, deg = Math.PI / 180; _ts.setData({ width: size, height: size, schedule: text + 1 }); // Clear the canvas ctx.clearRect(0, 0, size, size); // Draw a white background ctx.beginPath(); ctx.arc(r, r, r, 0 * deg, 360 * deg); ctx.fillStyle = ' rgba(255,255,255,1)'; ctx.closePath(); ctx.fill(); // Draw orange ctx.beginPath(); ctx.arc(r, r, r - 2, 0 * deg, 360 * deg); ctx.fillStyle = 'rgba(248,200,80,1)'; ctx.closePath(); ctx.fill(); // Draw a white progress bar let v = schedule * 360; ctx.beginPath(); ctx.moveTo(r, r); ctx.arc(r, r, r, -90 * deg, (-90 + v) * deg); ctx.fillStyle = 'rgba(255,255,255,1)'; ctx.closePath (); ctx.fill(); // Center blue bottom ctx.beginPath(); ctx.arc(r, r, r - 12, 0 * deg, 360 * deg); ctx.fillStyle = 'rgba(90,140,220,1)'; ctx.closePath(); ctx.fill(); // Draw text ctx.strokeText(); // Unified drawing ctx.draw(); },The above is the entire content of this article. I hope it will be helpful to everyone’s study. I also hope everyone will support VeVb Wulin Network.