feat(canvas): resistors default to vertical on add

Every resistor variant ('resistor' + 'resistor-<value>') now lands on
the canvas rotated 90 degrees: reads better, takes less horizontal
space, and drops straight into breadboard columns. Explicit rotations
in metadata defaults are respected. The breadboard auto-vertical drag
check widens from the two-entry set to the same prefix predicate, so
preconfigured variants (resistor-330 etc.) rotate on the board too.
This commit is contained in:
David Montero 2026-07-18 18:02:41 +02:00
parent f98c3268fa
commit aab5e1be08
3 changed files with 18 additions and 6 deletions

View File

@ -746,11 +746,20 @@ export function createComponentFromMetadata(
// dark LED). Also strip '-' from metadata.id (e.g. 'led-bar-graph') so
// the prefix doesn't reintroduce a hyphen.
const safePrefix = metadata.id.replace(/-/g, '_');
const properties: Record<string, any> = { ...metadata.defaultValues };
// Resistors default to vertical: they read better, take less horizontal
// space, and drop straight into breadboard columns (their pin span
// bridges the center trench). Covers 'resistor' and every preconfigured
// 'resistor-<value>' variant; anything with an explicit rotation in its
// metadata defaults keeps it.
if (metadata.id.startsWith('resistor') && properties.rotation === undefined) {
properties.rotation = 90;
}
return {
id: `${safePrefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
metadataId: metadata.id,
x,
y,
properties: { ...metadata.defaultValues },
properties,
};
}

View File

@ -30,7 +30,7 @@ import { calculatePinPosition } from '../../utils/pinPositionCalculator';
import { isBoardComponent, boardPinToNumber } from '../../utils/boardPinMapping';
import { autoWireColor, WIRE_KEY_COLORS, expandOrthogonalPoints } from '../../utils/wireUtils';
import {
AUTO_VERTICAL_PARTS,
isAutoVerticalPart,
isOverBreadboard,
snapPositionToBreadboard,
} from '../../utils/breadboardSnap';
@ -832,7 +832,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => {
);
if (dragged) {
if (
AUTO_VERTICAL_PARTS.has(dragged.metadataId) &&
isAutoVerticalPart(dragged.metadataId) &&
(Number(dragged.properties?.rotation) || 0) === 0 &&
isOverBreadboard(dragged, nx, ny, simState.components)
) {
@ -1424,7 +1424,7 @@ export const SimulatorCanvas = ({ headerSlot }: SimulatorCanvasProps = {}) => {
// Axial parts entering a breadboard flip to vertical so they
// bridge the trench columns like on a real board.
if (
AUTO_VERTICAL_PARTS.has(dragged.metadataId) &&
isAutoVerticalPart(dragged.metadataId) &&
(Number(dragged.properties?.rotation) || 0) === 0 &&
isOverBreadboard(dragged, nx, ny, simState.components)
) {

View File

@ -218,5 +218,8 @@ export function isOverBreadboard(
return false;
}
/** Axial 2-pin parts that read better vertical on a breadboard. */
export const AUTO_VERTICAL_PARTS = new Set(['resistor', 'wokwi-resistor']);
/** Axial 2-pin parts that read better vertical on a breadboard: 'resistor'
* plus every preconfigured 'resistor-<value>' variant. */
export function isAutoVerticalPart(metadataId: string): boolean {
return metadataId.startsWith('resistor') || metadataId.startsWith('wokwi-resistor');
}