使用js画布(canvas)实现倒计时特效

一、文章前言

js是一种神奇的语言,它可以实现非常炫酷的网页特效,给人一种视觉上的盛宴,下面附上倒计时的特效图。

这里写图片描述

这里写图片描述
 

二、内容

1.像素点般的倒计时
如图所似的倒计时是用一个个类似于像素点的小球,这是怎么实现的呢?首先学习这个需要先去了解画布的基础知识,我们需要知道时间在屏幕上该怎么画出来,显而易见肯定和画布坐标脱不了关系,然后我们就需要将一整块画布分割成3块:时、分、秒。然后我们就在每一块的区域来实现像素小球,实现这个小球我们需要准备先准备一个js文件,这个文件的作用是什么?
注意看我们的每一块区域本来是一块矩形,但是现在我们要在这一块矩形里填充小球来形成数字,每一个数字的小球也是有一定的位置限制,所以我们事先需要规划好每个数字什么地方有球什么地方没有。
下面给出digit.js文件代码
    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,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]
        ],//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]
        ],//2
        [
            [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]
        ],//3
        [
            [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]
        ],//4
        [
            [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]
        ],//5
        [
            [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]
        ],//6
        [
            [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]
        ],//7
        [
            [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]
        ],//8
        [
            [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]
        ],//9
        [
            [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]
        ]//:
    ];
2.下面将来实现整个功能
var WINDOW_WIDTH = 1200
var WINDOW_HEIGHT = 768
var RADIUS = 8
var MARGIN_LEFT = 50
var MARGIN_TOP = 50 

var curShowTimeSeconds = 0

var balls = [];
//该数组是给跳动的小球随机赋上颜色用的
const colors = ["#33B5E5","#0099CC","#AA66CC","#9933CC","#99CC00","#669900","#FFBB33","#FF8800","#FF4444","#CC0000"]


window.onload = function () {
    // body...
    var canvas = document.getElementById("digit")
    var context = canvas.getContext("2d")
    canvas.width = WINDOW_WIDTH
    canvas.height = WINDOW_HEIGHT

    curShowTimeSeconds = getCurrentTimeSecond()
    //用个定时器不停的刷新屏幕上面的小球
    var timer = setInterval(function(){
        render(context)
        update()
    },50)
}
//时分秒三个区域当前时间若是和先前的不一样则会产生小球跳动一次
function update() {
    // body...
    var nextShowTimeSecond = getCurrentTimeSecond()
    var nextHours = parseInt( nextShowTimeSecond / 3600);
    var nextMinutes = parseInt( (nextShowTimeSecond - nextHours * 3600)/60 )
    var nextSeconds = nextShowTimeSecond % 60

    var curHours = parseInt( curShowTimeSeconds / 3600);
    var curMinutes = parseInt( (curShowTimeSeconds - curHours * 3600)/60 )
    var curSeconds = curShowTimeSeconds % 60
    if (nextSeconds!=curSeconds) {
        if (parseInt(curHours/10)!=parseInt(nextHours/10)) {
            addBalls(MARGIN_LEFT+0,MARGIN_TOP,parseInt(curHours/10))
        }
        if (parseInt(curHours%10)!=parseInt(nextHours%10)) {
            addBalls(MARGIN_LEFT+15*(RADIUS+1),MARGIN_TOP,parseInt(curHours%10))
        }
        if (parseInt(curMinutes/10)!=parseInt(nextMinutes/10)) {
            addBalls(MARGIN_LEFT+40,MARGIN_TOP,parseInt(curHours/10))
        }
        if (parseInt(curMinutes%10)!=parseInt(nextMinutes%10)) {
            addBalls(MARGIN_LEFT+55*(RADIUS+1),MARGIN_TOP,parseInt(curHours%10))
        }
        if (parseInt(curSeconds/10)!=parseInt(nextSeconds/10)) {
            addBalls(MARGIN_LEFT+80,MARGIN_TOP,parseInt(curHours/10))
        }
        if (parseInt(curSeconds%10)!=parseInt(nextSeconds%10)) {
            addBalls(MARGIN_LEFT+95*(RADIUS+1),MARGIN_TOP,parseInt(curHours%10))
        }
        curShowTimeSeconds = nextShowTimeSecond
    }

    updateBalls()
}

