基于 SOC 职业分类
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/shushuitie2017/design-agent-skills --skill webgl-laser命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
审计工作、用具体证据核验声明,并用五年级生也能懂的简单语言解释结果。当用户要求 review、审计、检查、核验、解释一处改动、解释一处修复、总结测试结果、验证某个东西是否有效,或把技术性发现翻译成给非技术读者看的大白话时使用。
当用户想为任何页面撰写、重写或改进营销文案时使用——包括首页、落地页、定价页、功能页、关于页或产品页。也在用户说"write copy for""improve this copy""rewrite this page""marketing copy""headline help""CTA copy""value proposition""tagline""subheadline""hero section copy""above the fold""this copy is weak""make this more compelling"或"help me describe my product"时使用。只要有人在处理需要说服或转化的网站文本,就用它。邮件文案见 email-sequence;弹窗文案见 popup-cro;编辑已有文案见 copy-editing。
仅起草的 Gmail 客户支持分诊,并为每封草稿创建对应的 Codex 项目线程。当用户要求运行客户邮件自动化、检查未读/最近的支持邮件、准备 Gmail 草稿回复、对客户/个人邮件分诊同时跳过自动化邮件,或为已起草邮件的跟进创建 agent/项目线程时使用。
| name | webgl-laser |
| description | 创建一个固定的全屏 WebGL 激光背景特效:一根极细的白热垂直核心、克制的品牌色光晕,以及环绕光束的柔和烟雾。仅用于激光背景特效,不用于整页布局、文案、通用主视觉场景、粒子或无关的动效系统。 |
pointer-events: none。<canvas class="laser-canvas" data-webgl-laser></canvas>
<main class="page-content">
...
</main>
.laser-canvas {
position: fixed;
inset: 0;
z-index: 0;
width: 100vw;
height: 100vh;
pointer-events: none;
}
.page-content {
position: relative;
z-index: 1;
}
用产品强调色作为源色。着色器让核心接近白色,并由该色推导出光晕/烟雾。
function hexToRgb01(hex) {
const clean = hex.replace("#", "").trim();
const value = clean.length === 3
? clean.split("").map((char) => char + char).join("")
: clean;
return [
parseInt(value.slice(0, 2), 16) / 255,
parseInt(value.slice(2, 4), 16) / 255,
parseInt(value.slice(4, 6), 16) / 255,
];
}
const accent = getComputedStyle(document.documentElement)
.getPropertyValue("--brand-accent")
.trim() || "#ff4d8d";
除非当前文件已使用其他渲染器,否则优先用带全屏四边形的原生 WebGL。
const laserVertexShader = `
attribute vec2 a_position;
varying vec2 v_uv;
void main() {
v_uv = a_position * 0.5 + 0.5;
gl_Position = vec4(a_position, 0.0, 1.0);
}
`;
const laserFragmentShader = `
precision highp float;
uniform vec2 u_resolution;
uniform float u_time;
uniform vec3 u_color;
uniform float u_xOffset;
uniform float u_coreWidth;
uniform float u_glowWidth;
uniform float u_smokeDensity;
varying vec2 v_uv;
float hash(vec2 p) {
p = fract(p * vec2(123.34, 456.21));
p += dot(p, p + 45.32);
return fract(p.x * p.y);
}
float noise(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
vec2 u = f * f * (3.0 - 2.0 * f);
float a = hash(i);
float b = hash(i + vec2(1.0, 0.0));
float c = hash(i + vec2(0.0, 1.0));
float d = hash(i + vec2(1.0, 1.0));
return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
}
float fbm(vec2 p) {
float value = 0.0;
float amplitude = 0.5;
for (int i = 0; i < 5; i++) {
value += amplitude * noise(p);
p *= 2.02;
amplitude *= 0.5;
}
return value;
}
void main() {
vec2 aspect = vec2(u_resolution.x / u_resolution.y, 1.0);
vec2 p = (v_uv - 0.5) * aspect;
float x = p.x - u_xOffset;
float distanceToBeam = abs(x);
float core = exp(-pow(distanceToBeam / u_coreWidth, 2.0));
float glow = exp(-pow(distanceToBeam / u_glowWidth, 1.45));
float scatter = exp(-pow(distanceToBeam / (u_glowWidth * 5.5), 1.25));
float pulse = 0.9 + 0.1 * sin(u_time * 1.15);
vec2 fogUv = p * 3.1 + vec2(0.0, -u_time * 0.035);
fogUv.x += sin(p.y * 3.5 + u_time * 0.11) * 0.14;
float fogBase = fbm(fogUv);
float fogFine = fbm(p * 8.0 + vec2(sin(u_time * 0.07) * 0.35, u_time * 0.05));
float fog = smoothstep(0.30, 0.86, fogBase * 0.72 + fogFine * 0.28);
float smoke = fog * scatter * u_smokeDensity;
vec3 brand = clamp(u_color, 0.0, 1.0);
vec3 haloColor = mix(brand, vec3(1.0), 0.16);
vec3 smokeColor = mix(brand, vec3(0.55), 0.28) * 0.55;
vec3 hotCore = vec3(1.0, 0.96, 0.90);
vec3 color = vec3(0.006, 0.007, 0.010);
color += smokeColor * smoke;
color += haloColor * glow * 0.46 * pulse;
color += hotCore * core * 1.35;
float vignette = smoothstep(1.25, 0.18, length(p));
color *= vignette;
float alpha = clamp(smoke * 0.72 + glow * 0.68 + core, 0.0, 1.0);
gl_FragColor = vec4(color, alpha);
}
`;
在 resize 时保持 u_resolution 同步,并通过 u_time 驱动动画。
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(shader) || "Shader compile failed");
}
return shader;
}
function createProgram(gl, vertexSource, fragmentSource) {
const program = gl.createProgram();
gl.attachShader(program, createShader(gl, gl.VERTEX_SHADER, vertexSource));
gl.attachShader(program, createShader(gl, gl.FRAGMENT_SHADER, fragmentSource));
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error(gl.getProgramInfoLog(program) || "Program link failed");
}
return program;
}
function initWebGLLaser(canvas, options = {}) {
if (!canvas) return () => {};
const gl = canvas.getContext(, {
: ,
: ,
: ,
});
(!gl) {};
program = (gl, laserVertexShader, laserFragmentShader);
positionBuffer = gl.();
positions = ([
-, -,
, -,
-, ,
-, ,
, -,
, ,
]);
gl.(gl., positionBuffer);
gl.(gl., positions, gl.);
gl.(program);
positionLocation = gl.(program, );
uniforms = {
: gl.(program, ),
: gl.(program, ),
: gl.(program, ),
: gl.(program, ),
: gl.(program, ),
: gl.(program, ),
: gl.(program, ),
};
gl.(positionLocation);
gl.(positionLocation, , gl., , , );
gl.(gl.);
gl.(gl., gl.);
color = options. || (accent);
reduceMotion = .().;
width = ;
height = ;
rafId = ;
() {
dpr = .(. || , options. || );
width = .(, .);
height = .(, .);
canvas. = .(width * dpr);
canvas. = .(height * dpr);
gl.(, , canvas., canvas.);
}
() {
gl.(program);
gl.(uniforms., canvas., canvas.);
gl.(uniforms., time * );
gl.(uniforms., color[], color[], color[]);
gl.(uniforms., options. || );
gl.(uniforms., options. || );
gl.(uniforms., options. || );
gl.(uniforms., options. || );
gl.(, , , );
gl.(gl.);
gl.(gl., , );
(!reduceMotion) rafId = (render);
}
() {
();
();
}
();
();
.(, handleResize);
{
(rafId);
.(, handleResize);
gl.(positionBuffer);
gl.(program);
};
}
cleanupLaser = (.(), {
: (accent),
: ,
: ,
: ,
: ,
: ,
});
xOffset;保持在保持宽高比的居中 UV 空间内。coreWidth 与 glowWidth 分开调;让核心极细。color,再在着色器里柔化光晕与烟雾。smokeDensity、FBM 缩放、漂移速度、散射宽度与边缘衰减。maxDpr,再改动视觉结构。