canvasda gap ko'p

March 1, 2026 · 6 min read

HTML Canvas
<canvas> bu odatiy website yasash uchun kerak bo'lmedigan lekin real powerful tool yasamoqchi bo'linsa usiz deyarli ish bitmedigan HTML element.
<canvas> bilan odatda brauzer ichida realtime grafika, animatsiya и vizual effektlar yasash mumkin
ya'ni:
  • 2D/3D o‘yinlar
  • Real-time grafika va diagrammalar
  • Murakkab animatsiyalar va vizual effektlar
  • Custom dizayn elementlar
  • Interaktiv tajribalar (masalan: particle systems, physics simulyatsiya)
va hokazolarni yasash mumkin.
Agar odamda <canvas> haqida chuqur bilim va creativelik bo'lsa u любой websiteni san'at darajasiga obchiqishi mumkin. Masalan awwwards.com ga joylashtirilgan juda juda ko'p sitelarda canvas ishlatilingan, chunki <canvas> saytni bezash uchun kuchli element hisoblanadi.
Canvas kuchining asosiy sabablari AI DATA:
  • Yuqori performance – to‘g‘ridan-to‘g‘ri pixel darajasida ishlaydi
  • To‘liq nazorat – har bir elementni o‘zingiz boshqarasiz
  • Real-time animatsiya – requestAnimationFrame bilan silliq harakat
  • Interaktivlik – mouse, touch va keyboard hodisalar bilan ishlaydi
  • Cheksiz kreativ imkoniyat – dizayn va effektlar bo‘yicha deyarli cheklov yo‘q
Agar siz zamonaviy, dinamik va vizual jihatdan boy web tajriba yaratmoqchi bo‘lsangiz, Canvas sizga oddiy DOM animatsiyalardan ancha yuqori darajadagi imkoniyat beradi
Simple code example
Reactda <canvas>ni tushunish uchun oddiy misol:
import { useRef, useEffect } from "react";

export default function SimpleCanvas() {
  const canvasRef = useRef(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext("2d");

    // To'rtburchak chizish
    ctx.fillStyle = "blue";
    ctx.fillRect(50, 50, 150, 100);

    // Doira chizish
    ctx.beginPath();
    ctx.arc(200, 200, 40, 0, Math.PI * 2);
    ctx.fillStyle = "red";
    ctx.fill();
  }, []);

  return (
    <canvas
      ref={canvasRef}
      width={400}
      height={300}
    />
  );
}
Result:
List of examples on internet
Home page canvas animation
mutawirr.uz home page'idagi canvas animation kodi (AI commentlar orqali tushuntirgan):
import { JSX, useEffect, useRef } from "react";

// Har bir wave (to‘lqin) uchun konfiguratsiya tipi
interface Wave {
  fx: number;   // X o‘qi bo‘yicha sinus chastotasi
  fy: number;   // Y o‘qi bo‘yicha sinus chastotasi
  ft: number;   // Vaqt bo‘yicha tezlik (animatsiya tezligi)
  phi: number;  // Boshlang‘ich faza (sinus boshlanish burchagi)
}

// Tasodifiy to‘lqinlar generatsiya qiluvchi funksiya
function generateWaves(count: number): Wave[] {
  return Array.from({ length: count }, () => ({
    // fx va fy kichik qiymat — silliq gradient effekt uchun
    fx: (Math.random() - 0.5) * 0.15,
    fy: (Math.random() - 0.5) * 0.15,

    // ft — animatsiya tezligi (+ yoki - yo‘nalishda)
    ft: (Math.random() * 0.5 + 0.2) * (Math.random() > 0.5 ? 1 : -1),

    // phi — 0 dan 2π gacha random faza
    phi: Math.random() * Math.PI * 2,
  }));
}

interface DecorativeProps {
  revealed?: boolean; // tashqaridan keladigan reveal trigger
}

