{"version":3,"file":"parts.mjs","names":[],"sources":["../../../../package/common/weatherIcon/parts.tsx"],"sourcesContent":["import type { CSSProperties, ReactElement } from 'react';\nimport cx from 'classnames';\n\nimport type { WeatherPartProps } from './weatherIcon.types';\nimport styles from './weatherIcon.module.pcss';\n\n/** Exported so a scene can clip what sits behind the cloud to this same silhouette. */\nexport const CLOUD_PATH =\n  'M 26.3 62.9 C 15.4 65.0 15.0 48.5 27.8 49.8 C 23.9 43.9 34.2 34.0 43.0 39.6 C 46.0 26.2 73.9 32.0 68.9 46.3 C 85.0 44.3 84.6 64.2 72.4 62.5 Z';\n\n/**\n * A still frame of a falling part must not be its first one, which bunches every drop right under\n * the cloud. A negative delay on a paused animation freezes it that far into its cycle. The\n * fractions come from a jitter table rather than a ramp: lanes run left to right, so a ramp would\n * freeze them along one diagonal line.\n */\nfunction fallStyle(animated: boolean, duration: number, delay: number, freezeFraction: number): CSSProperties {\n  return {\n    animationDuration: `${duration}s`,\n    animationDelay: `${animated ? delay : -freezeFraction * duration}s`,\n  };\n}\n\nexport function Cloud({ className, delayed = false }: { className?: string; delayed?: boolean }): ReactElement {\n  return (\n    <path\n      className={cx(styles.weatherIconCloud, delayed && styles.weatherIconCloudDelayed, className)}\n      d={CLOUD_PATH}\n    />\n  );\n}\n\nconst RAY_COUNT = 12;\n\nexport function Sun({ className }: { className?: string }): ReactElement {\n  return (\n    <g className={className}>\n      <g className={styles.weatherIconSunRays}>\n        {Array.from({ length: RAY_COUNT }, (_, index) => (\n          <g key={index} transform={`rotate(${(index / RAY_COUNT) * 360} 50 50)`}>\n            {/* Every second ray reaches further. */}\n            <line className={styles.weatherIconSunRay} x1={50} y1={23} x2={50} y2={index % 2 === 0 ? 16 : 11} />\n          </g>\n        ))}\n      </g>\n      <circle className={styles.weatherIconSunCore} cx={50} cy={50} r={18} />\n    </g>\n  );\n}\n\n// Scattered at uneven distances as well as angles: at one distance they read as a ring.\nconst STARS = [\n  { x: 74, y: 32, size: 2.2, duration: 2.4, delay: 0 },\n  { x: 28, y: 30, size: 2.6, duration: 3.1, delay: 0.4 },\n  { x: 80, y: 60, size: 1.8, duration: 2.7, delay: 0.9 },\n  { x: 22, y: 66, size: 2.4, duration: 3.6, delay: 0.2 },\n  { x: 58, y: 82, size: 2, duration: 2.9, delay: 1.3 },\n  { x: 34, y: 80, size: 2.5, duration: 3.3, delay: 0.6 },\n];\n\nexport function Moon({ className }: { className?: string }): ReactElement {\n  return (\n    <g className={className}>\n      {STARS.map((star) => (\n        // The position sits on its own group: an animated `transform` would replace a static one.\n        <g key={`${star.x}-${star.y}`} transform={`translate(${star.x}, ${star.y})`}>\n          <g\n            className={styles.weatherIconStar}\n            style={{ animationDuration: `${star.duration}s`, animationDelay: `${star.delay}s` }}\n          >\n            <path d={`M 0 ${-star.size} L 0 ${star.size} M ${-star.size} 0 L ${star.size} 0`} />\n          </g>\n        </g>\n      ))}\n      <circle className={styles.weatherIconMoonCore} cx={50} cy={50} r={18} />\n    </g>\n  );\n}\n\nexport enum RainIntensity {\n  Light = 'light',\n  Medium = 'medium',\n  Heavy = 'heavy',\n}\n\n// Density and speed rise together: speed alone reads as light rain on fast-forward.\nconst RAIN = {\n  [RainIntensity.Light]: { lanes: 4, duration: 1.5 },\n  [RainIntensity.Medium]: { lanes: 6, duration: 0.95 },\n  [RainIntensity.Heavy]: { lanes: 10, duration: 0.55 },\n};\n\nconst DURATION_JITTER = [0.85, 1.1, 0.95, 1.2, 0.9, 1.05, 1.15, 0.8, 1, 1.08];\nconst DELAY_JITTER = [0.05, 0.62, 0.31, 0.85, 0.18, 0.5, 0.74, 0.1, 0.43, 0.95];\nconst PER_LANE = 2;\n// A drop fades out from 80% of its fall, so a still frame keeps every drop short of that.\nconst RAIN_FREEZE_SPAN = 0.65;\n\nfunction freezeAt(index: number, jitter: number[] = DELAY_JITTER, span = 0.8): number {\n  return 0.1 + span * jitter[index % jitter.length];\n}\n\nexport function Rain({\n  animated,\n  intensity = RainIntensity.Medium,\n}: WeatherPartProps & { intensity?: RainIntensity }): ReactElement {\n  const { lanes, duration: base } = RAIN[intensity];\n  return (\n    <g className={styles.weatherIconRain}>\n      {Array.from({ length: lanes }, (_, lane) => {\n        const x1 = 26 + (50 * lane) / (lanes - 1);\n        const duration = base * DURATION_JITTER[lane];\n        const delay = duration * DELAY_JITTER[lane];\n        return Array.from({ length: PER_LANE }, (_, drop) => {\n          const style = fallStyle(\n            animated,\n            duration,\n            delay + (drop * duration) / PER_LANE,\n            freezeAt(lane * PER_LANE + drop, DELAY_JITTER, RAIN_FREEZE_SPAN),\n          );\n          return (\n            <g key={`${lane}-${drop}`}>\n              <line className={styles.weatherIconDrop} style={style} x1={x1} y1={68} x2={x1 - 2.4} y2={92} />\n              <ellipse className={styles.weatherIconSplash} style={style} cx={x1 - 2.4} cy={92} rx='1.4' ry='0.7' />\n            </g>\n          );\n        });\n      })}\n    </g>\n  );\n}\n\n// A wide spread of speeds: with similar ones, flakes drift out of step so slowly that they spend\n// long stretches falling in a line.\nconst FLAKE_DURATION_JITTER = [0.65, 1.5, 0.85, 1.25, 1.65, 0.75, 1.1];\nconst FLAKE_DELAY_JITTER = [0.15, 0.7, 0.35, 0.9, 0.05, 0.55, 0.8];\nconst FLAKE_LANES = 7;\n\nexport function Snow({ animated }: WeatherPartProps): ReactElement {\n  return (\n    <g className={styles.weatherIconSnow}>\n      {Array.from({ length: FLAKE_LANES }, (_, lane) => {\n        const x = 24 + (54 * lane) / (FLAKE_LANES - 1);\n        const duration = 7 * FLAKE_DURATION_JITTER[lane];\n        const delay = duration * FLAKE_DELAY_JITTER[lane];\n        return Array.from({ length: PER_LANE }, (_, flake) => (\n          <g key={`${lane}-${flake}`} transform={`translate(${x}, 68)`}>\n            <g\n              className={styles.weatherIconFlake}\n              style={fallStyle(\n                animated,\n                duration,\n                delay + flake * duration * 0.7,\n                freezeAt(lane * PER_LANE + flake, FLAKE_DELAY_JITTER),\n              )}\n            >\n              <path d='M 0 -2 L 0 2 M -1.7 -1 L 1.7 1 M -1.7 1 L 1.7 -1' />\n            </g>\n          </g>\n        ));\n      })}\n    </g>\n  );\n}\n\n// `dx`/`dy` is where the stone first lands. The keyframe bounces it on from there, so every lane\n// shares one keyframe instead of having its own.\nconst HAIL_LANES = [\n  { x: 34, y: 66, dx: -1, dy: 18, duration: 0.6, delay: 0.05 },\n  { x: 47, y: 68, dx: -2, dy: 17, duration: 0.7, delay: 0.3 },\n  { x: 58, y: 65, dx: 1, dy: 18, duration: 0.55, delay: 0.15 },\n  { x: 40, y: 70, dx: -1, dy: 16, duration: 0.75, delay: 0.45 },\n  { x: 65, y: 67, dx: -2, dy: 17, duration: 0.65, delay: 0 },\n  { x: 52, y: 71, dx: 1, dy: 16, duration: 0.7, delay: 0.35 },\n];\n\nexport function Hail({ animated }: WeatherPartProps): ReactElement {\n  const total = HAIL_LANES.length * PER_LANE;\n  return (\n    <g className={styles.weatherIconHail}>\n      {HAIL_LANES.flatMap((lane, laneIndex) =>\n        Array.from({ length: PER_LANE }, (_, stone) => {\n          const index = laneIndex * PER_LANE + stone;\n          const style = fallStyle(\n            animated,\n            lane.duration,\n            lane.delay + (stone * lane.duration) / PER_LANE,\n            0.1 + (0.8 * (index + 0.5)) / total,\n          );\n          return (\n            <g key={index}>\n              <g transform={`translate(${lane.x}, ${lane.y})`}>\n                <g\n                  className={styles.weatherIconStone}\n                  style={{ ...style, '--weather-icon-dx': lane.dx, '--weather-icon-dy': lane.dy } as CSSProperties}\n                >\n                  <circle r='2' />\n                </g>\n              </g>\n              <ellipse\n                className={styles.weatherIconImpact}\n                style={style}\n                cx={lane.x + lane.dx}\n                cy={lane.y + lane.dy}\n                rx='1.8'\n                ry='0.9'\n              />\n            </g>\n          );\n        }),\n      )}\n    </g>\n  );\n}\n\nexport function Fog(): ReactElement {\n  return (\n    <g className={styles.weatherIconFog}>\n      <line x1='32' y1='40' x2='68' y2='40' />\n      <line x1='20' y1='52' x2='80' y2='52' />\n      <line x1='26' y1='64' x2='74' y2='64' />\n      <line x1='34' y1='76' x2='66' y2='76' />\n    </g>\n  );\n}\n\nexport function Lightning(): ReactElement {\n  return <path className={styles.weatherIconBolt} d='M 54 52 L 44 72 H 52 L 46 90 L 62 66 H 54 L 60 52 Z' />;\n}\n"],"mappings":"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"}