¿Cómo hacer un cilindro con css?

publicado por: Anonymous

Estoy utilizando HTML y CSS para aprender/practicar transformaciones 2D y 3D y para ello estoy dibujando una pila 9v tridimensional (porque es sencilla y cuadradita). Hasta ahora todo ha sido sencillo porque sólo he necesitado transformaciones para rotar y mover las diferentes caras (rectangulares) de la pila.

Pero me encuentro con que los electrodos de la pila son circulares y no sé cómo hacer que un div (u otro elemento) tenga forma de circular (de tubo en 3D). Me imagino que sería “simular” un círculo utilizando muchos vertices, pero eso parece complicado.

Esto es lo que llevo hasta ahora (en JSFiddle):

_x000D_

_x000D_

@-moz-keyframes spin {_x000D_
  from {transform:rotateY(0deg) rotateX(0) rotateZ(0);}_x000D_
  to {transform:rotateY(360deg) rotateX(360deg) rotateZ(360deg);}_x000D_
}_x000D_
@-webkit-keyframes spin {_x000D_
  from {transform:rotateY(0deg) rotateX(0) rotateZ(0);}_x000D_
  to {transform:rotateY(360deg) rotateX(360deg) rotateZ(360deg);}_x000D_
}_x000D_
@keyframes spin {_x000D_
  from {transform:rotateY(0deg) rotateX(0) rotateZ(360);}_x000D_
  to {transform:rotateY(360deg) rotateX(360deg) rotateZ(0deg);}_x000D_
}_x000D_
_x000D_
.container {_x000D_
  -webkit-perspective: 1000px;_x000D_
  perspective: 1000px;_x000D_
  position:relative;_x000D_
  width:120px;_x000D_
  height:200px;_x000D_
  margin:100px;_x000D_
}_x000D_
#battery {_x000D_
  width: 100%;_x000D_
  height: 100%;_x000D_
  position: absolute;_x000D_
  transform-style: preserve-3d;_x000D_
  -webkit-animation: spin 14s infinite linear;_x000D_
  -moz-animation: spin 14s infinite linear;_x000D_
  animation: spin 14s infinite linear;_x000D_
}_x000D_
.face {_x000D_
  position:absolute;_x000D_
  top:0;_x000D_
  left:0;_x000D_
  transform-origin:0 0;_x000D_
  opacity:10.6;_x000D_
  overflow:hidden;_x000D_
}_x000D_
.face:before, .face:after, .face span:after, .face span:before {_x000D_
  position:absolute;_x000D_
  top:0;_x000D_
  left:0;_x000D_
  transform-origin: left top 0;_x000D_
  display:block;_x000D_
  font-family:arial,sans-serif;_x000D_
  white-space: pre;_x000D_
}_x000D_
.large {_x000D_
  width:120px;_x000D_
  height:200px;_x000D_
  background:#111111;_x000D_
  box-sizing:border-box;_x000D_
  box-shadow:inset 0px 66px 0px #CC7722;_x000D_
}_x000D_
.side {_x000D_
  width:66px;_x000D_
  height:200px;_x000D_
  background:black;_x000D_
  box-sizing:border-box;_x000D_
  box-shadow:inset 0px 66px 0px #AA5500;_x000D_
}_x000D_
.short {_x000D_
  width:120px;_x000D_
  height:66px;_x000D_
  background:#222222;_x000D_
}_x000D_
.top {_x000D_
  box-shadow:inset 0 0 0 8px #BB6611;_x000D_
}_x000D_
.bottom {_x000D_
  box-shadow:inset 0 0 0 8px #111111;_x000D_
}_x000D_
.front:before, .back:before, .right:before {_x000D_
  content:"DURACELL";_x000D_
  color:silver;_x000D_
  transform: rotate(90deg) translate(72px, -68px);_x000D_
  font-weight:bold;_x000D_
  font-size:1.3em;_x000D_
}_x000D_
.front:after, .back:after {_x000D_
  content:"ALKALINE BATTERY";_x000D_
  color:silver;_x000D_
  transform: rotate(90deg) translate(73px, -44px);_x000D_
  font-weight:bold;_x000D_
  font-size:0.5em;_x000D_
}_x000D_
.back:after { content:"PILE ALCALINE"; }_x000D_
.right:before { transform: rotate(90deg) translate(72px, -50px) }_x000D_
.right:after {_x000D_
  content:"Duracell, div of P&G, Bethel, CT 06801 a P&G Inc., Toronto, ON M5W1C5 a Made in U.S.A. / Fabrique aux E.-U. a 95756099";_x000D_
  width:130px;_x000D_
  color:silver;_x000D_
  transform: rotate(90deg) translate(73px, -27px);_x000D_
  font-weight:bold;_x000D_
  font-size:0.29em;_x000D_
  letter-spacing:-0.1px;_x000D_
  line-height:1.2em;_x000D_
}_x000D_
.right span:before {_x000D_
  content:"2b06a+";_x000D_
  font-weight:bold;_x000D_
  line-height:0.8em;_x000D_
  top:20px;_x000D_
  left:20px;_x000D_
  font-size:1.3em;_x000D_
}_x000D_
.right span:after {_x000D_
  content:"MAR a 2015";_x000D_
  color:#AA5500;_x000D_
  transform: rotate(90deg) translate(150px, -23px);_x000D_
  width:60px;_x000D_
  font-weight:bold;_x000D_
  font-size:0.6em;_x000D_
  text-align:center;_x000D_
}_x000D_
.left:before {_x000D_
  content:"MN1604 a 6LR61 a 9 VOLTS";_x000D_
  line-height:1em;_x000D_
  transform: rotate(90deg) translate(15px, -59px);_x000D_
  font-size:0.5em;_x000D_
  font-weight:bold;_x000D_
  letter-spacing:-0.1px;_x000D_
}_x000D_
.left span:before {_x000D_
  content:"Caution: do not connect improperly. Charge or dispose of in fire. Battery may explode or leak. Do not carry batteries loose in your pocket or elsewhere as burn injury could result.";_x000D_
  width:120px;_x000D_
  color:silver;_x000D_
  transform: rotate(90deg) translate(73px, -60px);_x000D_
  font-weight:200;_x000D_
  font-size:0.25em;_x000D_
  letter-spacing:-0.2px;_x000D_
  line-height:1.2em;_x000D_
  text-transform:uppercase;_x000D_
  white-space: normal;_x000D_
}_x000D_
_x000D_
#battery .front { transform: rotateY( 0deg ) translateZ( 66px ); }_x000D_
#battery .back { transform: rotateY( 180deg ) translateX( -120px ); }_x000D_
#battery .right { transform: rotateY( 90deg ) translateZ( 120px ) translateX(-66px); }_x000D_
#battery .left { transform: rotateY( -90deg ) translateZ( 0 ); }_x000D_
#battery .top { transform: rotateX( -270deg ) translateZ( 0 ); }_x000D_
#battery .bottom { transform: rotateX( 90deg ) translateZ( -200px ); }

