Provo ad implementare un bel drag and drop su una tela che rappresenta 3 dischi.Nice Trascina su una tela HTML5
Vorrei cambiare con il mouse la posizione di ciascuna massa. Il mio problema principale è che sono limitato dalla lunghezza dell'ascia per ognuna di queste 3 sfere.
Per il momento, ho implementato la seguente funzione quando il mouse si muove all'interno della tela (valore indexMass indica quale massa viene spostata: 1, 2 or 3
e t1, t2, t3
rappresenta rispettivamente 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);
}
}
Come si può vedere , l'ho fatto per ogni angolo:
t = t + 0.1*Math.atan(y/x);
con:
var x = event.offsetX;
var y = event.offsetY;
Ma questo effetto non è molto bello. Una volta che la sfera è stata selezionata con il mouse (con il mouse), vorrei che il cursore fosse bloccato con questa sfera o sfera per seguire "delta
" delle coordinate del mouse quando non sono più sulla sfera.
Per riassumere, non so come creare un trascinamento fine e intuitivo, se qualcuno potesse aiutarmi o darmi dei consigli, sarebbe fantastico.
Grazie
UPDATE 1
@ Blindman67: grazie per il vostro aiuto, il vostro frammento di codice è piuttosto complessa per me, non ho capito tutto. Ma io sono sulla buona strada.
Sto iniziando dal primo problema: fai ruotare il disco selezionato con il mouse rimanendo molto chiuso su di esso o sopra di esso, durante il trascinamento.
Per il momento, ho modificato la mia funzione myMove
(che viene chiamato quando ho cliccato e sposta il mouse per trascinare) come:
// 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');
}
}
dove indexMass
è l'indice del disco trascinato e window['x'+indexMass]
, window['y'+indexMass]
sono le coordinate correnti del centro del disco selezionato.
Dopo, ho calcolato il dx, dy
rispettivamente dalle coordinate del mouse su cui si è fatto clic quando si avvia il trascinamento (mx, my
restituito da getMousePos function
) e le coordinate del mouse con lo spostamento.
Infine, modificare l'angolo di disco fisso, per la variabile globale (theta del disco selezionato), cioè window['t'+indexMass]
:
// Change angle when dragging
window['t'+indexMass] = Math.atan2(dy, dx);
ho preso la tua parte di codice con Math.atan2
.
Ma il risultato di questa funzione non crea una buona animazione con il trascinamento del mouse, vorrei sapere da dove potrebbe venire.
In questo momento, vorrei implementare solo il trascinamento senza modificare la lunghezza dell'asse, vedrò più avanti per questa funzionalità.
UPDATE 2
ho continuare ad andare avanti per trovare una soluzione per il trascinamento di una massa selezionata con il mouse.
per aver tentato una sintesi di quello che ho fatto in precedenza, credo che il seguente metodo è buono, ma questo metodo di trascinamento non sta funzionando molto bene: il disco selezionato non segue correttamente il mouse e non so perché.
In myMove function
(funzione chiamata quando inizio trascinamento), abbiamo deciso di:
- Calcolare il dx, dy fra le coordinate del mouse e le coordinate disco selezionato, cioè:
var dx = parseInt (event.offsetX - window ['x' + indexMass]);
var dy = parseInt (event.offsetY - window ['y' + indexMass]);
indexMass
rappresenta l'indice del disco selezionato.
Incremento posizione del disco selezionato (memorizzato in variabili temporanee
tmpX, tmpY
) dadx, dy
.Calcola il nuovo angolo
theta
(identificata nel codice variabile globalewindow['t'+indexMass]
Calcola le nuove posizioni di disco selezionato con questo nuovo valore di
theta
, cioè ad esempio condisk1
(indexMass=1
e theta =t1
):x1= x0 +l1 * sin(t1) y1= y0 +l1 * sin(t1)
devo fare si nota che voglio trascinando con il mouse non modificare le lunghezze di assi con il mouse, questo è un vincolo.
Ecco l'intero myMove function
(chiamato quando la resistenza sta cominciando):
// 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:
Problema risolto! Ho dimenticato di prendere in considerazione la posizione del disco "indexMass-1" per calcolare il nuovo angolo con la funzione Math.atan2.