Skip to content

Instantly share code, notes, and snippets.

@yinkakun
Created September 9, 2023 15:24
Show Gist options
  • Save yinkakun/782389a4efd1b4a1d3a88602c9be2892 to your computer and use it in GitHub Desktop.
Save yinkakun/782389a4efd1b4a1d3a88602c9be2892 to your computer and use it in GitHub Desktop.
export default function App() {
return (
<div
style={{
height: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "space-around",
}}
>
<AfroProfile size="sm" score={80} />
<AfroProfile size="md" score={90} />
<AfroProfile size="lg" score={20} />
</div>
);
}
import React from "react";
type Size = "sm" | "md" | "lg" | "xl";
interface AfroProfileProps {
size: Size;
score: number;
}
const SIZE_TO_PX: Record<Size, number> = {
sm: 60,
md: 110,
lg: 150,
xl: 200,
};
const AfroProfile: React.FC<AfroProfileProps> = ({ score, size }) => {
const sizeInPx = SIZE_TO_PX[size];
const STROKE_WIDTH = sizeInPx * 0.06;
const radius = sizeInPx / 2 - STROKE_WIDTH / 2;
// calculate circumference based on sizeInPx
const circumference = 2 * Math.PI * radius;
// calculate inactive stroke-dash offset based on score
const offset = ((100 - score) / 100) * circumference;
return (
<div
style={{
transform: "rotate(90deg)",
borderRadius: 999,
width: sizeInPx,
height: sizeInPx,
backgroundImage:
"url(https://i.postimg.cc/6Qc3z8Xh/paktscore-gradient.png)",
backgroundSize: "cover",
}}
>
<svg
width={sizeInPx}
height={sizeInPx}
viewBox={`0 0 ${sizeInPx} ${sizeInPx}`}
>
<defs>
<pattern
id="paktscore"
patternUnits="objectBoundingBox"
x={0}
y={0}
width={1}
height={1}
>
<image
width={sizeInPx}
height={sizeInPx}
xlinkHref="https://i.postimg.cc/6Qc3z8Xh/paktscore-gradient.png"
></image>
</pattern>
</defs>
{/* white background circle */}
<circle
cx={sizeInPx / 2}
cy={sizeInPx / 2}
r={sizeInPx / 2 - STROKE_WIDTH / 2}
fill="white"
></circle>
{/* gray track circle */}
<circle
stroke="#ccc"
strokeLinecap="round"
cx={sizeInPx / 2}
cy={sizeInPx / 2}
fill="transparent"
strokeWidth={STROKE_WIDTH}
r={sizeInPx / 2 - STROKE_WIDTH / 2}
></circle>
{/* progress circle */}
<circle
cx={sizeInPx / 2}
cy={sizeInPx / 2}
fill="url(#paktscore)"
strokeLinecap="round"
stroke="url(#paktscore)"
strokeWidth={STROKE_WIDTH}
strokeDashoffset={offset}
strokeDasharray={`${circumference} ${circumference}`}
r={sizeInPx / 2 - STROKE_WIDTH / 2}
></circle>
</svg>
</div>
);
};
@Paul-Taiwo
Copy link

Paul-Taiwo commented Sep 9, 2023

import React from "react";

const score = 80;

const AfroProfile = () => {
  const sizeInPx = 200;
  const STROKE_WIDTH = sizeInPx * 0.06;

  const radius = sizeInPx / 2 - STROKE_WIDTH / 2;

  // calculate circumference based on sizeInPx
  const circumference = 2 * Math.PI * radius;

  // calculate inactive stroke-dash offset based on score
  const offset = ((100 - score) / 100) * circumference;

  return (
    <div
      style={{
        borderRadius: "50%",
        width: sizeInPx,
        height: sizeInPx,
        overflow: "hidden"
      }}
    >
      <svg
        width={sizeInPx}
        height={sizeInPx}
        viewBox={`0 0 ${sizeInPx} ${sizeInPx}`}
      >
        {/* Define the pattern */}
        <defs>
          <pattern
            id="imagePattern"
            x="0"
            y="0"
            width="1"
            height="1"
            patternContentUnits="objectBoundingBox"
            patternTransform="translate(-100 -100) scale(2)"
          >
            <image
              x="0"
              y="0"
              width="1"
              height="1"
              xlinkHref="https://i.postimg.cc/6Qc3z8Xh/paktscore-gradient.png"
            />
          </pattern>
        </defs>

        {/* white background circle  */}
        <circle
          cx={sizeInPx / 2}
          cy={sizeInPx / 2}
          r={sizeInPx / 2 - STROKE_WIDTH / 2}
          fill="white"
        ></circle>

        {/* gray track circle  */}
        <circle
          stroke="#ccc"
          strokeLinecap="round"
          cx={sizeInPx / 2}
          cy={sizeInPx / 2}
          fill="transparent"
          strokeWidth={STROKE_WIDTH}
          r={sizeInPx / 2 - STROKE_WIDTH / 2}
        ></circle>

        {/* progress circle */}
        <circle
          cx={sizeInPx / 2}
          cy={sizeInPx / 2}
          fill="transparent"
          strokeLinecap="round"
          strokeWidth={STROKE_WIDTH}
          r={sizeInPx / 2 - STROKE_WIDTH / 2}
          stroke="url(#imagePattern)"
          strokeDashoffset={offset}
          strokeDasharray={`${circumference} ${circumference}`}
        />
      </svg>
    </div>
  );
};

export default AfroProfile;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment