Próbuję zaimplementować ładny przeciągnij i upuść na płótnie reprezentującym 3 dyski.Nice Przeciągnij i upuść na płótnie HTML5
Chciałbym zmienić za pomocą myszki pozycję każdej masy. Moim głównym problemem jest to, że jestem ograniczony przez długość topora dla każdej z tych 3 sfer.
W tej chwili mam realizowane następujące funkcje gdy mysz porusza się wewnątrz obszaru roboczego (wartość indexMass wskazuje których masa jest przemieszczana: 1, 2 or 3
i t1, t2, t3
reprezentuje odpowiednio 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);
}
}
Jak widać zrobiłem dla każdego kąta:
t = t + 0.1*Math.atan(y/x);
z:
var x = event.offsetX;
var y = event.offsetY;
Ale ten efekt nie jest zbyt miły. Gdy sfera zostanie wybrana za pomocą myszy (kliknięciem myszki), chciałbym, aby kursor został zablokowany za pomocą tej kuli lub kuli podążając za "delta
" współrzędnych myszy, kiedy nie jestem już na kuli.
Podsumowując, nie wiem, jak stworzyć dobry i przyjazny dla użytkownika przeciągnij i upuść, jeśli ktoś mógłby mi pomóc lub udzielił mi rad, byłoby świetnie.
Dzięki
UPDATE 1
@ Blindman67: Dzięki za pomoc, Twój fragment kodu jest dość skomplikowane dla mnie, to nie wszystko rozumiem. Ale jestem na dobrej drodze.
Rozpoczynam od pierwszego wydania: obróć zaznaczony dysk myszką, pozostając bardzo zamkniętą do niego lub ponad nią, podczas przeciągania.
na chwilę, mam zmodyfikowane mojej funkcji myMove
(która jest wywoływana kiedy kliknięciu w dół i przesunąć kursor myszy do przeciągania), takie jak:
// 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');
}
}
gdzie indexMass
jest indeksem przeciągnięty dysku i window['x'+indexMass]
, window['y'+indexMass]
są bieżącymi współrzędnymi wybranego centrum dysku.
Po tym, obliczam odpowiednio dx, dy
ze współrzędnych myszy klikniętych podczas uruchamiania przeciągania (mx, my
zwrócona przez getMousePos function
) i współrzędnych myszy z ruchem.
Wreszcie zmienić kąt dysku przez zestaw, dla zmiennej globalnej (theta wybranego dysku), tj window['t'+indexMass]
:
// Change angle when dragging
window['t'+indexMass] = Math.atan2(dy, dx);
mam zabrał swoją część kodu z Math.atan2
.
Ale wynik tej funkcji nie zapewnia dobrej animacji z przeciąganiem myszy, chciałbym wiedzieć, skąd to może pochodzić.
W tej chwili chciałbym wdrożyć tylko przeciąganie bez modyfikowania długości osi, zobaczę więcej później dla tej funkcjonalności.
UPDATE 2
Ciągle dzieje się znaleźć rozwiązanie dotyczące przeciągania wybranego masy z myszy.
Do próby syntezy tego, co zrobiłem wcześniej, Wierzę, że następująca metoda jest dobra, ale ta metoda przeciągania nie działa bardzo dobrze: wybrany dysk nie podąża poprawnie myszą i nie wiem czemu.
W myMove function
(funkcja wywoływana, gdy zacznę przeciąganie), postanowiłem:
- obliczyć dx, dy między współrzędnych myszy i wybranych współrzędnych dyskowych, a mianowicie:
var dx = parseInt (event.offsetX - window ['x' + indexMass]);
var dy = parseInt (event.offsetY - window ['y' + indexMass]);
indexMass
reprezentuje indeks wybranego dysku.
Przyrost położenie wybranego dysku (przechowywany w zmiennych tymczasowych
tmpX, tmpY
) przezdx, dy
.Oblicz nowy kąt
theta
(oznaczony w kodzie o zmiennej globalnejwindow['t'+indexMass]
obliczyć nowe położenia wybranej dysku z nowej wartości
theta
, to znaczy na przykład zdisk1
(indexMass=1
i teta =t1
)x1= x0 +l1 * sin(t1) y1= y0 +l1 * sin(t1)
muszę zrobić można zauważyć, że chcę przeciągając myszką, aby nie modyfikować długości osie z myszą, jest to ograniczenie.
Oto cała myMove function
(tzw kiedy zaczyna drag):
// 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');
}
}
UPDATE 4 - Bounty:
Problem rozwiązany! Zapomniałem wziąć pod uwagę pozycję dysku "indexMass-1", aby obliczyć nowy kąt z funkcją Math.atan2.