<! 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 ] ] ] ;