<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>刻度线</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="container-tickMarks">
<canvas id="myCanvas" width="100" height="300"></canvas>
<div class="val">
<span id="val">86</span>bpm
</div>
</div>
</body>
</html>
<script src="./index.js"></script>
index.html
style.css
index.js
现在支持上传本地图片了!
index.html
style.css
body {
background-color: #4a4a53;
margin: 0;
padding: 0;
}
.container-tickMarks {
position: relative;
width: 150px;
height: 450px;
/* background: url(./img/measuring_xl.png) no-repeat; */
/* background-size: cover; */
background-color: #fff;
box-shadow: 0px 7px 10px 0px rgba(1, 36, 160, 0.06);
border-radius: 20px;
margin: 0 auto;
text-align: center;
margin-top: 50px;
}
#myCanvas {
border-radius: 10px;
margin-top: 30px;
}
.val {
width: 100%;
position: absolute;
text-align: center;
bottom: 30px;
font-weight: 500;
font-size: 18px;
color: #4a4a53;
}
.val span {
font-weight: 500;
font-size: 48px;
color: #4a4a53;
}
编辑器加载中
index.js
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var yaxis_start = 40; //坐标轴开始值
var yaxis_end = 140; //坐标轴结尾值
// 定义刻度尺的起点、终点和间隔 Cavan的y轴是反的
var start = canvas.height - 10;
var end = 10;
var gap = 2;
var target = 85, //目标值
cury = yaxis_start; //动画进行时的值
var step = 0; //动画进度 0~1
function drawAxis() {
// console.log(start, end); //290~10 -> 280~0
// 绘制刻度尺背景
ctx.fillStyle = "transparent"; //transparent
ctx.fillRect(0, 0, canvas.width, canvas.height);
var x_pos = 50;
var area = yaxis_end - yaxis_start;
// 绘制刻度尺刻度线
for (var i = 0; i <= area; i += gap) {
// 计算刻度线的坐标
var x = x_pos;
var y = ((start - end) / area) * (area - i) + end;
// 绘制刻度线
let longline = 24;
let shortline = 12;
let drawline = shortline;
if (i % 10 == 0) {
drawline = longline;
x = x_pos;
} else {
//短线居中
x = x_pos + (longline - drawline) / 2;
}
ctx.strokeStyle = "#8E8D9A";
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + drawline, y);
ctx.stroke();
// 绘制刻度值
ctx.fillStyle = "black";
ctx.font = "12px Arial";
let fontgap = 20
let fontNum = i + yaxis_start;
if (fontNum < 10) fontgap = 15;
if (fontNum >= 100)
fontgap = 25
if (fontNum % 10 == 0)
ctx.fillText(fontNum, x - fontgap, y + 5);
}
}
function drawBg() {
ctx.globalCompositeOperation = 'darken';
// 创建渐变
const grdl = ctx.createLinearGradient(0, 0, canvas.width / 2, 0);
grdl.addColorStop(0, "#E6E9F6");
grdl.addColorStop(1, "white");
// 用渐变填充
ctx.fillStyle = grdl;
ctx.fillRect(0, 0, canvas.width / 2, canvas.height);
const grdr = ctx.createLinearGradient(canvas.width / 2, 0, canvas.width, 0, );
grdr.addColorStop(0, "white");
grdr.addColorStop(1, "#E6E9F6");
ctx.fillStyle = grdr;
ctx.fillRect(canvas.width / 2, 0, canvas.width, canvas.height);
}
function drawBar() {
var val = cury;
if (val < yaxis_start.value || val > yaxis_end.value || step > 1) {
return
};
ctx.clearRect(0, 0, canvas.width, canvas.height); //清空上一帧
drawAxis(); //绘制刻度轴
drawBg(); //绘制背景
var area = yaxis_end - yaxis_start;
var h = ((start - end) / area) * (val - yaxis_start);
var w = 15;
var x = 55;
var y = start - h;
// lighten 绘制新图和原图,重叠部分加色处理
// darken 保留重叠部分最黑的像素
// lighter 保证重叠部分最量的像素
// copy 绘制新图,覆盖原图
// xor 重叠部分会变成透明
ctx.globalCompositeOperation = 'darken';
ctx.fillStyle = "#A4C8FA";
ctx.fillRect(x, y, w, h);
// console.log(step);
//计算y轴增量和y位置
step += 0.02; //0~1
var nexty = easeOutQuart(step) * (target - cury) + cury;
cury = nexty;
// cury += 0.2; //线性增加
requestAnimationFrame(drawBar);
}
function easeOutQuad(x) {
return 1 - (1 - x) * (1 - x);
}
function easeOutQuart(x) {
return 1 - Math.pow(1 - x, 4);
}
drawBar();
setInterval(() => {
target = getRandomInt(41, 138);
document.getElementById("val").innerText = target
step = 0;
console.log("重新执行",target);
drawBar();
}, 1500);
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
编辑器加载中
预览页面