From 5d976734062eb3d943bfdfdd125473c56b533759 Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Mon, 3 Nov 2025 15:21:41 -0600 Subject: [PATCH] fix: remove wobble physics and enhance wood grain visibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Changes:** - Removed wobble physics feature (was janky and distracting) - Increased wood grain opacity from 0.15 → 0.4 (realistic) and 0.45 (delightful) - Enhanced wood grain pattern with bolder strokes and more visible knots - Removed getWobbleRotation utility function - Simplified Abacus3DPhysics interface to only hoverParallax - Updated all stories to remove wobble references - Removed velocity tracking code from Bead component Wood grain is now much more visible on frame elements without affecting bead spacing or layout. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- apps/web/.claude/settings.local.json | 7 ++- .../app/api/create/calendar/generate/route.ts | 2 +- apps/web/src/components/MyAbacus.tsx | 7 ++- packages/abacus-react/src/Abacus3D.css | 29 ++--------- packages/abacus-react/src/Abacus3DUtils.ts | 34 ++++--------- .../src/AbacusReact.3d-effects.stories.tsx | 50 ++----------------- packages/abacus-react/src/AbacusReact.tsx | 21 +------- 7 files changed, 29 insertions(+), 121 deletions(-) diff --git a/apps/web/.claude/settings.local.json b/apps/web/.claude/settings.local.json index de4d811c..88fe87d7 100644 --- a/apps/web/.claude/settings.local.json +++ b/apps/web/.claude/settings.local.json @@ -161,11 +161,14 @@ "Bash(printenv:*)", "Bash(typst:*)", "Bash(npx tsx:*)", - "Bash(sort:*)" + "Bash(sort:*)", + "Bash(scp:*)" ], "deny": [], "ask": [] }, "enableAllProjectMcpServers": true, - "enabledMcpjsonServers": ["sqlite"] + "enabledMcpjsonServers": [ + "sqlite" + ] } diff --git a/apps/web/src/app/api/create/calendar/generate/route.ts b/apps/web/src/app/api/create/calendar/generate/route.ts index 8ab23330..e123a349 100644 --- a/apps/web/src/app/api/create/calendar/generate/route.ts +++ b/apps/web/src/app/api/create/calendar/generate/route.ts @@ -1,4 +1,4 @@ -import { NextRequest, NextResponse } from 'next/server' +import { type NextRequest, NextResponse } from 'next/server' import { writeFileSync, readFileSync, mkdirSync, rmSync } from 'fs' import { tmpdir } from 'os' import { join } from 'path' diff --git a/apps/web/src/components/MyAbacus.tsx b/apps/web/src/components/MyAbacus.tsx index 9ad26d6a..edd8e3ac 100644 --- a/apps/web/src/components/MyAbacus.tsx +++ b/apps/web/src/components/MyAbacus.tsx @@ -6,7 +6,6 @@ import { AbacusReact, useAbacusConfig } from '@soroban/abacus-react' import { css } from '../../styled-system/css' import { useMyAbacus } from '@/contexts/MyAbacusContext' import { HomeHeroContext } from '@/contexts/HomeHeroContext' -import { Z_INDEX } from '@/constants/zIndex' export function MyAbacus() { const { isOpen, close, toggle } = useMyAbacus() @@ -99,7 +98,7 @@ export function MyAbacus() { inset: 0, bg: 'rgba(0, 0, 0, 0.8)', backdropFilter: 'blur(12px)', - zIndex: Z_INDEX.MY_ABACUS_BACKDROP, + zIndex: 101, animation: 'backdropFadeIn 0.4s ease-out', })} onClick={close} @@ -129,7 +128,7 @@ export function MyAbacus() { fontWeight: 'bold', cursor: 'pointer', transition: 'all 0.2s', - zIndex: Z_INDEX.MY_ABACUS + 1, + zIndex: 103, animation: 'fadeIn 0.3s ease-out 0.2s both', _hover: { bg: 'rgba(255, 255, 255, 0.2)', @@ -149,7 +148,7 @@ export function MyAbacus() { onClick={isOpen || isHeroMode ? undefined : toggle} className={css({ position: isHeroMode ? 'absolute' : 'fixed', - zIndex: Z_INDEX.MY_ABACUS, + zIndex: 102, cursor: isOpen || isHeroMode ? 'default' : 'pointer', transition: 'all 0.6s cubic-bezier(0.4, 0, 0.2, 1)', // Three modes: hero (absolute - scrolls with document), button (fixed), open (fixed) diff --git a/packages/abacus-react/src/Abacus3D.css b/packages/abacus-react/src/Abacus3D.css index 71f352ea..547c76fa 100644 --- a/packages/abacus-react/src/Abacus3D.css +++ b/packages/abacus-react/src/Abacus3D.css @@ -103,7 +103,7 @@ /* Wood grain texture overlay */ .abacus-3d-container.enhanced-realistic .frame-wood { - opacity: 0.15; + opacity: 0.4; mix-blend-mode: multiply; pointer-events: none; } @@ -293,11 +293,6 @@ z-index: -1; } -/* Wobble physics - applied via inline styles from React Spring */ -.bead-wobble { - /* transform-origin set dynamically */ - transform-style: preserve-3d; -} /* Frame depth enhancement */ .abacus-3d-container.enhanced-delightful rect[class*="column-post"], @@ -307,25 +302,11 @@ drop-shadow(0 0 2px rgba(0, 0, 0, 0.1)); } -/* Wood grain texture - enhanced */ -.frame-wood-enhanced { - background-image: - repeating-linear-gradient( - 90deg, - transparent, - transparent 2px, - rgba(139, 90, 43, 0.03) 2px, - rgba(139, 90, 43, 0.03) 4px - ), - repeating-linear-gradient( - 0deg, - transparent, - transparent 1px, - rgba(101, 67, 33, 0.02) 1px, - rgba(101, 67, 33, 0.02) 2px - ); - opacity: 0.2; +/* Wood grain texture - enhanced for delightful mode */ +.abacus-3d-container.enhanced-delightful .frame-wood { + opacity: 0.45; mix-blend-mode: multiply; + pointer-events: none; } /* Accessibility - Reduced motion */ diff --git a/packages/abacus-react/src/Abacus3DUtils.ts b/packages/abacus-react/src/Abacus3DUtils.ts index ce163501..467dc20d 100644 --- a/packages/abacus-react/src/Abacus3DUtils.ts +++ b/packages/abacus-react/src/Abacus3DUtils.ts @@ -143,19 +143,6 @@ export function getBeadZDepth( } } -/** - * Generate wobble rotation based on velocity (for delightful mode) - */ -export function getWobbleRotation(velocity: number, axis: "x" | "y" = "x"): string { - const maxRotation = 3; // degrees - const rotation = Math.max(-maxRotation, Math.min(maxRotation, velocity * -2)); - - if (axis === "x") { - return `rotateX(${rotation}deg)`; - } - return `rotateY(${rotation}deg)`; -} - /** * Calculate parallax offset based on mouse position */ @@ -197,16 +184,17 @@ export function calculateParallaxOffset( export function getWoodGrainPattern(id: string): string { return ` - - - - - - - - - - + + + + + + + + + + + `; } diff --git a/packages/abacus-react/src/AbacusReact.3d-effects.stories.tsx b/packages/abacus-react/src/AbacusReact.3d-effects.stories.tsx index f7c34838..15b29d37 100644 --- a/packages/abacus-react/src/AbacusReact.3d-effects.stories.tsx +++ b/packages/abacus-react/src/AbacusReact.3d-effects.stories.tsx @@ -30,7 +30,6 @@ Three levels of progressive 3D enhancement for the abacus to make interactions f ## Proposal 3: Delightful (Physics + Micro-interactions) - Everything from Proposal 2 + - Enhanced physics with satisfying bounce -- Wobble rotation during movement - Hover parallax with Z-depth lift - Maximum satisfaction ` @@ -99,7 +98,7 @@ export const CompareAllLevels: Story = {
-

Proposal 3: Delightful (Glossy + Wobble + Parallax)

+

Proposal 3: Delightful (Glossy + Parallax)

@@ -386,44 +384,13 @@ export const Delightful_FullExperience: Story = { woodGrain: true }, physics3d: { - wobble: true, hoverParallax: true } }, parameters: { docs: { description: { - story: '🎉 **Full delightful experience!** Click beads to see wobble physics. Hover your mouse over the abacus to see parallax lift. Sound enabled for maximum satisfaction!' - } - } - } -}; - -export const Delightful_WobblePhysics: Story = { - name: '3️⃣ Delightful - Wobble Physics', - args: { - value: 5555, - columns: 4, - showNumbers: true, - interactive: true, - animated: true, - colorScheme: 'heaven-earth', - scaleFactor: 1.3, - enhanced3d: 'delightful', - material3d: { - heavenBeads: 'glossy', - earthBeads: 'glossy', - lighting: 'top-down' - }, - physics3d: { - wobble: true, // Enable wobble rotation - hoverParallax: false - } - }, - parameters: { - docs: { - description: { - story: '**Wobble physics enabled!** Click beads rapidly to see them wobble and rotate during movement. Enhanced spring physics with bounce!' + story: '🎉 **Full delightful experience!** Click beads to see enhanced physics. Hover your mouse over the abacus to see parallax lift. Sound enabled for maximum satisfaction!' } } } @@ -446,7 +413,6 @@ export const Delightful_HoverParallax: Story = { lighting: 'ambient' }, physics3d: { - wobble: false, hoverParallax: true // Enable hover parallax } }, @@ -477,7 +443,6 @@ export const Delightful_Traditional: Story = { woodGrain: true }, physics3d: { - wobble: true, hoverParallax: true } }, @@ -501,7 +466,6 @@ export const Playground: Story = { const [material, setMaterial] = React.useState<'glossy' | 'satin' | 'matte'>('glossy'); const [lighting, setLighting] = React.useState<'top-down' | 'ambient' | 'dramatic'>('dramatic'); const [woodGrain, setWoodGrain] = React.useState(true); - const [wobble, setWobble] = React.useState(true); const [parallax, setParallax] = React.useState(true); return ( @@ -549,17 +513,10 @@ export const Playground: Story = {
-
- -
-
@@ -581,7 +538,6 @@ export const Playground: Story = { woodGrain: woodGrain }} physics3d={{ - wobble: wobble, hoverParallax: parallax }} /> diff --git a/packages/abacus-react/src/AbacusReact.tsx b/packages/abacus-react/src/AbacusReact.tsx index 11d29bc4..d4464f91 100644 --- a/packages/abacus-react/src/AbacusReact.tsx +++ b/packages/abacus-react/src/AbacusReact.tsx @@ -254,11 +254,7 @@ export interface Abacus3DMaterial { } export interface Abacus3DPhysics { - wobble?: boolean; // Beads rotate slightly during movement - clackEffect?: boolean; // Visual ripple when beads snap - hoverParallax?: boolean; // Beads lift on hover - particleSnap?: "off" | "subtle" | "sparkle"; // Particle effects on snap - hapticFeedback?: boolean; // Trigger haptic feedback on mobile + hoverParallax?: boolean; // Beads lift on hover (delightful mode only) } export interface AbacusConfig { @@ -1306,10 +1302,6 @@ const Bead: React.FC = ({ config: physicsConfig })); - // Track velocity for wobble effect (delightful mode only) - const velocityRef = useRef(0); - const lastYRef = useRef(y); - // Calculate parallax offset for hover effect const parallaxOffset = React.useMemo(() => { if (enhanced3d === 'delightful' && physics3d?.hoverParallax && mousePosition && containerBounds) { @@ -1402,11 +1394,6 @@ const Bead: React.FC = ({ React.useEffect(() => { if (enableAnimation) { - // Calculate velocity for wobble effect - const deltaY = y - lastYRef.current; - velocityRef.current = deltaY; - lastYRef.current = y; - api.start({ x, y, config: physicsConfig }); } else { api.set({ x, y }); @@ -1508,7 +1495,6 @@ const Bead: React.FC = ({ }; // Build style object based on animation mode - const wobbleEnabled = enhanced3d === 'delightful' && physics3d?.wobble; const parallaxEnabled = enhanced3d === 'delightful' && physics3d?.hoverParallax; const beadStyle: any = enableAnimation ? { @@ -1523,11 +1509,6 @@ const Bead: React.FC = ({ transforms.push(`translateZ(${parallaxOffset.z}px)`); } - // Add wobble rotation - if (wobbleEnabled && velocityRef.current !== 0) { - transforms.push(Abacus3DUtils.getWobbleRotation(velocityRef.current, 'x')); - } - return transforms.join(' '); }, ),