JeuWeb - Crée ton jeu par navigateur
Drag & drop par les scrolls plutot que de bouger le DOM? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Drag & drop par les scrolls plutot que de bouger le DOM? (/showthread.php?tid=7454)

Pages : 1 2 3


Drag & drop par les scrolls plutot que de bouger le DOM? - Argorate - 04-09-2015

Bonjour,

j'aimerais savoir si vous avez une idée pour faire comme ici : http://jsfiddle.net/8ub5e21L/ à la différence prêt, que j'aimerais ne pas utiliser le drag&drop de jQuery, mais qu'à la place, le fait de déplacer le <div> déplace les scroll de l'élément parent et non l'élément lui meme.

Un peu comme avec la molette de la souris qui bouge la scroll, moi je veux drag & dropé pour bouger les scroll vertical et horizontal.

Je ne sais pas si je suis clair?^^


RE: Drag & drop par les scrolls plutot que de bouger le DOM? - niahoo - 04-09-2015

Yep, c'est pas trop compliqué.

Au mousedow, tu enregistres la postion x,y de l'évènement. Tu lances un timer qui va appeler une fonction f et se relancer (timer récursif).
Au mouseup, tu cancel le timer.


// je code à l'arrache dans la réponse rapide donc bon ...
var x, y, currentX, currentY,
div = document.getMachinById('qzdqzdqzd'),
timer

function onDown(evt) {
x = evt.clientX, y = evt.clientY,
currentX = currentScrollLeft(div), currentY = currentScrollTop(div)
timer = timerLoop()
}


function onUp(evt) {
clearTimeout(timer)
}

function timerLoop() {
timer = setTimeout(function(){
// ici on check le déplacement
var newX = getMouseX(),
newY = getMouseY(),
var moveX = newX - x,
moveY = newY - y,
x = newX,
y = newY,
currentX += moveX,
currentY += moveY,
setScrollLeft(currentX)
setScrollTop(currentY)
timerLoop()
},1)
}

// alors là chuis pas du tout sur pour la syntaxe, je le fais en mode hideux,
// il faut bien entendu utiliser les event listeners hein !
// PS: c'est quoi ces "strong" moisis qui se rajoutent dessous ?
div.onmousedown = onDown, div.onmouseup = onUp


bon, setTimeout c'est pas forcément le meilleur pour lancer une fonction asynchrone mais bon, y en a d'autres

