html画布实现小球沿直线下落,canvas实现波浪进度小球

看一下最终效果:

0ad6f2a87445

canvas波浪进度球.gif

首先:

HTML放三个canvas标签

这里考虑到需求页面有三个类似小球,且后续可能还会用到,所以对绘制小球的方法进行封装:

1、定义方法,并创建画布cW,cH为canvas宽高

function drawRate(id, rate, color1, color2, color3, color4){

//创建画布

var canvas = document.getElementById(id);

var ctx = canvas.getContext('2d');

//canvas属性

var clientW = document.documentElement.clientWidth > 1000 ? document.documentElement.clientWidth : 1000; //由于画布width和height自适应宽高

var cW = canvas.width = 309/1920 * clientW;

var cH = canvas.height = 309/1920 * clientW;

}

2、添加球的属性以及后续sin曲线的属性

function drawRate(id, rate, color1, color2, color3, color4){

//创建画布

var canvas = document.getElementById(id);

var ctx = canvas.getContext('2d');

//canvas属性

var clientW = document.documentElement.clientWidth > 1000 ? document.documentElement.clientWidth : 1000; //由于画布width和height自适应宽高

var cW = canvas.width = 309/1920 * clientW;

var cH = canvas.height = 309/1920 * clientW;

var lineWidth = 2;

console.log(cW ,cH,clientW)

//内圆属性

var r = 0.8 * cW / 2; //半径

var cR = r - 2 * lineWidth;

//sin曲线属性

var sX = 0; //sin函数的初始x值

var axisLength = cW; //轴长

var waveWidth = 0.035; //波浪宽度,数越小越宽

var waveHeight = 6; //波浪高度,数越大越高

var speed = 0.05; //波浪速度,数越大速度越快

var xOffset = 0; //波浪x偏移量

}

//画圈函数

ctx.lineWidth = lineWidth;

var IsdrawCircled = false;

var drawCircle = function () {

ctx.beginPath();

ctx.strokeStyle = color1;

ctx.arc(cW / 2, cH / 2, cR + 21, 0, 2 * Math.PI);

ctx.stroke();

ctx.fillStyle = color1;

ctx.fill();

ctx.beginPath();

ctx.strokeStyle = color4;

ctx.arc(cW/2, cH/2, cR + 11, 0, 2 * Math.PI);

ctx.stroke();

ctx.fillStyle = color2;

ctx.fill();

ctx.beginPath();

ctx.strokeStyle = color4;

ctx.arc(cW/2, cH/2, cR + 1, 0, 2 * Math.PI);

ctx.stroke();

ctx.beginPath();

ctx.arc(cW / 2, cH / 2, cR, 0, 2 * Math.PI);

ctx.fillStyle = color2;

ctx.fill();

ctx.clip();

IsdrawCircled = true

}

4、绘制sin曲线:

//画sin 曲线函数

var drawSin = function (xOffset) {

ctx.save();

ctx.rect(0, 0, cW, cH);

ctx.fillStyle = color3;

ctx.fill();

//用于存放绘制Sin曲线的点

var points = [];

ctx.beginPath();

//在整个轴长上取点

for (var x = sX; x < sX + axisLength; x += 20 / axisLength) {

//公式 “振幅高*sin(x*振幅宽 + 振幅偏移量)”

var y = Math.sin((-sX - x) * waveWidth + xOffset);

var dY = cH * (1 - rate / 100) - 10;

points.push([x, dY + y * waveHeight]);

ctx.lineTo(x, dY + y * waveHeight);

}

//绘制路径

ctx.lineTo(axisLength, cH);

ctx.lineTo(sX, cH);

ctx.lineTo(points[0][0], points[0][1]);

//填充sin曲线画出的区域

ctx.fillStyle = color4;

ctx.fill();

ctx.restore();

};

5、小球内部写入百分比

//写百分比文本函数

var drawText = function () {

ctx.save();

var size = 0.3 * cR;

ctx.font = size + 'px Microsoft Yahei';

ctx.textAlign = 'center';

ctx.fillStyle = "#ffffff";

ctx.fillText(rate + '%', cW/2, cW/2 + size / 2);

ctx.restore();

};

6、最后绘制的方法:

