35 votes

Comment faire pour que le conteneur grandisse et prenne de la place

J'ai donc un conteneur que je tiens à l'échelle en haut et en bas (zoom in et out), mais aussi d'avoir son agrandi ou rétréci forme à prendre de la place plutôt que de simplement se chevauchent d'autres choses.

Mise à jour

Il y a une image avec laquelle il y a absolute divs qui sont placés dans les coordonnées, ils doivent garder leur position relative lors de la taille en haut et en bas (c'est pourquoi je suis à l'aide de l'échelle).

var b = document.getElementById("outer");
var scale = 1;

function increase() {
  scale += 0.1
  b.style.transform = `scale(${scale})`;
}

function decrease() {
  scale -= 0.1
  b.style.transform = `scale(${scale})`;
}
#outer {
  overflow-x: auto position: relative;
  transform-origin: left top;
}

.pointer {
  width: 20px;
  height: 20px;
  background-color: orange;
  position: absolute;
}

#a1 {
  top: 50px;
  left: 150px;
}

#a2 {
  top: 150px;
  left: 50px;
}

#a3 {
  top: 250px;
  left: 550px;
}
<div>
  <button onclick="increase()">Increase</button>
  <button onclick="decrease()">Decrease</button>
</div>
<div id=outer>
  <img src="http://via.placeholder.com/600x350" />
  <div id="a1" class='pointer'>
  </div>
  <div id="a2" class='pointer'>
  </div>
  <div id="a3" class='pointer'>
  </div>
</div>
<div>
  please don't cover me
</div>

Serait plutôt de ne pas avoir de bibliothèques tierces (à côté de jQuery) mais vous pouvez envisager.

21voto

kukkuz Points 24428

CSS3 scale transitions fonctionnent comme que. Malheureusement, mise à l'échelle permettrait de se superposent à d'autres éléments comme il prend le contenu du récipient hors de la circulation par la création d'un nouveau contexte d'empilement (essentiellement en y mettant tout son contenu placé par rapport au conteneur) - voir doc description:

Si la propriété a une valeur différente de none, un empilement contexte sera créé.

Source: MDN

Voir une démo ci-dessous mise à l'échelle de tous les éléments par force brute:

var b, scale = 1, offset, pointers;

window.onload = function() {
  b = document.getElementById("outer");
  offset = b.getBoundingClientRect();
  pointers = Array.prototype.map.call(b.querySelectorAll('.pointer'), function(e) {
    return {
      el: e,
      offset: e.getBoundingClientRect()
    }
  });
}

function increase() {
  scale += 0.1;
  scaleIt();
}

function decrease() {
  scale -= 0.1;
  scaleIt();
}

function scaleIt() {
  b.style.width = scale * offset.width + 'px';
  b.style.height = scale * offset.height + 'px';
  Array.prototype.forEach.call(pointers, function(e) {
    e.el.style.width = scale * e.offset.width + 'px';
    e.el.style.height = scale * e.offset.height + 'px';
    e.el.style.top = scale * e.offset.top + 'px';
    e.el.style.left = scale * e.offset.left + 'px';
  });
}
#outer {
  /*overflow-x: auto;*/
  position: relative;
  transform-origin: left top;
}
.pointer {
  width: 20px;
  height: 20px;
  background-color: orange;
  position: absolute;
}
#outer > img {
  height: 100%;
}

#a1 {
  top: 50px;
  left: 150px;
}
#a2 {
  top: 150px;
  left: 50px;
}
#a3 {
  top: 250px;
  left: 550px;
}
<div>
    <button onclick="increase()">Increase</button>
    <button onclick="decrease()">Decrease</button>
</div>
<div id=outer>
  <img src="http://via.placeholder.com/600x350" />
  <div id="a1" class='pointer'>
  </div>
  <div id="a2" class='pointer'>
  </div>
  <div id="a3" class='pointer'>
  </div>
</div>
<div>
    please don't cover me
</div>

6voto

Awsme Sandy Points 1189

Je l'ai essayé avec la largeur et la hauteur, je pense que ce sera fonctionne de la même manière que vous le souhaitez, ajouter une petite animation et vous pouvez l'utiliser.

var b = document.getElementById("outer");
var b_width = document.getElementById("outer").offsetWidth;
var b_height = document.getElementById("outer").offsetHeight;

function increase()
{
    b_width += 10
    b_height += 10
    b.style.width = b_width+"px";
    b.style.height = b_height+"px";
}

function decrease()
{
    b_width -= 10
    b_height -= 10
    b.style.width = b_width+"px";
    b.style.height = b_height+"px";
}
#outer {
  background-color: red;
  padding: 1em;
  height: 80px;
  width: 80px;
  transform-origin: left top;
}

#inner {
  background-color: yellow;
  height: 50px;
  width: 100%;
}
<div>
    <button onclick="increase()">Increase</button>
    <button onclick="decrease()">Decrease</button>
</div>
<div id=outer>
  <div id=inner>
  </div>
</div>
<div>
    please don't cover me
</div>

5voto

sahbeewah Points 2639

Edit: désolé, il se précipita, je voulais mettre à jour le conteneur

Vous pouvez, ajouter un conteneur. Magasin de la taille initiale de ce conteneur. Maintenant, quand la mise à l'échelle à l'intérieur de l'élément, mise à jour le conteneur largeur/hauteur pour le même ratio.