voilà, pour implémenter currentScrollLeft (et Top) tu as $.scrollLeft sur jQuery qui le fait bien, tu peux copier leur implémentation (et si tu utilises jQuery bah c'est encore plus simple)
pareil pour $.scrollLeft(value) qui est un setter afin d'implémenter setScrollLeft
et pour getMouseX() je ne sais pas mais ça doit être natif et simple.

Sinon bien sur au lieu du timer il faut tester avec onMouseMove qui devrait être plus gourmand mais plus fluide

edit: et je me suis probablement planté dans l'algo (genre soustraction au lieu de addition ou des mauvais remplacements de variables), mais en gros tu as compris le truc: tu calcules de combien de pixels tu as bougé (éventuellement en négatif) et tu ajoutes cette valeur à la valeur du scroll de ton div ; pour les x puis pour les y.


RE: Drag & drop par les scrolls plutot que de bouger le DOM? - Max72 - 04-09-2015

Peut-être HS mais avec HTML5 de mémoire y avait moyen de faire du drag and drop et c'était un peu la merde pour le faire fonctionner sous FF. C'est toujours le cas ?


RE: Drag & drop par les scrolls plutot que de bouger le DOM? - Xenos - 04-09-2015

C'est ce que j'allais dire ^^
Je suis en train de creuser cette direction... parce que les mousedown/up/mouse, sur tactile c'est risqué, et tu risques d'avoir des emmerdes type <a> non cliquables à la souris, textes non sélectionnables à la souris, etc. Si je trouve, je vous dis.



<div style="height:400px;width:400px;overflowConfusedcroll;" draggable="true" id="qzdqzdqzd">
<div style="height:900px; width:40px;">
<a href="http://127.0.0.1/">un lien</a>
</div>
<span style="width:800px;display:inline-block;">Une span</span>
<a href="http://127.0.0.1/">un autre lien</a>
</div>


<script>
var div = document.getElementById('qzdqzdqzd');
div.style.border = '1px solid red';

var startX, startY, scrollX, scrollY;
function startDrag(evt) {
console.log('dragStart', evt);
startX = evt.clientX;
startY = evt.clientY;
scrollX = div.scrollLeft;
scrollY = div.scrollTop;
if (!evt.dataTransfer.getData('text/plain')) { // No drag drop if data already set (user is drag and dropping a DOM item)
evt.dataTransfer.setData('text/x-coords', '<<NoData>>');
evt.dataTransfer.setDragImage(document.createElement('img'), 0, 0);
}
}

function moveDrag(evt) {
evt.preventDefault();
if (evt.dataTransfer.getData('text/x-coords')) {
div.scrollTop = scrollY + evt.clientY - startY;
div.scrollLeft = scrollX + evt.clientX - startX;
return true;
}
return false;
}

var dragOk = false;
function stopDrag(evt) {
console.log('dragStop', evt);
evt.preventDefault();
dragOk = true;
console.log(evt.dataTransfer);
var matches = evt.dataTransfer.getData('text/plain').match(/^(\d+);(\d+)$/); // ie: 50;50
if (matches) {
div.scrollTop = parseInt(matches[0]);
div.scrollLeft = parseInt(matches[1]);
return false;
}
else if (evt.dataTransfer.getData('text/plain+x-coords')) {
moveDrag();
}
return false;
}

function dragEnd(evt) {
if (!dragOk) {
div.scrollLeft = scrollX;
div.scrollTop = scrollY;
}
dragOk = false;
}

div.addEventListener('dragstart', startDrag);
div.addEventListener('dragover', moveDrag);
div.addEventListener('drop', stopDrag);
div.addEventListener('dragend', dragEnd);
</script>

Faudrait voir pour la sélection de texte, mais tu peux encore cliquer les liens ou les drag & dropper. Tu peux même drag & drop des coordonnées dans la div, genre XX;YY Smile


RE: Drag & drop par les scrolls plutot que de bouger le DOM? - Max72 - 05-09-2015

Citation :parce que les mousedown/up/mouse, sur tactile c'est risqué, et tu risques d'avoir des emmerdes type <a> non cliquables à la souris, textes non sélectionnables à la souris, etc. Si je trouve, je vous dis.
Je suis déjà tombé sur des sites qui mettaient des événements sur le mousemove ou qui jouaient avec le scroll etc, et c'est pas génial quand on est sur tactile (menus au mousehover qui disparaissent sans arrêt, login box qui fuit la vue active, ..).

Il existe les Touch Events en JS pur pour gérer le tactile, et ça a l'air d'être supporté par tous les navigateurs mobiles. A voir si tu en as l'utilité (et le courage Smile ).
Ou alors si tu utilises jQuery, il y a un plugin qui unifie les événements de la souris et du tactile (pas testé ) : https://github.com/dotmaster/Touchable-jQuery-Plugin


RE: Drag & drop par les scrolls plutot que de bouger le DOM? - Argorate - 08-09-2015

Pour le coup je me fiche du tactile, il s'agit de mon interface admin en l’occurrence.
Je regarde ça dans la semaine, je fini la V6 de DVO^^


RE: Drag & drop par les scrolls plutot que de bouger le DOM? - Argorate - 09-09-2015

solution fonctionnelle sous FF only : http://jsfiddle.net/8ub5e21L/7/


RE: Drag & drop par les scrolls plutot que de bouger le DOM? - niahoo - 09-09-2015

HMm le feeling est pas terrible, je préfère le feeling comme sur google maps (c'est à dire que tu inverse les directions de scroll pas rapport à celle de la souris)

Code :
div.scrollTop = divScrollY = scrollY - (evt.clientY - startY);
div.scrollLeft = divScrollX = scrollX - (evt.clientX - startX);

Par contre t'as un genre de threshold avant le déclenchement c'est pas terrible.


RE: Drag & drop par les scrolls plutot que de bouger le DOM? - Xenos - 09-09-2015

Je suis d'accord sur l'inversion des axes (de sorte que la souris reste au-dessus du pixel de départ en gros).


RE: Drag & drop par les scrolls plutot que de bouger le DOM? - Max72 - 09-09-2015

niahoo a écrit :HMm le feeling est pas terrible, je préfère le feeling comme sur google maps (c'est à dire que tu inverse les directions de scroll pas rapport à celle de la souris)
+1. Lorsque tu cliques et glisses d'un point, c'est en général pour le centrer, là c'est difficile.

Sinon ça fonctionne aussi sous Chrome sur mon téléphone (version mobile) Smile

Edit : Grilled !