Skip to content

Commit 6ad518e

Browse files
committed
fix(renderer): Use semi-transparent selection overlay like VS Code
Changed selection rendering from solid color replacement to a semi-transparent overlay (40% opacity) that preserves original text colors. This matches VS Code's editor selection behavior and improves readability. - Selection background now overlays on top of cell background - Text keeps original colors unless selectionForeground is defined - Added TODO for configurable opacity via theme.selectionOpacity
1 parent 53fa302 commit 6ad518e

1 file changed

Lines changed: 31 additions & 21 deletions

File tree

‎lib/renderer.ts‎

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -553,12 +553,8 @@ export class CanvasRenderer {
553553
// Check if this cell is selected
554554
const isSelected = this.isInSelection(x, y);
555555

556-
if (isSelected) {
557-
// Draw selection background (solid color, not overlay)
558-
this.ctx.fillStyle = this.theme.selectionBackground;
559-
this.ctx.fillRect(cellX, cellY, cellWidth, this.metrics.height);
560-
return; // Selection background replaces cell background
561-
}
556+
// For selected cells, we'll draw the selection overlay AFTER the normal background
557+
// This creates a tinted effect like VS Code's editor selection
562558

563559
// Extract background color and handle inverse
564560
let bg_r = cell.bg_r,
@@ -579,6 +575,17 @@ export class CanvasRenderer {
579575
this.ctx.fillStyle = this.rgbToCSS(bg_r, bg_g, bg_b);
580576
this.ctx.fillRect(cellX, cellY, cellWidth, this.metrics.height);
581577
}
578+
579+
// Draw selection overlay on top (semi-transparent like VS Code editor)
580+
// This creates a tinted highlight effect that preserves text readability
581+
// TODO: Make opacity configurable via theme.selectionOpacity (default 0.4)
582+
if (isSelected && this.theme.selectionBackground) {
583+
const selectionOpacity = 0.4; // Adjust for lighter/darker selection tint
584+
this.ctx.globalAlpha = selectionOpacity;
585+
this.ctx.fillStyle = this.theme.selectionBackground;
586+
this.ctx.fillRect(cellX, cellY, cellWidth, this.metrics.height);
587+
this.ctx.globalAlpha = 1.0;
588+
}
582589
}
583590

584591
/**
@@ -604,22 +611,24 @@ export class CanvasRenderer {
604611
if (cell.flags & CellFlags.BOLD) fontStyle += 'bold ';
605612
this.ctx.font = `${fontStyle}${this.fontSize}px ${this.fontFamily}`;
606613

607-
// Set text color - use selection foreground if selected
608-
if (isSelected) {
609-
this.ctx.fillStyle = this.theme.selectionForeground;
610-
} else {
611-
// Extract colors and handle inverse
612-
let fg_r = cell.fg_r,
613-
fg_g = cell.fg_g,
614-
fg_b = cell.fg_b;
615-
616-
if (cell.flags & CellFlags.INVERSE) {
617-
// When inverted, foreground becomes background
618-
fg_r = cell.bg_r;
619-
fg_g = cell.bg_g;
620-
fg_b = cell.bg_b;
621-
}
614+
// Extract colors and handle inverse
615+
let fg_r = cell.fg_r,
616+
fg_g = cell.fg_g,
617+
fg_b = cell.fg_b;
622618

619+
if (cell.flags & CellFlags.INVERSE) {
620+
// When inverted, foreground becomes background
621+
fg_r = cell.bg_r;
622+
fg_g = cell.bg_g;
623+
fg_b = cell.bg_b;
624+
}
625+
626+
// Set text color - use selection foreground only if explicitly defined
627+
// Otherwise keep original text color (works better with semi-transparent overlay)
628+
const selFg = this.theme.selectionForeground;
629+
if (isSelected && selFg && selFg !== 'undefined') {
630+
this.ctx.fillStyle = selFg;
631+
} else {
623632
this.ctx.fillStyle = this.rgbToCSS(fg_r, fg_g, fg_b);
624633
}
625634

@@ -926,6 +935,7 @@ export class CanvasRenderer {
926935
return false;
927936
}
928937

938+
929939
/**
930940
* Set the currently hovered hyperlink ID for rendering underlines
931941
*/

0 commit comments

Comments
 (0)