_x000D_

<div class="container">_x000D_
  <div id="battery">_x000D_
    <div class="face large front"></div>_x000D_
    <div class="face large back"></div>_x000D_
    <div class="face side right"><span></span></div>_x000D_
    <div class="face side left"><span></span></div>_x000D_
    <div class="face short top"></div>_x000D_
    <div class="face short bottom"></div>_x000D_
  </div>_x000D_
</div>

_x000D_

_x000D_

_x000D_

y así es como se ve:

Pila en HTML + CSS, faltan los electrodos

Me imagino que podría hacerse con SVG o un canvas, pero quiero limitarme a HTML+CSS3 (con transformaciones 2D y 3D). Entonces mis preguntas realmente son:

  • ¿Se puede tener un div curvo? (no un círculo, sino un tubo)
  • ¿Se pueden hacer div curvados? (p.e. para crear dos semicírculos y juntarlos en un círculo)

Y si no se puede curvar el elemento, ¿cuál podría ser una alternativa? ¿O mi única opción es simularlo como decía antes?

solución

Lo primero que debes tener presente cuando manejas transformaciones tridimensionales en CSS es que los elementos html no tienen grosor por lo que es imposible hacer un círculo, cuadrado u otra figura en CSS que tenga profundidad ya que siempre estarán reducidos a un plano.

En tu ejemplo la pila esta compuesta por diferentes elementos planos que juntos componen un cubo dando la impresión de profundidad precisamente para sortear dicha limitación.

La forma correcta de simular lo que quieres es con canvas que trae funciones para manipular este tipo de transformaciones tridimensionales. Te recomiendo echarle un vistazo a three.js

Crear un círculo plano con CSS es muy sencillo con la propiedad border-radius: 50% pero lograr un cilindro superponiendo muchas capas necesitaría muchos elementos(y probablemente la ayuda de javascript para lograr simplicidad). Aquí tienes un demo.

_x000D_

_x000D_

