Tôi cố gắng triển khai kéo và thả đẹp trên canvas đại diện cho 3 đĩa.Kéo và thả đẹp trên canvas HTML5
Tôi muốn thay đổi bằng chuột với vị trí của từng khối. Vấn đề chính của tôi là tôi bị ràng buộc bởi chiều dài của rìu cho mỗi 3 quả cầu.
Đối với thời điểm này, tôi đã thực hiện các chức năng sau khi chuột được di chuyển bên trong vải (giá trị của indexMass chỉ đó khối lượng được chuyển: 1, 2 or 3
và t1, t2, t3
đại diện tương ứng the angle of mass 1, 2, 3
):
// Happens when the mouse is moving inside the canvas
function myMove(event) {
if (isDrag) {
var x = event.offsetX;
var y = event.offsetY;
if (indexMass == 1)
{ // Update theta1 value
t1 = t1 + 0.1*Math.atan(y/x);
}
else if (indexMass == 2)
{ // Update theta2 value
t2 = t2 + 0.1*Math.atan(y/x);
}
else if (indexMass == 3)
{ // Update theta3 value
t3 = t3 + 0.1*Math.atan(y/x);
}
// Update drawing
DrawPend(canvas);
}
}
Như bạn có thể nhìn thấy , tôi đã làm cho mỗi góc:
t = t + 0.1*Math.atan(y/x);
với:
var x = event.offsetX;
var y = event.offsetY;
Nhưng hiệu ứng này không phải là rất tốt đẹp. Khi quả cầu được chọn bằng chuột (khi nhấp chuột), tôi muốn con trỏ bị mắc kẹt với quả cầu này hoặc hình cầu theo sau "delta
" của tọa độ chuột khi tôi không ở trên quả cầu nữa.
Để tóm tắt, tôi không biết cách tạo và kéo thả thân thiện và dễ sử dụng, nếu ai đó có thể giúp tôi hoặc cho tôi một số lời khuyên, điều này thật tuyệt.
Cảm ơn
UPDATE 1
@ Blindman67: nhờ sự giúp đỡ của bạn, đoạn mã của bạn là khá phức tạp đối với tôi, tôi không hiểu tất cả. Nhưng tôi đang đi đúng hướng.
Tôi bắt đầu bằng vấn đề đầu tiên: làm cho xoay đĩa đã chọn bằng chuột ở rất gần với nó hoặc trên nó, khi kéo.
Đối với thời điểm này, tôi đã sửa đổi chức năng của tôi myMove
(được gọi là khi tôi đã nhấp xuống và di chuyển chuột để kéo) như:
// Happens when the mouse is moving inside the canvas
function myMove(event) {
// If dragging
if (isDrag) {
// Compute dx and dy before calling DrawPend
var lastX = parseInt(event.offsetX - mx);
var lastY = parseInt(event.offsetY - my);
var dx = lastX - window['x'+indexMass];
var dy = lastY - window['y'+indexMass];
// Change angle when dragging
window['t'+indexMass] = Math.atan2(dy, dx);
// Update drawing
DrawPend(canvas);
// Highlight dragging disk
fillDisk(indexMass, 'pink');
}
}
nơi indexMass
là chỉ số của đĩa kéo và window['x'+indexMass]
, window['y'+indexMass]
là tọa độ hiện tại của trung tâm đĩa đã chọn.
Sau đó, tôi tính toán tương ứng dx, dy
từ tọa độ được nhấp chuột khi bắt đầu kéo (mx, my
được trả lại bởi getMousePos function
) và tọa độ chuột khi di chuyển.
Cuối cùng, tôi thay đổi góc của đĩa bằng cách thiết lập, cho biến toàn cục (theta của đĩa được chọn), tức là window['t'+indexMass]
:
// Change angle when dragging
window['t'+indexMass] = Math.atan2(dy, dx);
Tôi đã mất một phần của mã với Math.atan2
.
Nhưng kết quả của chức năng này không tạo ra hoạt ảnh tốt bằng tính năng kéo chuột, tôi muốn biết vị trí này có thể đến từ đâu.
Ngay bây giờ, tôi chỉ muốn thực hiện thao tác kéo mà không sửa đổi độ dài của trục, tôi sẽ xem thêm sau này cho chức năng này.
UPDATE 2
Tôi tiếp tục xảy ra để tìm một giải pháp về việc kéo một khối lượng được lựa chọn với chuột.
Để thử tổng hợp những gì tôi đã làm trước đây, tôi tin rằng phương pháp sau là tốt nhưng phương pháp kéo này không hoạt động tốt: đĩa đã chọn không theo đúng con chuột và tôi không biết tại sao.
Trong myMove function
(hàm được gọi khi tôi bắt đầu kéo), tôi quyết định:
- Tính dx, dy giữa các tọa độ chuột và tọa độ đĩa được lựa chọn, ví dụ:
var dx = parseInt (event.offsetX - window ['x' + indexMass]);
var dy = parseInt (event.offsetY - window ['y' + indexMass]);
indexMass
đại diện cho chỉ mục của đĩa đã chọn.
Tăng vị trí của đĩa đã chọn (được lưu trong các biến tạm thời
tmpX, tmpY
) bởidx, dy
.Tính góc mới
theta
(được xác định trong mã của biến toàn cầuwindow['t'+indexMass]
Tính các vị trí mới của đĩa được lựa chọn với giá trị mới này của
theta
, tức là ví dụ vớidisk1
(indexMass=1
và theta =t1
):x1= x0 +l1 * sin(t1) y1= y0 +l1 * sin(t1)
tôi phải làm cho bạn nhận thấy rằng tôi muốn kéo với chuột không điều chỉnh độ dài của trục với chuột, đây là một ràng buộc.
Dưới đây là toàn bộ myMove function
(gọi khi kéo được bắt đầu):
// Happens when the mouse is moving inside the canvas
function myMove(event) {
// If dragging
if (isDrag) {
console.log('offsetX', event.offsetX);
console.log('offsetY', event.offsetY);
var dx = parseInt(event.offsetX - window['x'+indexMass]);
var dy = parseInt(event.offsetY - window['y'+indexMass]);
console.log('dx', dx);
console.log('dy', dy);
// Temp variables
var tmpX = window['x'+indexMass];
var tmpY = window['y'+indexMass];
// Increment temp positions
tmpX += dx;
tmpY += dy;
// Compute new angle for indexMass
window['t'+indexMass] = Math.atan2(tmpX, tmpY);
console.log('printf', window['t'+indexMass]);
// Compute new positions of disks
dragComputePositions();
// Update drawing
DrawPend(canvas);
// Highlight dragging disk
fillDisk(indexMass, 'pink');
}
}
CẬP NHẬT 4 - Bounty:
Vấn đề giải quyết! Tôi quên tính đến vị trí của đĩa "indexMass-1" để tính toán góc mới với hàm Math.atan2.