132 lines
3.7 KiB
TypeScript
132 lines
3.7 KiB
TypeScript
import {
|
|
SYMBOL_FILL,
|
|
SYMBOL_STROKE,
|
|
SymbolSvg,
|
|
} from "./primitives";
|
|
|
|
const PNCH012_STROKE = "#8b134f";
|
|
const PNCH_CHAMBER_CONTENT_SCALE = 0.45;
|
|
const PNCH_CHAMBER_CONTENT_CENTER = { x: 32, y: 24 } as const;
|
|
const PNCH_CHAMBER_CONTENT_TRANSFORM = `translate(${PNCH_CHAMBER_CONTENT_CENTER.x} ${PNCH_CHAMBER_CONTENT_CENTER.y}) scale(${PNCH_CHAMBER_CONTENT_SCALE}) translate(${-PNCH_CHAMBER_CONTENT_CENTER.x} ${-PNCH_CHAMBER_CONTENT_CENTER.y})`;
|
|
const PNCH_CHAMBER_LABEL_RENDERED_SIZE = 15;
|
|
const PNCH_CHAMBER_SMALL_CANVAS_SCALE = 96 / 64;
|
|
// SVG 字号使用 viewBox 逻辑单位;抵消 small 画布缩放后,工作区最终显示为 15px。
|
|
const PNCH_CHAMBER_LABEL_FONT_SIZE =
|
|
PNCH_CHAMBER_LABEL_RENDERED_SIZE / PNCH_CHAMBER_SMALL_CANVAS_SCALE;
|
|
|
|
function scalePnchChamberAnchor(x: number, y: number) {
|
|
return {
|
|
x:
|
|
PNCH_CHAMBER_CONTENT_CENTER.x +
|
|
(x - PNCH_CHAMBER_CONTENT_CENTER.x) * PNCH_CHAMBER_CONTENT_SCALE,
|
|
y:
|
|
PNCH_CHAMBER_CONTENT_CENTER.y +
|
|
(y - PNCH_CHAMBER_CONTENT_CENTER.y) * PNCH_CHAMBER_CONTENT_SCALE,
|
|
} as const;
|
|
}
|
|
|
|
export const PNCH012_PORT_ANCHORS = {
|
|
bottom: scalePnchChamberAnchor(32, 56),
|
|
left: scalePnchChamberAnchor(0, 24),
|
|
right: scalePnchChamberAnchor(64, 24),
|
|
top: scalePnchChamberAnchor(32, -8),
|
|
} as const;
|
|
|
|
export const PNCH023_PORT_ANCHORS = {
|
|
left: PNCH012_PORT_ANCHORS.left,
|
|
right: PNCH012_PORT_ANCHORS.right,
|
|
} as const;
|
|
|
|
export function AmesimPnch023Symbol() {
|
|
return (
|
|
<SymbolSvg domain="pneumatic">
|
|
<g data-pnch023-part="symbol" transform={PNCH_CHAMBER_CONTENT_TRANSFORM}>
|
|
<path
|
|
d="M0 24H11M53 24H64"
|
|
data-pnch023-part="ports"
|
|
stroke={SYMBOL_STROKE}
|
|
strokeLinecap="butt"
|
|
strokeWidth="2"
|
|
/>
|
|
<circle
|
|
cx="32"
|
|
cy="24"
|
|
data-pnch023-part="chamber"
|
|
fill={SYMBOL_FILL}
|
|
r="21"
|
|
stroke={SYMBOL_STROKE}
|
|
strokeWidth="2"
|
|
/>
|
|
</g>
|
|
<text
|
|
data-pnch023-part="label"
|
|
dominantBaseline="central"
|
|
fill={PNCH012_STROKE}
|
|
fontFamily="Arial, sans-serif"
|
|
fontSize={PNCH_CHAMBER_LABEL_FONT_SIZE}
|
|
fontWeight="600"
|
|
textAnchor="middle"
|
|
x="32"
|
|
y="24"
|
|
>
|
|
Cp
|
|
</text>
|
|
</SymbolSvg>
|
|
);
|
|
}
|
|
|
|
export function AmesimPnch012Symbol() {
|
|
return (
|
|
<SymbolSvg domain="pneumatic">
|
|
<g data-pnch012-part="symbol" transform={PNCH_CHAMBER_CONTENT_TRANSFORM}>
|
|
<path
|
|
d="M0 24H11M53 24H64M32-8V3M32 45V56"
|
|
data-pnch012-part="ports"
|
|
stroke={PNCH012_STROKE}
|
|
strokeLinecap="butt"
|
|
strokeWidth="1.5"
|
|
/>
|
|
<circle
|
|
cx="32"
|
|
cy="24"
|
|
data-pnch012-part="chamber"
|
|
fill={SYMBOL_FILL}
|
|
r="21"
|
|
stroke={PNCH012_STROKE}
|
|
strokeWidth="1.5"
|
|
/>
|
|
<g
|
|
data-pnch012-part="volume-arrows"
|
|
fill="none"
|
|
stroke={PNCH012_STROKE}
|
|
strokeLinecap="butt"
|
|
strokeLinejoin="miter"
|
|
strokeWidth="1.5"
|
|
>
|
|
{[0, 90, 180, 270].map((rotation) => (
|
|
<path
|
|
d="M4-3 10 3M3 9H16V-4L3 9Z"
|
|
data-pnch012-part="volume-arrow"
|
|
key={rotation}
|
|
transform={`rotate(${rotation} 32 24)`}
|
|
/>
|
|
))}
|
|
</g>
|
|
</g>
|
|
<text
|
|
data-pnch012-part="label"
|
|
dominantBaseline="central"
|
|
fill={PNCH012_STROKE}
|
|
fontFamily="Arial, sans-serif"
|
|
fontSize={PNCH_CHAMBER_LABEL_FONT_SIZE}
|
|
fontWeight="600"
|
|
textAnchor="middle"
|
|
x="32"
|
|
y="24"
|
|
>
|
|
Cp
|
|
</text>
|
|
</SymbolSvg>
|
|
);
|
|
}
|