Compare commits
4 Commits
abacus-rea
...
abacus-rea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93f4cb0b11 | ||
|
|
c5ebc635af | ||
|
|
491b299e28 | ||
|
|
bb9959f7fb |
@@ -23,6 +23,7 @@ export function AbacusTarget({ number }: AbacusTargetProps) {
|
||||
columns={1}
|
||||
interactive={false}
|
||||
showNumbers={false}
|
||||
hideInactiveBeads={true}
|
||||
scaleFactor={0.72}
|
||||
customStyles={{
|
||||
columnPosts: { opacity: 0 }
|
||||
|
||||
@@ -332,8 +332,8 @@ export function GameDisplay() {
|
||||
<span style={{ color: '#6b7280' }}>+</span>
|
||||
{state.currentQuestion.showAsAbacus ? (
|
||||
<div style={{
|
||||
transform: 'scale(2.4)',
|
||||
transformOrigin: 'center',
|
||||
transform: 'scale(2.4) translateY(8%)',
|
||||
transformOrigin: 'center center',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
|
||||
import { useSpring, animated } from '@react-spring/web'
|
||||
import { AbacusReact } from '@soroban/abacus-react'
|
||||
|
||||
interface PressureGaugeProps {
|
||||
pressure: number // 0-150 PSI
|
||||
@@ -36,7 +37,7 @@ export function PressureGauge({ pressure }: PressureGaugeProps) {
|
||||
background: 'rgba(255, 255, 255, 0.95)',
|
||||
padding: '16px',
|
||||
borderRadius: '12px',
|
||||
minWidth: '160px',
|
||||
minWidth: '220px',
|
||||
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.2)'
|
||||
}}>
|
||||
{/* Title */}
|
||||
@@ -52,7 +53,7 @@ export function PressureGauge({ pressure }: PressureGaugeProps) {
|
||||
|
||||
{/* SVG Gauge */}
|
||||
<svg
|
||||
viewBox="0 0 210 130"
|
||||
viewBox="-40 -20 280 170"
|
||||
style={{
|
||||
width: '100%',
|
||||
height: 'auto',
|
||||
@@ -78,6 +79,10 @@ export function PressureGauge({ pressure }: PressureGaugeProps) {
|
||||
const x2 = 100 + Math.cos(tickRad) * 80
|
||||
const y2 = 100 - Math.sin(tickRad) * 80 // Subtract for SVG coords
|
||||
|
||||
// Position for abacus label
|
||||
const labelX = 100 + Math.cos(tickRad) * 112
|
||||
const labelY = 100 - Math.sin(tickRad) * 112
|
||||
|
||||
return (
|
||||
<g key={`tick-${index}`}>
|
||||
<line
|
||||
@@ -89,16 +94,31 @@ export function PressureGauge({ pressure }: PressureGaugeProps) {
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
<text
|
||||
x={100 + Math.cos(tickRad) * 92}
|
||||
y={100 - Math.sin(tickRad) * 92 + 4} // Subtract for SVG coords
|
||||
textAnchor="middle"
|
||||
fontSize="10"
|
||||
fill="#6b7280"
|
||||
fontWeight="600"
|
||||
<foreignObject
|
||||
x={labelX - 30}
|
||||
y={labelY - 25}
|
||||
width="60"
|
||||
height="100"
|
||||
>
|
||||
{psi}
|
||||
</text>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
lineHeight: 0
|
||||
}}>
|
||||
<AbacusReact
|
||||
value={psi}
|
||||
columns={3}
|
||||
interactive={false}
|
||||
showNumbers={false}
|
||||
hideInactiveBeads={false}
|
||||
scaleFactor={0.6}
|
||||
customStyles={{
|
||||
columnPosts: { opacity: 0 }
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</foreignObject>
|
||||
</g>
|
||||
)
|
||||
})}
|
||||
@@ -121,17 +141,34 @@ export function PressureGauge({ pressure }: PressureGaugeProps) {
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* Digital readout - animated */}
|
||||
{/* Abacus readout */}
|
||||
<div style={{
|
||||
textAlign: 'center',
|
||||
fontSize: '20px',
|
||||
fontWeight: 'bold'
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: '8px',
|
||||
minHeight: '32px'
|
||||
}}>
|
||||
<animated.span style={{ color }}>
|
||||
{spring.pressure.to(p => Math.round(p))}
|
||||
</animated.span>
|
||||
{' '}
|
||||
<span style={{ fontSize: '12px' }}>PSI</span>
|
||||
<div style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
lineHeight: 0
|
||||
}}>
|
||||
<AbacusReact
|
||||
value={Math.round(pressure)}
|
||||
columns={3}
|
||||
interactive={false}
|
||||
showNumbers={false}
|
||||
hideInactiveBeads={true}
|
||||
scaleFactor={0.35}
|
||||
customStyles={{
|
||||
columnPosts: { opacity: 0 }
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span style={{ fontSize: '12px', color: '#6b7280', fontWeight: 'bold' }}>PSI</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -172,8 +172,8 @@ export const GameHUD = memo(({
|
||||
<span style={{ color: '#6b7280' }}>+</span>
|
||||
{currentQuestion.showAsAbacus ? (
|
||||
<div style={{
|
||||
transform: 'scale(2.4)',
|
||||
transformOrigin: 'center',
|
||||
transform: 'scale(2.4) translateY(8%)',
|
||||
transformOrigin: 'center center',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
# [1.7.0](https://github.com/antialias/soroban-abacus-flashcards/compare/abacus-react-v1.6.0...abacus-react-v1.7.0) (2025-10-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **abacus-react:** apply global columnPosts styling and fix reckoning bar width ([bb9959f](https://github.com/antialias/soroban-abacus-flashcards/commit/bb9959f7fb8985e0c6496247306838d97e7121f7))
|
||||
* **complement-race:** improve abacus display in equations ([491b299](https://github.com/antialias/soroban-abacus-flashcards/commit/491b299e28ee82c49069cf892609b1b2b3c0aee3))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **complement-race:** add abacus displays to pressure gauge ([c5ebc63](https://github.com/antialias/soroban-abacus-flashcards/commit/c5ebc635afb6e78f9f4b1192ff39dcec53879a60))
|
||||
|
||||
# [1.6.0](https://github.com/antialias/soroban-abacus-flashcards/compare/abacus-react-v1.5.1...abacus-react-v1.6.0) (2025-10-01)
|
||||
|
||||
|
||||
|
||||
@@ -1756,13 +1756,14 @@ export const AbacusReact: React.FC<AbacusConfig> = ({
|
||||
const rodStartY = 0; // Start from top for now, will be refined
|
||||
const rodEndY = dimensions.height; // End at bottom for now, will be refined
|
||||
|
||||
// Apply custom column post styling
|
||||
// Apply custom column post styling (column-specific overrides global)
|
||||
const columnStyles = customStyles?.columns?.[colIndex];
|
||||
const globalColumnPosts = customStyles?.columnPosts;
|
||||
const rodStyle = {
|
||||
fill: "rgb(0, 0, 0, 0.1)", // Default Typst color
|
||||
stroke: columnStyles?.columnPost?.stroke || "none",
|
||||
strokeWidth: columnStyles?.columnPost?.strokeWidth || 0,
|
||||
opacity: columnStyles?.columnPost?.opacity ?? 1
|
||||
stroke: columnStyles?.columnPost?.stroke || globalColumnPosts?.stroke || "none",
|
||||
strokeWidth: columnStyles?.columnPost?.strokeWidth ?? globalColumnPosts?.strokeWidth ?? 0,
|
||||
opacity: columnStyles?.columnPost?.opacity ?? globalColumnPosts?.opacity ?? 1
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -1780,11 +1781,11 @@ export const AbacusReact: React.FC<AbacusConfig> = ({
|
||||
);
|
||||
})}
|
||||
|
||||
{/* Reckoning bar - matching Typst implementation */}
|
||||
{/* Reckoning bar - spans from leftmost to rightmost bead */}
|
||||
<rect
|
||||
x={0}
|
||||
x={dimensions.rodSpacing / 2 - dimensions.beadSize / 2}
|
||||
y={barY}
|
||||
width={dimensions.width}
|
||||
width={(effectiveColumns - 1) * dimensions.rodSpacing + dimensions.beadSize}
|
||||
height={dimensions.barThickness}
|
||||
fill="black" // Typst uses black
|
||||
stroke="none"
|
||||
|
||||
Reference in New Issue
Block a user