IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Mise en page CSS Discussion :

Garder même position absolute d'un div après transformation rotate et scale


Sujet :

Positionnement en CSS

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 56
    Points : 53
    Points
    53
    Par défaut Garder même position absolute d'un div après transformation rotate et scale
    Bonjour à tous,

    Après moultes recherches, je n'arrive pas à trouver de solution simple à mon problème. Je génère des pages html contenant des DIV rectangulaires dont la position est absolute sur ma page. Je dois effectuer ensuite des transformations différentes sur chaque div : rotation et scale, mais j'aimerais que mes div gardent la même position absolute qu'avant transformation.
    En jouant sur le centre de rotation avec transform-origin je n'arrive pas à obtenir ce que je souhaite car les rotations n'ont jamais la même valeur (90, 180, 270 deg).

    Voici un exemple de div :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <div id='divTest' style='display:block;position:absolute;border: solid 1 px;left: 97px;top: 858px;transform: scale(0.5) rotate(270deg);transform-origin: 50% 50%;-ms-transform: scale(0.5) rotate(270deg);-ms-transform-origin: 50% 50%;-webkit-transform: scale(0.5) rotate(270deg);-webkit-transform-origin: 50% 50%;'></div>

    Voici ce que j'aimerais faire :
    Le div initial en rouge est le div ci-dessus. Le div en bleu est ce que j'obtiens et le div vert est ce que j'aimerais obtenir.

    Nom : rotate_pb.png
Affichages : 2459
Taille : 9,3 Ko

    Auriez vous une solution à mon problème ?

    Merci beaucoup d'avance

  2. #2
    Membre averti
    Profil pro
    Chef Gérant
    Inscrit en
    Octobre 2005
    Messages
    230
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Chef Gérant
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2005
    Messages : 230
    Points : 399
    Points
    399
    Par défaut
    as tu essayer, logiquement, transform-origin:top left; ou transform-origin: 0 0 ; ?

    Sinon,par exemple : top right + positionement relatif avec decalage : http://codepen.io/anon/pen/qcADf

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 56
    Points : 53
    Points
    53
    Par défaut
    Merci pour ta réponse. Le problème avec transform-origin top left (équivalent à 0 0) c'est que le centre de rotation se retrouve en haut à gauche donc ma div ne se retrouve pas du tout à la même distance left et top qu'initialement.

    Le positonnement relatif avec décalage semble ne pas marcher, car par exemple si je fais une rotation de 90deg, il faut faire margin-left:[height de la div]px et si je fais une rotation de 270deg par exemple, c'est margin-top:[width de la div] qu'il faut faire ...

    Je suis ouvert aux solutions en javascript

  4. #4
    Membre averti
    Profil pro
    Chef Gérant
    Inscrit en
    Octobre 2005
    Messages
    230
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Chef Gérant
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2005
    Messages : 230
    Points : 399
    Points
    399
    Par défaut
    Il ya la solution de donner une class a chaque degrés de rotation utilisé , de façon a maitriser totalement coordonnées d'origine et eventuellement le repositionement visuel en relatif, plutôt que d'inserer les degres de rotation dans le code.

    Maintenant, si il y a 360 class a sortir, pas sur que ce soit la solution

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 56
    Points : 53
    Points
    53
    Par défaut
    Il n'y a que 4 rotations (3 en fait) : 0(360) 90 180 270 degrés
    par contre chaque div a une position différente ... Comment faire ?

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 56
    Points : 53
    Points
    53
    Par défaut
    une solution avec transform origin = top left (0;0)

    si rotate(0deg) :
    margin-left:0px
    margin-top:0px

    si rotate(90deg) :
    margin-left: 0px
    margin-top: [Width]px

    si rotate(180deg) :
    margin-left: [Width]px
    margin-top: [Height]px

    si rotate(270deg) :
    margin-left: [Height]px
    margin-top: 0px

    On peut généraliser avec un peu de trigonométrie :
    0 <= deg <= 90° :
    margin-left: 0px
    margin-top: sin(deg)x[width]px

    90 <= deg <= 180° :
    margin-left: -cos(deg)x[width]px
    margin-top: -cos(deg)x[height]+sin(deg)x[width]px

    180 <= deg <= 270° :
    margin-left: -cos(deg)x[width]-sin(deg)x[height]px
    margin-top: -cos(deg)x[height]px

    270 <= deg <= 360° :
    margin-left: -sin(deg)x[height]px
    margin-top: 0px

    schéma : Nom : rotations.png
