Déplacement dans une image style Google Maps.
:salut:
Vous avez tous vu une carte Google : on clique sur la carte pour la déplacer et le déplacement est synchronisé sur une petite vignette.
C'est le script que je vous propose ajourd'hui avec une image.
Le code n'est pas commenté car je compte faire un tuto pour en expliquer les principes et le fonctionnement.
Du coup, n'hésitez pas à me rapporter les bugs que vous pourriez constater :aie:
Il en reste un gros que j'ai du mal à résoudre : sur certains navigateurs, si l'on clique sur la partie cachée de l'image, celle-ci se sélectionne... :furax:
Le code :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| var Clipper = function(tgtImg,opts){
this.image = this.getConteneur(tgtImg);
if(!this.image){
return false;
}
var that = this;
this.haveThumb = opts.haveThumb && this.initThumb(opts.thumbId);
this.speed = opts.speed || 1;
this.currentX = 0;
this.currentY = 0;
this.minX = this.image.parentNode.clientWidth - this.image.width;
this.minY = this.image.parentNode.clientHeight - this.image.height;
this.origX = 0;
this.origY = 0;
this.image.parentNode.onmousedown = function(e1){
var evt = window.event || e1;
that.origX = evt.clientX;
that.origY = evt.clientY;
that.image.onmousemove = function(e2){
var evt2 = window.event || e2;
var dX = (evt2.clientX - that.origX) * that.speed;
var dY = (evt2.clientY - that.origY) * that.speed;
dX += that.currentX;
dY += that.currentY;
dX = Math.min(dX,0);
dX = Math.max(dX,that.minX);
dY = Math.min(dY,0);
dY = Math.max(dY,that.minY);
that.currentX = dX;
that.currentY = dY;
that.origX = evt2.clientX;
that.origY = evt2.clientY;
that.image.style.marginLeft = dX + 'px';
that.image.style.marginTop = dY + 'px';
if(that.haveThumb){
that.cadre.style.left = (Math.abs(dX/that.ratioX)-3)+'px';
that.cadre.style.top = (Math.abs(dY/that.ratioY)-3)+'px';
}
};
};
this.image.onmouseup = function(){
that.image.onmousemove = null;
};
this.image.onmouseout = function(){
that.image.onmousemove = null;
};
this.image.ondragstart = function(){return false;};
};
Clipper.prototype.getConteneur = function(conteneur){
if(conteneur.tagName){
return conteneur;
}
else if(typeof conteneur === 'string'){
return document.getElementById(conteneur);
}
else{
return false;
}
};
Clipper.prototype.initThumb = function(thImg){
this.thumb = this.getConteneur(thImg);
if(!this.thumb.tagName || this.thumb.tagName.toLowerCase()!=='img'){
return false;
}
var that = this;
this.thumb.parentNode.style.position = 'relative';
this.thumb.parentNode.style.width = this.thumb.width + 'px';
this.thumb.parentNode.style.height = this.thumb.height + 'px';
this.ratioX = this.image.width / this.thumb.width;
this.ratioY = this.image.height / this.thumb.height;
this.cadre = document.createElement('div');
this.cadreWidth = this.image.parentNode.clientWidth / this.ratioX;
this.cadreHeight = this.image.parentNode.clientHeight / this.ratioY;
this.refX = this.thumb.parentNode.offsetLeft;
this.refY = this.thumb.parentNode.offsetTop;
this.thumbMinX = this.refX + this.thumb.width - this.cadreWidth;
this.thumbMinY = this.refY + this.thumb.height - this.cadreHeight;
this.cadre.style.cssText = 'background-image:url(transp.gif);position:absolute;top:-3px;left:-3px;width:'+this.cadreWidth+'px;height:'+this.cadreHeight+'px;border:3px solid yellow;cursor:move;';
this.thumb.parentNode.appendChild(this.cadre);
this.cadre.onmousedown = function(){
that.cadre.onmousemove = function(e4){
var evt4 = window.event || e4;
var dX = Math.max(evt4.clientX - that.cadreWidth/2,that.refX);
dX = Math.min(dX,that.thumbMinX);
dX = dX - that.refX;
var dY = Math.max(evt4.clientY - that.cadreHeight/2,that.refY);
dY = Math.min(dY,that.thumbMinY);
dY = dY - that.refY;
that.cadre.style.left = (dX - 3) + 'px';
that.cadre.style.top = (dY - 3) + 'px';
that.currentX = -dX * that.ratioX;
that.currentY = -dY * that.ratioY;
that.image.style.marginLeft = that.currentX + 'px';
that.image.style.marginTop = that.currentY + 'px';
};
};
this.cadre.onmouseup = function(){
that.cadre.onmousemove = null;
};
this.thumb.onmouseout = function(){
that.cadre.onmousemove = null;
};
this.thumb.ondragstart = function(){return false;};
this.cadre.ondragstart = function(){return false;};
return true;
};
window.onload = function(){window.myClip = new Clipper('clip',{speed:5,haveThumb:true,thumbId:'thumbImg'});}; |
En gros, il faut placer les deux images (attention aux proportions) dans des div de taille quelconque, le premier paramètre correspond à l'objet HTML contenant l'image ou à son id, puis en paramètres :
- speed : coefficient de déplacement de l'image.
- haveThumb : y a-t-il une vignette ?
- thumbId : si oui, son id.
Précision, le script se charge de créer le cadre sur la vignette en calculant les proportions de celui-ci.
Voir une démo en ligne : http://dmouronval.developpez.com/clipper/