image-crop
kibo-ui-registry/image-cropFreeComponent
Helps you crop images to a specific size or aspect ratio.
Live preview
live · rendered by the registry
Rendered by Kibo UI Registry on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://www.kibo-ui.com/r/image-crop.jsonSource
1"use client";23import { Button } from "@repo/shadcn-ui/components/ui/button";4import { CropIcon, RotateCcwIcon } from "lucide-react";5import { Slot } from "radix-ui";6import {7 type ComponentProps,8 type CSSProperties,9 createContext,10 type MouseEvent,11 type ReactNode,12 type RefObject,13 type SyntheticEvent,14 useCallback,15 useContext,16 useEffect,17 useRef,18 useState,19} from "react";20import ReactCrop, {21 centerCrop,22 makeAspectCrop,23 type PercentCrop,24 type PixelCrop,25 type ReactCropProps,26} from "react-image-crop";27import { cn } from "@/lib/utils";2829import "react-image-crop/dist/ReactCrop.css";3031const centerAspectCrop = (32 mediaWidth: number,33 mediaHeight: number,34 aspect: number | undefined35): PercentCrop =>36 centerCrop(37 aspect38 ? makeAspectCrop(39 {40 unit: "%",41 width: 90,42 },43 aspect,44 mediaWidth,45 mediaHeight46 )47 : { x: 0, y: 0, width: 90, height: 90, unit: "%" },48 mediaWidth,49 mediaHeight50 );5152const getCroppedPngImage = async (53 imageSrc: HTMLImageElement,54 scaleFactor: number,55 pixelCrop: PixelCrop,56 maxImageSize: number57): Promise<string> => {58 const canvas = document.createElement("canvas");59 const ctx = canvas.getContext("2d");6061 if (!ctx) {62 throw new Error("Context is null, this should never happen.");63 }6465 const scaleX = imageSrc.naturalWidth / imageSrc.width;66 const scaleY = imageSrc.naturalHeight / imageSrc.height;6768 ctx.imageSmoothingEnabled = false;69 canvas.width = pixelCrop.width;70 canvas.height = pixelCrop.height;7172 ctx.drawImage(73 imageSrc,74 pixelCrop.x * scaleX,75 pixelCrop.y * scaleY,76 pixelCrop.width * scaleX,77 pixelCrop.height * scaleY,78 0,79 0,80 canvas.width,81 canvas.height82 );8384 const croppedImageUrl = canvas.toDataURL("image/png");85 const response = await fetch(croppedImageUrl);86 const blob = await response.blob();8788 if (blob.size > maxImageSize) {89 return await getCroppedPngImage(90 imageSrc,91 scaleFactor * 0.9,92 pixelCrop,93 maxImageSize94 );95 }9697 return croppedImageUrl;98};99100type ImageCropContextType = {101 file: File;102 maxImageSize: number;103 imgSrc: string;104 crop: PercentCrop | undefined;105 completedCrop: PixelCrop | null;106 imgRef: RefObject<HTMLImageElement | null>;107 onCrop?: (croppedImage: string) => void;108 reactCropProps: Omit<ReactCropProps, "onChange" | "onComplete" | "children">;109// … truncated
What it pulls in
npm packages
Files it writes
More from Kibo UI Registry
All 41 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| announcementannouncement | Kibo UI Registry | Components | Free | no deps | |
| avatar-stackavatar-stack | Kibo UI Registry | Components | Free | no deps | |
| bannerbanner | Kibo UI Registry | Components | Free | 2 deps | |
| calendarcalendar | Kibo UI Registry | Components | Free | 3 deps | |
| choiceboxchoicebox | Kibo UI Registry | Components | Free | 2 deps | |
| code-blockcode-block | Kibo UI Registry | Components | Free | 5 deps · 2 files | |
| color-pickercolor-picker | Kibo UI Registry | Components | Free | 3 deps | |
| comboboxcombobox | Kibo UI Registry | Components | Free | 2 deps |
