11"use strict" ;
2+ const TAU = 2 * Math . PI ;
23const CLOCK_CONFIG = {
34 radius : 144 ,
45 center : { x : 0 , y : 0 } ,
@@ -26,60 +27,45 @@ const CLOCK_CONFIG = {
2627 clockTypes : {
2728 hour : {
2829 segmentNames : [ '12' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '10' , '11' ] ,
29- segmentCount : 12 ,
30- segmentFractions : Array . from ( { length : 12 } , ( _ , i ) => i / 12 ) ,
3130 markCount : 48
3231 } ,
3332 month : {
3433 segmentNames : [ 'Jan' , 'Feb' , 'Mar' , 'Apr' , 'May' , 'Jun' , 'Jul' , 'Aug' , 'Sep' , 'Oct' , 'Nov' , 'Dec' ] ,
35- segmentCount : 12 ,
36- segmentFractions : Array . from ( { length : 12 } , ( _ , i ) => i / 12 ) ,
3734 markCount : 48
3835 } ,
3936 year : {
4037 segmentNames : [ '2000' , '' , '2010' , '' , '2020' , '' , '2030' , '' , '2040' , '' , '2050' , '' ] ,
41- segmentCount : 12 ,
42- segmentFractions : Array . from ( { length : 12 } , ( _ , i ) => i / 12 ) ,
4338 markCount : 60
4439 } ,
4540 decimal : {
4641 segmentNames : [ '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '10' ] ,
47- segmentCount : 10 ,
48- segmentFractions : Array . from ( { length : 10 } , ( _ , i ) => i / 10 ) ,
4942 markCount : 100
5043 } ,
5144 decade : {
5245 segmentNames : [ '0' , '10' , '20' , '30' , '40' , '50' , '60' , '70' , '80' , '90' , '' ] ,
53- segmentCount : 10 ,
54- segmentFractions : Array . from ( { length : 10 } , ( _ , i ) => i / 10 ) ,
5546 markCount : 20
5647 } ,
5748 century : {
5849 segmentNames : [ '1200' , '' , '' , '1500' , '' , '' , '1800' , '' , '' , '2100' , '' , '' , '' ] ,
59- segmentCount : 12 ,
60- segmentFractions : Array . from ( { length : 12 } , ( _ , i ) => i / 12 ) ,
6150 markCount : 48
6251 } ,
6352 millennia : {
6453 segmentNames : [ '' , '' , '' , '' , '' , '' , '' , '' , '' , '' , '' , '' , '' ] ,
65- segmentCount : 12 ,
66- segmentFractions : Array . from ( { length : 12 } , ( _ , i ) => i / 12 ) ,
6754 markCount : 60
6855 }
6956 }
7057} ;
58+ const POSITION_FUNCTIONS = {
59+ 'hour' : getHourPosition ,
60+ 'month' : getMonthPosition ,
61+ 'year' : getYearPosition ,
62+ 'decimal' : getDecimalPosition ,
63+ 'decade' : getDecadePosition ,
64+ 'century' : getCenturyPosition ,
65+ 'millennia' : getMillenniaPosition
66+ } ;
7167function getCurrentPosition ( type ) {
72- const positionFunctions = {
73- 'hour' : getHourPosition ,
74- 'month' : getMonthPosition ,
75- 'year' : getYearPosition ,
76- 'decimal' : getDecimalPosition ,
77- 'decade' : getDecadePosition ,
78- 'century' : getCenturyPosition ,
79- 'millennia' : getMillenniaPosition
80- } ;
81- const positionFunction = positionFunctions [ type ] || positionFunctions [ 'year' ] ;
82- return positionFunction ( ) ;
68+ return ( POSITION_FUNCTIONS [ type ] || POSITION_FUNCTIONS [ 'year' ] ) ( ) ;
8369}
8470function getClockSetup ( type ) {
8571 return CLOCK_CONFIG . clockTypes [ type ] || CLOCK_CONFIG . clockTypes . year ;
@@ -92,11 +78,10 @@ function drawLine(ctx, startX, startY, endX, endY, color, width, opacity = 1.0)
9278 ctx . strokeStyle = color ;
9379 ctx . lineWidth = width ;
9480 ctx . stroke ( ) ;
95- return ctx ;
9681}
9782function drawCircle ( ctx , x , y , radius , color , fill = true , opacity = 1.0 ) {
9883 ctx . beginPath ( ) ;
99- ctx . arc ( x , y , radius , 0 , 2 * Math . PI ) ;
84+ ctx . arc ( x , y , radius , 0 , TAU ) ;
10085 ctx . globalAlpha = opacity ;
10186 if ( fill ) {
10287 ctx . fillStyle = color ;
@@ -106,7 +91,6 @@ function drawCircle(ctx, x, y, radius, color, fill = true, opacity = 1.0) {
10691 ctx . strokeStyle = color ;
10792 ctx . stroke ( ) ;
10893 }
109- return ctx ;
11094}
11195function drawText ( ctx , text , x , y , color , fontSize , opacity = 1.0 ) {
11296 ctx . font = `${ fontSize } px sans-serif` ;
@@ -115,7 +99,6 @@ function drawText(ctx, text, x, y, color, fontSize, opacity = 1.0) {
11599 ctx . textBaseline = 'middle' ;
116100 ctx . globalAlpha = opacity ;
117101 ctx . fillText ( text , x , y ) ;
118- return ctx ;
119102}
120103function getPointFromAngle ( center , angle , distance ) {
121104 return {
@@ -128,13 +111,13 @@ function getHourPosition() {
128111 const hour = now . hour ( ) % 12 ;
129112 const minute = now . minute ( ) ;
130113 const second = now . second ( ) ;
131- return ( ( hour * 60 + minute + second / 60 ) / 720 ) * 2 * Math . PI ;
114+ return ( ( hour * 60 + minute + second / 60 ) / 720 ) * TAU ;
132115}
133116function getMonthPosition ( ) {
134117 const now = moment ( ) ;
135118 const month = now . month ( ) ;
136119 const day = now . date ( ) ;
137- return ( month + day / now . daysInMonth ( ) ) / 12 * 2 * Math . PI ;
120+ return ( month + day / now . daysInMonth ( ) ) / 12 * TAU ;
138121}
139122function getYearPosition ( ) {
140123 const now = moment ( ) ;
@@ -143,7 +126,7 @@ function getYearPosition() {
143126 const day = now . date ( ) ;
144127 const yearsSince2000 = year - 2000 ;
145128 const fractionOfYear = ( month * 30 + day ) / 365 ;
146- return ( ( yearsSince2000 + fractionOfYear ) / 60 ) * 2 * Math . PI ;
129+ return ( ( yearsSince2000 + fractionOfYear ) / 60 ) * TAU ;
147130}
148131function getDecimalPosition ( ) {
149132 return 0 ;
@@ -152,39 +135,40 @@ function getDecadePosition() {
152135 const now = moment ( ) ;
153136 const year = now . year ( ) ;
154137 const month = now . month ( ) ;
155- return ( year + month / 12 - 2000 ) / 100 * 2 * Math . PI ;
138+ return ( year + month / 12 - 2000 ) / 100 * TAU ;
156139}
157140function getCenturyPosition ( ) {
158141 const now = moment ( ) ;
159142 const year = now . year ( ) ;
160143 const month = now . month ( ) ;
161- return ( year + month / 12 - 1200 ) / 1200 * 2 * Math . PI ;
144+ return ( year + month / 12 - 1200 ) / 1200 * TAU ;
162145}
163146function getMillenniaPosition ( ) {
164- const year = moment ( ) . year ( ) ;
165- return ( year ) / 12000 * 2 * Math . PI ;
147+ return moment ( ) . year ( ) / 12000 * TAU ;
166148}
167149function drawClockDial ( ctx , config , clockSetup ) {
168150 ctx . clearRect ( 0 , 0 , ctx . canvas . width , ctx . canvas . height ) ;
169151 drawCircle ( ctx , config . center . x , config . center . y , config . radius , config . colors . dial , false , config . opacities . dial ) ;
170- for ( let segment = 0 ; segment < clockSetup . segmentCount ; segment ++ ) {
171- drawMarks ( ctx , config , clockSetup , segment ) ;
152+ const segmentCount = clockSetup . segmentNames . length ;
153+ for ( let segment = 0 ; segment < segmentCount ; segment ++ ) {
154+ drawMarks ( ctx , config , clockSetup , segment / segmentCount ) ;
172155 }
173156 drawMiniMarks ( ctx , config , clockSetup ) ;
174157}
175- function drawMarks ( ctx , config , clockSetup , segment ) {
158+ function drawMarks ( ctx , config , clockSetup , fraction ) {
176159 const { sizes, colors, opacities } = config ;
177- const segmentAngle = clockSetup . segmentFractions [ segment ] * 2 * Math . PI ;
160+ const segmentAngle = fraction * TAU ;
178161 const innerPoint = getPointFromAngle ( config . center , segmentAngle , config . radius - sizes . markLength ) ;
179162 const outerPoint = getPointFromAngle ( config . center , segmentAngle , config . radius - sizes . markLength / 2 ) ;
180163 drawLine ( ctx , innerPoint . x , innerPoint . y , outerPoint . x , outerPoint . y , colors . marks , sizes . markWidth , opacities . marks ) ;
181164 const labelPoint = getPointFromAngle ( config . center , segmentAngle , config . radius - sizes . markLength - sizes . labelPadding ) ;
182- drawText ( ctx , clockSetup . segmentNames [ segment ] , labelPoint . x , labelPoint . y , colors . marks , sizes . labelFontSize , opacities . labels ) ;
165+ const segmentIndex = Math . round ( fraction * clockSetup . segmentNames . length ) % clockSetup . segmentNames . length ;
166+ drawText ( ctx , clockSetup . segmentNames [ segmentIndex ] , labelPoint . x , labelPoint . y , colors . marks , sizes . labelFontSize , opacities . labels ) ;
183167}
184168function drawMiniMarks ( ctx , config , clockSetup ) {
185169 const { sizes, colors, opacities } = config ;
186170 for ( let i = 0 ; i < clockSetup . markCount ; i ++ ) {
187- const angle = ( i / clockSetup . markCount ) * 2 * Math . PI ;
171+ const angle = ( i / clockSetup . markCount ) * TAU ;
188172 const innerPoint = getPointFromAngle ( config . center , angle , config . radius - sizes . markLength ) ;
189173 const outerPoint = getPointFromAngle ( config . center , angle , config . radius - sizes . markLength * 0.5 ) ;
190174 drawLine ( ctx , innerPoint . x , innerPoint . y , outerPoint . x , outerPoint . y , colors . marks , sizes . markWidth , opacities . miniMarks ) ;
@@ -201,8 +185,7 @@ function drawHand(ctx, config, angle) {
201185 drawLine ( ctx , config . center . x , config . center . y , handPoint . x , handPoint . y , colors . hands , sizes . handWidth , 1.0 ) ;
202186 drawLine ( ctx , handPoint . x , handPoint . y , handEnd . x , handEnd . y , colors . highlight , sizes . handWidth * 0.5 , 1.0 ) ;
203187 const circleRadius = config . radius * sizes . handCircleRadius ;
204- const circleDistance = handLength * tip ;
205- const circlePoint = getPointFromAngle ( config . center , angle , circleDistance ) ;
188+ const circlePoint = getPointFromAngle ( config . center , angle , handLength * tip ) ;
206189 drawCircle ( ctx , circlePoint . x , circlePoint . y , circleRadius , colors . highlight , true , 1.0 ) ;
207190}
208191function drawCenterDot ( ctx , config ) {
@@ -226,7 +209,8 @@ function updateClock(ctx, config, clockSetup, type) {
226209 drawCenterDot ( ctx , config ) ;
227210 requestAnimationFrame ( ( ) => updateClock ( ctx , config , clockSetup , type ) ) ;
228211}
229- function initClock ( options ) {
212+ let themeObserver = null ;
213+ function draw_clock ( options ) {
230214 const id = options . id || 'default' ;
231215 const type = options . type || 'year' ;
232216 const canvas = document . getElementById ( `clockCanvas-${ id } ` ) ;
@@ -238,10 +222,8 @@ function initClock(options) {
238222 canvas . width = canvas . height = config . radius * 2 * dpr ;
239223 ctx . scale ( dpr , dpr ) ;
240224 syncThemeColors ( config ) ;
241- const observer = new MutationObserver ( ( ) => syncThemeColors ( config ) ) ;
242- observer . observe ( document . documentElement , { attributes : true , attributeFilter : [ 'data-theme' ] } ) ;
225+ themeObserver === null || themeObserver === void 0 ? void 0 : themeObserver . disconnect ( ) ;
226+ themeObserver = new MutationObserver ( ( ) => syncThemeColors ( config ) ) ;
227+ themeObserver . observe ( document . documentElement , { attributes : true , attributeFilter : [ 'data-theme' ] } ) ;
243228 updateClock ( ctx , config , clockSetup , type ) ;
244229}
245- function draw_clock ( options ) {
246- initClock ( options ) ;
247- }
0 commit comments