最近学了点canvas,做了个滴滴的进度条效果,由于本人未使用过滴滴,所以不太清楚该具体效果以及该页面是怎样的。yy出了以下效果:
先从简单的圆开始吧!
代码:
let c = document.getElementById("myCanvas")
// getContext() 方法返回一个用于在画布上绘图的环境。
let ctx = c.getContext("2d")
// 起始一条路径,或重置当前路径
ctx.beginPath()
// 创建弧/曲线(用于创建圆形或部分圆)
ctx.arc(100, 75, 50, 0, 2*Math.PI)
// 绘制已定义的路径
ctx.stroke()
这里贴出arc()函数说明:
context.arc(x,y,r,sAngle,eAngle,counterclockwise);
有兴趣的同学可以进入链接查看更多属性和方法: http://caibaojian.com/html5-c...
接下来我们绘制圆环以及动画:
let canvas = document.getElementById('myCanvas'),
context = canvas.getContext('2d'),
cirX = canvas.width/2,
cirY = canvas.height/2,
rad = Math.PI*2/100,
n = 0,
r = 45;
绘制图形并生成动画:
function DreamLoading() {
// clearRect() 方法清空给定矩形内的指定像素。
context.clearRect(0,0,canvas.width,canvas.height);
writeCircle();
writeText(n);
writeOrange(n);
if(n < 100) {
n = n + 0.1
} else {
n = 100;
}
window.requestAnimationFrame(DreamLoading);
}
当我们写window.requestAnimationFrame(回调函数)时,浏览器会在下次重绘前执行回调函数。这样就有进度条的效果了。
画圆:
function writeCircle() {
// 画个圆
// save() 方法把当前状态的一份拷贝压入到一个保存图像状态的栈中。这就允许您临时地改变图像状态,然后,通过调用 restore() 来恢复以前的值。
context.save();
context.beginPath();
context.strokeStyle = "#FF8C00";
context.arc(cirX,cirY,r,0,Math.PI*2,false);
context.stroke();
context.restore();
}
进度条:圆的厚边框,lineWidth自行设置
function writeOrange(n) {
context.save();
context.strokeStyle = "#FF8C00";
context.lineWidth = 3;
context.beginPath();
context.arc(cirX,cirY,r,-Math.PI/2,-Math.PI/2+rad*n,false);
context.stroke();
// restore() 方法将绘图状态置为保存值。
context.restore();
}
文本,百分比效果:
function writeText(n) {
context.save();
context.strokeStyle = '#FF8C00';
context.font = '20px Arail';
context.strokeText(n.toFixed() + '%', cirX-30,cirY+10);
context.stroke();
context.restore();
}
百分比进度条效果全部代码:
<!doctype html>
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
canvas {
margin: 0 auto;
display: block;
}
</style>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
window.onload = function () {
let canvas = document.getElementById('myCanvas'),
context = canvas.getContext('2d'),
cirX = canvas.width/2,
cirY = canvas.height/2,
rad = Math.PI*2/100,
n = 0,
r = 45;
function DreamLoading() {
context.clearRect(0,0,canvas.width,canvas.height);
writeCircle();
writeText(n);
writeOrange(n);
if(n < 100) {
n = n + 0.1
} else {
n = 100;
}
window.requestAnimationFrame(DreamLoading);
}
function writeText(n) {
context.save();
context.strokeStyle = '#FF8C00';
context.font = '20px Arail';
context.strokeText(n.toFixed() + '%', cirX-30,cirY+10);
context.stroke();
context.restore();
}
function writeOrange(n) {
context.save();
context.strokeStyle = ' #FF8C00';
context.lineWidth = 3;
context.beginPath();
context.arc(cirX,cirY,r,-Math.PI/2,-Math.PI/2+rad*n,false);
context.stroke();
context.restore();
}
function writeCircle() {
// 画个圆
// stroke 边框
// 保存当前的绘制缓冲区
context.save();
// 开始路径
context.beginPath();
context.strokeStyle = " #FF8C00";
context.arc(cirX,cirY,r,0,Math.PI*2,false);
context.stroke();
context.restore();
}
DreamLoading();
}
</script>
</body>
</html>
倒计时效果代码:
let minute = 1
const Time = minute*60
let second = 0
render(minute, second)
const interval = setInterval(() => {
if (second < 60) {
second--
if (second < 0) {
second = 59
minute--
}
}
if(minute == 0 && second == 0) {
clearInterval(interval)
}
render(minute, second)
},1000)
function render(minute, second) {
if (minute < 10) {
document.querySelector('.minute').innerText = '0' + minute;
} else {
document.querySelector('.minute').innerText = minute;
}
if (second < 10) {
document.querySelector('.second').innerText = '0' + second;
} else {
document.querySelector('.second').innerText = second;
}
}
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.header {
height: 44px;
border-bottom: 1px solid #eee;
background-color: #ddd;
display: -webkit-flex;
display: flex;
align-items: center;
}
.header-left {
width: 3rem;
margin-left: 1rem;
}
.header-left .back {
display: block;
width: .8rem;
height: .8rem;
border-left: 1px solid red;
border-bottom: 1px solid red;
transform: rotateZ(45deg);
}
.header-middle {
flex: 1;
text-align: center;
}
.header-right {
width: 4rem;
margin-right: .5rem;
}
.content {
width: 100%;
height: 11rem;
background: url(http://st2.depositphotos.com/6064568/10599/v/950/depositphotos_105993268-stock-illustration-man-holding-smartphone-in-hand.jpg);
background-size: cover;
position: relative;
}
canvas {
margin: 0 auto;
display: block;
}
.tip {
text-align: center;
font-size: 1.2rem;
margin-top: -.5rem;
}
.time {
/*width: 5rem;
height: 1rem;*/
/*position: absolute;
top: 30%;*/
/*left: 42%;*/
margin: 0 auto;
margin-top: -7rem;
}
.time p:first-child {
font-size: 1.5rem;
text-align: center;
}
.time p:last-child {
font-size: .8rem;
text-align: center;
}
</style>
</head>
<body>
<div class="header">
<div class="header-left">
<i class="back"></i>
</div>
<div class="header-middle">
派单中
</div>
<div class="header-right">
取消订单
</div>
</div>
<div class="content">
<canvas id="canvas"></canvas>
<div class="tip">系统选择司机</div>
<div class="time">
<p><span class="minute"></span>:<span class="second"></span></p>
<p>秒倒计时</p>
</div>
</div>
<script>
window.onload = function() {
let minute = 1
const Time = minute*60
let second = 0
render(minute, second)
const interval = setInterval(() => {
if (second < 60) {
second--
if (second < 0) {
second = 59
minute--
}
}
if(minute == 0 && second == 0) {
clearInterval(interval)
}
render(minute, second)
},1000)
function render(minute, second) {
if (minute < 10) {
document.querySelector('.minute').innerText = '0' + minute;
} else {
document.querySelector('.minute').innerText = minute;
}
if (second < 10) {
document.querySelector('.second').innerText = '0' + second;
} else {
document.querySelector('.second').innerText = second;
}
}
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
cirX = canvas.width/2,
cirY = canvas.height/2,
rad = Math.PI*2/(Time*Math.PI*2),
n = 0,
r = 45;
function DreamLoading() {
context.clearRect(0,0,canvas.width,canvas.height);
writeCircle();
// writeText(n);
writeOrange(n);
if(n < Time*Math.PI*2) {
n = n + 0.105
} else {
n = Time*Math.PI*2;
}
window.requestAnimationFrame(DreamLoading);
}
// function writeText(n) {
// context.save();
// context.strokeStyle = '#FF8C00';
// context.font = '20px Arail';
// context.strokeText(n.toFixed() + '%', cirX-30,cirY+10);
// context.stroke();
// context.restore();
// }
function writeOrange(n) {
context.save();
context.strokeStyle = ' #FF8C00';
context.lineWidth = 3;
context.beginPath();
context.arc(cirX,cirY,r,-Math.PI/2,-Math.PI/2+rad*n,false);
context.stroke();
context.restore();
}
function writeCircle() {
// 画个圆
// stroke 边框
// 保存当前的绘制缓冲区
context.save();
// 开始路径
context.beginPath();
context.strokeStyle = " #FF8C00";
context.arc(cirX,cirY,r,0,Math.PI*2,false);
context.stroke();
context.restore();
}
DreamLoading();
}
</script>
</body>
</html>
不够精确,在计算的时候有些错误。希望同学们能一起解决。谢谢!