[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"github-stars":3,"guide-nav":5,"doc-\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields":129},{"stars":4},5505,[6,11,15,19,23,27,31,35,39,43,47,51,55,59,63,67,72,76,80,84,88,93,97,101,105,109,113,117,121,125],{"path":7,"title":8,"description":9,"category":10},"\u002Fdocs\u002Fguide","Getting started","Shaders is a library of GPU effect components for Vue, React, Svelte, Solid, JavaScript and Framer, with a design editor for building with them.","code",{"path":12,"title":13,"description":14,"category":10},"\u002Fdocs\u002Fguide\u002Fquickstart","Quickstart","Install Shaders, render your first effect, and drive a prop from state.",{"path":16,"title":17,"description":18,"category":10},"\u002Fdocs\u002Fguide\u002Fcomposing-effects","Composing effects","Stack components as layers and nest them to control which layers an effect touches.",{"path":20,"title":21,"description":22,"category":10},"\u002Fdocs\u002Fguide\u002Fblending-masking","Blending and masking","Control how a layer mixes with the layers below it, and reveal one layer through another.",{"path":24,"title":25,"description":26,"category":10},"\u002Fdocs\u002Fguide\u002Fprops-reactivity","Props and reactivity","Bind props to your framework's state so effects update when it changes, and animate props with an animation library.",{"path":28,"title":29,"description":30,"category":10},"\u002Fdocs\u002Fguide\u002Fdynamic-props","Dynamic props","Drive any numeric or position prop from time, the cursor, or another layer, without writing animation code.",{"path":32,"title":33,"description":34,"category":10},"\u002Fdocs\u002Fguide\u002Flayout-positioning","Layout and positioning","Size and place a shader in your page with CSS, as a background, a fill, or an inline block.",{"path":36,"title":37,"description":38,"category":10},"\u002Fdocs\u002Fguide\u002Fsizing-and-units","Sizing and units","Size and place layers in CSS units (px, %, vw, rem, and canvas units) that stay correct as the canvas and window resize.",{"path":40,"title":41,"description":42,"category":10},"\u002Fdocs\u002Fguide\u002Ftransforms","Transforms","Position, size, and rotate any layer inside the canvas with a bounding box, in any CSS unit.",{"path":44,"title":45,"description":46,"category":10},"\u002Fdocs\u002Fguide\u002Fshape-effects","Shape effects","Pick the 2D, 3D or custom SVG shape that Glass, Neon, Emboss and other shape effects draw inside.",{"path":48,"title":49,"description":50,"category":10},"\u002Fdocs\u002Fguide\u002Fcolor-space","Color space","Match colors to your design tool with the output color space, and keep bright layers from clipping with tone mapping.",{"path":52,"title":53,"description":54,"category":10},"\u002Fdocs\u002Fguide\u002Fhooks-events","Hooks and events","Run code when an effect is ready to show, and show a fallback when the GPU can't run it.",{"path":56,"title":57,"description":58,"category":10},"\u002Fdocs\u002Fguide\u002Fperformance","Performance","Learn what makes an effect expensive on the GPU and how to keep it inside the frame budget.",{"path":60,"title":61,"description":62,"category":10},"\u002Fdocs\u002Fguide\u002Fcustom-shaders","Custom components","Write your own component in TypeScript, use it like any component in the library, and write WGSL by hand when you need to.",{"path":64,"title":65,"description":66,"category":10},"\u002Fdocs\u002Fguide\u002Ftelemetry","Telemetry","The `\u003CShader>` component occasionally sends an anonymous performance report to help us improve the engine over time.",{"path":68,"title":69,"description":70,"category":71},"\u002Fdocs\u002Fguide\u002Fmcp","Shaders MCP","Connect your AI coding agent to Shaders so it can find, install and edit effects in your codebase.","workflows",{"path":73,"title":74,"description":75,"category":71},"\u002Fdocs\u002Fguide\u002Fcli","Shaders CLI","Install your own shaders and Pro shaders into your codebase as component files, and keep them in sync with the design editor.",{"path":77,"title":78,"description":79,"category":71},"\u002Fdocs\u002Fguide\u002Fagent-skill","Agent skill","Give your coding agent a skill that teaches it to build with Shaders components, the CLI and Pro shaders.",{"path":81,"title":82,"description":83,"category":10},"\u002Fdocs\u002Fguide\u002Fvideo-rendering","Rendering to video","Turn a shader effect into a video file, from the design editor or from a frame-by-frame pipeline such as Remotion, Hyperframes or Puppeteer.",{"path":85,"title":86,"description":87,"category":10},"\u002Fdocs\u002Fguide\u002Fssr","Server rendering","Render Shaders in Next.js, Nuxt, SvelteKit, SolidStart and other SSR apps by keeping each shader on the client.",{"path":89,"title":90,"description":91,"category":92},"\u002Fdocs\u002Fguide\u002Fquick-tour-of-the-design-editor","Quick tour of the design editor","A short walkthrough of the full Shaders workflow, from designing on the infinite canvas to exporting code.","editor",{"path":94,"title":95,"description":96,"category":92},"\u002Fdocs\u002Fguide\u002Fintro-to-the-interface","Intro to the interface","A tour of the design editor interface: the canvas, layers, the Properties panel, and the ways to share and export.",{"path":98,"title":99,"description":100,"category":92},"\u002Fdocs\u002Fguide\u002Fcomposing-your-first-shader-effect","Composing your first shader effect","Building a first shader effect in the design editor by stacking and nesting components as layers.",{"path":102,"title":103,"description":104,"category":92},"\u002Fdocs\u002Fguide\u002Fmasking-and-blending","Masking and blending","How blend modes and masks combine components in the design editor.",{"path":106,"title":107,"description":108,"category":92},"\u002Fdocs\u002Fguide\u002Fdynamic-prop-mapping","Dynamic prop mapping","Turning static props into dynamic ones in the design editor: mapping one layer's output into another's prop, following the cursor, or animating automatically.",{"path":110,"title":111,"description":112,"category":92},"\u002Fdocs\u002Fguide\u002Fcustom-media-and-transformations","Custom media and transformations","Uploading images, videos, and SVG files to the media gallery, adding them to a composition, and placing them with transformations.",{"path":114,"title":115,"description":116,"category":92},"\u002Fdocs\u002Fguide\u002Finstalling-a-shader-via-mcp","Installing a shader via MCP","Installing a shader from the design editor into a hero section with the Shaders MCP.",{"path":118,"title":119,"description":120,"category":92},"\u002Fdocs\u002Fguide\u002Fexploring-shape-effects","Exploring shape effects","Applying shape effects such as liquid glass, liquid metal, and glowing edges to built-in shapes and your own SVG.",{"path":122,"title":123,"description":124,"category":92},"\u002Fdocs\u002Fguide\u002Fglass-component-spotlight","Component spotlight: Glass","A short look at the Glass component and the liquid-glass look it creates.",{"path":126,"title":127,"description":128,"category":92},"\u002Fdocs\u002Fguide\u002Fdigital-looks-component-spotlight","Component spotlight: Digital looks","A look at the digital stylization components for glitchy, futuristic, or technical effects.",{"id":130,"title":131,"body":132,"categoryId":744,"categorySlug":745,"categoryTitle":746,"curated":323,"description":747,"editUrl":748,"extension":749,"group":750,"groupTitle":751,"kind":746,"meta":752,"navigation":323,"path":753,"seo":754,"sourceUrl":755,"stem":756,"wordCount":357,"__hash__":757},"primitives\u002Fdocs\u002Fprimitives\u002F35.effects-pointerfields\u002Findex.md","Pointer fields",{"type":133,"value":134,"toc":739},"minimark",[135,139,167,191,220,225,298,302,679,683,735],[136,137,131],"h1",{"id":138},"pointer-fields",[140,141,142,143,146,147,150,151,154,155,158,159,162,163,166],"p",{},"Push fields the pointer stirs. Each word is a whole simulation: a grid of cells, each holding\nhow far the layer inside should shift there, that the cursor pushes and that settles back on\nits own. Spread the word into a warp definition with ",[10,144,145],{},"...sim.grids.gridSim(word)"," and it\npublishes the field under its ",[10,148,149],{},"output"," name; the warp's ",[10,152,153],{},"map:"," then reads it with\n",[10,156,157],{},"warps.gridCellDisplace"," (per cell, blocky) or ",[10,160,161],{},"warps.liquidDisplace"," (smoothly, scaled by an\nintensity prop). The definition needs ",[10,164,165],{},"usesPointer: true",".",[140,168,169,176,177,183,184,190],{},[170,171,173],"a",{"href":172},"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields\u002Fpointersplatfield",[10,174,175],{},"pointerSplatField"," smears pixels along the cursor and lets them fade back; its grid size is a\nprop, so pair it with ",[170,178,180],{"href":179},"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields\u002Fclampsplatgridsize",[10,181,182],{},"clampSplatGridSize"," in a recompile rule. ",[170,185,187],{"href":186},"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields\u002Fspringlatticefield",[10,188,189],{},"springLatticeField"," is a cloth\nof springs on a fixed 64-cell grid that stretches, rings and settles like fabric. Both stop\ncomputing once the field has settled, and both give a displacement in uv.",[192,193,198],"pre",{"className":194,"code":195,"language":196,"meta":197,"style":197},"language-ts shiki shiki-themes github-dark","import {effects} from 'shaders\u002Fstd'\n","ts","",[10,199,200],{"__ignoreMap":197},[201,202,205,209,213,216],"span",{"class":203,"line":204},"line",1,[201,206,208],{"class":207},"snl16","import",[201,210,212],{"class":211},"s95oV"," {effects} ",[201,214,215],{"class":207},"from",[201,217,219],{"class":218},"sU2Wk"," 'shaders\u002Fstd'\n",[221,222,224],"h2",{"id":223},"reach-for-it-when","Reach for it when",[226,227,228,241],"table",{},[229,230,231],"thead",{},[232,233,234,238],"tr",{},[235,236,237],"th",{},"When you need",[235,239,240],{},"Use",[242,243,244,256,267,278],"tbody",{},[232,245,246,250],{},[247,248,249],"td",{},"a smear that follows the cursor and fades",[247,251,252],{},[170,253,254],{"href":172},[10,255,175],{},[232,257,258,261],{},[247,259,260],{},"fabric or liquid that ripples after a push",[247,262,263],{},[170,264,265],{"href":186},[10,266,189],{},[232,268,269,272],{},[247,270,271],{},"the grid-size prop's recompile rule",[247,273,274],{},[170,275,276],{"href":179},[10,277,182],{},[232,279,280,283],{},[247,281,282],{},"the range that rule holds the grid to",[247,284,285,291,292],{},[170,286,288],{"href":287},"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields\u002Fsplat-min-grid",[10,289,290],{},"SPLAT_MIN_GRID",", ",[170,293,295],{"href":294},"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields\u002Fsplat-max-grid",[10,296,297],{},"SPLAT_MAX_GRID",[221,299,301],{"id":300},"example","Example",[192,303,305],{"className":194,"code":304,"language":196,"meta":197,"style":197},"import {defineShader, p, effects, sim, warps, recompileWhen, transformEdges} from 'shaders\u002Fstd'\n\nconst {pointerSplatField, clampSplatGridSize} = effects.pointerFields\n\n\u002F\u002F Smear: the layer inside follows the cursor in coarse cells and eases back when it stops.\nexport const Smear = defineShader({\n  name: 'Smear',\n  usesPointer: true,\n  props: {\n    intensity: {default: 1},\n    decay: {default: 3},\n    radius: {default: 1},\n    \u002F\u002F Rebuild the simulation only when the cell count really changes, not on every slider step.\n    gridSize: {default: 20, recompile: recompileWhen((prev, next) => clampSplatGridSize(prev as number) !== clampSplatGridSize(next as number))},\n    edges: {default: 'stretch', transform: transformEdges, compileTime: true},\n  },\n  ...sim.grids.gridSim(pointerSplatField({\n    gridSize: p('gridSize'), decay: p('decay'), intensity: p('intensity'), radius: p('radius'),\n    output: 'displacement',\n  })),\n  map: warps.gridCellDisplace({gridSize: p('gridSize'), output: 'displacement'}),\n  \u002F\u002F Before the field exists (no GPU yet), the warp passes the layer through untouched.\n  uvRemapIdentityWhen: ({computeOutputs}) => !computeOutputs?.displacement,\n})\n",[10,306,307,318,325,350,355,362,384,396,407,413,425,436,446,452,514,530,536,555,601,612,618,644,650,673],{"__ignoreMap":197},[201,308,309,311,314,316],{"class":203,"line":204},[201,310,208],{"class":207},[201,312,313],{"class":211}," {defineShader, p, effects, sim, warps, recompileWhen, transformEdges} ",[201,315,215],{"class":207},[201,317,219],{"class":218},[201,319,321],{"class":203,"line":320},2,[201,322,324],{"emptyLinePlaceholder":323},true,"\n",[201,326,328,331,334,337,339,341,344,347],{"class":203,"line":327},3,[201,329,330],{"class":207},"const",[201,332,333],{"class":211}," {",[201,335,175],{"class":336},"sDLfK",[201,338,291],{"class":211},[201,340,182],{"class":336},[201,342,343],{"class":211},"} ",[201,345,346],{"class":207},"=",[201,348,349],{"class":211}," effects.pointerFields\n",[201,351,353],{"class":203,"line":352},4,[201,354,324],{"emptyLinePlaceholder":323},[201,356,358],{"class":203,"line":357},5,[201,359,361],{"class":360},"sAwPA","\u002F\u002F Smear: the layer inside follows the cursor in coarse cells and eases back when it stops.\n",[201,363,365,368,371,374,377,381],{"class":203,"line":364},6,[201,366,367],{"class":207},"export",[201,369,370],{"class":207}," const",[201,372,373],{"class":336}," Smear",[201,375,376],{"class":207}," =",[201,378,380],{"class":379},"svObZ"," defineShader",[201,382,383],{"class":211},"({\n",[201,385,387,390,393],{"class":203,"line":386},7,[201,388,389],{"class":211},"  name: ",[201,391,392],{"class":218},"'Smear'",[201,394,395],{"class":211},",\n",[201,397,399,402,405],{"class":203,"line":398},8,[201,400,401],{"class":211},"  usesPointer: ",[201,403,404],{"class":336},"true",[201,406,395],{"class":211},[201,408,410],{"class":203,"line":409},9,[201,411,412],{"class":211},"  props: {\n",[201,414,416,419,422],{"class":203,"line":415},10,[201,417,418],{"class":211},"    intensity: {default: ",[201,420,421],{"class":336},"1",[201,423,424],{"class":211},"},\n",[201,426,428,431,434],{"class":203,"line":427},11,[201,429,430],{"class":211},"    decay: {default: ",[201,432,433],{"class":336},"3",[201,435,424],{"class":211},[201,437,439,442,444],{"class":203,"line":438},12,[201,440,441],{"class":211},"    radius: {default: ",[201,443,421],{"class":336},[201,445,424],{"class":211},[201,447,449],{"class":203,"line":448},13,[201,450,451],{"class":360},"    \u002F\u002F Rebuild the simulation only when the cell count really changes, not on every slider step.\n",[201,453,455,458,461,464,467,470,474,476,479,482,485,488,491,494,497,499,502,504,507,509,511],{"class":203,"line":454},14,[201,456,457],{"class":211},"    gridSize: {default: ",[201,459,460],{"class":336},"20",[201,462,463],{"class":211},", recompile: ",[201,465,466],{"class":379},"recompileWhen",[201,468,469],{"class":211},"((",[201,471,473],{"class":472},"s9osk","prev",[201,475,291],{"class":211},[201,477,478],{"class":472},"next",[201,480,481],{"class":211},") ",[201,483,484],{"class":207},"=>",[201,486,487],{"class":379}," clampSplatGridSize",[201,489,490],{"class":211},"(prev ",[201,492,493],{"class":207},"as",[201,495,496],{"class":336}," number",[201,498,481],{"class":211},[201,500,501],{"class":207},"!==",[201,503,487],{"class":379},[201,505,506],{"class":211},"(next ",[201,508,493],{"class":207},[201,510,496],{"class":336},[201,512,513],{"class":211},"))},\n",[201,515,517,520,523,526,528],{"class":203,"line":516},15,[201,518,519],{"class":211},"    edges: {default: ",[201,521,522],{"class":218},"'stretch'",[201,524,525],{"class":211},", transform: transformEdges, compileTime: ",[201,527,404],{"class":336},[201,529,424],{"class":211},[201,531,533],{"class":203,"line":532},16,[201,534,535],{"class":211},"  },\n",[201,537,539,542,545,548,551,553],{"class":203,"line":538},17,[201,540,541],{"class":207},"  ...",[201,543,544],{"class":211},"sim.grids.",[201,546,547],{"class":379},"gridSim",[201,549,550],{"class":211},"(",[201,552,175],{"class":379},[201,554,383],{"class":211},[201,556,558,561,563,565,568,571,573,575,578,581,583,585,588,591,593,595,598],{"class":203,"line":557},18,[201,559,560],{"class":211},"    gridSize: ",[201,562,140],{"class":379},[201,564,550],{"class":211},[201,566,567],{"class":218},"'gridSize'",[201,569,570],{"class":211},"), decay: ",[201,572,140],{"class":379},[201,574,550],{"class":211},[201,576,577],{"class":218},"'decay'",[201,579,580],{"class":211},"), intensity: ",[201,582,140],{"class":379},[201,584,550],{"class":211},[201,586,587],{"class":218},"'intensity'",[201,589,590],{"class":211},"), radius: ",[201,592,140],{"class":379},[201,594,550],{"class":211},[201,596,597],{"class":218},"'radius'",[201,599,600],{"class":211},"),\n",[201,602,604,607,610],{"class":203,"line":603},19,[201,605,606],{"class":211},"    output: ",[201,608,609],{"class":218},"'displacement'",[201,611,395],{"class":211},[201,613,615],{"class":203,"line":614},20,[201,616,617],{"class":211},"  })),\n",[201,619,621,624,627,630,632,634,636,639,641],{"class":203,"line":620},21,[201,622,623],{"class":211},"  map: warps.",[201,625,626],{"class":379},"gridCellDisplace",[201,628,629],{"class":211},"({gridSize: ",[201,631,140],{"class":379},[201,633,550],{"class":211},[201,635,567],{"class":218},[201,637,638],{"class":211},"), output: ",[201,640,609],{"class":218},[201,642,643],{"class":211},"}),\n",[201,645,647],{"class":203,"line":646},22,[201,648,649],{"class":360},"  \u002F\u002F Before the field exists (no GPU yet), the warp passes the layer through untouched.\n",[201,651,653,656,659,662,665,667,670],{"class":203,"line":652},23,[201,654,655],{"class":379},"  uvRemapIdentityWhen",[201,657,658],{"class":211},": ({",[201,660,661],{"class":472},"computeOutputs",[201,663,664],{"class":211},"}) ",[201,666,484],{"class":207},[201,668,669],{"class":207}," !",[201,671,672],{"class":211},"computeOutputs?.displacement,\n",[201,674,676],{"class":203,"line":675},24,[201,677,678],{"class":211},"})\n",[221,680,682],{"id":681},"words","Words",[684,685,687],"primitive-words",{":words":686},"[{\"name\":\"pointerSplatField\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields\u002Fpointersplatfield\",\"summary\":\"A field the cursor smears: cells near the pointer move with it, then fade back to rest.\"},{\"name\":\"springLatticeField\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields\u002Fspringlatticefield\",\"summary\":\"A cloth of springs the cursor pushes: it stretches, rings and settles like fabric.\"},{\"name\":\"clampSplatGridSize\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields\u002Fclampsplatgridsize\",\"summary\":\"The grid size `pointerSplatField` really uses for a prop value: floored, then held to 8–128.\"},{\"name\":\"SPLAT_MIN_GRID\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields\u002Fsplat-min-grid\",\"summary\":\"The smallest grid `pointerSplatField` runs on: 8 cells per side.\"},{\"name\":\"SPLAT_MAX_GRID\",\"path\":\"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields\u002Fsplat-max-grid\",\"summary\":\"The largest grid `pointerSplatField` runs on: 128 cells per side.\"}]",[688,689,690,698,705,715,725],"ul",{},[691,692,693,697],"li",{},[170,694,695],{"href":172},[10,696,175],{}," — A field the cursor smears: cells near the pointer move with it, then fade back to rest.",[691,699,700,704],{},[170,701,702],{"href":186},[10,703,189],{}," — A cloth of springs the cursor pushes: it stretches, rings and settles like fabric.",[691,706,707,711,712,714],{},[170,708,709],{"href":179},[10,710,182],{}," — The grid size ",[10,713,175],{}," really uses for a prop value: floored, then held to 8–128.",[691,716,717,721,722,724],{},[170,718,719],{"href":287},[10,720,290],{}," — The smallest grid ",[10,723,175],{}," runs on: 8 cells per side.",[691,726,727,731,732,734],{},[170,728,729],{"href":294},[10,730,297],{}," — The largest grid ",[10,733,175],{}," runs on: 128 cells per side.",[736,737,738],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}",{"title":197,"searchDepth":320,"depth":320,"links":740},[741,742,743],{"id":223,"depth":320,"text":224},{"id":300,"depth":320,"text":301},{"id":681,"depth":320,"text":682},"effects.pointerFields","effects-pointerfields",null,"Push fields the pointer stirs.","https:\u002F\u002Fgithub.com\u002Fshader-effects-inc\u002Fshaders\u002Fedit\u002Fmain\u002Fpackages\u002Fcore\u002Fdocs\u002Fstd\u002Feffects.pointerFields.md","md","effects","Filters & effects",{},"\u002Fdocs\u002Fprimitives\u002Feffects-pointerfields",{"title":131,"description":747},"https:\u002F\u002Fgithub.com\u002Fshader-effects-inc\u002Fshaders\u002Fblob\u002Fmain\u002Fpackages\u002Fcore\u002Fsrc\u002Fstd\u002Feffects\u002FpointerFields.ts","docs\u002Fprimitives\u002F35.effects-pointerfields\u002Findex","DdCnR2d-D43ebGq02P5KkOFmYo55ZNK6RAQkrTQk0vU"]