그려지는 내용을 추적하기 위해 그리기 응용 프로그램, CAD 시스템(Computer-Aided Design System) 및 게임과 같은 많은 응용 프로그램은 현재 표시된 개체 목록을 유지 관리합니다. 일반적으로 이러한 응용 프로그램을 통해 사용자는 현재 화면에 표시된 개체를 조작할 수 있습니다. 예를 들어 CAD 애플리케이션에서는 디자인 요소를 선택, 이동, 확대/축소하는 등의 작업을 수행할 수 있습니다.
-"HTML5 캔버스 핵심 기술"
Canvas에서 实现拖拽
마찬가지입니다. Canvas는 点(x, y)
경로에 있는지 확인하는 isPointInPath(x, y)
라는 API를 제공합니다. 경로 내에 있으면 true를 반환합니다. 따라서 우리는 다음과 같은 아이디어를 가질 수 있습니다.
각 경로를 설명할 수 있는 数组
유지하고 ispointInPath(x, y)
사용하여 클릭한 위치가 특정 경로에 있는지 확인합니다. 이 경로에 있으면 이 경로를 선택하고 작업(이동, 확대/축소 등)을 수행합니다. 을 누른 다음 그래픽을 그립니다.
이 기사에서는 多边形拖拽为例进行说明
사용합니다. 데모는 다음과 같습니다(각인 뒤에 있는 이유는 화면 녹화 소프트웨어 japanese_ogre:입니다).
코드펜이 열립니다
데모에서 다각형을 그리는 방법은 이전에 요약되었으므로 다시 자세히 설명하지 않겠습니다. ghost:: Canvas 다각형 그리기
아이디어 설명아래 그림은 대략적인 설명과 의사 코드를 제공합니다. 아이디어는 어렵지 않지만 처리해야 할 몇 가지 세부 사항이 있습니다.
코드 구조는 여기에 나열되어 있으며 해당 아이디어는 CodePen에 표시되어 있습니다.
이번 글은 드래그에 중점을 두고 있기 때문에 드로잉 부분에 대한 설명은 생략하겠습니다.
//다각형 경로 그리기 함수 function drawPolygonPath//다각형 클래스 정의 class Polygon{ ...}//클릭 이벤트에 따라 캔버스의 위치를 반환합니다. function positoinInCanvas//두 점 사이의 직선 거리 가져오기 function getDistance// 시작 단계에서 드래그 개체 드래그 canvas.onmousedown//드래그 단계, 그리기 경로, 스트로크 canvas.onmousemove//끝 단계, 드래그 개체 위치 업데이트 canvas.onmouseup을 기록합니다.주요 부분 설명
다음으로 코드의 주요 부분과 세부 사항 처리를 시작합니다.
드래그 객체의 배열을 유지하는 방법프로그램 초기화 중에 우리는 PolygonArray 배열을 정의합니다.
다각형 배열 = []
새 다각형이 그려질 때마다 유지 관리를 위해 새 다각형 개체가 배열로 푸시됩니다.
const 다각형 = new Polygon(mouseStart.get('x'), mouseStart.get('y'), sideNum, radius);polygonArray.push(polygon);//경로 객체 기록
이후의 클릭 동작에서는 해당 정보를 바탕으로 클릭 위치가 경로에 있는지 판단해야 한다.
클릭 시 드래그할 개체를 선택하는 방법 먼저, 클릭하면 canvas中
해당 위치를 가져옵니다. 내 코드는 mouseStart
사용하여 x
와 y
그런 다음 polygonArray
의 polygon
순회하고 순회 중에 polygon.createPath()
호출하고 isPointInPath()
사용하여 클릭한 위치에 경로가 있는지 확인합니다. 그렇다면 draggingPolygon = polygon
이 함수를 종료합니다.
const pos = positionInCanvas(e, canvasLeft, canvasTop);//캔버스의 픽셀 위치 가져오기//마우스 시작점 기록 smouseStart.set('x', pos.x);mouseStart.set('y', pos. y);...for(polygonArray의 다각형 허용) {polygon.createPath(); (ctx.isPointInPath(mouseStart.get('x'), mouseStart.get('y'))) { draggingPolygon = 다각형 } }드래그 시 계산
이 부분을 충분히 이해하셔야 합니다. 현재는 mousemove
단계이고 이 단계에서 함수가 매우 자주 실행되기 때문에 두 개의 console.log(draggingPolygon)
와 데모의 코드를 기반으로 디버깅하는 것이 좋습니다.
말로는 확실히 표현하려고 노력해요
먼저 move
때 mouseStart
로부터의 거리를 계산합니다. 이는 diff로 기록됩니다. x축에는 offsetX
있고 y축에는 offsetY
있습니다.
const pos = positionInCanvas(e, canvasLeft, canvasTop), diff = new Map([ ['offsetX', pos.x - mouseStart.get('x')], ['offsetY', pos.y - mouseStart.get( 'y')] ]);
그런 다음 현재 드래그 개체의 centerX
및 centerY
기록하고 temp로 기록합니다.
tempCenterX = draggingPolygon.centerX, tempCenterY = draggingPolygon.centerY를 허용합니다.
이것이 이해하기 어려운 점이다. 왜 기록해야 하는가? 계속 읽으십시오. 나중에 사용하게 될 것입니다.
diff
의 오프셋에 따라 draggingPolygon의 새로운 중심 위치를 설정합니다.
draggingPolygon.centerX += diff.get('offsetX'); draggingPolygon.centerY += diff.get('offsetY');
그런 다음 캔버스를 지우고 새 경로와 선을 그립니다.
ctx.clearRect(0, 0, canvas.width, canvas.height);for(polygonArray의 다각형 설정) { drawPolygonPath(polygon.sideNum,polygon.radius,polygon.centerX,polygon.centerY,ctx); );}
마지막으로 위에서 언급한 tempCenterX
및 tempCenterY
사용됩니다.
draggingPolygon.centerX = tempCenterX; draggingPolygon.centerY = tempCenterY;
왜 우리는 이것을 해야 합니까?
우리의 드래그는 基于多边形的原位置
하고 mousemove
단계는 不能确定函数的最终位置
때문에 이때 복구가 없으면 漂移
발생하고 이 두 줄의 코드는 주석 처리됩니다. 효과는 다음과 같습니다.
명확하게 밝히지 않았다면 모든 사람이 코드를 수정하고 디버그할 것을 권장합니다.
드래그 후 처리 드래그가 완료되면 mouseup
단계가 되는데 이때 dragginPolygon의 최종 위치를 결정하고 업데이트할 수 있게 됩니다. 마지막으로 在没有拖拽多边形情况下,鼠标在画布上移动触发对应代码
제외하기 위해 null로 설정합니다. 在没有拖拽多边形情况下,鼠标在画布上移动触发对应代码
const pos = positionInCanvas(e, canvasLeft, canvasTop), offsetMap = new Map([ ['offsetX', pos.x - mouseStart.get('x')], ['offsetY', pos.y - mouseStart.get( 'y')] ]); draggingPolygon.centerX += offsetMap.get('offsetX'); draggingPolygon.centerY += offsetMap.get('offsetY'); draggingPolygon = null;결론
실제로 이 기능을 구현하는 것은 어렵지 않습니다. 개념을 이해하는 것이 중요합니다. 추적은 현재 표시된 개체 목록을 유지하고 isPointInPath로 판단하여 수행됩니다.
마지막으로, 모두가 교류하고 배울 수 있도록 환영합니다
참고자료"HTML5 캔버스 핵심 기술"
위 내용은 이 기사의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다. 또한 모든 분들이 VeVb Wulin Network를 지지해 주시길 바랍니다.