Loading...
Searching...
No Matches
image_value_tracker.h
1
3const char* image_value_tracker = R"JS(/* src/js/image_value_tracker.js */
4function RadarDataEncoding(encoding){
5
6 this.type = "";
7 this.scale = 1.0;
8 this.offset = 0.0;
9 this.nodata = null;
10 this.undetect = null;
11
12 // Could be hidden, for now
13 this.precision = 2; // digits
14
15 if (!encoding)
16 return;
17
18 if (typeof(encoding) === "string"){
19 // console.info(elem);
20 encoding = encoding.split(',');
21 switch (encoding.length){
22 case 5:
23 this.undetect = parseFloat(encoding[4]);
24 case 4:
25 this.nodata = parseFloat(encoding[3]);
26 case 3:
27 this.offset = parseFloat(encoding[2]);
28 case 2:
29 this.scale = parseFloat(encoding[1]);
30 case 1:
31 this.type = encoding[0];
32 break;
33 default:
34 console.warn("data has extra 'encoding' attributes: ", encoding);
35 //console.warn(elem);
36 }
37 console.info('encoding: ' + this);
38 }
39
40}
41
42RadarDataEncoding.prototype.toString = function(){ return `${this.type},${this.scale},${this.offset},${this.nodata},${this.undetect}`}
43
44RadarDataEncoding.prototype.decode = function(value){
45
46 if (value === this.nodata){
47 return 'nodata';
48 }
49 else if (value === this.undetect){
50 return 'undetect';
51 }
52 else {
53 return (this.scale*value + this.offset).toFixed(this.precision);
54 }
55
56}
57
58
59async function set_image_value_tracker(imgElem, encoding, coordMonitorElem, valueMonitorElem){
60
61 const svg = document.querySelector("svg");
62
63 await imgElem.decode();
64 const bbox = imgElem.getBoundingClientRect();
65 console.log('bbox: ', bbox);
66 // const w = imgElem.naturalWidth | 1;
67 // const h = imgElem.naturalHeight | 1;
68 const w = Math.round(bbox.width);
69 const h = Math.round(bbox.height);
70 const canvas = new OffscreenCanvas(w, h);
71 console.info(canvas)
72
73 const ctx = canvas.getContext("2d", { willReadFrequently: true });
74
75 // Expose for debugging
76 // window.rackster = { imgElem, w, h, canvas, ctx };
77
78 // Draw and read
79 ctx.clearRect(0, 0, w, h);
80 // ctx.drawImage(imgElem, 0, 0);
81 ctx.drawImage(imgElem, 0, 0, w, h);
82
83
84
85 // critical:
86 const imageData = ctx.getImageData(0, 0, w, h);
87 const data = imageData.data;
88
89 // console.warn(imageData)
90
91 function grayAt(x, y) {
92
93 const e = encoding;
94
95 //x = Math.floor(x)
96 //y = Math.floor(y)
97
98 if (x < 0 || y < 0 || x >= w || y >= h) return "";
99 const i = (y * w + x) * 4;
100 // Red: higher bits, Green: lower bits
101 const v = (data[i]<<8) + data[i+1];
102 // return ""+(data[i])+'+'+data[i+1] + " = " + e.decode(v);
103 return e.decode(v);
104
105 }
106
107 imgElem.addEventListener("mousemove", (ev) => {
108
109 // svg - doc root linked above
110 /*
111 // This worked badly, if browser zoom applied.
112 const pt = svg.createSVGPoint();
113 pt.x = ev.clientX;
114 pt.y = ev.clientY;
115 const p = pt.matrixTransform(imgElem.getScreenCTM().inverse());
116 const x = Math.floor(p.x);
117 const y = Math.floor(p.y);
118 */
119 var my_bbox = imgElem.getBoundingClientRect();
120 var x = Math.floor(ev.clientX - my_bbox.left);
121 var y = Math.floor(ev.clientY - my_bbox.top);
122 coordMonitorElem.textContent = '('+x+','+y+')'; //.toFixed(2);
123 valueMonitorElem.textContent = grayAt(x,y); //.toFixed(2);
124 })
125
126 // window.rackdata = data
127
128}
129
130function image_value_tracker(){
131
132 // const elems = document.querySelectorAll("metadata[data-base64]");
133 const elems = document.querySelectorAll(".MOUSE_VALUE");
134
135 elems.forEach(elem => {
136
137 const dataElem = elem.querySelector(".MOUSE_VALUE_DATA");
138 window.metadata = dataElem;
139 var encoding = new RadarDataEncoding(dataElem.getAttribute("data-encoding"))
140
141 const coordMonitorElem = elem.querySelector(".COORD_MONITOR");
142 const valueMonitorElem = elem.querySelector(".VALUE_MONITOR");
143
144 set_image_value_tracker(dataElem, encoding, coordMonitorElem, valueMonitorElem);
145 // var type = dataElem.getAttribute("data-basetype");
146
147 });
148
149}
150)JS";