texture

افزودن بافت‌های زنده، نویز ارگانیک و حس فیلم به رابط‌ها و ویدیوها

این skill برای ساخت و تنظیم بافت‌های متحرک مانند film grain، نویز procedural، الگوهای اسکرول‌شونده، shimmer و شبیه‌سازی سطح طراحی شده است. توکن‌های آماده برای opacity، frequency، amplitude، سرعت و زبری، انتخاب تنظیمات مناسب را ساده می‌کنند.

با استفاده از CSS، Canvas، SVG Filters و Framer Motion می‌توانید به رابط‌ها حس ارگانیک، سینمایی یا مادی بدهید؛ در عین حال برای prefers-reduced-motion نیز جایگزین‌های کم‌تحرک در نظر بگیرید.

چه چیزی می‌گیرید

  • توکن‌های استاندارد برای grain، noise، pattern و surface
  • الگوهای آماده برای film grain متحرک با CSS و Canvas
  • نمونه پیاده‌سازی SVG noise displacement و افکت‌های سطحی
  • الگوهای اسکرول پس‌زمینه، metallic shimmer و تنظیمات سرعت
  • راهنمای سازگارکردن افکت‌ها با `prefers-reduced-motion`

برای چه کاری خوب است

  • طراحان و توسعه‌دهندگان رابط‌هایی با حس سینمایی، وینتیج یا ارگانیک
  • ساخت پس‌زمینه‌های پویا برای landing page، داشبورد یا وب‌سایت‌های برندمحور
  • افزودن grain، shimmer یا distortion کنترل‌شده به کامپوننت‌های UI
  • پروژه‌هایی که به سیستم توکن‌محور و تنظیمات قابل‌استفاده‌مجدد برای موشن نیاز دارند

برای چه کاری نیست

  • رابط‌های کاملاً ساده و مینیمال که هیچ بافت یا حرکت تزئینی نمی‌خواهند
  • پروژه‌هایی که به شبیه‌سازی فیزیکی دقیق مواد یا رندر سه‌بعدی نیاز دارند
  • افکت‌هایی که بدون بهینه‌سازی می‌توانند روی دستگاه‌های ضعیف هزینه پردازشی زیادی ایجاد کنند

دربارهٔ این اسکیل

Texture

Animated textures for organic and stylized visual effects.

Standards Reference

StandardDocumentation
W3C DTCGdesigntokens.org
SVG Filtersdeveloper.mozilla.org/SVG/Element/filter
CSS background-*developer.mozilla.org/CSS/background

Quick Reference

Load from: tokens/texture.tokens.json

Grain Parameters

TokenValueUse
grain.opacity.subtle0.05Barely visible
grain.opacity.medium0.15Film look
grain.size.fine1pxSmall particles
grain.speed.medium100msAnimated grain

Noise Parameters

TokenValueUse
noise.frequency.low0.01Large patterns
noise.frequency.high0.1Fine detail
noise.amplitude.medium15pxDisplacement

Selection Guide

What texture effect?
│
├── FILM GRAIN → Photographic texture
│   ├── Subtle → grain.opacity.subtle + size.fine
│   ├── Vintage → grain.opacity.medium + size.medium
│   └── High ISO → grain.opacity.heavy + size.coarse
│
├── PROCEDURAL NOISE → Organic movement
│   ├── Gentle → noise.amplitude.subtle + frequency.low
│   ├── Active → noise.amplitude.medium + frequency.medium
│   └── Chaotic → noise.amplitude.strong + frequency.high
│
├── PATTERN → Background animation
│   ├── Ambient → pattern.scroll-speed.slow
│   ├── Active → pattern.scroll-speed.medium
│   └── Dynamic → pattern.scroll-speed.fast
│
└── SURFACE → Material simulation
    ├── Polished → surface.roughness.polished
    ├── Matte → surface.roughness.matte
    └── Rough → surface.roughness.rough

Patterns

Animated Film Grain

CSS + Canvas:

class GrainEffect {
  constructor(canvas, options = {}) {
    this.canvas = canvas;
    this.ctx = canvas.getContext('2d');
    this.opacity = options.opacity || 0.15; // {motion.texture.grain.opacity.medium}
    this.size = options.size || 2; // {motion.texture.grain.size.medium}
    this.speed = options.speed || 100; // {motion.texture.grain.speed.medium}

    this.animate();
  }

