All files / src/components/VirtualWalkthrough GradientSky.tsx

0% Statements 0/37
0% Branches 0/12
0% Functions 0/4
0% Lines 0/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89                                                                                                                                                                                 
import React, { useEffect, useMemo } from 'react';
 
import { Entity } from '@playcanvas/react';
import { Render } from '@playcanvas/react/components';
import { useApp } from '@playcanvas/react/hooks';
import { Color, PIXELFORMAT_RGBA8, StandardMaterial, Texture } from 'playcanvas';
 
interface GradientSkyProps {
  topColor?: string;
  horizonColor?: string;
  groundColor?: string;
  resolution?: number;
}
 
const GradientSky = ({
  topColor = '#1e90ff',
  horizonColor = '#87ceeb',
  groundColor = '#8b7355',
  resolution = 512,
}: GradientSkyProps) => {
  const app = useApp();
 
  const material = useMemo(() => {
    if (!app) {
      return null;
    }
 
    const canvas = document.createElement('canvas');
    canvas.width = resolution;
    canvas.height = resolution;
    const ctx = canvas.getContext('2d');
 
    if (!ctx) {
      return null;
    }
 
    const gradient = ctx.createLinearGradient(0, 0, 0, resolution);
    gradient.addColorStop(0, topColor);
    gradient.addColorStop(0.5, horizonColor);
    gradient.addColorStop(0.5, groundColor);
    gradient.addColorStop(1, groundColor);
 
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, resolution, resolution);
 
    const texture = new Texture(app.graphicsDevice, {
      width: resolution,
      height: resolution,
      format: PIXELFORMAT_RGBA8,
      mipmaps: false,
    });
 
    const pixels = ctx.getImageData(0, 0, resolution, resolution);
    texture.lock().set(new Uint8Array(pixels.data));
    texture.unlock();
 
    const mat = new StandardMaterial();
    mat.emissiveMap = texture;
    mat.emissive = new Color(1, 1, 1);
    mat.useLighting = false;
    mat.cull = 0;
    mat.depthWrite = false;
    mat.update();
 
    return mat;
  }, [app, topColor, horizonColor, groundColor, resolution]);
 
  useEffect(() => {
    // remove material to avoid memory leak
    return () => {
      if (material) {
        material.destroy();
      }
    };
  }, [material]);
 
  if (!material) {
    return null;
  }
 
  return (
    <Entity name='gradient-sky' position={[0, 0, 0]} scale={[500, 500, 500]}>
      <Render type='sphere' material={material} castShadows={false} receiveShadows={false} />
    </Entity>
  );
};
 
export default GradientSky;