//小球跳动规律
function updateBalls() {
    // body...
    for (var i = 0; i < balls.length; i++) {
        balls[i].x += balls[i].vx
        balls[i].y += balls[i].vy
        balls[i].vy += balls[i].g
        if (balls[i].y >= (WINDOW_HEIGHT - RADIUS) ){
            balls[i].y = WINDOW_HEIGHT-RADIUS
            balls[i].vy = - balls[i].vy*0.75
        }
    }
}

//在屏幕上添加小球
function addBalls(x,y,num) {
    // body...
    for (var i = 0; i < digit[num].length; i++) {
        for (var j = 0; j < digit[num][i].length; j++) {
            if (digit[num][i][j] == 1) {
                var oBalls = {
                    x:x+j*2*(RADIUS+1)+RADIUS+1,
                    y:y+i*2*(RADIUS+1)+RADIUS+1,
                    g:1.5+Math.random(),
                    vx : Math.pow(-1,Math.ceil(Math.random()*1000))*4,
                    vy:-5,
                    color:colors[ Math.floor( Math.random()*colors.length )]
                }
                balls.push(oBalls)
            }
        }
    }
}

//获取当前时间
function getCurrentTimeSecond(){
    var now  = new Date()
    var endTime = new Date(2017,10,22)
    var leftTime = endTime.getTime() - now.getTime()
    var ms = Math.round(leftTime/1000)

    return ms
}

//操作画布实现小球的改变
function render(context) {
    // body...

    context.clearRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT)
    var day = Math.floor(curShowTimeSeconds / 3600 /24)
    var hours = Math.floor((curShowTimeSeconds - (day*24*3600))/3600)
    var minute = Math.floor((curShowTimeSeconds - (hours * 3600) )/ 60)
    var second = Math.floor(curShowTimeSeconds - minute * 60 - hours * 3600)

    renderDigit(MARGIN_LEFT,MARGIN_TOP,parseInt(hours/10),context)
    renderDigit(MARGIN_LEFT+15*(RADIUS+1),MARGIN_TOP,parseInt(hours%10),context)
    renderDigit(MARGIN_LEFT+30*(RADIUS+1),MARGIN_TOP,10,context)
    renderDigit(MARGIN_LEFT+40*(RADIUS+1),MARGIN_TOP,parseInt(minute/10),context)
    renderDigit(MARGIN_LEFT+55*(RADIUS+1),MARGIN_TOP,parseInt(minute%10),context)
    renderDigit(MARGIN_LEFT+70*(RADIUS+1),MARGIN_TOP,10,context)
    renderDigit(MARGIN_LEFT+80*(RADIUS+1),MARGIN_TOP,parseInt(second/10),context)
    renderDigit(MARGIN_LEFT+95*(RADIUS+1),MARGIN_TOP,parseInt(second%10),context)

    for (var i = 0; i < balls.length; i++) {
        context.fillStyle = balls[i].color
        context.beginPath()
        context.arc(balls[i].x,balls[i].y,RADIUS,0,2*Math.PI)
        context.closePath()

        context.fill()
    }
}

function renderDigit(x,y,num,context) {
    // body...
    context.fillStyle = "blue"

    for (var i = 0; i < digit[num].length; i++) {
        for (var j = 0; j<digit[num][i].length; j++) {
            if (digit[num][i][j] == 1) {
                context.beginPath()
                context.arc(x+j*2*(RADIUS+1)+RADIUS+1,y+i*2*(RADIUS+1)+RADIUS+1,RADIUS,0,2*Math.PI)
                context.closePath()
                context.fill()
            }
        }
    }
}

三、总结

总而言之js就是一种神奇的语言,若能掌握明了,必定带给你意想不到的快乐。

(本文参考慕客网视频资料,具体哪一个不清楚了)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值