@ -21,10 +21,8 @@ const COLORS = {
} ,
} ;
const KEY _OUT _COLOR = "#2b6ec6" ;
// The width from the left side of the bus image to the front of the bus
const BUS _FRONT _OFFSET = 7 3 ;
const BUS _FRONT _OFFSET = 72 ;
// Start time of each day phase
const DAY _START _MINUTES = 450 ;
@ -49,7 +47,12 @@ const POINT_IMAGE = new Image();
POINT _IMAGE . src = "point.png" ;
// This should match the HTML canvas width
const CANVAS _PIXEL _WIDTH = 1920 ;
const CANVAS _PIXEL _WIDTH = 1580 ;
const BUS _TRAVEL _WIDTH = CANVAS _PIXEL _WIDTH - BUS _FRONT _OFFSET ;
const PIXELS _PER _MILE = BUS _TRAVEL _WIDTH / 360 ;
const PIXELS _PER _MINUTE = BUS _TRAVEL _WIDTH / 480 ;
const FULL _SPEED _MILES _PER _MINUTE = 0.75 ;
function nextPhase ( timeOfDay ) {
switch ( timeOfDay ) {
@ -81,17 +84,12 @@ function drawBackground(context, timeOfDay, leftX, width) {
const groundColor = COLORS [ timeOfDay ] . ground ;
const surfaceColor = COLORS [ timeOfDay ] . surface ;
context . fillStyle = KEY _OUT _COLOR ;
context . fillRect ( leftX , 80 , width , 20 ) ;
context . fillStyle = COLORS [ timeOfDay ] . sky ;
context . fillRect ( leftX , 0 , width , 80 ) ;
context . fillRect ( leftX , 0 , width , 56 ) ;
context . fillStyle = COLORS [ timeOfDay ] . surface ;
context . fillRect ( leftX , 80 , width , 1 ) ;
context . fillRect ( leftX , 56 , width , 1 ) ;
context . fillStyle = COLORS [ timeOfDay ] . ground ;
context . fillRect ( leftX , 81 , width , 7 ) ;
context . fillRect ( leftX , 89 , width , 3 ) ;
context . fillRect ( leftX , 94 , width , 2 ) ;
context . fillRect ( leftX , 99 , width , 1 ) ;
context . fillRect ( leftX , 57 , width , 5 ) ;
}
async function drawRoad ( ) {
@ -108,19 +106,62 @@ async function drawRoad() {
const context = canvas . getContext ( "2d" ) ;
// Clear the previous canvas before starting
context . clearRect ( 0 , 0 , CANVAS _PIXEL _WIDTH , 100 ) ;
// Background the whole thing as the key-out color in case we need to bail
// out before drawing (e.g. we're in a non-DB game menu)
context . fillStyle = KEY _OUT _COLOR ;
context . fillRect ( 0 , 0 , CANVAS _PIXEL _WIDTH , 100 ) ;
context . clearRect ( 0 , 0 , CANVAS _PIXEL _WIDTH , 62 ) ;
const pointModeCheckbox = document . getElementById ( "point-progress-checkbox" ) ;
if ( pointModeCheckbox . checked ) {
drawRoadPoint ( context , busData ) ;
} else {
drawRoadDynamic ( context , busData ) ;
}
}
function drawRoadPoint ( context , busData ) {
const busDistance = ( busData . odometer + 250.7 ) % 360 ;
const busRemainingDistance = 360 - busDistance ;
const busRemainingDistancePixels = busRemainingDistance * PIXELS _PER _MILE ;
const busDistancePixels = busDistance * PIXELS _PER _MILE ;
let x = busDistancePixels + BUS _FRONT _OFFSET ;
drawBackground ( context , busData . timeofday , 0 , x ) ;
let currentTimeOfDay = busData . timeofday ;
let currentTime = busData . clock _minutes ;
while ( x < CANVAS _PIXEL _WIDTH ) {
const nextTimeOfDay = nextPhase ( currentTimeOfDay ) ;
const nextStartTime = phaseStartTime ( nextTimeOfDay ) ;
let thisDuration = nextStartTime - currentTime ;
if ( thisDuration < 0 ) {
thisDuration += 1440 ;
}
const pixelWidth = thisDuration * PIXELS _PER _MINUTE ;
drawBackground ( context , currentTimeOfDay , x , pixelWidth ) ;
x += pixelWidth ;
currentTimeOfDay = nextTimeOfDay ;
currentTime += thisDuration ;
}
context . drawImage ( POINT _IMAGE , CANVAS _PIXEL _WIDTH - POINT _OFFSET , 0 ) ;
for ( const busStopDistance of BUS _STOP _POSITIONS ) {
const busStopPixelPosition =
BUS _FRONT _OFFSET + PIXELS _PER _MILE * busStopDistance - BUS _STOP _OFFSET ;
context . drawImage ( BUS _STOP _IMAGE , busStopPixelPosition , 16 ) ;
}
if ( busData . timeofday === "night" ) {
context . drawImage ( BUS _NIGHT _IMAGE , busDistancePixels , 32 ) ;
} else {
context . drawImage ( BUS _DAY _IMAGE , busDistancePixels , 32 ) ;
}
}
const currentTime = busData . clock _minutes ;
function drawRoadDynamic ( context , busData ) {
const distance = busData . odometer ;
const timeOfDay = busData . timeofday ;
drawBackground ( context , timeOfDay , 0 , BUS _FRONT _OFFSET ) ;
const maxWidth = CANVAS _PIXEL _WIDTH - BUS _FRONT _OFFSET ;
// The default scaling factor (1) is 20 seconds per pixel at max speed.
// This gives us
// - 3px per minute
@ -131,13 +172,11 @@ async function drawRoad() {
}
const startMinute = busData . clock _minutes ;
const timeDuration = maxWidth / ( 3 * scaleFactor ) ;
let previousTime = startMinute ;
let previousTimeOfDay = timeOfDay ;
let remainingDuration = timeDuration ;
let x = BUS _FRONT _OFFSET ;
while ( remainingDuration > 0 ) {
while ( x < CANVAS _PIXEL _WIDTH ) {
const nextTimeOfDay = nextPhase ( previousTimeOfDay ) ;
const nextStartTime = phaseStartTime ( nextTimeOfDay ) ;
@ -146,11 +185,9 @@ async function drawRoad() {
thisDuration += 1440 ;
}
// TODO Figure out scaling factor
const pixelWidth = thisDuration * 3 * scaleFactor ;
drawBackground ( context , previousTimeOfDay , x , pixelWidth ) ;
remainingDuration -= thisDuration ;
previousTime = nextStartTime ;
previousTimeOfDay = nextTimeOfDay ;
x += pixelWidth ;
@ -187,7 +224,7 @@ async function drawRoad() {
const distanceTrackedOnRoute = distanceTracked % 360 ;
let nextBusStopPosition = null ;
for ( const busStopPosition of BUS _STOP _POSITIONS ) {
if ( busStopPosition >= distanceTrackedOnRoute + 1 ) {
if ( busStopPosition >= distanceTrackedOnRoute + 0.05 ) {
nextBusStopPosition = busStopPosition ;
break ;
}
@ -198,17 +235,17 @@ async function drawRoad() {
const nextBusStopDistance = nextBusStopPosition - distanceTrackedOnRoute ;
distanceTracked += nextBusStopDistance ;
x += nextBusStopDistance * 4 * scaleFactor ;
context . drawImage ( BUS _STOP _IMAGE , x - BUS _STOP _OFFSET , 0 ) ;
context . drawImage ( BUS _STOP _IMAGE , x - BUS _STOP _OFFSET , 16 ) ;
}
if ( timeOfDay === "night" ) {
context . drawImage ( BUS _NIGHT _IMAGE , 0 , 0 ) ;
context . drawImage ( BUS _NIGHT _IMAGE , 0 , 32 ) ;
} else {
context . drawImage ( BUS _DAY _IMAGE , 0 , 0 ) ;
context . drawImage ( BUS _DAY _IMAGE , 0 , 32 ) ;
}
}
window . addEventListener ( "DOMContentLoaded" , ( event ) => {
drawRoad ( ) ;
setInterval ( drawRoad , 100 00) ;
setInterval ( drawRoad , 25 00) ;
} ) ;