Affichages : 2345
Taille : 57,6 Ko

    formule générique (fonctionne entre 0 et 360°) :
    margin-left: Max(-cos(deg)x[width];0) - Max(sin(deg)x[height];0) px
    margin-top: Max(-cos(deg)x[height];0) + Max(sin(deg)x[width];0) px

    Il n'existe rien de plus simple ?
    Je pense que je vais utiliser du javascript pour repositionner mes div après transformation, cependant j'ai cru comprendre que selon les navigateurs, les comportements ne sont jamais les mêmes ...

  7. #7
    Membre averti
    Profil pro
    Chef Gérant
    Inscrit en
    Octobre 2005
    Messages
    230
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Chef Gérant
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2005
    Messages : 230
    Points : 399
    Points
    399
    Par défaut
    j'opterais plutot pour un déplacement visuel en relatif, les éléments gardent leur place d'origine dans le flow du document sans le perturber ou modifier(idem avec transform).
    Les marges ont un effet sur l'espace occupé, réservé pour l'affichage des balises, tant qu'il sont dans le flux..

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 56
    Points : 53
    Points
    53
    Par défaut
    un transform: translate(x,y) ?

    Est-il possible du coup en CSS de translater un div d'une valeur égale à sa largeur ou à sa hauteur ?

  9. #9
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Bonjour,
    toujours bon à lire
    Les transformations en CSS3

    Un petit exemple de manipulation
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    <!DOCTYPE html>
    <html lang="fr">
    <head>
    <meta charset="UTF-8">
    <title>[...]</title>
    <meta name="Author" content="NoSmoking">
    <style>
    html, body{
      height:100%;
    }
    .effet{
      position:absolute;
      width:200px;
      height:200px;
      -moz-box-sizing: border-box;
      box-sizing: border-box;
     
      -webkit-transform: scale(0.5) rotate(0deg);
         -moz-transform: scale(0.5) rotate(0deg);
          -ms-transform: scale(0.5) rotate(0deg);
           -o-transform: scale(0.5) rotate(0deg);
              transform: scale(0.5) rotate(0deg);
     
      -webkit-transition: all 1.5s ease-in-out;
         -moz-transition: all 1.5s ease-in-out;
          -ms-transition: all 1.5s ease-in-out;
           -o-transition: all 1.5s ease-in-out;
              transition: all 1.5s ease-in-out;
    }
    .effet:hover{
      -webkit-transform: scale(1) rotate(45deg) translate(0px, -50%);
         -moz-transform: scale(1) rotate(45deg) translate(0px, -50%);
          -ms-transform: scale(1) rotate(45deg) translate(0px, -50%);
           -o-transform: scale(1) rotate(45deg) translate(0px, -50%);
              transform: scale(1) rotate(45deg) translate(0px, -50%);
    }
    #pos_1{
      left:500px;
      top:100px;
      border: 2px solid green;
      background:#EFE;
     
      -webkit-transform-origin: 0% 0%;
         -moz-transform-origin: 0% 0%;
          -ms-transform-origin: 0% 0%;
           -o-transform-origin: 0% 0%;
              transform-origin: 0% 0%;
    }
    #traitv{
      position:absolute;
      left:500px;
      top:0;
      height:100%;
      width:1px;
      border-left:1px dashed black;
    }
    #traith{
      position:absolute;
      left:0;
      width:100%;
      top:100px;
      height:1px;
      border-top:1px dashed black;
    }
    </style>
    </head>
    <body>
    <div id='pos_1' class="effet">DIV #1</div>
    <div id='traitv'></div><div id='traith'></div>
    </body>
    </html>
    n'hésite pas à modifier certaines valeur pour voir le résultat obtenu

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 56
    Points : 53
    Points
    53
    Par défaut
    Pour les 4 cas suivants, ça fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    rotate(0deg) translate(0px,0px)
    rotate(90deg) translate(0px,-100%)
    rotate(180deg) translate(-100%,-100%)
    rotate(270deg) translate(-100%,0px)

  11. #11
    Membre averti
    Profil pro
    Chef Gérant
    Inscrit en
    Octobre 2005
    Messages
    230
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Chef Gérant
    Secteur : Santé

    Informations forums :
    Inscription : Octobre 2005
    Messages : 230
    Points : 399
    Points
    399
    Par défaut
    mais oui, tiens , translate à le même effet que le décalage visuel en relatif, mais plus court a écrire et surtout, la correction n'a lieu que si transform: est compris par le navigateur. bien vu !

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 56
    Points : 53
    Points
    53
    Par défaut
    oui ! mais ça ne marche que pour les cas où le translate ne dépend que de la hauteur ou que de la largeur (cad que l'on puisse convertir en %) donc que pour les rotations de 90 180 270 et 360°
    J'ai fini par résoudre mon problème avec du javascript.

    Pour résumer, 2 solutions :

    1ère solution, en CSS uniquement, la plus simple, mais ne fonctionne que dans les 4 cas suivants : rotations de 90 180 270 360° :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    rotate(0deg) translate(0px,0px)
    rotate(90deg) translate(0px,-100%)
    rotate(180deg) translate(-100%,-100%)
    rotate(270deg) translate(-100%,0px)
    2ème solution, en javascript, fonctionne pour tous les angles possibles :
    à éxécuter après chargement de la page :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    var DivRot = new Array()
    DivRot = document.getElementsByTagName('DIV')
    for(i=0;i<DivRot.length;i++){
    	//on ne traite que les divs qui ont une style 'transform' :
    	if(DivRot[i].style['-webkit-transform'] || DivRot[i].style['-moz-transform'] || DivRot[i].style['-ms-transform'] || DivRot[i].style['-o-transform'] || DivRot[i].style['transform']){
    		var rotation=DivRot[i].style['-webkit-transform'] || DivRot[i].style['-moz-transform'] || DivRot[i].style['-ms-transform'] || DivRot[i].style['-o-transform'] || DivRot[i].style['transform'];
    		// extraction de l angle dans la chaine du type 'rotation(270deg)'
    		rotation=parseFloat(rotation.substring(rotation.indexOf('rotate(')+7,rotation.indexOf('deg')));
    		// pour passer du sens anti trigo utilisé par le webkit-transform au sens trigo utilisé dans mes formules en-dessous avec un petit modulo 2PI au passage :
    		rotation=360-(rotation%360);
    		//conversion degrés en radians :
    		rotationgrad=rotation * Math.PI/180;			
    		if(rotation>=0 && rotation<=90){
    			var leftRot = 0;
    			var topRot = Math.sin(rotationgrad)*DivRot[i].offsetWidth;
    		}else if(rotation>90 && rotation<=180){
    			var leftRot = -Math.cos(rotationgrad)*DivRot[i].offsetWidth;
    			var topRot = -Math.cos(rotationgrad)*DivRot[i].offsetHeight+Math.sin(rotationgrad)*DivRot[i].offsetWidth;
    		}else if(rotation>180 && rotation<=270){
    			var leftRot = -Math.cos(rotationgrad)*DivRot[i].offsetWidth-Math.sin(rotationgrad)*DivRot[i].offsetHeight;
    			var topRot = -Math.cos(rotationgrad)*DivRot[i].offsetHeight;
    		}else if(rotation>270 && rotation<=360){
    			var leftRot = -Math.sin(rotationgrad)*DivRot[i].offsetHeight;
    			var topRot = 0;
    		}else{
    			console.log('Erreur : angle inconnu ' + rotation);
    			var leftRot = 0;
    			var topRot = 0;
    		}
    		console.log('Déplacement de ' + DivRot[i].id + ' (rotation de ' + rotation + ' degrés) de (' + leftRot.toFixed(2) + 'px, ' + topRot.toFixed(2) + 'px)');
    		DivRot[i].style.left=parseInt(DivRot[i].offsetLeft+leftRot).toFixed(2) + 'px';
    		DivRot[i].style.top=parseInt(DivRot[i].offsetTop+topRot).toFixed(2) + 'px';
    	}
    }

  13. #13
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    en CSS uniquement, la plus simple, mais ne fonctionne que dans les 4 cas suivants : rotations de 90 180 270 360° :
    si tu connais les angles avant qu'est ce qui t'empêche de calculer les pourcentages ?

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 56
    Points : 53
    Points
    53
    Par défaut
    La translation en Y dépend de l'angle mais aussi de Width et de Height

    donc juste en CSS ça ne me paraît pas jouable

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Position d'un div après une rotation
    Par icl1c dans le forum jQuery
    Réponses: 3
    Dernier message: 23/03/2011, 23h47
  2. position absolute d''un div, bug IE6
    Par ginkgomedia dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 24/03/2009, 19h14
  3. position:absolute dans un div
    Par MayOL69bg dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 28/03/2007, 16h10
  4. Div : position: absolute, relative ou static ?
    Par philippef dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 16/01/2007, 12h59
  5. [CSS] Redimensionnement de div en position absolute
    Par Fluckysan dans le forum Mise en page CSS
    Réponses: 9
    Dernier message: 25/09/2006, 13h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo