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 mumkinya'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"
/>
);
}