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