캔버스를 마우스 커서로 확대
스크롤 휠을 사용하여 이미지를 확대 및 축소하는 HTML5 <canvas> 프로젝트를 프로그래밍하고 있습니다. 나는 구글지도처럼 커서를 향해 확대하고 싶지만 움직임을 계산하는 방법을 완전히 잊어 버렸습니다.
내가 가진 것 : 이미지 x 및 y (왼쪽 상단 모서리); 이미지 너비와 높이; 캔버스의 중심을 기준으로 커서 x 및 y.
간단히 말해, translate()
오프셋으로 캔버스 컨텍스트 scale()
를 확대하거나 축소 한 다음 translate()
마우스 오프셋의 반대 방향으로 되돌아 가기 를 원합니다 . 커서 위치를 화면 공간에서 변환 된 캔버스 컨텍스트로 변환해야합니다.
ctx.translate(pt.x,pt.y);
ctx.scale(factor,factor);
ctx.translate(-pt.x,-pt.y);
데모 : http://phrogz.net/tmp/canvas_zoom_to_cursor.html
나는 올려 한 전체 작업 예를 들어 당신이 아래 인 / 아웃에 Shift 키를 누른 채 클릭하거나 스크롤 휠까지 확대하려면 클릭 지원 드래그, 검사에 대한 내 웹 사이트에.
유일한 (현재) 문제는 Safari가 Chrome 또는 Firefox에 비해 너무 빠르게 확대 된다는 것 입니다.
이 JS 라이브러리가 도움이되기를 바랍니다. (HTML5, JS)
- 루페
http://www.netzgesta.de/loupe/
- CanvasZoom
https://github.com/akademy/CanvasZoom
- 스크롤러
https://github.com/zynga/scroller
저는 루페를 사용하고 있습니다. 그것은 굉장! 당신을 위해 최고의 경우-스크롤러.
최근에 Phrogz가 이미 수행 한 것과 동일한 결과를 보관해야했지만를 사용하는 대신 context.scale()
비율에 따라 각 개체 크기를 계산했습니다.
이것이 제가 생각 해낸 것입니다. 그 뒤에있는 논리는 매우 간단합니다. 배율을 조정하기 전에 가장자리에서 포인트 거리를 백분율로 계산하고 나중에 올바른 위치에 뷰포트를 조정합니다.
그것을 생각해내는 데 꽤 오랜 시간이 걸렸습니다. 누군가의 시간을 절약하기를 바랍니다.
$(function () {
var canvas = $('canvas.main').get(0)
var canvasContext = canvas.getContext('2d')
var ratio = 1
var vpx = 0
var vpy = 0
var vpw = window.innerWidth
var vph = window.innerHeight
var orig_width = 4000
var orig_height = 4000
var width = 4000
var height = 4000
$(window).on('resize', function () {
$(canvas).prop({
width: window.innerWidth,
height: window.innerHeight,
})
}).trigger('resize')
$(canvas).on('wheel', function (ev) {
ev.preventDefault() // for stackoverflow
var step
if (ev.originalEvent.wheelDelta) {
step = (ev.originalEvent.wheelDelta > 0) ? 0.05 : -0.05
}
if (ev.originalEvent.deltaY) {
step = (ev.originalEvent.deltaY > 0) ? 0.05 : -0.05
}
if (!step) return false // yea..
var new_ratio = ratio + step
var min_ratio = Math.max(vpw / orig_width, vph / orig_height)
var max_ratio = 3.0
if (new_ratio < min_ratio) {
new_ratio = min_ratio
}
if (new_ratio > max_ratio) {
new_ratio = max_ratio
}
// zoom center point
var targetX = ev.originalEvent.clientX || (vpw / 2)
var targetY = ev.originalEvent.clientY || (vph / 2)
// percentages from side
var pX = ((vpx * -1) + targetX) * 100 / width
var pY = ((vpy * -1) + targetY) * 100 / height
// update ratio and dimentsions
ratio = new_ratio
width = orig_width * new_ratio
height = orig_height * new_ratio
// translate view back to center point
var x = ((width * pX / 100) - targetX)
var y = ((height * pY / 100) - targetY)
// don't let viewport go over edges
if (x < 0) {
x = 0
}
if (x + vpw > width) {
x = width - vpw
}
if (y < 0) {
y = 0
}
if (y + vph > height) {
y = height - vph
}
vpx = x * -1
vpy = y * -1
})
var is_down, is_drag, last_drag
$(canvas).on('mousedown', function (ev) {
is_down = true
is_drag = false
last_drag = { x: ev.clientX, y: ev.clientY }
})
$(canvas).on('mousemove', function (ev) {
is_drag = true
if (is_down) {
var x = vpx - (last_drag.x - ev.clientX)
var y = vpy - (last_drag.y - ev.clientY)
if (x <= 0 && vpw < x + width) {
vpx = x
}
if (y <= 0 && vph < y + height) {
vpy = y
}
last_drag = { x: ev.clientX, y: ev.clientY }
}
})
$(canvas).on('mouseup', function (ev) {
is_down = false
last_drag = null
var was_click = !is_drag
is_drag = false
if (was_click) {
}
})
$(canvas).css({ position: 'absolute', top: 0, left: 0 }).appendTo(document.body)
function animate () {
window.requestAnimationFrame(animate)
canvasContext.clearRect(0, 0, canvas.width, canvas.height)
canvasContext.lineWidth = 1
canvasContext.strokeStyle = '#ccc'
var step = 100 * ratio
for (var x = vpx; x < width + vpx; x += step) {
canvasContext.beginPath()
canvasContext.moveTo(x, vpy)
canvasContext.lineTo(x, vpy + height)
canvasContext.stroke()
}
for (var y = vpy; y < height + vpy; y += step) {
canvasContext.beginPath()
canvasContext.moveTo(vpx, y)
canvasContext.lineTo(vpx + width, y)
canvasContext.stroke()
}
canvasContext.strokeRect(vpx, vpy, width, height)
canvasContext.beginPath()
canvasContext.moveTo(vpx, vpy)
canvasContext.lineTo(vpx + width, vpy + height)
canvasContext.stroke()
canvasContext.beginPath()
canvasContext.moveTo(vpx + width, vpy)
canvasContext.lineTo(vpx, vpy + height)
canvasContext.stroke()
canvasContext.restore()
}
animate()
})
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<canvas class="main"></canvas>
</body>
</html>
@Phrogz의 대답을 기본으로하여 드래그, 확대 / 축소 및 회전으로 캔버스를 사용할 수있는 작은 라이브러리를 만들었습니다. 다음은 그 예입니다.
var canvas = document.getElementById('canvas')
//assuming that @param draw is a function where you do your main drawing.
var control = new CanvasManipulation(canvas, draw)
control.init()
control.layout()
//now you can drag, zoom and rotate in canvas
프로젝트 페이지 에서 더 자세한 예제와 문서를 찾을 수 있습니다 .
참고 URL : https://stackoverflow.com/questions/5189968/zoom-canvas-to-mouse-cursor
'UFO ET IT' 카테고리의 다른 글
PHP에서 파일의 마지막 줄을 읽는 가장 좋은 방법은 무엇입니까? (0) | 2020.11.15 |
---|---|
PHP 재귀 함수를 사용하여 디렉토리의 모든 파일 및 폴더 나열 (0) | 2020.11.15 |
사용자 정의 Sublime Text 2 스 니펫의 범위 정의 (0) | 2020.11.15 |
Flutter에서 위젯에 테두리를 어떻게 추가하나요? (0) | 2020.11.15 |
JavaScript에서 숫자를 반올림하려면 어떻게합니까? (0) | 2020.11.15 |