var render = function () {

ctx.clearRect(0, 0, cW, cH);

if (IsdrawCircled == false) {

drawCircle();

}

//drawSin(xOffset + Math.PI * 0.7);

drawSin(xOffset);

drawText();

xOffset += speed;

requestAnimationFrame(render);

}

render();

最后贴一个封装好的方法:

//画波浪球id:dom节点id, rate:占比, color1-4:由外到内圆的颜色

function drawRate(id, rate, color1, color2, color3, color4){

//创建画布

var canvas = document.getElementById(id);

var ctx = canvas.getContext('2d');

//canvas属性

var clientW = document.documentElement.clientWidth > 1000 ? document.documentElement.clientWidth : 1000; //由于画布width和height自适应宽高

var cW = canvas.width = 309/1920 * clientW;

var cH = canvas.height = 309/1920 * clientW;

var lineWidth = 2;

console.log(cW ,cH,clientW)

//内圆属性

var r = 0.8 * cW / 2; //半径

var cR = r - 2 * lineWidth;

//sin曲线属性

var sX = 0; //sin函数的初始x值

var axisLength = cW; //轴长

var waveWidth = 0.035; //波浪宽度,数越小越宽

var waveHeight = 6; //波浪高度,数越大越高

var speed = 0.05; //波浪速度,数越大速度越快

var xOffset = 0; //波浪x偏移量

ctx.lineWidth = lineWidth;

//画圈函数

var IsdrawCircled = false;

var drawCircle = function () {

ctx.beginPath();

ctx.strokeStyle = color1;

ctx.arc(cW / 2, cH / 2, cR + 21, 0, 2 * Math.PI);

ctx.stroke();

ctx.fillStyle = color1;

ctx.fill();

ctx.beginPath();

ctx.strokeStyle = color4;

ctx.arc(cW/2, cH/2, cR + 11, 0, 2 * Math.PI);

ctx.stroke();

ctx.fillStyle = color2;

ctx.fill();

ctx.beginPath();

ctx.strokeStyle = color4;

ctx.arc(cW/2, cH/2, cR + 1, 0, 2 * Math.PI);

ctx.stroke();

ctx.beginPath();

ctx.arc(cW / 2, cH / 2, cR, 0, 2 * Math.PI);

ctx.fillStyle = color2;

ctx.fill();

ctx.clip();

IsdrawCircled = true

}

//画sin 曲线函数

var drawSin = function (xOffset) {

ctx.save();

ctx.rect(0, 0, cW, cH);

ctx.fillStyle = color3;

ctx.fill();

var points = []; //用于存放绘制Sin曲线的点

ctx.beginPath();

//在整个轴长上取点

for (var x = sX; x < sX + axisLength; x += 20 / axisLength) {

//此处坐标(x,y)的取点,依靠公式 “振幅高*sin(x*振幅宽 + 振幅偏移量)”

var y = Math.sin((-sX - x) * waveWidth + xOffset);

var dY = cH * (1 - rate / 100) - 10;

points.push([x, dY + y * waveHeight]);

ctx.lineTo(x, dY + y * waveHeight);

}

//封闭路径

ctx.lineTo(axisLength, cH);

ctx.lineTo(sX, cH);

ctx.lineTo(points[0][0], points[0][1]);

ctx.fillStyle = color4;

ctx.fill();

ctx.restore();

};

//写百分比文本函数

var drawText = function () {

ctx.save();

var size = 0.3 * cR;

ctx.font = size + 'px Microsoft Yahei';

ctx.textAlign = 'center';

ctx.fillStyle = "#ffffff";

ctx.fillText(rate + '%', cW/2, cW/2 + size / 2);

ctx.restore();

};

var render = function () {

ctx.clearRect(0, 0, cW, cH);

if (IsdrawCircled == false) {

drawCircle();

}

//drawSin(xOffset + Math.PI * 0.7);

drawSin(xOffset);

drawText();

xOffset += speed;

requestAnimationFrame(render);

}

render();

}

使用封装好的方法绘制进度球,并且在页面大小变化时重新绘制进度球的大小:

$(function () {

window.onresize = function () {

initRates();

}

})

function initRates() {

drawRate('rate-one', '50', '#e9faff', '#afecff', '#94e5ff', '#29caff');

drawRate('rate-two', '30', '#fefbed', '#fdefbc', '#fce79a', '#fad44b');

drawRate('rate-three', '70', '#feefef', '#fcd4d4', '#f9b3b3', '#f36666');

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值