import React, { useState } from 'react'; import { SnowDriftDiagram } from '../diagrams/SnowDriftDiagram'; export const SnowLoadsSheet: React.FC = () => { // Basic Inputs const [inputs, setInputs] = useState({ slopeDeg: 0.4, width: 11.9, length: 50.4, roofType: 'Hip and gable w/ trussed systems', Pg: 21.0, risk: 'III', snowFactor: 1.0, R: 35, Ct: 1.1, // Thermal factor input (1.0, 1.1, 1.2, etc.) Ce: 1.0, // Exposure factor input userInputCs: 1.0, // Override userInputPf: 0, // Not used directly if we calc it rainSurcharge: false, }); // Unbalanced Inputs const [unbalanced, setUnbalanced] = useState({ W2: 0.35, required: false, }); // Drift Inputs 1 const [drift1, setDrift1] = useState({ lu: 78.0, h: 5.0, lp: 121.0, }); // Drift Inputs 2 const [drift2, setDrift2] = useState({ lu: 0.0, h: 0.0, lp: 0.0, }); // Constants / Derived const Is = inputs.risk === 'I' ? 0.8 : inputs.risk === 'II' ? 1.0 : inputs.risk === 'III' ? 1.1 : 1.2; const snowDensity = Math.min(30, 0.13 * inputs.Pg + 14); // Gamma = 0.13Pg + 14 (ASCE 7-22 approx) // Calc Pf // Pf = 0.7 * Ce * Ct * Is * Pg const Pf = 0.7 * inputs.Ce * inputs.Ct * Is * inputs.Pg; // Calc Cs (Slope Factor) - simplified placeholder logic const Cs = inputs.userInputCs; // Sloped Roof Load Ps const Ps = Cs * Pf; // Rain on Snow const rainSurchargeLoad = inputs.rainSurcharge ? 5.0 : 0.0; // Minimum Snow Load Pm // Pg <= 20: Pm = Is * Pg. Pg > 20: Pm = Is * 20. const Pm = inputs.Pg <= 20 ? Is * inputs.Pg : Is * 20; // Design Snow Load (Uniform) const designLoad = Math.max(Ps + rainSurchargeLoad, Pm); // --- Drift Calculation Helper --- // hd = 0.43 * lu^(1/3) * (pg + 10)^(1/4) - 1.5 const calculateDrift = (lu: number, h: number, lp: number) => { if (lu <= 0) return { hd: 0, w: 0, pd: 0, hc: 0, hb: 0, driftReq: false, msg: '' }; const hb = Pf / snowDensity; // drift height hd const hd_calc = 0.43 * Math.pow(lu, 1 / 3) * Math.pow(inputs.Pg + 10, 0.25) - 1.5; const hd = Math.max(0, hd_calc); // hc = h - hb const hc = h - hb; // Check if drift required: hc/hb > 0.2 const ratio = hb > 0 ? hc / hb : 100; // safe fallback let driftReq = true; let msg = ''; if (ratio < 0.2) { driftReq = false; msg = `hc/hb < 0.2 (${ratio.toFixed(2)})`; } if (lp < 15 && lp > 0) { driftReq = false; msg = `lp < 15', drift not req'd`; } if (hc <= 0) { driftReq = false; msg = 'hc <= 0'; } // Actual drift height limited by hc const design_hd = Math.min(hd, hc); // Drift width w = 4 * hd const w = 4 * design_hd; // Surcharge pd = gamma * hd const pd = snowDensity * design_hd; return { hd: design_hd, w, pd, hc, hb, driftReq, msg }; }; const d1Results = calculateDrift(drift1.lu, drift1.h, drift1.lp); const d2Results = calculateDrift(drift2.lu, drift2.h, drift2.lp); return (

Snow Loads: ASCE 7-22

Ultimate Snow Forces
{/* Main Inputs Grid */}
{/* Row 1: Slope, W, L */}
Roof slope = setInputs({ ...inputs, slopeDeg: parseFloat(e.target.value) })} style={{ width: '60px' }} /> deg
Horiz. eave to ridge dist (W) = setInputs({ ...inputs, width: parseFloat(e.target.value) })} style={{ width: '60px' }} /> ft
Roof length parallel to ridge (L) = setInputs({ ...inputs, length: parseFloat(e.target.value) })} style={{ width: '60px' }} /> ft
Type of Roof
Ground Snow Load Pg =
setInputs({ ...inputs, Pg: parseFloat(e.target.value) })} style={{ width: '60px', color: 'red' }} /> psf
Risk Category =
Roof R value Rroof =
setInputs({ ...inputs, R: parseFloat(e.target.value) })} style={{ width: '60px', border: '1px solid green' }} />
Thermal Factor Ct =
setInputs({ ...inputs, Ct: parseFloat(e.target.value) })} style={{ width: '60px', color: 'red' }} />
Exposure Factor Ce =
setInputs({ ...inputs, Ce: parseFloat(e.target.value) })} style={{ width: '60px', color: 'red' }} />
Pf = 0.7*Ce*Ct*I*Pg
= {Pf.toFixed(1)} psf
Sloped-roof Factor Cs =
setInputs({ ...inputs, userInputCs: parseFloat(e.target.value) })} style={{ width: '60px', background: '#e0f7fa' }} />
Balanced Snow Load =
{Ps.toFixed(1)} psf
Rain on Snow Surcharge Angle
0.24 deg
Rain on Snow Surcharge =
{rainSurchargeLoad.toFixed(1)} psf
Minimum Snow Load Pm =
{Pm.toFixed(1)} psf
Uniform Roof Design Snow Load =
{designLoad.toFixed(1)} psf
{/* Right Panel - Info */}
Snow load tools
asce7hazardtool.online
hazards.atcouncil.org
Exposure Factor, Ce
{/* Placeholder Table */}
Refer to ASCE 7 Table 7.3-1
{/* Unbalanced Snow Loads */}

