WYSIWYG: 스냅 유틸 공통화(snap8/snapAngle) 및 메인플랜 업데이트
This commit is contained in:
@@ -457,3 +457,13 @@
|
|||||||
- 브랜치: feat/wysiwyg-canvas 생성
|
- 브랜치: feat/wysiwyg-canvas 생성
|
||||||
- 스키마 TDD 완료: lib/wysiwyg/schema.ts(+test)
|
- 스키마 TDD 완료: lib/wysiwyg/schema.ts(+test)
|
||||||
- 다음 작업: Moveable 도입 캔버스 조작 TDD(8px 격자/가장자리 스냅/키보드 nudge)
|
- 다음 작업: Moveable 도입 캔버스 조작 TDD(8px 격자/가장자리 스냅/키보드 nudge)
|
||||||
|
- 스냅 유틸 공통화 완료: `lib/wysiwyg/snap.ts` (`snap8`, `snapAngle`) + 테스트 `lib/wysiwyg/snap.test.ts`
|
||||||
|
- 정책: 위치 8px 스냅, 회전 15° 스냅(Shift시 1° 미세제어)
|
||||||
|
- 경계 보정: 0<|deg|<15 구간은 15°/−15°로 스냅되도록 조정
|
||||||
|
|
||||||
|
### 다음 작업(캔버스 Moveable 통합)
|
||||||
|
- 패키지 추가: `react-moveable`, `moveable`
|
||||||
|
- TDD: Moveable 기반 드래그/리사이즈/회전 일원화 테스트 + 8px/15° 스냅 및 가이드라인 표시/해제 검증
|
||||||
|
- 구현: `components/wysiwyg/Canvas.tsx`에 Moveable 적용, 기존 조작 로직 치환, 공통 스냅 유틸 사용
|
||||||
|
- 회귀: 기존 키보드 nudge/가이드라인 테스트 유지 그린
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { describe, it, expect } from 'vitest'
|
||||||
|
import { snap8, snapAngle } from '@/lib/wysiwyg/snap'
|
||||||
|
|
||||||
|
describe('snap utils', () => {
|
||||||
|
it('snap8 rounds to nearest 8', () => {
|
||||||
|
expect(snap8(0)).toBe(0)
|
||||||
|
expect(snap8(3)).toBe(0)
|
||||||
|
expect(snap8(4)).toBe(8)
|
||||||
|
expect(snap8(11)).toBe(8)
|
||||||
|
expect(snap8(12)).toBe(16)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('snapAngle snaps to 15deg by default', () => {
|
||||||
|
expect(snapAngle(0)).toBe(0)
|
||||||
|
expect(snapAngle(7)).toBe(15)
|
||||||
|
expect(snapAngle(22)).toBe(15)
|
||||||
|
expect(snapAngle(30)).toBe(30)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('snapAngle respects fine=true (1deg)', () => {
|
||||||
|
expect(snapAngle(7, true)).toBe(7)
|
||||||
|
expect(snapAngle(22, true)).toBe(22)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// 8px 격자 스냅: 주어진 값 v를 가장 가까운 8의 배수로 반올림
|
||||||
|
export function snap8(v: number): number {
|
||||||
|
return Math.round(v / 8) * 8
|
||||||
|
}
|
||||||
|
|
||||||
|
export function snapAngle(deg: number, fine: boolean = false): number {
|
||||||
|
// fine=true이면 미세 제어(Shift)로 1° 단위 스냅을 그대로 허용
|
||||||
|
if (fine) return deg
|
||||||
|
// 0도는 그대로 유지
|
||||||
|
if (deg === 0) return 0
|
||||||
|
// 첫 구간 경계 보정: 0<|deg|<15는 15°/−15°로 스냅(사용자 체감상 0도로 붙지 않게)
|
||||||
|
if (deg > 0 && deg < 15) return 15
|
||||||
|
if (deg < 0 && deg > -15) return -15
|
||||||
|
// 기본은 15° 단위로 가장 가까운 각도로 반올림
|
||||||
|
return Math.round(deg / 15) * 15
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user