<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>华丽小球滚动时钟</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<canvas id="mainCanvas" style="display: block;border: 1px solid #eee;margin: 0 auto;"></canvas>
<script type="text/javascript" src="digit.js"></script>
<script type="text/javascript">
const CANVAS_WIDTH = document.body.clientWidth - 4;
const CANVAS_HEIGHT = document.body.clientHeight - 4;
const BALL_ARC_R = 8;
const OFF_LEFT = parseInt((CANVAS_WIDTH - (6 * 7 + 2 * 4) * 20)/2);
const OFF_TOP = 50;
const BALL_TUPLE = [];
const COLORS = ["#33B5E5","#0099CC","#AA66CC","#9933CC","#99CC00","#669900","#FFBB33","#FF8800","#FF4444","#CC0000"];
let animationTimer = null;
let lastTimes = {times: 0, hour_t: 0, hour_a: 0, minute_t: 0, minute_a: 0, second_t: 0, second_a: 0};
window.onload = () => {
let canvasDom = document.querySelector('#mainCanvas')
canvasDom.width = CANVAS_WIDTH;
canvasDom.height = CANVAS_HEIGHT;
let ctx = canvasDom.getContext('2d')
function animationEntry() {
renderCanvas(ctx);
animationTimer = window.requestAnimationFrame(animationEntry);
}
animationTimer = window.requestAnimationFrame(animationEntry);
}
function updateFPS() {
}
function renderCanvas(ctx) {
let dateObj = new Date();
let tempTimes = parseInt(dateObj.valueOf()/ 50);
if (lastTimes.times != tempTimes) {
let hour = dateObj.getHours();
let minute = dateObj.getMinutes();
let second = dateObj.getSeconds();
let hour_t = parseInt(hour/10)
let hour_a = parseInt(hour%10)
let minute_t = parseInt(minute/10)
let minute_a = parseInt(minute%10)
let second_t = parseInt(second/10)
let second_a = parseInt(second%10)
if (lastTimes.times == 0) {
lastTimes.hour_t = hour_t
lastTimes.hour_a = hour_a
lastTimes.minute_t = minute_t
lastTimes.minute_a = minute_a
lastTimes.second_t = second_t
lastTimes.second_a = second_a
}
lastTimes.times = tempTimes;
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
drawDigit(ctx, OFF_LEFT, OFF_TOP, hour_t, 'rgb(0, 102, 153)', lastTimes.hour_t != hour_t? (lastTimes.hour_t = hour_t,true): false)
drawDigit(ctx, OFF_LEFT + 140, OFF_TOP, hour_a, 'rgb(0, 102, 153)', lastTimes.hour_a != hour_a? (lastTimes.hour_a = hour_a,true): false)
drawDigit(ctx, OFF_LEFT + 140 * 2, OFF_TOP, 10, 'rgb(0, 102, 153)')
drawDigit(ctx, OFF_LEFT + 140 * 2 + 80, OFF_TOP, minute_t, 'rgb(0, 102, 153)', lastTimes.minute_t != minute_t? (lastTimes.minute_t = minute_t,true): false)
drawDigit(ctx, OFF_LEFT + 140 * 3 + 80, OFF_TOP, minute_a, 'rgb(0, 102, 153)', lastTimes.minute_a != minute_a? (lastTimes.minute_a = minute_a,true): false)
drawDigit(ctx, OFF_LEFT + 140 * 4 + 80, OFF_TOP, 10, 'rgb(0, 102, 153)')
drawDigit(ctx, OFF_LEFT + 140 * 4 + 80 * 2, OFF_TOP, second_t, 'rgb(0, 102, 153)', lastTimes.second_t != second_t? (lastTimes.second_t = second_t,true): false)
drawDigit(ctx, OFF_LEFT + 140 * 5 + 80 * 2, OFF_TOP, second_a, 'rgb(0, 102, 153)', lastTimes.second_a != second_a? (lastTimes.second_a = second_a,true): false)
let j = 0;
for (let i = 0; i < BALL_TUPLE.length; i++) {
let item = BALL_TUPLE[i];
item.x += item.vx;
item.y += item.vy;
item.vy += item.vg;
if (ctx.canvas.height < item.y) {
item.y = ctx.canvas.height - BALL_ARC_R;
item.vy *= -0.8;
}
if (ctx.canvas.width > (item.x - BALL_ARC_R) && (item.x + BALL_ARC_R) > 0) {
BALL_TUPLE[j++] = item;
}
}
if (BALL_TUPLE.length != j) {
BALL_TUPLE.splice(j);
}
console.log(BALL_TUPLE.length);
drawBallMotion(ctx);
}
}
function drawDigit(ctx, x, y, num, color, isChange = false) {
ctx.fillStyle = color;
const PI2 = 2 * Math.PI;
let nums = digit[num];
for (let i = 0; i < nums.length; i++)
for (let j = 0; j < nums[i].length; j++)
if (digit[num][i][j] == 1) {
let ballX = x + (BALL_ARC_R + 1) * ( 2 * j - 1);
let ballY = y + (BALL_ARC_R + 1) * ( 2 * i - 1);
if (isChange) {
BALL_TUPLE.push({
x: ballX,
y: ballY,
vx: Math.pow( -1, Math.ceil( Math.random() * 1000)) * 2,
vy: -5,
vg: 1.5 + Math.random(),
color: COLORS[ Math.floor(Math.random() * COLORS.length)]
})
}
ctx.beginPath();
ctx.arc(ballX, ballY, BALL_ARC_R, 0, PI2);
ctx.closePath();
ctx.fill();
}
}
function drawBallMotion(ctx) {
const PI2 = 2 * Math.PI;
for (let item of BALL_TUPLE) {
ctx.fillStyle = item.color;
ctx.beginPath();
ctx.arc(item.x, item.y, BALL_ARC_R, 0, PI2);
ctx.closePath();
ctx.fill();
}
}
</script>
</body>
</html>
digit.js
const digit=[[[0,0,1,1,1,0,0],[0,1,1,0,1,1,0],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,0,1,1,0],[0,0,1,1,1,0,0]],[[0,0,0,1,1,0,0],[0,1,1,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[1,1,1,1,1,1,1]],[[0,1,1,1,1,1,0],[1,1,0,0,0,1,1],[0,0,0,0,0,1,1],[0,0,0,0,1,1,0],[0,0,0,1,1,0,0],[0,0,1,1,0,0,0],[0,1,1,0,0,0,0],[1,1,0,0,0,0,0],[1,1,0,0,0,1,1],[1,1,1,1,1,1,1]],[[1,1,1,1,1,1,1],[0,0,0,0,0,1,1],[0,0,0,0,1,1,0],[0,0,0,1,1,0,0],[0,0,1,1,1,0,0],[0,0,0,0,1,1,0],[0,0,0,0,0,1,1],[0,0,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,1,1,0]],[[0,0,0,0,1,1,0],[0,0,0,1,1,1,0],[0,0,1,1,1,1,0],[0,1,1,0,1,1,0],[1,1,0,0,1,1,0],[1,1,1,1,1,1,1],[0,0,0,0,1,1,0],[0,0,0,0,1,1,0],[0,0,0,0,1,1,0],[0,0,0,1,1,1,1]],[[1,1,1,1,1,1,1],[1,1,0,0,0,0,0],[1,1,0,0,0,0,0],[1,1,1,1,1,1,0],[0,0,0,0,0,1,1],[0,0,0,0,0,1,1],[0,0,0,0,0,1,1],[0,0,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,1,1,0]],[[0,0,0,0,1,1,0],[0,0,1,1,0,0,0],[0,1,1,0,0,0,0],[1,1,0,0,0,0,0],[1,1,0,1,1,1,0],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,1,1,0]],[[1,1,1,1,1,1,1],[1,1,0,0,0,1,1],[0,0,0,0,1,1,0],[0,0,0,0,1,1,0],[0,0,0,1,1,0,0],[0,0,0,1,1,0,0],[0,0,1,1,0,0,0],[0,0,1,1,0,0,0],[0,0,1,1,0,0,0],[0,0,1,1,0,0,0]],[[0,1,1,1,1,1,0],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,1,1,0],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,1,1,0]],[[0,1,1,1,1,1,0],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[1,1,0,0,0,1,1],[0,1,1,1,0,1,1],[0,0,0,0,0,1,1],[0,0,0,0,0,1,1],[0,0,0,0,1,1,0],[0,0,0,1,1,0,0],[0,1,1,0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0],[0,1,1,0],[0,1,1,0],[0,0,0,0],[0,0,0,0]]];