Unbalanced Snow Loads - for Hip & Gable roofs only

Winter Wind Parameter W2 = setUnbalanced({ ...unbalanced, W2: parseFloat(e.target.value) })} style={{ width: '60px', color: 'red' }} />
Required if slope is between 7 on 12 = 30.26 deg
and 2.38 deg
Unbalanced snow loads {inputs.slopeDeg > 2.38 && inputs.slopeDeg < 30.26 ? "ARE required" : "are not required"}
Windward snow load = {Ps.toFixed(1)} psf
Leeward snow load = {(Ps + d1Results.pd).toFixed(1)} psf (Placeholder calc)
{/* Snow Drift 1 */}

Snow Drift 1 - Against roof projections, parapets, etc

Up or downwind fetch lu =
setDrift1({ ...drift1, lu: parseFloat(e.target.value) })} style={{ color: 'red' }} />
ft
Projection height h =
setDrift1({ ...drift1, h: parseFloat(e.target.value) })} style={{ color: 'red' }} />
ft
Projection width/length lp =
setDrift1({ ...drift1, lp: parseFloat(e.target.value) })} style={{ color: 'red' }} />
ft
Snow density gamma = {snowDensity.toFixed(1)} pcf
Balanced snow height hb = {d1Results.hb.toFixed(2)} ft
Drift height hd = {d1Results.hd.toFixed(2)} ft
Clear height hc = {d1Results.hc.toFixed(2)} ft
{d1Results.driftReq ? "Therefore, design for drift" : d1Results.msg || "Drift not required"}
Drift width w = {d1Results.w.toFixed(2)} ft
Surcharge load pd = {d1Results.pd.toFixed(1)} psf
Balanced Snow load = {Pf.toFixed(1)} psf
Total = {(d1Results.pd + Pf).toFixed(1)} psf
{/* Diagram for Drift 1 */}
{/* Snow Drift 2 */}

Snow Drift 2 - Against roof projections, parapets, etc

{/* Similar to Drift 1 */}
Up or downwind fetch lu =
setDrift2({ ...drift2, lu: parseFloat(e.target.value) })} style={{ color: 'red' }} />
ft
Projection height h =
setDrift2({ ...drift2, h: parseFloat(e.target.value) })} style={{ color: 'red' }} />
ft
Projection width/length lp =
setDrift2({ ...drift2, lp: parseFloat(e.target.value) })} style={{ color: 'red' }} />
ft
Snow density gamma = {snowDensity.toFixed(1)} pcf
Balanced snow height hb = {d2Results.hb.toFixed(2)} ft
Drift height hd = {d2Results.hd.toFixed(2)} ft
Clear height hc = {d2Results.hc.toFixed(2)} ft
{d2Results.driftReq ? "Therefore, design for drift" : d2Results.msg || "Drift not required"}
Drift width w = {d2Results.w.toFixed(2)} ft
Surcharge load pd = {d2Results.pd.toFixed(1)} psf
Balanced Snow load = {Pf.toFixed(1)} psf
Total = {(d2Results.pd + Pf).toFixed(1)} psf
); };