How would I create an arch of images in css

Viewed 312

I'm trying to add a nice little piece to my portfolio to make it stand out a little bit more with cards spread out in an arch. I'm struggling to figure out how to place them on the bottom of the container to match what I mocked in figma.

Also, a secondary concern is how I am placing the cards into the arch. I feel as if there should be a better way to translate this by calculating hypotenuse of a right triangle using sine and cosine, but css doesn't directly support it and manually calculating seems like too much of a clutter. Any advice on this part too would be appreciated.

this is what I have now. what I have now

this is what I have in figma what I want to create

I'm using react but I'd prefer to keep everything for this in my css file. Here's my react component.

import * as React from 'react';
import '@styles/cardRadial.css';

interface Props {
    cardPaths: Array<string>;
}

const CardRadial: React.FC<Props> = (props: Props) => {
    const { cardPaths } = props;

    let filteredPaths: Array<string> = [];
    let offset: number = 0;
    for (let i: number = 0; i < cardPaths.length; i += 4) {
        offset = Math.floor(Math.random() * 4);
        console.log(i, offset, cardPaths[i + offset]);
        filteredPaths.push(cardPaths[i + offset]);
    }

    const images: JSX.Element[] =
        filteredPaths &&
        filteredPaths.map((imagePath: string, i) => {
            return (
                <img
                    key={imagePath.slice(-15) + i}
                    src={imagePath}
                    alt='Skill Card'
                    width={150}
                    className='skill-card'
                />
            );
        });

    return (
        <div className='skill-card-radial-container'>
            <div className='skill-card-base'>{images}</div>
        </div>
    );
};

export default CardRadial;

Here's the css file.

div.skill-card-radial-container{
    text-align:center;
    height: 100%;
} 

div.skill-card-base{
    position: relative;
}

/* position is calculated by (n * (180 / 14))*/
img.skill-card:nth-child(1){ --position: -12.857deg; --angle: -60deg;}
img.skill-card:nth-child(2){ --position: -25.714deg; --angle: -50deg; }
img.skill-card:nth-child(3){ --position: -38.571deg; --angle: -40deg; }
img.skill-card:nth-child(4){ --position: -51.428deg; --angle: -30deg; }
img.skill-card:nth-child(5){ --position: -64.285deg; --angle: -20deg; }
img.skill-card:nth-child(6){ --position: -77.142deg; --angle: -10deg; }
img.skill-card:nth-child(7){ --position: -90deg; --angle: 0deg;  }
img.skill-card:nth-child(8){ --position: -102.857deg; --angle: 10deg; }
img.skill-card:nth-child(9){ --position: -115.714deg; --angle: 20deg; }
img.skill-card:nth-child(10){ --position:-128.571deg; --angle: 30deg; }
img.skill-card:nth-child(11){ --position: -141.428deg; --angle: 40deg; }
img.skill-card:nth-child(12){ --position: -154.285deg; --angle: 50deg; }
img.skill-card:nth-child(13){ --position: -167.142deg; --angle: 60deg; }


img.skill-card {
    padding: 10px;
    position: absolute;
    transform: rotate(var(--position)) translate(15em) rotate(calc(calc((-1 * var(--position)) - var(--angle)))) ;
}
2 Answers

You can use javascript for that. Here's a code snippet taken from codepen.

function arc(x) {
  // (x)^2 + y^2 = 100^2
  var ySquare = 10000 - (x ) * (x )
  ySquare = Math.abs(ySquare)
  return Math.sqrt(ySquare)
}

$(".point").each(function(index) {
  var x = 50 * (2 * index / 10 - 1)
  var y = arc(x)
  
  $(this).css('left', (x + 200) + 'px')
  $(this).css('top', (200 - y) + 'px')
})
.container {
  position: relative;
}

.point {
  position: absolute;
  border-radius: 50%;
  height: 10px;
  width: 10px;
  background: black;
}
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<div class="container">
  <div class="point"></div>
  <div class="point"></div>  
  <div class="point"></div>  
  <div class="point"></div>  
  <div class="point"></div>  
  <div class="point"></div>  
  <div class="point"></div>  
  <div class="point"></div>  
  <div class="point"></div>  
  <div class="point"></div>  
  <div class="point"></div>  
</div>

You can run this code snipped & see that it creates an arc of points. You can use your images instead of points.

Related