@-moz-keyframes spin {_x000D_
  from {_x000D_
    transform: rotateY(0deg) rotateX(0deg) rotateZ(0deg);_x000D_
  }_x000D_
  to {_x000D_
    transform: rotateY(360deg) rotateX(360deg) rotateZ(360deg);_x000D_
  }_x000D_
}_x000D_
@-webkit-keyframes spin {_x000D_
  from {_x000D_
    transform: rotateY(0deg) rotateX(0deg) rotateZ(0deg);_x000D_
  }_x000D_
  to {_x000D_
    transform: rotateY(360deg) rotateX(360deg) rotateZ(360deg);_x000D_
  }_x000D_
}_x000D_
@keyframes spin {_x000D_
  from {_x000D_
    transform: rotateY(0deg) rotateX(0deg) rotateZ(360deg);_x000D_
  }_x000D_
  to {_x000D_
    transform: rotateY(360deg) rotateX(360deg) rotateZ(0deg);_x000D_
  }_x000D_
}_x000D_
.container {_x000D_
  -webkit-perspective: 1000px;_x000D_
  perspective: 1000px;_x000D_
  position: relative;_x000D_
  width: 120px;_x000D_
  height: 200px;_x000D_
  margin: 100px;_x000D_
}_x000D_
#battery {_x000D_
  width: 100%;_x000D_
  height: 100%;_x000D_
  position: absolute;_x000D_
  transform-style: preserve-3d;_x000D_
  -webkit-animation: spin 14s infinite linear;_x000D_
  -moz-animation: spin 14s infinite linear;_x000D_
  animation: spin 14s infinite linear;_x000D_
}_x000D_
.face {_x000D_
  position: absolute;_x000D_
  top: 0;_x000D_
  left: 0;_x000D_
  transform-origin: 0 0;_x000D_
  opacity: 10.6;_x000D_
  overflow: hidden;_x000D_
}_x000D_
.face:before,_x000D_
.face:after,_x000D_
.face span:after,_x000D_
.face span:before {_x000D_
  position: absolute;_x000D_
  top: 0;_x000D_
  left: 0;_x000D_
  transform-origin: left top 0;_x000D_
  display: block;_x000D_
  font-family: arial, sans-serif;_x000D_
  white-space: pre;_x000D_
}_x000D_
.large {_x000D_
  width: 120px;_x000D_
  height: 200px;_x000D_
  background: #111111;_x000D_
  box-sizing: border-box;_x000D_
  box-shadow: inset 0px 66px 0px #CC7722;_x000D_
}_x000D_
.side {_x000D_
  width: 66px;_x000D_
  height: 200px;_x000D_
  background: black;_x000D_
  box-sizing: border-box;_x000D_
  box-shadow: inset 0px 66px 0px #AA5500;_x000D_
}_x000D_
.short {_x000D_
  width: 120px;_x000D_
  height: 66px;_x000D_
  background: #222222;_x000D_
}_x000D_
.top {_x000D_
  box-shadow: inset 0 0 0 8px #BB6611;_x000D_
}_x000D_
.bottom {_x000D_
  box-shadow: inset 0 0 0 8px #111111;_x000D_
}_x000D_
.front:before,_x000D_
.back:before,_x000D_
.right:before {_x000D_
  content: "DURACELL";_x000D_
  color: silver;_x000D_
  transform: rotate(90deg) translate(72px, -68px);_x000D_
  font-weight: bold;_x000D_
  font-size: 1.3em;_x000D_
}_x000D_
.front:after,_x000D_
.back:after {_x000D_
  content: "ALKALINE BATTERY";_x000D_
  color: silver;_x000D_
  transform: rotate(90deg) translate(73px, -44px);_x000D_
  font-weight: bold;_x000D_
  font-size: 0.5em;_x000D_
}_x000D_
.back:after {_x000D_
  content: "PILE ALCALINE";_x000D_
}_x000D_
.right:before {_x000D_
  transform: rotate(90deg) translate(72px, -50px)_x000D_
}_x000D_
.right:after {_x000D_
  content: "Duracell, div of P&G, Bethel, CT 06801 a P&G Inc., Toronto, ON M5W1C5 a Made in U.S.A. / Fabrique aux E.-U. a 95756099";_x000D_
  width: 130px;_x000D_
  color: silver;_x000D_
  transform: rotate(90deg) translate(73px, -27px);_x000D_
  font-weight: bold;_x000D_
  font-size: 0.29em;_x000D_
  letter-spacing: -0.1px;_x000D_
  line-height: 1.2em;_x000D_
}_x000D_
.right span:before {_x000D_
  content: "2b06a+";_x000D_
  font-weight: bold;_x000D_
  line-height: 0.8em;_x000D_
  top: 20px;_x000D_
  left: 20px;_x000D_
  font-size: 1.3em;_x000D_
}_x000D_
.right span:after {_x000D_
  content: "MAR a 2015";_x000D_
  color: #AA5500;_x000D_
  transform: rotate(90deg) translate(150px, -23px);_x000D_
  width: 60px;_x000D_
  font-weight: bold;_x000D_
  font-size: 0.6em;_x000D_
  text-align: center;_x000D_
}_x000D_
.left:before {_x000D_
  content: "MN1604 a 6LR61 a 9 VOLTS";_x000D_
  line-height: 1em;_x000D_
  transform: rotate(90deg) translate(15px, -59px);_x000D_
  font-size: 0.5em;_x000D_
  font-weight: bold;_x000D_
  letter-spacing: -0.1px;_x000D_
}_x000D_
.left span:before {_x000D_
  content: "Caution: do not connect improperly. Charge or dispose of in fire. Battery may explode or leak. Do not carry batteries loose in your pocket or elsewhere as burn injury could result.";_x000D_
  width: 120px;_x000D_
  color: silver;_x000D_
  transform: rotate(90deg) translate(73px, -60px);_x000D_
  font-weight: 200;_x000D_
  font-size: 0.25em;_x000D_
  letter-spacing: -0.2px;_x000D_
  line-height: 1.2em;_x000D_
  text-transform: uppercase;_x000D_
  white-space: normal;_x000D_
}_x000D_
#battery .front {_x000D_
  transform: rotateY(0deg) translateZ(66px);_x000D_
}_x000D_
#battery .back {_x000D_
  transform: rotateY(180deg) translateX(-120px);_x000D_
}_x000D_
#battery .right {_x000D_
  transform: rotateY(90deg) translateZ(120px) translateX(-66px);_x000D_
}_x000D_
#battery .left {_x000D_
  transform: rotateY(-90deg) translateZ(0);_x000D_
}_x000D_
#battery .top {_x000D_
  transform: rotateX(-270deg) translateZ(0);_x000D_
}_x000D_
#battery .bottom {_x000D_
  transform: rotateX(90deg) translateZ(-200px);_x000D_
}_x000D_
#battery .electrodo1 .layer1 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(26px) translateY(-9px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo1 .layer2 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(26px) translateY(-10px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo1 .layer3 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(26px) translateY(-11px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo1 .layer4 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(26px) translateY(-12px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo1 .layer5 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(26px) translateY(-13px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo1 .layer6 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(26px) translateY(-14px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo1 .layer7 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(26px) translateY(-15px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo2 .layer1 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(86px) translateY(-9px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo2 .layer2 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(86px) translateY(-10px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo2 .layer3 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(86px) translateY(-11px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo2 .layer4 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(86px) translateY(-12px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo2 .layer5 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(86px) translateY(-13px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo2 .layer6 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(86px) translateY(-14px) translateZ(33px) rotateX(-270deg);_x000D_
}_x000D_
#battery .electrodo2 .layer7 {_x000D_
  position: absolute;_x000D_
  width: 10px;_x000D_
  height: 10px;_x000D_
  border-radius: 50%;_x000D_
  background-color: goldenrod;_x000D_
  transform: translateX(86px) translateY(-15px) translateZ(33px) rotateX(-270deg);_x000D_
}

