|
| 1 | +const font = { |
| 2 | + "0": [ |
| 3 | + [[0,0],[1,0]], |
| 4 | + [[1,0],[1,1]], |
| 5 | + [[1,1],[0,1]], |
| 6 | + [[0,1],[0,0]] |
| 7 | + ], |
| 8 | + |
| 9 | + "1": [ |
| 10 | + [[1,0],[1,1]] |
| 11 | + ], |
| 12 | + |
| 13 | + "2": [ |
| 14 | + [[0,0],[1,0]], |
| 15 | + [[1,0],[1,0.5]], |
| 16 | + [[1,0.5],[0,0.5]], |
| 17 | + [[0,0.5],[0,1]], |
| 18 | + [[0,1],[1,1]] |
| 19 | + ], |
| 20 | + |
| 21 | + "3": [ |
| 22 | + [[0,0],[1,0]], |
| 23 | + [[1,0],[1,1]], |
| 24 | + [[0,0.5],[1,0.5]], |
| 25 | + [[0,1],[1,1]] |
| 26 | + ], |
| 27 | + |
| 28 | + "4": [ |
| 29 | + [[0,0],[0,0.5]], |
| 30 | + [[1,0],[1,1]], |
| 31 | + [[0,0.5],[1,0.5]] |
| 32 | + ], |
| 33 | + |
| 34 | + "5": [ |
| 35 | + [[1,0],[0,0]], |
| 36 | + [[0,0],[0,0.5]], |
| 37 | + [[0,0.5],[1,0.5]], |
| 38 | + [[1,0.5],[1,1]], |
| 39 | + [[1,1],[0,1]] |
| 40 | + ], |
| 41 | + |
| 42 | + "6": [ |
| 43 | + [[1,0],[0,0]], |
| 44 | + [[0,0],[0,1]], |
| 45 | + [[0,1],[1,1]], |
| 46 | + [[1,1],[1,0.5]], |
| 47 | + [[1,0.5],[0,0.5]] |
| 48 | + ], |
| 49 | + |
| 50 | + "7": [ |
| 51 | + [[0,0],[1,0]], |
| 52 | + [[1,0],[1,1]] |
| 53 | + ], |
| 54 | + |
| 55 | + "8": [ |
| 56 | + [[0,0],[1,0]], |
| 57 | + [[1,0],[1,1]], |
| 58 | + [[1,1],[0,1]], |
| 59 | + [[0,1],[0,0]], |
| 60 | + [[0,0.5],[1,0.5]] |
| 61 | + ], |
| 62 | + |
| 63 | + "9": [ |
| 64 | + [[0,0],[1,0]], |
| 65 | + [[0,0],[0,0.5]], |
| 66 | + [[0,0.5],[1,0.5]], |
| 67 | + [[1,0],[1,1]] |
| 68 | + ], |
| 69 | + |
| 70 | + "NaN": [ |
| 71 | + [[],[]] |
| 72 | + ] |
| 73 | +}; |
| 74 | + |
| 75 | +const corner_base_positions = [ |
| 76 | + [[10, 10], [78, 78]], // top-left (unchanged) |
| 77 | + [[93, 10], [165, 78]], // top-right (x + 5) |
| 78 | + [[10, 93], [78, 165]], // bottom-left (y + 5) |
| 79 | + [[93, 93], [165, 165]] // bottom-right (x + 5, y + 5) |
| 80 | +]; |
| 81 | + |
| 82 | +let corner_positions = []; |
| 83 | +let previous_corner_positions = []; |
| 84 | + |
| 85 | +const padding = 10; |
| 86 | +const width = 175; |
| 87 | +const height = 175; |
| 88 | + |
| 89 | +const colors = { |
| 90 | + "Black": [0,0,0], |
| 91 | + "White": [1,1,1], |
| 92 | + "Red": [1,0,0], |
| 93 | + "Blue": [0,0,1], |
| 94 | + "Green": [0,1,0], |
| 95 | + "Yellow": [1,1,0], |
| 96 | + "Orange": [1,0.6,0], |
| 97 | + "Purple": [0.7,0,1], |
| 98 | + "Lime": [0,1,0.5], |
| 99 | + "Cyan": [0, 1, 1], |
| 100 | + "Light Blue": [0,0.5,1], |
| 101 | + "Pink": [1,0.5,1] |
| 102 | +}; |
| 103 | + |
| 104 | +let bg_color = [0,0,0]; |
| 105 | +let fg_color = [1,1,1]; |
| 106 | +let bg_color_topo = [1,0,0.5]; |
| 107 | +let fg_color_topo = [0,1,0.5]; |
| 108 | + |
| 109 | +function randomize_numbers(){ |
| 110 | + previous_corner_positions = JSON.parse(JSON.stringify(corner_positions)); |
| 111 | + corner_positions = JSON.parse(JSON.stringify(corner_base_positions)); |
| 112 | + |
| 113 | + if (!previous_corner_positions || previous_corner_positions.length === 0) { |
| 114 | + previous_corner_positions = JSON.parse(JSON.stringify(corner_positions)); |
| 115 | + } |
| 116 | + |
| 117 | + // Your offsets and modifications follow here as before |
| 118 | + let x_offset = Math.floor(Math.random() * 61) - 30; |
| 119 | + let left_y_offset = Math.floor(Math.random() * 61) - 30; |
| 120 | + let right_y_offset = Math.floor(Math.random() * 61) - 30; |
| 121 | + |
| 122 | + [0,1,2,3].forEach(function(i) { |
| 123 | + let min_x = corner_positions[i][0][0]; |
| 124 | + let min_y = corner_positions[i][0][1]; |
| 125 | + let max_x = corner_positions[i][1][0]; |
| 126 | + let max_y = corner_positions[i][1][1]; |
| 127 | + |
| 128 | + if (min_x !== padding) { |
| 129 | + min_x += x_offset; |
| 130 | + } |
| 131 | + if (max_x !== width - padding) { |
| 132 | + max_x += x_offset; |
| 133 | + } |
| 134 | + |
| 135 | + let yoff = (i % 2) > 0 ? right_y_offset : left_y_offset; |
| 136 | + |
| 137 | + if (min_y !== padding) { |
| 138 | + min_y += yoff; |
| 139 | + } |
| 140 | + if (max_y !== height - padding) { |
| 141 | + max_y += yoff; |
| 142 | + } |
| 143 | + |
| 144 | + // Update corner_positions with new offsets |
| 145 | + corner_positions[i][0][0] = min_x; |
| 146 | + corner_positions[i][0][1] = max_x; |
| 147 | + corner_positions[i][1][0] = min_y; |
| 148 | + corner_positions[i][1][1] = max_y; |
| 149 | + }); |
| 150 | +} |
| 151 | + |
| 152 | +function drawThickLine(x1, y1, x2, y2, width, topoY) { |
| 153 | + let half = Math.floor(width / 2); |
| 154 | + |
| 155 | + // Expand to thickness by offsetting both ends |
| 156 | + if (x1 === x2) { |
| 157 | + // Vertical line |
| 158 | + x1 -= half; |
| 159 | + x2 += half; |
| 160 | + } else if (y1 === y2) { |
| 161 | + // Horizontal line |
| 162 | + y1 -= half; |
| 163 | + y2 += half; |
| 164 | + } else { |
| 165 | + // Diagonal fallback |
| 166 | + for (let i = -half; i <= half; i++) { |
| 167 | + g.drawLine(x1 + i, y1, x2 + i, y2); |
| 168 | + } |
| 169 | + return; |
| 170 | + } |
| 171 | + |
| 172 | + // Order the coordinates for fillRect |
| 173 | + let left = Math.min(x1, x2); |
| 174 | + let right = Math.max(x1, x2); |
| 175 | + let top = Math.min(y1, y2); |
| 176 | + let bottom = Math.max(y1, y2); |
| 177 | + |
| 178 | + // Split based on topoY (topographic height) |
| 179 | + if (top < topoY && bottom > topoY) { |
| 180 | + // Split into two regions |
| 181 | + g.setColor(fg_color_topo[0], fg_color_topo[1], fg_color_topo[2]); |
| 182 | + g.fillRect(left, top, right, topoY); |
| 183 | + |
| 184 | + g.setColor(fg_color[0], fg_color[1], fg_color[2]); |
| 185 | + g.fillRect(left, topoY + 1, right, bottom); |
| 186 | + } else if (bottom <= topoY) { |
| 187 | + // Entire line is above topo |
| 188 | + g.setColor(fg_color_topo[0], fg_color_topo[1], fg_color_topo[2]); |
| 189 | + g.fillRect(left, top, right, bottom); |
| 190 | + } else { |
| 191 | + // Entire line is below topo |
| 192 | + g.setColor(fg_color[0], fg_color[1], fg_color[2]); |
| 193 | + g.fillRect(left, top, right, bottom); |
| 194 | + } |
| 195 | +} |
| 196 | + |
| 197 | + |
| 198 | + |
| 199 | + |
| 200 | +function draw_numbers(transition_value, topo_position){ |
| 201 | + //console.log(previous_corner_positions); |
| 202 | + topo_position *= height; |
| 203 | + let d = new Date(); |
| 204 | + |
| 205 | + let hour = d.getHours(); |
| 206 | + let padded = ("0" + hour).slice(-2); |
| 207 | + |
| 208 | + let tl = padded[0]; |
| 209 | + let tr = padded[1]; |
| 210 | + |
| 211 | + let min = d.getMinutes(); |
| 212 | + padded = ("0" + min).slice(-2); |
| 213 | + |
| 214 | + |
| 215 | + let bl = padded[0]; |
| 216 | + let br = padded[1]; |
| 217 | + |
| 218 | + g.clear(); |
| 219 | + g.setColor(bg_color_topo[0],bg_color_topo[1],bg_color_topo[2]); |
| 220 | + g.fillRect(0,0,width,topo_position); |
| 221 | + g.setColor(bg_color[0],bg_color[1],bg_color[2]); |
| 222 | + g.fillRect(0,topo_position,width,height); |
| 223 | + |
| 224 | + [tl,tr,bl,br].forEach(function(corner, i) { |
| 225 | + let path = font[corner]; |
| 226 | + path.forEach(function(line){ |
| 227 | + let pcp = previous_corner_positions[i].slice(); |
| 228 | + let ccp = corner_positions[i].slice(); |
| 229 | + |
| 230 | + let x1 = (ccp[0][0] - pcp[0][0]) * transition_value + pcp[0][0]; |
| 231 | + let x2 = (ccp[0][1] - pcp[0][1]) * transition_value + pcp[0][1]; |
| 232 | + let y1 = (ccp[1][0] - pcp[1][0]) * transition_value + pcp[1][0]; |
| 233 | + let y2 = (ccp[1][1] - pcp[1][1]) * transition_value + pcp[1][1]; |
| 234 | + |
| 235 | + |
| 236 | + |
| 237 | + let point_1 = [line[0][0]*(x2-x1) + x1, line[0][1]*(y2-y1) + y1]; |
| 238 | + let point_2 = [line[1][0]*(x2-x1) + x1, line[1][1]*(y2-y1) + y1]; |
| 239 | + |
| 240 | + drawThickLine(point_1[0], point_1[1], point_2[0], point_2[1], 10, topo_position); |
| 241 | + }); |
| 242 | + }); |
| 243 | +} |
| 244 | + |
| 245 | +let powersaver = false; |
| 246 | +let update_timeout = null; |
| 247 | + |
| 248 | +let prev_min = -1; |
| 249 | +function update_clock() { |
| 250 | + let d = new Date(); |
| 251 | + let min = d.getMinutes(); |
| 252 | + |
| 253 | + if (min != prev_min) { |
| 254 | + randomize_numbers(); |
| 255 | + prev_min = min; |
| 256 | + } |
| 257 | + |
| 258 | + if (powersaver) { |
| 259 | + if (direction == 1) { |
| 260 | + draw_numbers(1, 2); |
| 261 | + } |
| 262 | + else if (direction == 0) { |
| 263 | + draw_numbers(1, 0); |
| 264 | + } |
| 265 | + update_timeout = setTimeout(update_clock, 5000); |
| 266 | + } |
| 267 | + else { |
| 268 | + let seconds = d.getSeconds() + d.getMilliseconds() / 1000; |
| 269 | + if (direction == 1) { |
| 270 | + draw_numbers(Math.min(seconds, 1) / 1, 1.00-(seconds/60)); |
| 271 | + } |
| 272 | + else if (direction == 0) { |
| 273 | + draw_numbers(Math.min(seconds, 1) / 1, seconds / 60); |
| 274 | + } |
| 275 | + if (seconds < 1.5) { |
| 276 | + update_timeout = setTimeout(update_clock, 50); |
| 277 | + } else { |
| 278 | + update_timeout = setTimeout(update_clock, 1000); |
| 279 | + } |
| 280 | + } |
| 281 | +} |
| 282 | + |
| 283 | +let settings = require("Storage").readJSON("flux.settings.json", 1) || {}; |
| 284 | +console.log(settings); |
| 285 | +let direction = settings.direction || 0; |
| 286 | +bg_color = colors[settings.bg || "Black"]; |
| 287 | +fg_color = colors[settings.fg || "White"]; |
| 288 | +bg_color_topo = colors[settings.bg2 || "Green"]; |
| 289 | +fg_color_topo = colors[settings.fg2 || "Black"]; |
| 290 | +if (direction == 1) { |
| 291 | + let temp = bg_color; |
| 292 | + bg_color = bg_color_topo; |
| 293 | + bg_color_topo = temp; |
| 294 | + |
| 295 | + temp = fg_color; |
| 296 | + fg_color = fg_color_topo; |
| 297 | + fg_color_topo = temp; |
| 298 | +} |
| 299 | + |
| 300 | + |
| 301 | +update_clock(); |
| 302 | + |
| 303 | +Bangle.on('backlight', function(isOn) { |
| 304 | + if (isOn) { |
| 305 | + powersaver = false; |
| 306 | + clearTimeout(update_timeout); |
| 307 | + update_clock(); |
| 308 | + } else { |
| 309 | + powersaver = true; |
| 310 | + let d = new Date(); |
| 311 | + let seconds = d.getSeconds() + d.getMilliseconds() / 1000; |
| 312 | + draw_numbers(Math.min(seconds, 1) / 1, 0); |
| 313 | + } |
| 314 | +}); |
| 315 | + |
| 316 | +Bangle.setUI("clock"); |
0 commit comments