多次包含倒数计时器
Include Countdown Timer multiple times
我找到了这个倒数计时器,我想将它包含在我的模块之一中。不幸的是,我不知道如何在一个页面上多次使用计时器(经典的 - 只有最后一个计时器是 运行) - 我也知道可能(?)go 函数应该是原因 -但目前我不知道如何实例化计时器。
我目前拥有的(但它不起作用):
Codepen 原文:https://codepen.io/l422y/pen/cdwhm
我有深入的JS基础知识,但这仍然超出了我的视野。
var ringer = {
//countdown_to: "10/31/2014",
//countdown_to: targetdaytime,
rings: {
'DAYS': {
s: 86400000, // mseconds in a day,
max: 365
},
'HOURS': {
s: 3600000, // mseconds per hour,
max: 24
},
'MINUTES': {
s: 60000, // mseconds per minute
max: 60
},
'SECONDS': {
s: 1000,
max: 60
},
'MICROSEC': {
s: 10,
max: 100
}
},
r_count: 5,
r_spacing: 10, // px
r_size: 100, // px
r_thickness: 2, // px
update_interval: 11, // ms
init: function(container, targetdaytime) {
$r = ringer;
$r.cvs = document.createElement('canvas');
$r.size = {
w: ($r.r_size + $r.r_thickness) * $r.r_count + ($r.r_spacing * ($r.r_count - 1)),
h: ($r.r_size + $r.r_thickness)
};
$r.cvs.setAttribute('width', $r.size.w);
$r.cvs.setAttribute('height', $r.size.h);
$r.ctx = $r.cvs.getContext('2d');
$(container).append($r.cvs);
$r.cvs = $($r.cvs);
$r.ctx.textAlign = 'center';
$r.actual_size = $r.r_size + $r.r_thickness;
$r.countdown_to_time = new Date(targetdaytime).getTime();
$r.cvs.css({
width: $r.size.w + "px",
height: $r.size.h + "px"
});
$r.go();
},
ctx: null,
go: function() {
var idx = 0;
$r.time = (new Date().getTime()) - $r.countdown_to_time;
for (var r_key in $r.rings) $r.unit(idx++, r_key, $r.rings[r_key]);
setTimeout($r.go, $r.update_interval);
},
unit: function(idx, label, ring) {
var x, y, value, ring_secs = ring.s;
value = parseFloat($r.time / ring_secs);
$r.time -= Math.round(parseInt(value)) * ring_secs;
value = Math.abs(value);
x = ($r.r_size * .5 + $r.r_thickness * .5);
x += +(idx * ($r.r_size + $r.r_spacing + $r.r_thickness));
y = $r.r_size * .5;
y += $r.r_thickness * .5;
// calculate arc end angle
var degrees = 360 - (value / ring.max) * 360.0;
var endAngle = degrees * (Math.PI / 180);
$r.ctx.save();
$r.ctx.translate(x, y);
$r.ctx.clearRect($r.actual_size * -0.5, $r.actual_size * -0.5, $r.actual_size, $r.actual_size);
// first circle
$r.ctx.strokeStyle = "rgba(128,128,128,0.2)";
$r.ctx.beginPath();
$r.ctx.arc(0, 0, $r.r_size / 2, 0, 2 * Math.PI, 2);
$r.ctx.lineWidth = $r.r_thickness;
$r.ctx.stroke();
// second circle
$r.ctx.strokeStyle = "rgba(253, 128, 1, 0.9)";
$r.ctx.beginPath();
$r.ctx.arc(0, 0, $r.r_size / 2, 0, endAngle, 1);
$r.ctx.lineWidth = $r.r_thickness;
$r.ctx.stroke();
// label
$r.ctx.fillStyle = "#ffffff";
$r.ctx.font = '12px Helvetica';
$r.ctx.fillText(label, 0, 23);
$r.ctx.fillText(label, 0, 23);
$r.ctx.font = 'bold 40px Helvetica';
$r.ctx.fillText(Math.floor(value), 0, 10);
$r.ctx.restore();
}
}
jQuery(document).ready(function($) {
new ringer.init('#cd-container-1', '12/24/2020');
new ringer.init('#cd-container-2', '10/31/2020');
});
body,
html {
width: 100%;
height: 100%;
margin: 0;
}
html {
display: table;
}
canvas {
width: 900px;
height: 200px;
display: block;
position: relative;
background: transparent;
margin: 40px auto;
}
body {
background: #000000;
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/12399/free-pumpkin-wallpaper-25771-26455-hd-wallpapers.jpg");
background-position: top center;
background-size: cover;
color: #fff;
margin: 0;
padding: 0;
overflow: hidden;
display: table-cell;
vertical-align: middle;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="cd-container-1"></div>
<div id="cd-container-2"></div>
因为您的对象不是JS class,所以无法创建它的实例。它基本上是 class.
的单个实例
我为您将其转换为 class,因此现在您可以初始化它的多个实例:
class Ringer { // <-- make class from it
rings = { // <-- object properties to class fields
'DAYS': {
s: 86400000, // mseconds in a day,
max: 365
},
'HOURS': {
s: 3600000, // mseconds per hour,
max: 24
},
'MINUTES': {
s: 60000, // mseconds per minute
max: 60
},
'SECONDS': {
s: 1000,
max: 60
},
'MICROSEC': {
s: 10,
max: 100
}
};
r_count = 5;
r_spacing = 10; // px
r_size = 100; // px
r_thickness = 2; // px
update_interval = 11; // ms
ctx = null;
init (container, targetdaytime) { // <-- functions to class methods
this.cvs = document.createElement('canvas'); // <-- just access this instead of reference to the object
this.size = {
w: (this.r_size + this.r_thickness) * this.r_count + (this.r_spacing * (this.r_count - 1)),
h: (this.r_size + this.r_thickness)
};
this.cvs.setAttribute('width', this.size.w);
this.cvs.setAttribute('height', this.size.h);
this.ctx = this.cvs.getContext('2d');
$(container).append(this.cvs);
this.cvs = $(this.cvs);
this.ctx.textAlign = 'center';
this.actual_size = this.r_size + this.r_thickness;
this.countdown_to_time = new Date(targetdaytime).getTime();
this.cvs.css({
width: this.size.w + "px",
height: this.size.h + "px"
});
this.go();
}
go() {
var idx = 0;
this.time = (new Date().getTime()) - this.countdown_to_time;
for (var r_key in this.rings) this.unit(idx++, r_key, this.rings[r_key]);
setTimeout(() => this.go(), this.update_interval); // () => this.go() instead of $r.go
}
unit(idx, label, ring) {
var x, y, value, ring_secs = ring.s;
value = parseFloat(this.time / ring_secs);
this.time -= Math.round(parseInt(value)) * ring_secs;
value = Math.abs(value);
x = (this.r_size * .5 + this.r_thickness * .5);
x += +(idx * (this.r_size + this.r_spacing + this.r_thickness));
y = this.r_size * .5;
y += this.r_thickness * .5;
// calculate arc end angle
var degrees = 360 - (value / ring.max) * 360.0;
var endAngle = degrees * (Math.PI / 180);
this.ctx.save();
this.ctx.translate(x, y);
this.ctx.clearRect(this.actual_size * -0.5, this.actual_size * -0.5, this.actual_size, this.actual_size);
// first circle
this.ctx.strokeStyle = "rgba(128,128,128,0.2)";
this.ctx.beginPath();
this.ctx.arc(0, 0, this.r_size / 2, 0, 2 * Math.PI, 2);
this.ctx.lineWidth = this.r_thickness;
this.ctx.stroke();
// second circle
this.ctx.strokeStyle = "rgba(253, 128, 1, 0.9)";
this.ctx.beginPath();
this.ctx.arc(0, 0, this.r_size / 2, 0, endAngle, 1);
this.ctx.lineWidth = this.r_thickness;
this.ctx.stroke();
// label
this.ctx.fillStyle = "#ffffff";
this.ctx.font = '12px Helvetica';
this.ctx.fillText(label, 0, 23);
this.ctx.fillText(label, 0, 23);
this.ctx.font = 'bold 40px Helvetica';
this.ctx.fillText(Math.floor(value), 0, 10);
this.ctx.restore();
}
}
jQuery(document).ready(function($) {
(new Ringer()).init('#cd-container-1', '12/24/2020'); // <-- init new instance with new Ringer() and call init() on that instance
(new Ringer()).init('#cd-container-2', '10/31/2020');
});
body,
html {
width: 100%;
height: 100%;
margin: 0;
}
html {
display: table;
}
canvas {
width: 900px;
height: 200px;
display: block;
position: relative;
background: transparent;
margin: 40px auto;
}
body {
background: #000000;
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/12399/free-pumpkin-wallpaper-25771-26455-hd-wallpapers.jpg");
background-position: top center;
background-size: cover;
color: #fff;
margin: 0;
padding: 0;
overflow: hidden;
display: table-cell;
vertical-align: middle;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="cd-container-1"></div>
<div id="cd-container-2"></div>
如果您想详细了解 classes 及其工作原理,我在这里找到了一个很酷的小摘要:https://www.digitalocean.com/community/tutorials/js-objects-prototypes-classes
简单:将其包装在一个函数中。
function createRinger() {
const ringer = { ... }
return ringer
}
const ringer1 = createRinger()
const ringer2 = createRinger()
ringer1.init(target1, targetDateTime1)
ringer2.init(target2, targetDateTime2)
还有其他方法可以提高内存使用效率(例如使用原型链),但除非页面上有很多计时器,否则这些方法没有实际意义。
我找到了这个倒数计时器,我想将它包含在我的模块之一中。不幸的是,我不知道如何在一个页面上多次使用计时器(经典的 - 只有最后一个计时器是 运行) - 我也知道可能(?)go 函数应该是原因 -但目前我不知道如何实例化计时器。
我目前拥有的(但它不起作用):
Codepen 原文:https://codepen.io/l422y/pen/cdwhm
我有深入的JS基础知识,但这仍然超出了我的视野。
var ringer = {
//countdown_to: "10/31/2014",
//countdown_to: targetdaytime,
rings: {
'DAYS': {
s: 86400000, // mseconds in a day,
max: 365
},
'HOURS': {
s: 3600000, // mseconds per hour,
max: 24
},
'MINUTES': {
s: 60000, // mseconds per minute
max: 60
},
'SECONDS': {
s: 1000,
max: 60
},
'MICROSEC': {
s: 10,
max: 100
}
},
r_count: 5,
r_spacing: 10, // px
r_size: 100, // px
r_thickness: 2, // px
update_interval: 11, // ms
init: function(container, targetdaytime) {
$r = ringer;
$r.cvs = document.createElement('canvas');
$r.size = {
w: ($r.r_size + $r.r_thickness) * $r.r_count + ($r.r_spacing * ($r.r_count - 1)),
h: ($r.r_size + $r.r_thickness)
};
$r.cvs.setAttribute('width', $r.size.w);
$r.cvs.setAttribute('height', $r.size.h);
$r.ctx = $r.cvs.getContext('2d');
$(container).append($r.cvs);
$r.cvs = $($r.cvs);
$r.ctx.textAlign = 'center';
$r.actual_size = $r.r_size + $r.r_thickness;
$r.countdown_to_time = new Date(targetdaytime).getTime();
$r.cvs.css({
width: $r.size.w + "px",
height: $r.size.h + "px"
});
$r.go();
},
ctx: null,
go: function() {
var idx = 0;
$r.time = (new Date().getTime()) - $r.countdown_to_time;
for (var r_key in $r.rings) $r.unit(idx++, r_key, $r.rings[r_key]);
setTimeout($r.go, $r.update_interval);
},
unit: function(idx, label, ring) {
var x, y, value, ring_secs = ring.s;
value = parseFloat($r.time / ring_secs);
$r.time -= Math.round(parseInt(value)) * ring_secs;
value = Math.abs(value);
x = ($r.r_size * .5 + $r.r_thickness * .5);
x += +(idx * ($r.r_size + $r.r_spacing + $r.r_thickness));
y = $r.r_size * .5;
y += $r.r_thickness * .5;
// calculate arc end angle
var degrees = 360 - (value / ring.max) * 360.0;
var endAngle = degrees * (Math.PI / 180);
$r.ctx.save();
$r.ctx.translate(x, y);
$r.ctx.clearRect($r.actual_size * -0.5, $r.actual_size * -0.5, $r.actual_size, $r.actual_size);
// first circle
$r.ctx.strokeStyle = "rgba(128,128,128,0.2)";
$r.ctx.beginPath();
$r.ctx.arc(0, 0, $r.r_size / 2, 0, 2 * Math.PI, 2);
$r.ctx.lineWidth = $r.r_thickness;
$r.ctx.stroke();
// second circle
$r.ctx.strokeStyle = "rgba(253, 128, 1, 0.9)";
$r.ctx.beginPath();
$r.ctx.arc(0, 0, $r.r_size / 2, 0, endAngle, 1);
$r.ctx.lineWidth = $r.r_thickness;
$r.ctx.stroke();
// label
$r.ctx.fillStyle = "#ffffff";
$r.ctx.font = '12px Helvetica';
$r.ctx.fillText(label, 0, 23);
$r.ctx.fillText(label, 0, 23);
$r.ctx.font = 'bold 40px Helvetica';
$r.ctx.fillText(Math.floor(value), 0, 10);
$r.ctx.restore();
}
}
jQuery(document).ready(function($) {
new ringer.init('#cd-container-1', '12/24/2020');
new ringer.init('#cd-container-2', '10/31/2020');
});
body,
html {
width: 100%;
height: 100%;
margin: 0;
}
html {
display: table;
}
canvas {
width: 900px;
height: 200px;
display: block;
position: relative;
background: transparent;
margin: 40px auto;
}
body {
background: #000000;
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/12399/free-pumpkin-wallpaper-25771-26455-hd-wallpapers.jpg");
background-position: top center;
background-size: cover;
color: #fff;
margin: 0;
padding: 0;
overflow: hidden;
display: table-cell;
vertical-align: middle;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="cd-container-1"></div>
<div id="cd-container-2"></div>
因为您的对象不是JS class,所以无法创建它的实例。它基本上是 class.
的单个实例我为您将其转换为 class,因此现在您可以初始化它的多个实例:
class Ringer { // <-- make class from it
rings = { // <-- object properties to class fields
'DAYS': {
s: 86400000, // mseconds in a day,
max: 365
},
'HOURS': {
s: 3600000, // mseconds per hour,
max: 24
},
'MINUTES': {
s: 60000, // mseconds per minute
max: 60
},
'SECONDS': {
s: 1000,
max: 60
},
'MICROSEC': {
s: 10,
max: 100
}
};
r_count = 5;
r_spacing = 10; // px
r_size = 100; // px
r_thickness = 2; // px
update_interval = 11; // ms
ctx = null;
init (container, targetdaytime) { // <-- functions to class methods
this.cvs = document.createElement('canvas'); // <-- just access this instead of reference to the object
this.size = {
w: (this.r_size + this.r_thickness) * this.r_count + (this.r_spacing * (this.r_count - 1)),
h: (this.r_size + this.r_thickness)
};
this.cvs.setAttribute('width', this.size.w);
this.cvs.setAttribute('height', this.size.h);
this.ctx = this.cvs.getContext('2d');
$(container).append(this.cvs);
this.cvs = $(this.cvs);
this.ctx.textAlign = 'center';
this.actual_size = this.r_size + this.r_thickness;
this.countdown_to_time = new Date(targetdaytime).getTime();
this.cvs.css({
width: this.size.w + "px",
height: this.size.h + "px"
});
this.go();
}
go() {
var idx = 0;
this.time = (new Date().getTime()) - this.countdown_to_time;
for (var r_key in this.rings) this.unit(idx++, r_key, this.rings[r_key]);
setTimeout(() => this.go(), this.update_interval); // () => this.go() instead of $r.go
}
unit(idx, label, ring) {
var x, y, value, ring_secs = ring.s;
value = parseFloat(this.time / ring_secs);
this.time -= Math.round(parseInt(value)) * ring_secs;
value = Math.abs(value);
x = (this.r_size * .5 + this.r_thickness * .5);
x += +(idx * (this.r_size + this.r_spacing + this.r_thickness));
y = this.r_size * .5;
y += this.r_thickness * .5;
// calculate arc end angle
var degrees = 360 - (value / ring.max) * 360.0;
var endAngle = degrees * (Math.PI / 180);
this.ctx.save();
this.ctx.translate(x, y);
this.ctx.clearRect(this.actual_size * -0.5, this.actual_size * -0.5, this.actual_size, this.actual_size);
// first circle
this.ctx.strokeStyle = "rgba(128,128,128,0.2)";
this.ctx.beginPath();
this.ctx.arc(0, 0, this.r_size / 2, 0, 2 * Math.PI, 2);
this.ctx.lineWidth = this.r_thickness;
this.ctx.stroke();
// second circle
this.ctx.strokeStyle = "rgba(253, 128, 1, 0.9)";
this.ctx.beginPath();
this.ctx.arc(0, 0, this.r_size / 2, 0, endAngle, 1);
this.ctx.lineWidth = this.r_thickness;
this.ctx.stroke();
// label
this.ctx.fillStyle = "#ffffff";
this.ctx.font = '12px Helvetica';
this.ctx.fillText(label, 0, 23);
this.ctx.fillText(label, 0, 23);
this.ctx.font = 'bold 40px Helvetica';
this.ctx.fillText(Math.floor(value), 0, 10);
this.ctx.restore();
}
}
jQuery(document).ready(function($) {
(new Ringer()).init('#cd-container-1', '12/24/2020'); // <-- init new instance with new Ringer() and call init() on that instance
(new Ringer()).init('#cd-container-2', '10/31/2020');
});
body,
html {
width: 100%;
height: 100%;
margin: 0;
}
html {
display: table;
}
canvas {
width: 900px;
height: 200px;
display: block;
position: relative;
background: transparent;
margin: 40px auto;
}
body {
background: #000000;
background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/12399/free-pumpkin-wallpaper-25771-26455-hd-wallpapers.jpg");
background-position: top center;
background-size: cover;
color: #fff;
margin: 0;
padding: 0;
overflow: hidden;
display: table-cell;
vertical-align: middle;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="cd-container-1"></div>
<div id="cd-container-2"></div>
如果您想详细了解 classes 及其工作原理,我在这里找到了一个很酷的小摘要:https://www.digitalocean.com/community/tutorials/js-objects-prototypes-classes
简单:将其包装在一个函数中。
function createRinger() {
const ringer = { ... }
return ringer
}
const ringer1 = createRinger()
const ringer2 = createRinger()
ringer1.init(target1, targetDateTime1)
ringer2.init(target2, targetDateTime2)
还有其他方法可以提高内存使用效率(例如使用原型链),但除非页面上有很多计时器,否则这些方法没有实际意义。