export default function Decorative({
  revealed = false,
}: DecorativeProps): JSX.Element {
  
  // Canvas elementiga referens
  const canvasRef = useRef<HTMLCanvasElement>(null);

  // Intro animatsiya start vaqtini saqlash uchun ref
  const introRef = useRef({ startTime: 0, active: false });

  // revealed true bo‘lganda intro animatsiyani boshlash
  useEffect(() => {
    if (
      revealed &&
      !introRef.current.active &&
      introRef.current.startTime === 0
    ) {
      introRef.current.active = true;
      introRef.current.startTime = Date.now(); // animatsiya start vaqti
    }
  }, [revealed]);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    // 2D context olish (alpha: false — shaffofliksiz, performance yaxshiroq)
    const ctx = canvas.getContext("2d", { alpha: false });
    if (!ctx) return;

    let animationId: number;
    let t = 0; // vaqt parametri (animatsiya uchun)

    // Grid o‘lchamlari
    let cols = 160;
    let rows = 65;

    // 4 ta sinus to‘lqin generatsiya qilinadi
    const waves = generateWaves(4);

    // Canvas resize funksiyasi
    const resize = (): void => {
      const isMobile = window.innerWidth < 768;

      // Mobil bo‘lsa grid kichrayadi (performance uchun)
      cols = isMobile ? 60 : 160;
      rows = isMobile ? 40 : 65;

      const dpr = window.devicePixelRatio || 1; // Retina display support
      const rect = canvas.getBoundingClientRect();

      // Canvas real pixel size
      canvas.width = rect.width * dpr;
      canvas.height = rect.height * dpr;

      // Chizish scale moslashtiriladi
      ctx.scale(dpr, dpr);
    };

    resize();
    window.addEventListener("resize", resize);

    // Asosiy chizish funksiyasi
    const draw = (): void => {
      const dpr = window.devicePixelRatio || 1;
      const W = canvas.width / dpr;
      const H = canvas.height / dpr;

      // Background tozalash (har frame)
      ctx.fillStyle = "#0a0a0a";
      ctx.fillRect(0, 0, W, H);

      // Har bir cell o‘lchami
      const cellW = W / cols;
      const cellH = H / rows;

      // Kvadratning maksimal tomoni
      const maxSide = Math.min(cellW, cellH) * 0.95;

      const now = Date.now();
      const introDuration = 1000; // reveal davomiyligi
      const sweepDelay = 500;     // ustun bo‘yicha kechikish

      // Grid bo‘yicha yuramiz
      for (let row = 0; row < rows; row++) {
        for (let col = 0; col < cols; col++) {

          // Har bir cell markazi
          const x = col * cellW + cellW / 2;
          const y = row * cellH + cellH / 2;

          // Sinus to‘lqinlar yig‘indisi
          let val = 0;
          for (const w of waves) {
            val += Math.sin(col * w.fx + row * w.fy + t * w.ft + w.phi);
          }

          // Normalizatsiya (0–1 oralig‘iga)
          let intensity = (val + waves.length) / (waves.length * 2);

          // Kontrastni kuchaytirish (exponential)
          intensity = Math.pow(intensity, 4.5);

          // Agar intro boshlangan bo‘lsa
          if (introRef.current.startTime > 0) {
            const elapsed = now - introRef.current.startTime;

            // Ustun bo‘yicha progress (chapdan o‘ngga reveal)
            const colRatio = col / cols;

            const revealProgress = Math.min(
              1,
              Math.max(0, (elapsed - colRatio * sweepDelay) / introDuration),
            );

            // Ripple (to‘lqincha) effekti
            const rippleDuration = 1000;
            const rippleDelay = 400;
            const rippleStart = colRatio * sweepDelay + rippleDelay;

            let rippleEffect = 0;

            if (
              elapsed > rippleStart &&
              elapsed < rippleStart + rippleDuration
            ) {
              const rippleNormalized = (elapsed - rippleStart) / rippleDuration;

              // Sinus asosida ripple
              rippleEffect = Math.sin(rippleNormalized * Math.PI) * 0.4;
            }

            intensity = intensity * revealProgress + rippleEffect;
          } else {
            intensity = 0; // reveal boshlanmaguncha ko‘rinmaydi
          }

          if (intensity < 0.001) continue; // juda kichik bo‘lsa chizilmaydi

          const glow = Math.min(1.5, intensity);

          // Kvadrat o‘lchami
          const size = maxSide * (0.15 + Math.min(1, glow) * 0.85);

          const borderRadius = size * 0.3;

          // Rang hisoblash (yorqinlashganda ko‘k tomonga o‘tadi)
          const colorFactor = Math.pow(Math.min(1, glow), 7);

          const r = Math.round(186 + colorFactor * 69);
          const g = Math.round(204 + colorFactor * 51);
          const b = Math.round(237 + colorFactor * 18);

          const alpha = Math.min(1, 0.12 + Math.pow(glow, 2) * 0.88);

          ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${alpha})`;

          // Kvadrat chizish
          ctx.beginPath();

          if (ctx.roundRect) {
            // Agar browser roundRect ni qo‘llasa
            ctx.roundRect(x - size / 2, y - size / 2, size, size, borderRadius);
          } else {
            // Aks holda oddiy rect
            ctx.rect(x - size / 2, y - size / 2, size, size);
          }

          ctx.fill();
        }
      }

      t += 0.02; // vaqtni oshiramiz (animatsiya harakati)

      animationId = requestAnimationFrame(draw); 
      // keyingi frame
    };

    draw(); // animatsiyani boshlash

    // Cleanup
    return (): void => {
      cancelAnimationFrame(animationId);
      window.removeEventListener("resize", resize);
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      className="h-[40vh] md:h-[55vh] w-full block transition-all duration-700"
    />
  );
}