Html5 倒计时/正计时 功能完成(一)

首先是插件代码,是参考了网上别人的倒计时项目(jQuery-Final-Countdown)。额外添加了 正计时,定时提醒,暂停,继续,开始,停止,以及计次的功能,并且将原来的精确到秒改成精确到毫秒,花了我整整一天完成。

如下是插件的核心逻辑:

/*!
 * jQuery Final Countdown
 *
 * @author Pragmatic Mates, http://pragmaticmates.com
 * @version 1.1.1
 * @license GPL 2
 * @link https://github.com/PragmaticMates/jquery-final-countdown
 */

(function($) {
	var settings;
	var timer;

	var circleSeconds;
	var circleMinutes;
	var circleHours;
	var circleDays;

	var layerMilSeconds;
	var layerSeconds;
	var layerMinutes;
	var layerHours;
	var layerDays;

	var element;
	var callbackFunction;
	var interval;
	$.fn.final_countdown = function(options, callback) {
		element = $(this);

		// Element is not visibile
		if(!element.is(':visible')) {
			return;
		}

		var defaults = $.extend({
			start: undefined,
			end: undefined,
			now: undefined,
			selectors: {
				value_mils: '.clock-mils .val',
				canvas_mils: 'canvas-mils',
				value_seconds: '.clock-seconds .val',
				canvas_seconds: 'canvas-seconds',
				value_minutes: '.clock-minutes .val',
				canvas_minutes: 'canvas-minutes',
				value_hours: '.clock-hours .val',
				canvas_hours: 'canvas-hours',
				value_days: '.clock-days .val',
				canvas_days: 'canvas-days'
			},
			mils: {
				borderColor: '#00FF00',
				borderWidth: '6'
			},
			seconds: {
				borderColor: '#7995D5',
				borderWidth: '6'
			},
			minutes: {
				borderColor: '#ACC742',
				borderWidth: '6'
			},
			hours: {
				borderColor: '#ECEFCB',
				borderWidth: '6'
			},
			days: {
				borderColor: '#FF9900',
				borderWidth: '6'
			},
			isCountDown:true,
			status:'start'
		}, options);

		settings = $.extend({}, defaults, options);

		if(settings.start === undefined) {
			settings.start = element.data('start');
			settings.start*=1000;
		}

		if(settings.end === undefined) {
			settings.end = element.data('end');
			settings.end*=1000;
		}

		if(settings.now === undefined) {
			settings.now = element.data('now');
			settings.now*=1000;
		}

		if(element.data('border-color')) {
			settings.seconds.borderColor = settings.minutes.borderColor = settings.hours.borderColor = settings.days.borderColor = element.data('border-color');
		}
		console.log("timer:"+settings.end)
		if(settings.now < settings.start) {
			settings.start = settings.now;
			settings.end = settings.now;
		}

		if(settings.now > settings.end) {
			settings.start = settings.now;
			settings.end = settings.now;
		}

		if(typeof callback == 'function') { // make sure the callback is a function
			callbackFunction = callback;
		}
		
		clearInterval(interval);
		console.log("settings.status:"+settings.status)
		if(settings.status == 'start'){
			responsive();
			dispatchTimer();
			prepareCounters();
			startCounters();
		}else if(settings.status == 'continue'){
			settings.status = 'start';
			startCounters();
		}else if(settings.status == 'pause'){
			
		}else if(settings.status == 'stop'){
			responsive();
			dispatchTimer();
			prepareCounters();
			updateCircles();
		}
	};
	

	$.fn.get_status = function(){
		if(settings == undefined){
			return "stop";
		}
		return settings.status;
	}
	
	
	
	function responsive() {
		$(window).load(updateCircles);

		$(window).on('redraw', function() {
			switched = false;
			updateCircles();
		});
		$(window).on('resize', updateCircles);
	}
	

	function updateCircles() {
		layerMilSeconds.draw();
		layerSeconds.draw();
		layerMinutes.draw();
		layerHours.draw();
		//layerDays.draw();
	}
	
	
	$.fn.get_time_shown = function(){
		var hours = $(settings.selectors.value_hours).html();
		var minutes=$(settings.selectors.value_minutes).html();
		var seconds=$(settings.selectors.value_seconds).html();
		var milSeconds=$(settings.selectors.value_mils).html();
		console.log("gfdgfd;"+hours+":"+minutes+":"+seconds+"."+milSeconds)
		 hours = (hours > 9?"":"0")+hours;
		 minutes = (minutes > 9?"":"0")+minutes;
		 seconds = (seconds > 9?"":"0")+seconds; 
		
		 milSeconds = milSeconds*5/2;
		 milSeconds = milSeconds>=100?milSeconds/10:milSeconds;
		  milSeconds = parseInt(milSeconds);
		milSeconds = (milSeconds > 9?"":"0")+milSeconds;
		return hours+":"+minutes+":"+seconds+"."+milSeconds;
	}

	function convertToDeg(degree) {
		return(Math.PI / 180) * degree - (Math.PI / 180) * 90
	}

	function dispatchTimer() {
		timer = {
				total: settings.isCountDown?Math.floor((settings.end - settings.start) / (86400 * 1000)):0,
				days: settings.isCountDown?Math.floor((settings.end - settings.now) / (86400 * 1000)):0,
				hours: settings.isCountDown?(24 - Math.floor(((settings.end - settings.now) / 1000 % 86400) / 3600)):0,
				minutes: settings.isCountDown?(60 - Math.floor((((settings.end - settings.now) / 1000 % 86400) % 3600) / 60)):0,
				seconds: settings.isCountDown?(60 - Math.floor((((settings.end - settings.now) / 1000 % 86400) % 3600) % 60)):0,
				mils: settings.isCountDown?(40 - Math.floor((((settings.end - settings.now) % (86400 * 1000)) % (3600 * 1000)) % 1000) / 40):0
			}

	}

	function prepareCounters() {
		
		// Mil_seconds
		var seconds_width = $('#' + settings.selectors.canvas_seconds).width()
		var milSecondsStage = new Kinetic.Stage({
			container: settings.selectors.canvas_mils,
			width: seconds_width,
			height: seconds_width
		});

		circleMilseconds = new Kinetic.Shape({
			drawFunc: function(context) {
				var seconds_width = $('#' + settings.selectors.canvas_mils).width()
				var radius = seconds_width / 2 - settings.seconds.borderWidth / 2;
				var x = seconds_width / 2;
				var y = seconds_width / 2;
				//console.log("radius:"+radius)
				context.beginPath();
				context.arc(x, y, radius, convertToDeg(0), convertToDeg(timer.mils * 9));
				context.fillStrokeShape(this);
				$(settings.selectors.value_mils).html(settings.isCountDown?(60 - parseInt(timer.mils*3/2)):parseInt(timer.mils*3/2));

			},
			stroke: settings.mils.borderColor,
			strokeWidth: settings.mils.borderWidth
		});
		

		layerMilSeconds = new Kinetic.Layer();
		layerMilSeconds.add(circleMilseconds);
		milSecondsStage.add(layerMilSeconds);
		
		// Seconds
		var seconds_width = $('#' + settings.selectors.canvas_seconds).width()
		var secondsStage = new Kinetic.Stage({
			container: settings.selectors.canvas_seconds,
			width: seconds_width,
			height: seconds_width
		});

		circleSeconds = new Kinetic.Shape({
			drawFunc: function(context) {
				var seconds_width = $('#' + settings.selectors.canvas_seconds).width()
				var radius = seconds_width / 2 - settings.seconds.borderWidth / 2;
				var x = seconds_width / 2;
				var y = seconds_width / 2;

				context.beginPath();
				context.arc(x, y, radius, convertToDeg(0), convertToDeg(timer.seconds * 6));
				context.fillStrokeShape(this);


				$(settings.selectors.value_seconds).html(settings.isCountDown?(60 - timer.seconds):timer.seconds);
			},
			stroke: settings.seconds.borderColor,
			strokeWidth: settings.seconds.borderWidth
		});

		layerSeconds = new Kinetic.Layer();
		layerSeconds.add(circleSeconds);
		secondsStage.add(layerSeconds);
		
		

		// Minutes
		var minutes_width = $('#' + settings.selectors.canvas_minutes).width();
		var minutesStage = new Kinetic.Stage({
			container: settings.selectors.canvas_minutes,
			width: minutes_width,
			height: minutes_width
		});

		circleMinutes = new Kinetic.Shape({
			drawFunc: function(context) {
				var minutes_width = $('#' + settings.selectors.canvas_minutes).width();
				var radius = minutes_width / 2 - settings.minutes.borderWidth / 2;
				var x = minutes_width / 2;
				var y = minutes_width / 2;

				context.beginPath();
				context.arc(x, y, radius, convertToDeg(0), convertToDeg(timer.minutes * 6));
				context.fillStrokeShape(this);

				$(settings.selectors.value_minutes).html(settings.isCountDown?(60 - timer.minutes):timer.minutes);

			},
			stroke: settings.minutes.borderColor,
			strokeWidth: settings.minutes.borderWidth
		});
		
		layerMinutes = new Kinetic.Layer();
		layerMinutes.add(circleMinutes);
		minutesStage.add(layerMinutes);

		// Hours
		var hours_width = $('#' + settings.selectors.canvas_hours).width();
		var hoursStage = new Kinetic.Stage({
			container: settings.selectors.canvas_hours,
			width: hours_width,
			height: hours_width
		});

		circleHours = new Kinetic.Shape({
			drawFunc: function(context) {
				var hours_width = $('#' + settings.selectors.canvas_hours).width();
				var radius = hours_width / 2 - settings.hours.borderWidth / 2;
				var x = hours_width / 2;
				var y = hours_width / 2;

				context.beginPath();
				context.arc(x, y, radius, convertToDeg(0), convertToDeg(timer.hours * 360 / 24));
				context.fillStrokeShape(this);

				$(settings.selectors.value_hours).html(settings.isCountDown?(24 - timer.hours): timer.hours);
			},
			stroke: settings.hours.borderColor,
			strokeWidth: settings.hours.borderWidth
		});

		layerHours = new Kinetic.Layer();
		layerHours.add(circleHours);
		hoursStage.add(layerHours);

		// Days
		/*var days_width = $('#' + settings.selectors.canvas_days).width();
		var daysStage = new Kinetic.Stage({
			container: settings.selectors.canvas_days,
			width: days_width,
			height: days_width
		});

		circleDays = new Kinetic.Shape({
			drawFunc: function(context) {
				var days_width = $('#' + settings.selectors.canvas_days).width();
				var radius = days_width / 2 - settings.days.borderWidth / 2;
				var x = days_width / 2;
				var y = days_width / 2;

				context.beginPath();
				if(timer.total == 0) {
					context.arc(x, y, radius, convertToDeg(0), convertToDeg(360));
				} else {
					context.arc(x, y, radius, convertToDeg(0), convertToDeg((360 / timer.total) * (timer.total - timer.days)));
				}
				context.fillStrokeShape(this);

				$(settings.selectors.value_days).html(timer.days);

			},
			stroke: settings.days.borderColor,
			strokeWidth: settings.days.borderWidth
		});

		layerDays = new Kinetic.Layer();
		layerDays.add(circleDays);
		daysStage.add(layerDays);*/
	}
	
	
	function playIfNeed(timeNum){
	var playInterval = localStorage.getItem("playInterval") || "6";
	try{
			timeNum = timeNum%parseFloat(playInterval)
		}catch(e){
		}
	if(timeNum == 0){
			playMusic();
		}
	
	
}

function playMusic() {
 	var audio = document.getElementById("bgMusic");
 	console.log("audio:"+audio)
 	audio.play();
 }

function playMusicWithInterval() {
 	//stopPlay();
 	playMusic();
// 	var playTime = localStorage.getItem("playInterval") || 6;
// 	if(playTime) {
// 		try {
// 			playTime = parseInt(playTime);
// 		} catch(e) {
// 			playTime = 6;
// 		}
// 	}
// 	console.log("playTime:" + playTime);
// 	playMusicTimer = setInterval(playMusic, playTime * 1000);
 }

 
 
 function stopPlay(){
 	if(playMusicTimer)
 		clearInterval(playMusicTimer);
 }

	function startCounters() {
		interval = setInterval(function() {
			if(timer.mils > 39) {
				timer.mils = 1;
				timer.seconds++;
				
				if(timer.seconds > 59) {
					if(60 - timer.minutes == 0 && 24 - timer.hours == 0 && timer.days == 0) {
						clearInterval(interval);
						if(callbackFunction !== undefined) {
							callbackFunction.call(this); // brings the scope to the callback
						}
						stopCount();
						playMusic();
						return;
					}
					
					timer.seconds = 0;
					
					if(timer.minutes > 59) {
						timer.minutes = 1;
						layerMinutes.draw();
						if(timer.hours > 23) {
							timer.hours = 1;
							/*if(timer.days > 0) {
								timer.days--;
								layerDays.draw();
							}*/
						} else {
							timer.hours++;
						}
						layerHours.draw()
					} else {
						timer.minutes++;
					}

					layerMinutes.draw();
				}
				layerSeconds.draw();
				var timeNum = timer.hours*60*60+timer.minutes*60+timer.seconds
				if(settings.isCountDown){
					timeNum = 24*60*60+(60-timer.minutes)*60+60-timer.hours*60*60-timer.seconds
					if(timeNum == parseInt(settings.end)/1000){
						timeNum = -1;
					}
				}
				playIfNeed(timeNum);
			} else {
				timer.mils++;
			}
			layerMilSeconds.draw();
		}, 1000 / 40);
	}
})(jQuery);



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值