Fix sprite aspect ratio distortion and bump version to 1.5.2

- 스프라이트 파티클의 종횡비 왜곡 방지를 위한 해상도 보정 로직 추가
- SpriteEffectManager 및 Instance의 update 메서드에 해상도 인자 추가
- NDC 좌표계 기준 OrthographicCamera의 종횡비 보정 구현
- 패키지 버전을 1.5.2로 업데이트
This commit is contained in:
BaekRyang 2026-03-13 15:23:12 +09:00
parent 77f44141a1
commit 15144240b7
4 changed files with 13 additions and 9 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@baekryang/responsive-image-canvas", "name": "@baekryang/responsive-image-canvas",
"version": "1.5.0", "version": "1.5.2",
"publishConfig": { "publishConfig": {
"registry": "https://git.bnovalab.com/api/packages/baekryang/npm/" "registry": "https://git.bnovalab.com/api/packages/baekryang/npm/"
}, },

View File

@ -115,7 +115,7 @@ export const ImageDistortion: React.FC<ImageDistortionProps> = ({
return; return;
} }
console.log('[ImageDistortion] 초기화 시작'); console.log('[ImageDistortion] v1.5.1 초기화 시작');
const scene = new ThreeScene(containerRef.current); const scene = new ThreeScene(containerRef.current);
sceneRef.current = scene; sceneRef.current = scene;
@ -277,13 +277,15 @@ export const ImageDistortion: React.FC<ImageDistortionProps> = ({
// 스프라이트 이펙트 업데이트 (왜곡 영역과 독립적) // 스프라이트 이펙트 업데이트 (왜곡 영역과 독립적)
if (spriteManagerRef.current) { if (spriteManagerRef.current) {
const mouseState = mouseInteractionHook.getMouseState(); const mouseState = mouseInteractionHook.getMouseState();
const resolution = sceneRef.current?.getResolution() ?? { x: 1, y: 1 };
spriteManagerRef.current.update( spriteManagerRef.current.update(
spriteEffectAreas, spriteEffectAreas,
deltaTime, deltaTime,
{ {
position: mouseState.position ?? null, position: mouseState.position ?? null,
isDragging: mouseState.isDragging, isDragging: mouseState.isDragging,
} },
resolution,
); );
// 스프라이트 메쉬 변경 후 렌더링 필요 // 스프라이트 메쉬 변경 후 렌더링 필요

View File

@ -240,7 +240,7 @@ export class SpriteEffectInstance {
*/ */
private _logCounter = 0; private _logCounter = 0;
update(deltaTime: number, emitCenter: Point): void { update(deltaTime: number, emitCenter: Point, resolution?: { x: number; y: number }): void {
if (!this.ready) return; if (!this.ready) return;
// ambient 방출 // ambient 방출
@ -297,7 +297,7 @@ export class SpriteEffectInstance {
particle.position.y += particle.velocity.y * deltaTime; particle.position.y += particle.velocity.y * deltaTime;
// Three.js 메쉬 동기화 // Three.js 메쉬 동기화
this.syncMesh(particle); this.syncMesh(particle, resolution);
} }
} }
@ -328,7 +328,7 @@ export class SpriteEffectInstance {
* Three.js * Three.js
* (0-1) NDC(-1~1) , y축 * (0-1) NDC(-1~1) , y축
*/ */
private syncMesh(particle: SpriteParticle): void { private syncMesh(particle: SpriteParticle, resolution?: { x: number; y: number }): void {
const mesh = this.meshes[particle.index]; const mesh = this.meshes[particle.index];
if (!mesh) return; if (!mesh) return;
@ -344,7 +344,9 @@ export class SpriteEffectInstance {
mesh.position.y = -(particle.position.y * 2 - 1); mesh.position.y = -(particle.position.y * 2 - 1);
mesh.position.z = -0.01; // 카메라가 -z를 바라보므로 음수가 앞쪽 mesh.position.z = -0.01; // 카메라가 -z를 바라보므로 음수가 앞쪽
mesh.scale.set(particle.scale, particle.scale, 1); // 종횡비 보정: OrthographicCamera(-1,1,1,-1) 기준 정사각형 NDC에서 직사각형 뷰포트 왜곡 방지
const aspect = resolution ? resolution.x / resolution.y : 1;
mesh.scale.set(particle.scale / aspect, particle.scale, 1);
mesh.rotation.z = particle.rotation; mesh.rotation.z = particle.rotation;
const mat = mesh.material as THREE.MeshBasicMaterial; const mat = mesh.material as THREE.MeshBasicMaterial;

View File

@ -90,7 +90,7 @@ export class SpriteEffectManager {
* @param deltaTime * @param deltaTime
* @param touchState / * @param touchState /
*/ */
update(effectAreas: SpriteEffectArea[], deltaTime: number, touchState: SpriteEffectTouchState): void { update(effectAreas: SpriteEffectArea[], deltaTime: number, touchState: SpriteEffectTouchState, resolution?: { x: number; y: number }): void {
// 현재 터치 중인 영역 감지 // 현재 터치 중인 영역 감지
const currentTouchingAreas = new Set<string>(); const currentTouchingAreas = new Set<string>();
@ -120,7 +120,7 @@ export class SpriteEffectManager {
} }
// 매 프레임 업데이트 (ambient 방출 + 파티클 물리) // 매 프레임 업데이트 (ambient 방출 + 파티클 물리)
instance.update(deltaTime, area.position); instance.update(deltaTime, area.position, resolution);
} }
} }