How can I reshape a complex shape to another shape using css or javascript?

For Example, I have a shape like this:

enter image description here

and would like to reshape it to something like this (in the form of animation): enter image description here

How can I create these shapes and do that reshape using HTML, CSS, javascript, or jquery after that?

Regard.

Upvotes: 1

Views: 195

Answers (2)

Paul LeBeau
Paul LeBeau

Reputation: 101860

Not exactly the same shape, it's missing the radius on the inside corner, but it is almost pure HTML and CSS...

document.getElementById("shape").addEventListener("click", evt => {
   evt.target.classList.toggle("open");
});
#shape {
  width: 600px;
  height: 60px;
  position: relative;
  transition: all 1s;
}

#shape::before {
  content: '';
  display: block;
  position: absolute;
  width: 400px;
  height: 60px;
  background-color: #eee;
  border-radius: 18px;
  transition: all 1s;
}

#shape::after {
  content: '';
  display: block;
  position: absolute;
  width: 400px;
  height: 60px;
  bottom: 0;
  background-color: #eee;
  border-radius: 18px;
  transition: all 1s;
}


#shape.open {
  height: 200px;
}

#shape.open::before {
  width: 300px;
  height: 200px;
}

#shape.open::after {
  width: 600px;
}
<div id="shape"></div>

Upvotes: 2

Michael Rovinsky
Michael Rovinsky

Reputation: 7210

Use computePath function:

const computePath = (widthTop, widthBottom, heightTop, heightBottom, radius) => {
  let path = `M ${radius},0 
    H ${widthTop-radius} 
    Q ${widthTop},0 ${widthTop},${radius} 
    V ${heightTop-radius}`;
    
  if (widthTop === widthBottom)
    path += `Q ${widthTop},${heightTop} ${widthTop},${heightTop} 
    H ${widthBottom-radius} 
    Q ${widthBottom},${heightTop} ${widthBottom},${heightTop}`;
  else
    path += `Q ${widthTop},${heightTop} ${widthTop + radius},${heightTop} 
    H ${widthBottom-radius} 
    Q ${widthBottom},${heightTop} ${widthBottom},${heightTop+radius}`; 
      
  path += `
  V ${heightTop + heightBottom - radius}
  Q ${widthBottom},${heightTop + heightBottom} ${widthBottom-radius},${heightTop + heightBottom} 
    H ${radius}
    Q 0,${heightTop + heightBottom} 0 ${heightTop + heightBottom - radius}
    V ${radius}
    Q 0,0 ${radius},0
    Z`;
    
  return path;  
}

d3.select('path')
  .attr('transform', 'translate(50, 20)')
  .attr('d', computePath(200,200, 40, 0, 10))
  .transition()
  .delay(500)
  .duration(1000)
  .attr('d', computePath(200,300, 100, 40, 10))
  
path {
  stroke: none;
  fill: lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="300">
  <path/>
</svg>

Upvotes: 2

Related Questions