_x000D_

<div class="container">_x000D_
  <div id="battery">_x000D_
    <div class="electrodo1">_x000D_
      <div class="layer1"></div>_x000D_
      <div class="layer2"></div>_x000D_
      <div class="layer3"></div>_x000D_
      <div class="layer4"></div>_x000D_
      <div class="layer5"></div>_x000D_
      <div class="layer6"></div>_x000D_
      <div class="layer7"></div>_x000D_
    </div>_x000D_
    <div class="electrodo2">_x000D_
      <div class="layer1"></div>_x000D_
      <div class="layer2"></div>_x000D_
      <div class="layer3"></div>_x000D_
      <div class="layer4"></div>_x000D_
      <div class="layer5"></div>_x000D_
      <div class="layer6"></div>_x000D_
      <div class="layer7"></div>_x000D_
    </div>_x000D_
    <div class="face large front"></div>_x000D_
    <div class="face large back"></div>_x000D_
    <div class="face side right"><span></span>_x000D_
    </div>_x000D_
    <div class="face side left"><span></span>_x000D_
    </div>_x000D_
    <div class="face short top"></div>_x000D_
    <div class="face short bottom"></div>_x000D_
  </div>_x000D_
</div>

_x000D_

_x000D_

_x000D_

Aún así en algún momento de la rotación verás un destello cuando todas las capas del electrodo esten perpendiculares a la pantalla donde se hace evidente el truco.

comparacion pila en posiciones diferentes

Como alternativa puedes hacer un prisma hexagonal a base de planos. Mientras más planos uses más te acercarás a la figura del círculo pero necesitarás una gran cantidad de elementos para lograr esto(uno por cada lado y varios para simular una capa superior).

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *