Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be323bfbc5 | ||
|
|
50fc3fdf7f | ||
|
|
e52d907087 | ||
|
|
c0fa926d16 |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -1,3 +1,17 @@
|
||||
## [4.63.2](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.63.1...v4.63.2) (2025-10-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **flashcards:** correct pivot point to rotate around card center ([50fc3fd](https://github.com/antialias/soroban-abacus-flashcards/commit/50fc3fdf7f2c9b7412f6d7d890f5e0d52cb86a9b))
|
||||
|
||||
## [4.63.1](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.63.0...v4.63.1) (2025-10-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **flashcards:** increase rotation sensitivity 10x for visible grab point physics ([c0fa926](https://github.com/antialias/soroban-abacus-flashcards/commit/c0fa926d16d02c1bfe880b7f0056a760e8461b3b))
|
||||
|
||||
## [4.63.0](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.62.1...v4.63.0) (2025-10-21)
|
||||
|
||||
|
||||
|
||||
@@ -191,18 +191,60 @@ function DraggableCard({ card }: DraggableCardProps) {
|
||||
// If grabbed on left and dragged right → clockwise rotation
|
||||
// If grabbed on right and dragged left → counter-clockwise rotation
|
||||
const crossProduct = grabOffsetRef.current.x * deltaY - grabOffsetRef.current.y * deltaX
|
||||
const rotationInfluence = crossProduct / 5000 // Scale factor for reasonable rotation (adjust as needed)
|
||||
const rotationInfluence = crossProduct / 500 // Reduced scale factor for more visible rotation
|
||||
const newRotation = baseRotationRef.current + rotationInfluence
|
||||
|
||||
// Clamp rotation to prevent excessive spinning
|
||||
const clampedRotation = Math.max(-45, Math.min(45, newRotation))
|
||||
setRotation(clampedRotation)
|
||||
|
||||
// Update card position
|
||||
setPosition({
|
||||
x: dragStartRef.current.cardX + deltaX,
|
||||
y: dragStartRef.current.cardY + deltaY,
|
||||
})
|
||||
// Log rotation changes occasionally (same throttle as shadow logging)
|
||||
const timeSinceLastLog = now - lastLogTimeRef.current
|
||||
if (timeSinceLastLog > 200) {
|
||||
console.log(
|
||||
`[GrabPoint] Rotation: ${clampedRotation.toFixed(1)}° (influence: ${rotationInfluence.toFixed(1)}°, cross: ${crossProduct.toFixed(0)})`
|
||||
)
|
||||
}
|
||||
|
||||
// Update card position - keep the grab point "stuck" to the cursor
|
||||
// As the card rotates, the grab point rotates with it, so we need to account for rotation
|
||||
const rotationRad = (clampedRotation * Math.PI) / 180
|
||||
const cosRot = Math.cos(rotationRad)
|
||||
const sinRot = Math.sin(rotationRad)
|
||||
|
||||
// Rotate the grab offset by the current rotation angle
|
||||
const rotatedGrabX = grabOffsetRef.current.x * cosRot - grabOffsetRef.current.y * sinRot
|
||||
const rotatedGrabY = grabOffsetRef.current.x * sinRot + grabOffsetRef.current.y * cosRot
|
||||
|
||||
// Current cursor position
|
||||
const cursorX = e.clientX
|
||||
const cursorY = e.clientY
|
||||
|
||||
// Card center should be at: cursor position - rotated grab offset
|
||||
// But we need to position the card element (top-left), not the center
|
||||
// Get card dimensions to calculate offset from center to top-left
|
||||
if (cardRef.current) {
|
||||
const rect = cardRef.current.getBoundingClientRect()
|
||||
const cardWidth = rect.width
|
||||
const cardHeight = rect.height
|
||||
|
||||
// Card center position in screen space
|
||||
const cardCenterX = cursorX - rotatedGrabX
|
||||
const cardCenterY = cursorY - rotatedGrabY
|
||||
|
||||
// Convert center position to top-left position (what we store in position state)
|
||||
// Note: position.x/y is used in translate(), which positions the element
|
||||
setPosition({
|
||||
x: cardCenterX - cardWidth / 2,
|
||||
y: cardCenterY - cardHeight / 2,
|
||||
})
|
||||
} else {
|
||||
// Fallback to simple delta if we don't have card dimensions yet
|
||||
setPosition({
|
||||
x: dragStartRef.current.cardX + deltaX,
|
||||
y: dragStartRef.current.cardY + deltaY,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handlePointerUp = (e: React.PointerEvent) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "soroban-monorepo",
|
||||
"version": "4.63.0",
|
||||
"version": "4.63.2",
|
||||
"private": true,
|
||||
"description": "Beautiful Soroban Flashcard Generator - Monorepo",
|
||||
"workspaces": [
|
||||
|
||||
Reference in New Issue
Block a user