Design
Picture Frames

Picture Frames

Implementing a Picture frame component using Next.js and Tailwind CSS. This component is inspired from Nedim Arabacı (opens in a new tab)'s portfolio website (opens in a new tab).

Preview

frame 1frame 2frame 3frame 4

Installation

Install dependencies

pnpm add clsx tailwind-merge

Add util file

utils/cn.ts
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
 
export function cn(...inputs: ClassValue[]): string {
  return twMerge(clsx(inputs));
}

Copy the source code

components/ui/pictureFrames.tsx
"use client";
import Image from "next/image";
import React, { useState } from "react";
import { cn } from "@/util/cn";
 
interface FrameProps {
  src: string;
  alt: string;
  rot?: number;
}
 
export function Frame({ src, alt, rot = 12 }: FrameProps): React.JSX.Element {
	const [isPressed, setIsPressed] = useState(false);
  return (
    <Image
      onMouseDown={() => {
        setIsPressed(true);
      }}
      onMouseUp={() => {
        setIsPressed(false);
      }}
      alt={alt}
      width={1920}
      height={1080}
      style={{ "--rotate": `${rot.toString()}deg` } as React.CSSProperties}
      className={cn(isPressed ? "scale-[5]" : "hover:scale-[1.5]" ,"relative w-[5rem] rotate-[--rotate] border bg-white p-2 drop-shadow-md transition-transform duration-300 ease-in-out hover:z-20 hover:rotate-0 ")}
      src={src}
    />
  );
}

Use the component

function PictureFrameDemo(): React.JSX.Element {
  return (
    <div className="grid h-[20rem] grid-cols-5 items-center -space-x-5 p-5">
      <Frame
        src="https://images.unsplash.com/photo-1715645942867-4c8649966352"
        alt="frame 1"
      />
      <Frame
        src="https://images.unsplash.com/photo-1557381733-949765af91b9"
        alt="frame 2"
        rot={40}
      />
      <Frame
        src="https://images.unsplash.com/photo-1711656166230-8e8ecfab7732"
        alt="frame 3"
        rot={-10}
      />
      <Frame
        src="https://images.unsplash.com/photo-1704923510885-5ff4f047ce28"
        alt="frame 4"
        rot={10}
      />
    </div>
  );
}
 
export default PictureFrameDemo;

File Structure of the project

        • pictureFrames.tsx
      • cn.ts