var a = document.getElementById("outer-wrapper");
var b = document.getElementById("outer");
var scale = 1;
var aWidth = a.offsetWidth;
var aHeight = a.offsetHeight;

function increase()
{
    scale += 0.1
    b.style.transform = `scale(${scale})`;
    a.style.width = `${scale * aWidth}px`;
    a.style.height = `${scale * aHeight}px`;
}

function decrease()
{
    scale -= 0.1
    b.style.transform = `scale(${scale})`;
    a.style.width = `${scale * aWidth}px`;
    a.style.height = `${scale * aHeight}px`;
}
#outer {
  position: relative;
  transform-origin: left top;
}

.pointer {
  width: 20px;
  height: 20px;
  background-color: orange;
  position: absolute;
}

#a1 {
  top: 50px;
  left: 150px;
}
#a2 {
  top: 150px;
  left: 50px;
}
#a3 {
  top: 250px;
  left: 550px;
}
<div>
    <button onclick="increase()">Increase</button>
    <button onclick="decrease()">Decrease</button>
</div>
<div id="outer-wrapper">
  <div id="outer">
    <img src="http://via.placeholder.com/600x350" />
    <div id="a1" class='pointer'>
    </div>
    <div id="a2" class='pointer'>
    </div>
    <div id="a3" class='pointer'>
    </div>
  </div>
</div>
<div>
    please don't cover me
</div>

4voto

LightBender Points 2635

Si votre cas d'utilisation est aussi simple que votre exemple, je pense que vous avez peut-être trop compliquer les choses. Si vous avez besoin de votre enfant éléments de maintenir leur position relative par rapport à la mère, vous avez juste besoin de définir leur emplacement à l'aide des unités relatives plutôt qu'absolues unités et de laisser le moteur de rendu CSS faire sa chose.

Ici j'ai mis de la largeur de la société mère (plutôt que de l'échelle), l'image ajustement automatique de la taille à l'intérieur du conteneur pour régler sa hauteur, et ont utilisé des pourcentages plutôt que des pixels.

var b = document.getElementById("outer");
var width = 600;

function increase() {
  width = width * 1.1
  b.style.width = width + 'px';
}

function decrease() {
  width = width / 1.1
  b.style.width = width + 'px';
}
#outer {
  position: relative;
}

#outer img {
    width: 100%;
    height: auto;
}

.pointer {
  width: 3.333%;
  height: 5.714%;
  background-color: orange;
  position: absolute;
}

#a1 {
  top: 8.333%;
  left: 14.285%;
}

#a2 {
  top: 42.857%;
  left: 8.333%;
}

#a3 {
  top: 71.428%;
  left: 91.667%;
}
<div>
  <button onclick="increase()">Increase</button>
  <button onclick="decrease()">Decrease</button>
</div>
<div id=outer>
  <img src="http://via.placeholder.com/600x350" />
  <div id="a1" class='pointer'>
  </div>
  <div id="a2" class='pointer'>
  </div>
  <div id="a3" class='pointer'>
  </div>
</div>
<div>
  please don't cover me
</div>

3voto

shramee Points 3213

La meilleure idée est d'utiliser dynamique pour cent (%) de hauteur, de largeur et de positions pour chaque élément enfant.

Nous venons de diviser toutes les valeurs des pixels de largeur ou de la hauteur, comme l'exige et en JS simple modification de la largeur du conteneur parent et regarder la magie ;)

Vous trouverez le code ci-dessous, les commentaires appropriés ajoutée où les valeurs ont changé.

var b = document.getElementById("outer");
var scale = 1;

function increase() {
  scale += 0.1
  // Just change the width of parent
  b.style.width = 600 * scale + "px";
}

function decrease() {
  scale -= 0.1
  // Just change the width of parent
  b.style.width = 600 * scale + "px";
}
#outer {
  overflow-x: auto;
  position: relative;
  transform-origin: left top;
  width: 600px; /* Give div static width for children to position correctly */
}

#outer img {
  width: 100%; /* Set image to stretch full width */
}

.pointer {
  width: 3.33%; /* 20px/600px*100% */
  padding-top: 3.33%;/* Don't use static height */
  background-color: orange;
  position: absolute;
}

#a1 {
  top: 14.28%;/* 50px/350px*100% */
  left: 25%;/* 150px/600px*100% */
}

#a2 {
  top: 42.85%;/* 150px/350px*100% */
  left: 8.33%;/* 50px/600px*100% */
}

#a3 {
  top: 71.42%;/* 250px/350px*100% */
  left: 91.66%; /* 550px/600px*100% */
}
<div>
  <button onclick="increase()">Increase</button>
  <button onclick="decrease()">Decrease</button>
</div>
<div id=outer>
  <img src="http://via.placeholder.com/600x350" />
  <div id="a1" class='pointer'>
  </div>
  <div id="a2" class='pointer'>
  </div>
  <div id="a3" class='pointer'>
  </div>
</div>
<div>
  please don't cover me
</div>

P. S. pour montrer marqueur de la boîte de nous définir sa largeur comme rembourrage supérieur (qui lorsqu'il est réglé sur un pourcentage est relatif à un parent de largeur), de sorte qu'elle présente toujours comme un carré. ;)

C'est, à mon avis, est beaucoup plus facile à utiliser que vous n'avez pas à traiter chaque élément en JS.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X