드래그 위치를 모델 상태로 계산하는 D2, UIST 2026 최우수 논문상 선정
D2는 도달 가능한 모델 상태를 미리 렌더링해 드롭 위치를 계산하고, 포인터 움직임에 맞춘 미리보기와 드롭 후 상태를 만듭니다. 요소 생성·삭제처럼 모델 상태만으로 위치를 정하기 어려운 동작에는 명시적 드롭 대상이나 새 상태에서 요소를 따라가는 연산자를 조합합니다. UIST 2026 최우수 논문상 수상작 여섯 편 가운데 하나로 선정됐으며, 연구에서는 목록 상태를 구성하는 학습 부담도 드러났습니다.

Joshua Horowitz·Andrew Blinn·Jeffrey Heer의 선언형 드래그(D2) 논문이 UIST 2026 최우수 논문상 수상작 여섯 편 가운데 하나로 선정됐습니다. D2는 놓을 위치를 화면 좌표로 일일이 지정하는 대신, 드래그로 갈 수 있는 모델 상태를 화면에 미리 그려 후보 위치와 동작을 구성합니다. 연구진은 이 방식을 TypeScript로 구현한 React·SVG 웹 라이브러리 Dragology도 공개했습니다.
포인터 이벤트를 직접 처리하면 좌표 계산과 임시 상태, 화면 전환을 여러 코드에 걸쳐 관리해야 합니다. 논문은 드래그 소스와 드롭 대상만 지정하는 방식은 간편하지만 동작이 정형화되기 쉽다고 설명합니다. D2는 화면 좌표 계산의 상당 부분을 애플리케이션의 모델과 렌더링 규칙으로 옮깁니다.
개발자는 모델 상태를 SVG로 나타내는 React 노드를 반환하는 순수 함수 Draggable을 작성해 DraggableRenderer에 전달합니다. Draggable은 React 컴포넌트가 아니어서 훅을 쓰거나 내부에 다른 React 컴포넌트를 넣을 수 없습니다. 렌더러는 화면 트리에서 dragologyOnDrag 속성을 찾아 포인터 입력을 연결합니다. 드래그가 시작되면 요소의 콜백이 DragSpec을 반환하고, 엔진은 이를 실행 가능한 DragBehavior로 컴파일합니다. 포인터가 움직일 때마다 동작은 화면에 보일 미리보기와 놓을 때 적용할 dropState를 계산하며, 포인터를 놓으면 해당 상태로 전환합니다.
목록 재정렬처럼 목적지가 몇 가지로 나뉘는 동작은 도달 가능한 모델 상태를 열거합니다. 논문의 타일 예제에서 B를 끌면 [B, A, C], [A, B, C], [A, C, B]가 후보가 됩니다. Dragology는 각 배열을 화면에 그려 B가 놓일 위치를 찾습니다. closest는 포인터와 가까운 후보를 선택하고, 놓으면 해당 배열로 전환합니다. 각 요소를 끌었을 때 도달할 다음 상태를 만드는 규칙은 개발자가 정해야 합니다.
논문의 시간표 시나리오는 이산적인 선택과 연속 값 조정을 나눠 보여줍니다. 회의 막대를 다른 방으로 옮기는 동작은 방 번호별 상태를 열거합니다. closest만 쓰면 막대가 현재 트랙에 머물다 포인터가 트랙 사이의 중간을 넘을 때 다른 방으로 붙습니다. closest에 withFloating을 더하면 막대가 좌우로도 움직입니다. 방 배정만 바꾸려는 동작에는 between을 사용해 후보 위치 사이의 세로 트랙을 따라 미리보기가 움직이게 합니다.
회의 시작 시각처럼 가능한 값이 연속적인 숫자는 하나씩 상태로 나열하기 어렵습니다. 이때 vary 연산자로 수치를 조정하고 허용 범위를 지정합니다. 논문의 예제는 시작 시각이 0보다 크고 종료 시각보다 최소 회의 길이만큼 앞서도록 제한합니다. Dragology는 후보 수치가 만드는 화면에서 끝점 위치를 구하고 포인터와의 거리를 줄이는 방향으로 값을 갱신합니다. 논문 구현은 이 계산에 COBYLA 최적화를 사용하며, 일반적인 드래그에서는 한두 개 수치를 다룬다고 설명합니다.
연산자를 조합하면 구조화된 배치와 자유 이동을 함께 만들 수 있습니다. 논문의 중첩 목록 화면에서는 타일을 목록 안에 정렬하고, 타일을 끌어내 캔버스에 새 목록을 만들며, 최상위 목록은 캔버스에서 자유롭게 움직입니다. 연구진은 목록에 붙는 스냅 동작과 자유 위치를 조정하는 vary를 whenFar로 결합합니다. 포인터가 스냅 대상에서 일정 거리 이상 멀어지면 목록에 붙는 동작에서 자유 이동으로 전환합니다. Dragology의 연산자는 동작을 만드는 함수이므로 개발자가 직접 구현할 수도 있습니다.
타일링 예제에서 도형을 휴지통에 끌어 삭제하면 결과 모델 상태에는 드래그 요소가 남지 않습니다. 화면에서 해당 요소의 새 위치를 추출할 수 없어, dropTarget으로 휴지통의 DOM id를 지정해 드롭 대상을 정합니다. 도구 모음에서 새 도형을 끌 때는 드래그 시작 시점에 대상이 아직 모델에 없습니다. switchToStateAndFollow로 새 도형을 포함한 상태로 먼저 전환한 뒤 그 도형을 따라갑니다. 생성과 삭제를 포함하는 동작도 다른 연산자와 조합할 수 있습니다.
Dragology는 SVG 뷰를 보간해 화면 전환을 매끄럽게 만듭니다. 두 화면의 요소 종류와 트리 구조가 같으면 숫자·색·변환·경로 속성을 보간합니다. 요소가 다른 부모로 이동하는 등 구조가 달라질 때는 DOM id로 화면 사이의 대응 요소를 찾습니다. between은 포인터 위치에 따라 후보 행동 사이의 미리보기를 보간합니다.
연구진은 드래그앤드롭 경험이 있는 개발자 13명을 대상으로 여섯 예제를 안내하는 실습 중심 인터뷰를 진행했습니다. 참여자들은 코드가 간결하고 좌표 계산 부담을 덜어주는 점을 장점으로 꼽았습니다. 반면 재정렬 목록에서는 도달 가능한 상태 집합을 구성하는 일이 학습 장벽으로 나타났습니다. 일부 참여자는 한 요소가 도달할 국소적인 다음 상태 대신 가능한 모든 순열을 열거하려 했습니다. 연구진은 참여자 모집이 HCI와 프로그래밍 언어 분야에 관심 있는 개발자 쪽으로 기울었고 안내된 단일 세션만 진행했으므로, 독립적 학습이나 실제 도입에 관한 근거는 제한적이라고 밝혔습니다.
Dragology 공개 저장소는 MIT 라이선스와 npm 설치 방법을 안내합니다. README는 정식 문서가 아직 준비되지 않았다고 밝히며 예제 프로젝트와 데모를 소개합니다.