@@ -207,47 +207,28 @@ export const ProbeCanvas = forwardRef<HTMLCanvasElement, ProbeCanvasProps>(
207207 if ( probe . probe_planar_contour && probe . probe_planar_contour . length > 1 ) {
208208 ctx . beginPath ( ) ;
209209 probe . probe_planar_contour . forEach ( ( point , index ) => {
210- const [ x , y ] = projectPoint ( point ) ;
210+ const [ px , py ] = projectPoint ( point ) ;
211211 if ( index === 0 ) {
212- ctx . moveTo ( x , y ) ;
212+ ctx . moveTo ( px , py ) ;
213213 } else {
214- ctx . lineTo ( x , y ) ;
214+ ctx . lineTo ( px , py ) ;
215215 }
216216 } ) ;
217217 ctx . closePath ( ) ;
218- ctx . fillStyle = "rgba(180, 185, 195, 0.7)" ; // Metallic silver
219- ctx . strokeStyle = "rgba(100, 105, 115, 0.95)" ;
220- ctx . lineWidth = Math . max ( 1.2 , 2.5 * ( scale / 100 ) ) ;
218+
219+ // Technical line-art: a faint cool wash so the shank reads as a region,
220+ // with a thin precise outline. No fill gradient or shadow.
221+ ctx . fillStyle = "rgba(51, 65, 85, 0.05)" ;
221222 ctx . fill ( ) ;
223+ ctx . strokeStyle = "rgba(51, 65, 85, 0.9)" ;
224+ ctx . lineWidth = Math . max ( 1 , Math . min ( 1.6 , 2 * ( scale / 120 ) ) ) ;
222225 ctx . stroke ( ) ;
223226 }
224227
225228 const contactPositions = probe . contact_positions ?? [ ] ;
226229 const contactShapes = probe . contact_shapes ?? [ ] ;
227230 const contactShapeParams = probe . contact_shape_params ?? [ ] ;
228231
229- // A contact's pixel dimensions, used both to size the metallic gradient and
230- // to skip the sheen on pads too small for it to register.
231- const contactDims = ( shape : string , params : ContactShapeParams ) => {
232- switch ( shape ) {
233- case "circle" : {
234- const d = ( params . radius ?? 5 ) * 2 * scale ;
235- return { w : d , h : d , minPx : d , gradient : true } ;
236- }
237- case "square" : {
238- const s = ( params . width ?? 10 ) * scale ;
239- return { w : s , h : s , minPx : s , gradient : true } ;
240- }
241- case "rect" : {
242- const w = ( params . width ?? 10 ) * scale ;
243- const h = ( params . height ?? 15 ) * scale ;
244- return { w, h, minPx : Math . min ( w , h ) , gradient : true } ;
245- }
246- default :
247- return { w : 0 , h : 0 , minPx : 0 , gradient : false } ;
248- }
249- } ;
250-
251232 // Draws one contact path centered on the current origin (callers translate
252233 // the context to the pad position first). Rectangular pads get lightly
253234 // rounded corners so they read as real electrode pads, not hard tiles.
@@ -263,7 +244,7 @@ export const ProbeCanvas = forwardRef<HTMLCanvasElement, ProbeCanvasProps>(
263244 case "rect" : {
264245 const w = ( params . width ?? 10 ) * scale ;
265246 const h = ( shape === "square" ? ( params . width ?? 10 ) : ( params . height ?? 15 ) ) * scale ;
266- const r = Math . min ( w , h ) * 0.18 ;
247+ const r = Math . min ( w , h ) * 0.12 ;
267248 if ( typeof ctx . roundRect === "function" ) {
268249 ctx . roundRect ( - w / 2 , - h / 2 , w , h , r ) ;
269250 } else {
@@ -283,54 +264,21 @@ export const ProbeCanvas = forwardRef<HTMLCanvasElement, ProbeCanvasProps>(
283264 }
284265 } ;
285266
286- // One metallic gold gradient per distinct pad size per frame. Contacts are
287- // usually uniform, so this is built once and reused across all of them.
288- const gradientCache = new Map < string , CanvasGradient > ( ) ;
289- const goldGradient = ( w : number , h : number ) => {
290- const key = `${ Math . round ( w ) } x${ Math . round ( h ) } ` ;
291- let g = gradientCache . get ( key ) ;
292- if ( ! g ) {
293- g = ctx . createLinearGradient ( - w / 2 , - h / 2 , w / 2 , h / 2 ) ;
294- g . addColorStop ( 0 , "rgba(248, 228, 156, 1)" ) ; // warm highlight (top-left)
295- g . addColorStop ( 0.45 , "rgba(212, 175, 55, 1)" ) ; // gold body
296- g . addColorStop ( 1 , "rgba(146, 108, 28, 1)" ) ; // deep bronze (bottom-right)
297- gradientCache . set ( key , g ) ;
298- }
299- return g ;
300- } ;
301-
267+ // Flat gold contacts (the recognizable electrode convention), with a defined
268+ // bronze outline and no gradient or shadow — focal without the metallic
269+ // shine that was pulling focus.
302270 contactPositions . forEach ( ( position , index ) => {
303271 const [ x , y ] = projectPoint ( position ) ;
304272 const shape = contactShapes [ index ] ?? "" ;
305273 const params = contactShapeParams [ index ] ?? { } ;
306- const dims = contactDims ( shape , params ) ;
307274
308275 ctx . save ( ) ;
309276 ctx . translate ( x , y ) ;
310277 drawContactShape ( shape , params ) ;
311-
312- // Metallic sheen when the pad is big enough to show it; below that a flat
313- // gold that looks identical at that size but is cheaper.
314- ctx . fillStyle =
315- dims . gradient && dims . minPx >= 5
316- ? goldGradient ( dims . w , dims . h )
317- : "rgba(212, 175, 55, 1)" ;
318-
319- // A soft, capped shadow lifts the pad off the silver shank without the
320- // hard offset double-image the previous two-pass approach produced.
321- ctx . shadowColor = "rgba(15, 12, 4, 0.35)" ;
322- ctx . shadowBlur = Math . min ( 5 , Math . max ( 1.5 , dims . minPx * 0.12 ) ) ;
323- ctx . shadowOffsetX = 0 ;
324- ctx . shadowOffsetY = Math . min ( 2.5 , Math . max ( 0.4 , dims . minPx * 0.06 ) ) ;
278+ ctx . fillStyle = "rgba(212, 175, 55, 1)" ;
325279 ctx . fill ( ) ;
326-
327- // Clear the shadow before the rim so the outline stays crisp.
328- ctx . shadowColor = "transparent" ;
329- ctx . shadowBlur = 0 ;
330- ctx . shadowOffsetY = 0 ;
331-
332- ctx . lineWidth = Math . min ( 2 , Math . max ( 0.8 , dims . minPx * 0.03 ) ) ;
333- ctx . strokeStyle = "rgba(110, 80, 25, 0.85)" ;
280+ ctx . lineWidth = Math . max ( 1 , Math . min ( 1.8 , 2.5 * ( scale / 150 ) ) ) ;
281+ ctx . strokeStyle = "rgba(110, 80, 25, 0.9)" ;
334282 ctx . stroke ( ) ;
335283 ctx . restore ( ) ;
336284 } ) ;
0 commit comments