  generateGrain() {
    const { width, height } = this.canvas;
    const imageData = this.ctx.createImageData(width, height);
    const data = imageData.data;

    for (let i = 0; i < data.length; i += 4) {
      const value = Math.random() * 255;
      data[i] = value;     // R
      data[i + 1] = value; // G
      data[i + 2] = value; // B
      data[i + 3] = this.opacity * 255; // A
    }

    this.ctx.putImageData(imageData, 0, 0);
  }

  animate() {
    this.generateGrain();
    setTimeout(() => this.animate(), this.speed);
  }
}

CSS Overlay:

.grain-overlay {
  position: absolute;
  inset: 0;
  background-image: url('grain.png');
  opacity: 0.15; /* {motion.texture.grain.opacity.medium} */
  pointer-events: none;
  animation: grainShift 100ms steps(4) infinite;
}

@keyframes grainShift {
  0% { transform: translate(0, 0); }
  25% { transform: translate(-2%, 2%); }
  50% { transform: translate(2%, -2%); }
  75% { transform: translate(-2%, -2%); }
  100% { transform: translate(2%, 2%); }
}

SVG Noise Displacement

SVG + CSS:

<svg style="position: absolute; width: 0; height: 0;">
  <defs>
    <filter id="noise-displacement">
      <feTurbulence
        type="fractalNoise"
        baseFrequency="0.05"
        numOctaves="3"
        result="noise"
      >
        <animate
          attributeName="baseFrequency"
          dur="10s"
          values="0.05;0.06;0.05"
          repeatCount="indefinite"
        />
      </feTurbulence>
      <feDisplacementMap
        in="SourceGraphic"
        in2="noise"
        scale="15"
        xChannelSelector="R"
        yChannelSelector="G"
      />
    </filter>
  </defs>
</svg>

<style>
  .noisy-element {
    filter: url(#noise-displacement);
  }
</style>

Scrolling Pattern Background

CSS:

.pattern-scroll {
  background-image: url('pattern.svg');
  background-size: 100px 100px;
  animation: patternScroll 15s linear infinite;
  /* {motion.texture.pattern.scroll-speed.medium} */
}

@keyframes patternScroll {
  from {
    background-position: 0 0;
  }
  to {
    background-position: 100px 100px;
  }
}

/* Diagonal scroll */
.pattern-diagonal {
  animation: patternDiagonal 15s linear infinite;
}

@keyframes patternDiagonal {
  from {
    background-position: 0 0;
  }
  to {
    background-position: 200px 100px;
  }
}

Metallic Shimmer

CSS:

.shimmer {
  background: linear-gradient(
    90deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,0.3) 50%,
    rgba(255,255,255,0) 100%
  );
  background-size: 200% 100%;
  animation: shimmer 2s ease-in-out infinite;
}

@keyframes shimmer {
  0% { background-position: -100% 0; }
  100% { background-position: 100% 0; }
}

Framer Motion:

const ShimmerEffect = () => (
  <motion.div
    style={{
      background: 'linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.3) 50%, transparent 100%)',
      backgroundSize: '200% 100%'
    }}
    animate={{ backgroundPosition: ['200% 0', '-200% 0'] }}
    transition={{ duration: 2, repeat: Infinity, ease: 'easeInOut' }}
  />
);

Reduced Motion

For prefers-reduced-motion: reduce:

Full MotionReduced Alternative
Animated grainStatic grain overlay
Noise displacementStatic or disabled
Scrolling patternFixed pattern
ShimmerStatic highlight

Implementation:

@media (prefers-reduced-motion: reduce) {
  .grain-overlay,
  .pattern-scroll,
  .shimmer {
    animation: none;
  }

  .noisy-element {
    filter: none;
  }
}

Cross-References

  • See stylization/ for artistic style presets
  • See particles/ for particle-based textures
  • See distortion/ for glitch textures
  • See color/ for color grading with texture
  • See cinematic/ for film grain in video

References

  • No additional references needed for this skill

دانلود ZIP