[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"github-stars":3,"guide-nav":5,"doc-\u002Fdocs\u002Fguide\u002Fsizing-and-units":129},{"stars":4},5276,[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":37,"body":131,"category":10,"description":38,"extension":1801,"icon":1802,"meta":1803,"navigation":1805,"path":36,"seo":1806,"stem":1807,"__hash__":1808},"guide\u002Fdocs\u002Fguide\u002F07.sizing-and-units.md",{"type":132,"value":133,"toc":1789},"minimark",[134,138,141,144,467,470,475,483,513,524,545,552,556,559,694,716,731,735,742,778,781,784,840,843,849,866,892,923,927,947,1216,1229,1264,1268,1285,1652,1659,1663,1673,1686,1690,1696,1702,1747,1753,1764,1768,1785],[135,136,37],"h1",{"id":137},"sizing-and-units",[139,140,38],"p",{},[139,142,143],{},"A shape takes the same lengths you'd write in CSS:",[145,146,148,230,288,342,394],"code-group",{":tabs":147},"[\"Vue\", \"React\", \"Svelte\", \"Solid\", \"JS\"]",[149,150,155],"pre",{"className":151,"code":152,"language":153,"meta":154,"style":154},"language-vue-html shiki shiki-themes github-dark","\u003CShader class=\"w-full h-96\">\n  \u003CRoundedRect width=\"50%\" height=\"12rem\" rounding=\"24px\" \u002F>\n\u003C\u002FShader>\n","vue-html","",[10,156,157,184,220],{"__ignoreMap":154},[158,159,162,166,170,174,177,181],"span",{"class":160,"line":161},"line",1,[158,163,165],{"class":164},"s95oV","\u003C",[158,167,169],{"class":168},"s4JwU","Shader",[158,171,173],{"class":172},"svObZ"," class",[158,175,176],{"class":164},"=",[158,178,180],{"class":179},"sU2Wk","\"w-full h-96\"",[158,182,183],{"class":164},">\n",[158,185,187,190,193,196,198,201,204,206,209,212,214,217],{"class":160,"line":186},2,[158,188,189],{"class":164},"  \u003C",[158,191,192],{"class":168},"RoundedRect",[158,194,195],{"class":172}," width",[158,197,176],{"class":164},[158,199,200],{"class":179},"\"50%\"",[158,202,203],{"class":172}," height",[158,205,176],{"class":164},[158,207,208],{"class":179},"\"12rem\"",[158,210,211],{"class":172}," rounding",[158,213,176],{"class":164},[158,215,216],{"class":179},"\"24px\"",[158,218,219],{"class":164}," \u002F>\n",[158,221,223,226,228],{"class":160,"line":222},3,[158,224,225],{"class":164},"\u003C\u002F",[158,227,169],{"class":168},[158,229,183],{"class":164},[149,231,235],{"className":232,"code":233,"language":234,"meta":154,"style":154},"language-jsx shiki shiki-themes github-dark","\u003CShader className=\"w-full h-96\">\n  \u003CRoundedRect width=\"50%\" height=\"12rem\" rounding=\"24px\" \u002F>\n\u003C\u002FShader>\n","jsx",[10,236,237,254,280],{"__ignoreMap":154},[158,238,239,241,244,247,250,252],{"class":160,"line":161},[158,240,165],{"class":164},[158,242,169],{"class":243},"sDLfK",[158,245,246],{"class":172}," className",[158,248,176],{"class":249},"snl16",[158,251,180],{"class":179},[158,253,183],{"class":164},[158,255,256,258,260,262,264,266,268,270,272,274,276,278],{"class":160,"line":186},[158,257,189],{"class":164},[158,259,192],{"class":243},[158,261,195],{"class":172},[158,263,176],{"class":249},[158,265,200],{"class":179},[158,267,203],{"class":172},[158,269,176],{"class":249},[158,271,208],{"class":179},[158,273,211],{"class":172},[158,275,176],{"class":249},[158,277,216],{"class":179},[158,279,219],{"class":164},[158,281,282,284,286],{"class":160,"line":222},[158,283,225],{"class":164},[158,285,169],{"class":243},[158,287,183],{"class":164},[149,289,292],{"className":290,"code":152,"language":291,"meta":154,"style":154},"language-tsx shiki shiki-themes github-dark","tsx",[10,293,294,308,334],{"__ignoreMap":154},[158,295,296,298,300,302,304,306],{"class":160,"line":161},[158,297,165],{"class":164},[158,299,169],{"class":243},[158,301,173],{"class":172},[158,303,176],{"class":249},[158,305,180],{"class":179},[158,307,183],{"class":164},[158,309,310,312,314,316,318,320,322,324,326,328,330,332],{"class":160,"line":186},[158,311,189],{"class":164},[158,313,192],{"class":243},[158,315,195],{"class":172},[158,317,176],{"class":249},[158,319,200],{"class":179},[158,321,203],{"class":172},[158,323,176],{"class":249},[158,325,208],{"class":179},[158,327,211],{"class":172},[158,329,176],{"class":249},[158,331,216],{"class":179},[158,333,219],{"class":164},[158,335,336,338,340],{"class":160,"line":222},[158,337,225],{"class":164},[158,339,169],{"class":243},[158,341,183],{"class":164},[149,343,344],{"className":290,"code":152,"language":291,"meta":154,"style":154},[10,345,346,360,386],{"__ignoreMap":154},[158,347,348,350,352,354,356,358],{"class":160,"line":161},[158,349,165],{"class":164},[158,351,169],{"class":243},[158,353,173],{"class":172},[158,355,176],{"class":249},[158,357,180],{"class":179},[158,359,183],{"class":164},[158,361,362,364,366,368,370,372,374,376,378,380,382,384],{"class":160,"line":186},[158,363,189],{"class":164},[158,365,192],{"class":243},[158,367,195],{"class":172},[158,369,176],{"class":249},[158,371,200],{"class":179},[158,373,203],{"class":172},[158,375,176],{"class":249},[158,377,208],{"class":179},[158,379,211],{"class":172},[158,381,176],{"class":249},[158,383,216],{"class":179},[158,385,219],{"class":164},[158,387,388,390,392],{"class":160,"line":222},[158,389,225],{"class":164},[158,391,169],{"class":243},[158,393,183],{"class":164},[149,395,399],{"className":396,"code":397,"language":398,"meta":154,"style":154},"language-javascript shiki shiki-themes github-dark","const shader = await createShader(canvas, {\n  components: [\n    { type: 'RoundedRect', props: { width: '50%', height: '12rem', rounding: '24px' } }\n  ]\n})\n","javascript",[10,400,401,421,426,455,461],{"__ignoreMap":154},[158,402,403,406,409,412,415,418],{"class":160,"line":161},[158,404,405],{"class":249},"const",[158,407,408],{"class":243}," shader",[158,410,411],{"class":249}," =",[158,413,414],{"class":249}," await",[158,416,417],{"class":172}," createShader",[158,419,420],{"class":164},"(canvas, {\n",[158,422,423],{"class":160,"line":186},[158,424,425],{"class":164},"  components: [\n",[158,427,428,431,434,437,440,443,446,449,452],{"class":160,"line":222},[158,429,430],{"class":164},"    { type: ",[158,432,433],{"class":179},"'RoundedRect'",[158,435,436],{"class":164},", props: { width: ",[158,438,439],{"class":179},"'50%'",[158,441,442],{"class":164},", height: ",[158,444,445],{"class":179},"'12rem'",[158,447,448],{"class":164},", rounding: ",[158,450,451],{"class":179},"'24px'",[158,453,454],{"class":164}," } }\n",[158,456,458],{"class":160,"line":457},4,[158,459,460],{"class":164},"  ]\n",[158,462,464],{"class":160,"line":463},5,[158,465,466],{"class":164},"})\n",[139,468,469],{},"The rectangle is half the canvas wide and 192px tall, and it stays that way as the canvas resizes.",[471,472,474],"h2",{"id":473},"writing-a-length","Writing a length",[139,476,477,478,482],{},"A ",[479,480,481],"strong",{},"length"," is a number with a unit. Write it as a string, the way you would in CSS:",[149,484,486],{"className":151,"code":485,"language":153,"meta":154,"style":154},"\u003CCircle radius=\"10vmin\" :center=\"{ x: '0', y: '-24px' }\" \u002F>\n",[10,487,488],{"__ignoreMap":154},[158,489,490,492,495,498,500,503,506,508,511],{"class":160,"line":161},[158,491,165],{"class":164},[158,493,494],{"class":168},"Circle",[158,496,497],{"class":172}," radius",[158,499,176],{"class":164},[158,501,502],{"class":179},"\"10vmin\"",[158,504,505],{"class":172}," :center",[158,507,176],{"class":164},[158,509,510],{"class":179},"\"{ x: '0', y: '-24px' }\"",[158,512,219],{"class":164},[139,514,515,516,519,520,523],{},"You can also write it as an object with a ",[10,517,518],{},"value"," and a ",[10,521,522],{},"unit",":",[149,525,527],{"className":151,"code":526,"language":153,"meta":154,"style":154},"\u003CCircle :radius=\"{ value: 10, unit: 'vmin' }\" \u002F>\n",[10,528,529],{"__ignoreMap":154},[158,530,531,533,535,538,540,543],{"class":160,"line":161},[158,532,165],{"class":164},[158,534,494],{"class":168},[158,536,537],{"class":172}," :radius",[158,539,176],{"class":164},[158,541,542],{"class":179},"\"{ value: 10, unit: 'vmin' }\"",[158,544,219],{"class":164},[139,546,547,548,551],{},"Both forms work on props and in bounding boxes. A string needs a unit, except ",[10,549,550],{},"'0'",".",[471,553,555],{"id":554},"choosing-a-unit","Choosing a unit",[139,557,558],{},"Each unit measures against something different:",[560,561,562,578],"table",{},[563,564,565],"thead",{},[566,567,568,572,575],"tr",{},[569,570,571],"th",{},"Unit",[569,573,574],{},"Measures against",[569,576,577],{},"Use it for",[579,580,581,595,608,625,641,662,681],"tbody",{},[566,582,583,589,592],{},[584,585,586],"td",{},[10,587,588],{},"px",[584,590,591],{},"CSS pixels",[584,593,594],{},"Fixed sizes: badges, logos, UI chrome",[566,596,597,602,605],{},[584,598,599],{},[10,600,601],{},"%",[584,603,604],{},"The canvas, on the prop's own axis",[584,606,607],{},"Layouts that scale with the canvas",[566,609,610,619,622],{},[584,611,612,615,616],{},[10,613,614],{},"cw",", ",[10,617,618],{},"ch",[584,620,621],{},"1% of the canvas width or height",[584,623,624],{},"Sizing one axis from the other",[566,626,627,635,638],{},[584,628,629,615,632],{},[10,630,631],{},"cmin",[10,633,634],{},"cmax",[584,636,637],{},"1% of the canvas's shorter or longer side",[584,639,640],{},"Shapes that fit any aspect ratio",[566,642,643,651,654],{},[584,644,645,615,648],{},[10,646,647],{},"vw",[10,649,650],{},"vh",[584,652,653],{},"1% of the browser window's width or height",[584,655,656,657,659,660],{},"Matching DOM elements sized in ",[10,658,647],{}," or ",[10,661,650],{},[566,663,664,672,675],{},[584,665,666,615,669],{},[10,667,668],{},"vmin",[10,670,671],{},"vmax",[584,673,674],{},"1% of the window's shorter or longer side",[584,676,656,677,659,679],{},[10,678,668],{},[10,680,671],{},[566,682,683,688,691],{},[584,684,685],{},[10,686,687],{},"rem",[584,689,690],{},"The page's root font size",[584,692,693],{},"Matching your typography",[139,695,696,699,700,703,704,707,708,711,712,715],{},[479,697,698],{},"Canvas units"," follow the ",[10,701,702],{},"\u003CShader>"," element. ",[479,705,706],{},"Viewport units"," follow the browser window, so the two only differ when the canvas isn't full-screen. In a canvas that fills a sidebar, ",[10,709,710],{},"50cw"," is half the sidebar and ",[10,713,714],{},"50vw"," is half the window.",[139,717,718,720,721,723,724,727,728,730],{},[10,719,647],{}," and ",[10,722,650],{}," match CSS exactly, including on mobile, where the address bar changes the window's height but not the size of ",[10,725,726],{},"100vh",". Without a browser window, as in server rendering, viewport units fall back to the canvas size and ",[10,729,687],{}," falls back to 16px.",[471,732,734],{"id":733},"sizing-a-shape","Sizing a shape",[139,736,737,738,741],{},"A length on a size prop sets the shape's full size on screen, the way CSS ",[10,739,740],{},"width"," does:",[149,743,745],{"className":151,"code":744,"language":153,"meta":154,"style":154},"\u003CCircle radius=\"120px\" \u002F>\n\u003CStar radius=\"20cmin\" \u002F>\n",[10,746,747,762],{"__ignoreMap":154},[158,748,749,751,753,755,757,760],{"class":160,"line":161},[158,750,165],{"class":164},[158,752,494],{"class":168},[158,754,497],{"class":172},[158,756,176],{"class":164},[158,758,759],{"class":179},"\"120px\"",[158,761,219],{"class":164},[158,763,764,766,769,771,773,776],{"class":160,"line":186},[158,765,165],{"class":164},[158,767,768],{"class":168},"Star",[158,770,497],{"class":172},[158,772,176],{"class":164},[158,774,775],{"class":179},"\"20cmin\"",[158,777,219],{"class":164},[139,779,780],{},"The circle is 120px across, not 120px from its center. The star fills a square that's 20% of the canvas's shorter side.",[139,782,783],{},"Props that take lengths include:",[785,786,787,807,820,830],"ul",{},[788,789,790,793,794,797,798,615,801,803,804,551],"li",{},[479,791,792],{},"Shape position and size",": ",[10,795,796],{},"center"," and the size props of every shape, such as ",[10,799,800],{},"radius",[10,802,740],{},", and ",[10,805,806],{},"height",[788,808,809,793,812,815,816,819],{},[479,810,811],{},"Shape details",[10,813,814],{},"rounding"," on rounded rectangles and ",[10,817,818],{},"softness"," on circles.",[788,821,822,793,825,720,828,551],{},[479,823,824],{},"Text",[10,826,827],{},"fontSize",[10,829,740],{},[788,831,832,835,836,839],{},[479,833,834],{},"Layout and patterns",": Repeater gaps, radius, and spacing, plus Checkerboard ",[10,837,838],{},"cells",", where a length sets the size of one cell.",[139,841,842],{},"Each prop's row in the component reference says when it accepts CSS units.",[471,844,846,847],{"id":845},"using","Using ",[10,848,601],{},[139,850,851,853,854,720,856,859,860,720,862,865],{},[10,852,601],{}," measures the canvas on the prop's own axis. ",[10,855,740],{},[10,857,858],{},"x"," use the canvas width, and ",[10,861,806],{},[10,863,864],{},"y"," use its height:",[149,867,869],{"className":151,"code":868,"language":153,"meta":154,"style":154},"\u003CRoundedRect width=\"80%\" height=\"50%\" \u002F>\n",[10,870,871],{"__ignoreMap":154},[158,872,873,875,877,879,881,884,886,888,890],{"class":160,"line":161},[158,874,165],{"class":164},[158,876,192],{"class":168},[158,878,195],{"class":172},[158,880,176],{"class":164},[158,882,883],{"class":179},"\"80%\"",[158,885,203],{"class":172},[158,887,176],{"class":164},[158,889,200],{"class":179},[158,891,219],{"class":164},[139,893,894,895,615,897,615,899,901,902,904,905,907,908,910,911,914,915,615,917,919,920,922],{},"Some props have no axis: a circle's ",[10,896,800],{},[10,898,814],{},[10,900,818],{},", and Text's ",[10,903,827],{},". They don't accept ",[10,906,601],{},", the same way CSS rejects ",[10,909,601],{}," on ",[10,912,913],{},"border-width",". Shaders ignores the value, uses the prop's default, and logs one console warning. Use ",[10,916,631],{},[10,918,588],{},", or ",[10,921,687],{}," for these instead.",[471,924,926],{"id":925},"positioning-with-lengths","Positioning with lengths",[139,928,929,930,932,933,936,937,940,941,943,944,946],{},"A length in ",[10,931,796],{}," is an offset from the edge named by the shape's ",[10,934,935],{},"origin",". Shapes default to ",[10,938,939],{},"origin: 'center'",", so offsets start from the middle of the canvas and ",[10,942,550],{}," is centered. Positive ",[10,945,864],{}," moves down, as in CSS. This circle sits 24px above the middle:",[145,948,949,997,1055,1108,1160],{":tabs":147},[149,950,952],{"className":151,"code":951,"language":153,"meta":154,"style":154},"\u003CShader class=\"w-full h-96\">\n  \u003CCircle radius=\"80px\" :center=\"{ x: '0', y: '-24px' }\" \u002F>\n\u003C\u002FShader>\n",[10,953,954,968,989],{"__ignoreMap":154},[158,955,956,958,960,962,964,966],{"class":160,"line":161},[158,957,165],{"class":164},[158,959,169],{"class":168},[158,961,173],{"class":172},[158,963,176],{"class":164},[158,965,180],{"class":179},[158,967,183],{"class":164},[158,969,970,972,974,976,978,981,983,985,987],{"class":160,"line":186},[158,971,189],{"class":164},[158,973,494],{"class":168},[158,975,497],{"class":172},[158,977,176],{"class":164},[158,979,980],{"class":179},"\"80px\"",[158,982,505],{"class":172},[158,984,176],{"class":164},[158,986,510],{"class":179},[158,988,219],{"class":164},[158,990,991,993,995],{"class":160,"line":222},[158,992,225],{"class":164},[158,994,169],{"class":168},[158,996,183],{"class":164},[149,998,1000],{"className":232,"code":999,"language":234,"meta":154,"style":154},"\u003CShader className=\"w-full h-96\">\n  \u003CCircle radius=\"80px\" center={{ x: '0', y: '-24px' }} \u002F>\n\u003C\u002FShader>\n",[10,1001,1002,1016,1047],{"__ignoreMap":154},[158,1003,1004,1006,1008,1010,1012,1014],{"class":160,"line":161},[158,1005,165],{"class":164},[158,1007,169],{"class":243},[158,1009,246],{"class":172},[158,1011,176],{"class":249},[158,1013,180],{"class":179},[158,1015,183],{"class":164},[158,1017,1018,1020,1022,1024,1026,1028,1031,1033,1036,1038,1041,1044],{"class":160,"line":186},[158,1019,189],{"class":164},[158,1021,494],{"class":243},[158,1023,497],{"class":172},[158,1025,176],{"class":249},[158,1027,980],{"class":179},[158,1029,1030],{"class":172}," center",[158,1032,176],{"class":249},[158,1034,1035],{"class":164},"{{ x: ",[158,1037,550],{"class":179},[158,1039,1040],{"class":164},", y: ",[158,1042,1043],{"class":179},"'-24px'",[158,1045,1046],{"class":164}," }} \u002F>\n",[158,1048,1049,1051,1053],{"class":160,"line":222},[158,1050,225],{"class":164},[158,1052,169],{"class":243},[158,1054,183],{"class":164},[149,1056,1058],{"className":290,"code":1057,"language":291,"meta":154,"style":154},"\u003CShader class=\"w-full h-96\">\n  \u003CCircle radius=\"80px\" center={{ x: '0', y: '-24px' }} \u002F>\n\u003C\u002FShader>\n",[10,1059,1060,1074,1100],{"__ignoreMap":154},[158,1061,1062,1064,1066,1068,1070,1072],{"class":160,"line":161},[158,1063,165],{"class":164},[158,1065,169],{"class":243},[158,1067,173],{"class":172},[158,1069,176],{"class":249},[158,1071,180],{"class":179},[158,1073,183],{"class":164},[158,1075,1076,1078,1080,1082,1084,1086,1088,1090,1092,1094,1096,1098],{"class":160,"line":186},[158,1077,189],{"class":164},[158,1079,494],{"class":243},[158,1081,497],{"class":172},[158,1083,176],{"class":249},[158,1085,980],{"class":179},[158,1087,1030],{"class":172},[158,1089,176],{"class":249},[158,1091,1035],{"class":164},[158,1093,550],{"class":179},[158,1095,1040],{"class":164},[158,1097,1043],{"class":179},[158,1099,1046],{"class":164},[158,1101,1102,1104,1106],{"class":160,"line":222},[158,1103,225],{"class":164},[158,1105,169],{"class":243},[158,1107,183],{"class":164},[149,1109,1110],{"className":290,"code":1057,"language":291,"meta":154,"style":154},[10,1111,1112,1126,1152],{"__ignoreMap":154},[158,1113,1114,1116,1118,1120,1122,1124],{"class":160,"line":161},[158,1115,165],{"class":164},[158,1117,169],{"class":243},[158,1119,173],{"class":172},[158,1121,176],{"class":249},[158,1123,180],{"class":179},[158,1125,183],{"class":164},[158,1127,1128,1130,1132,1134,1136,1138,1140,1142,1144,1146,1148,1150],{"class":160,"line":186},[158,1129,189],{"class":164},[158,1131,494],{"class":243},[158,1133,497],{"class":172},[158,1135,176],{"class":249},[158,1137,980],{"class":179},[158,1139,1030],{"class":172},[158,1141,176],{"class":249},[158,1143,1035],{"class":164},[158,1145,550],{"class":179},[158,1147,1040],{"class":164},[158,1149,1043],{"class":179},[158,1151,1046],{"class":164},[158,1153,1154,1156,1158],{"class":160,"line":222},[158,1155,225],{"class":164},[158,1157,169],{"class":243},[158,1159,183],{"class":164},[149,1161,1163],{"className":396,"code":1162,"language":398,"meta":154,"style":154},"const shader = await createShader(canvas, {\n  components: [\n    { type: 'Circle', props: { radius: '80px', center: { x: '0', y: '-24px' } } }\n  ]\n})\n",[10,1164,1165,1179,1183,1208,1212],{"__ignoreMap":154},[158,1166,1167,1169,1171,1173,1175,1177],{"class":160,"line":161},[158,1168,405],{"class":249},[158,1170,408],{"class":243},[158,1172,411],{"class":249},[158,1174,414],{"class":249},[158,1176,417],{"class":172},[158,1178,420],{"class":164},[158,1180,1181],{"class":160,"line":186},[158,1182,425],{"class":164},[158,1184,1185,1187,1190,1193,1196,1199,1201,1203,1205],{"class":160,"line":222},[158,1186,430],{"class":164},[158,1188,1189],{"class":179},"'Circle'",[158,1191,1192],{"class":164},", props: { radius: ",[158,1194,1195],{"class":179},"'80px'",[158,1197,1198],{"class":164},", center: { x: ",[158,1200,550],{"class":179},[158,1202,1040],{"class":164},[158,1204,1043],{"class":179},[158,1206,1207],{"class":164}," } } }\n",[158,1209,1210],{"class":160,"line":457},[158,1211,460],{"class":164},[158,1213,1214],{"class":160,"line":463},[158,1215,466],{"class":164},[139,1217,1218,1219,1221,1222,720,1225,1228],{},"To pin a shape to a corner, set ",[10,1220,935],{},". The offset then measures from that edge of the canvas to the same edge of the shape, like CSS ",[10,1223,1224],{},"right",[10,1226,1227],{},"top",". This circle sits 24px in from the top-right corner at any canvas size:",[149,1230,1232],{"className":151,"code":1231,"language":153,"meta":154,"style":154},"\u003CCircle origin=\"top-right\" radius=\"64px\" :center=\"{ x: '24px', y: '24px' }\" \u002F>\n",[10,1233,1234],{"__ignoreMap":154},[158,1235,1236,1238,1240,1243,1245,1248,1250,1252,1255,1257,1259,1262],{"class":160,"line":161},[158,1237,165],{"class":164},[158,1239,494],{"class":168},[158,1241,1242],{"class":172}," origin",[158,1244,176],{"class":164},[158,1246,1247],{"class":179},"\"top-right\"",[158,1249,497],{"class":172},[158,1251,176],{"class":164},[158,1253,1254],{"class":179},"\"64px\"",[158,1256,505],{"class":172},[158,1258,176],{"class":164},[158,1260,1261],{"class":179},"\"{ x: '24px', y: '24px' }\"",[158,1263,219],{"class":164},[471,1265,1267],{"id":1266},"sizing-a-bounding-box","Sizing a bounding box",[139,1269,1270,1273,1274,720,1276,1278,1279,720,1282,1284],{},[10,1271,1272],{},"boundingBox"," takes the same units. Its ",[10,1275,858],{},[10,1277,864],{}," place the box's edge, like ",[10,1280,1281],{},"left",[10,1283,1227],{}," on a positioned element, and a bare number means pixels:",[145,1286,1287,1340,1415,1482,1548],{":tabs":147},[149,1288,1290],{"className":151,"code":1289,"language":153,"meta":154,"style":154},"\u003CShader class=\"w-full h-96\">\n  \u003CLinearGradient \u002F>\n  \u003CBlur :bounding-box=\"{ x: 24, y: '1rem', width: '50vw', height: '40%', origin: 'bottom-right' }\" \u002F>\n\u003C\u002FShader>\n",[10,1291,1292,1306,1315,1332],{"__ignoreMap":154},[158,1293,1294,1296,1298,1300,1302,1304],{"class":160,"line":161},[158,1295,165],{"class":164},[158,1297,169],{"class":168},[158,1299,173],{"class":172},[158,1301,176],{"class":164},[158,1303,180],{"class":179},[158,1305,183],{"class":164},[158,1307,1308,1310,1313],{"class":160,"line":186},[158,1309,189],{"class":164},[158,1311,1312],{"class":168},"LinearGradient",[158,1314,219],{"class":164},[158,1316,1317,1319,1322,1325,1327,1330],{"class":160,"line":222},[158,1318,189],{"class":164},[158,1320,1321],{"class":168},"Blur",[158,1323,1324],{"class":172}," :bounding-box",[158,1326,176],{"class":164},[158,1328,1329],{"class":179},"\"{ x: 24, y: '1rem', width: '50vw', height: '40%', origin: 'bottom-right' }\"",[158,1331,219],{"class":164},[158,1333,1334,1336,1338],{"class":160,"line":457},[158,1335,225],{"class":164},[158,1337,169],{"class":168},[158,1339,183],{"class":164},[149,1341,1343],{"className":232,"code":1342,"language":234,"meta":154,"style":154},"\u003CShader className=\"w-full h-96\">\n  \u003CLinearGradient \u002F>\n  \u003CBlur boundingBox={{ x: 24, y: '1rem', width: '50vw', height: '40%', origin: 'bottom-right' }} \u002F>\n\u003C\u002FShader>\n",[10,1344,1345,1359,1367,1407],{"__ignoreMap":154},[158,1346,1347,1349,1351,1353,1355,1357],{"class":160,"line":161},[158,1348,165],{"class":164},[158,1350,169],{"class":243},[158,1352,246],{"class":172},[158,1354,176],{"class":249},[158,1356,180],{"class":179},[158,1358,183],{"class":164},[158,1360,1361,1363,1365],{"class":160,"line":186},[158,1362,189],{"class":164},[158,1364,1312],{"class":243},[158,1366,219],{"class":164},[158,1368,1369,1371,1373,1376,1378,1380,1383,1385,1388,1391,1394,1396,1399,1402,1405],{"class":160,"line":222},[158,1370,189],{"class":164},[158,1372,1321],{"class":243},[158,1374,1375],{"class":172}," boundingBox",[158,1377,176],{"class":249},[158,1379,1035],{"class":164},[158,1381,1382],{"class":243},"24",[158,1384,1040],{"class":164},[158,1386,1387],{"class":179},"'1rem'",[158,1389,1390],{"class":164},", width: ",[158,1392,1393],{"class":179},"'50vw'",[158,1395,442],{"class":164},[158,1397,1398],{"class":179},"'40%'",[158,1400,1401],{"class":164},", origin: ",[158,1403,1404],{"class":179},"'bottom-right'",[158,1406,1046],{"class":164},[158,1408,1409,1411,1413],{"class":160,"line":457},[158,1410,225],{"class":164},[158,1412,169],{"class":243},[158,1414,183],{"class":164},[149,1416,1418],{"className":290,"code":1417,"language":291,"meta":154,"style":154},"\u003CShader class=\"w-full h-96\">\n  \u003CLinearGradient \u002F>\n  \u003CBlur boundingBox={{ x: 24, y: '1rem', width: '50vw', height: '40%', origin: 'bottom-right' }} \u002F>\n\u003C\u002FShader>\n",[10,1419,1420,1434,1442,1474],{"__ignoreMap":154},[158,1421,1422,1424,1426,1428,1430,1432],{"class":160,"line":161},[158,1423,165],{"class":164},[158,1425,169],{"class":243},[158,1427,173],{"class":172},[158,1429,176],{"class":249},[158,1431,180],{"class":179},[158,1433,183],{"class":164},[158,1435,1436,1438,1440],{"class":160,"line":186},[158,1437,189],{"class":164},[158,1439,1312],{"class":243},[158,1441,219],{"class":164},[158,1443,1444,1446,1448,1450,1452,1454,1456,1458,1460,1462,1464,1466,1468,1470,1472],{"class":160,"line":222},[158,1445,189],{"class":164},[158,1447,1321],{"class":243},[158,1449,1375],{"class":172},[158,1451,176],{"class":249},[158,1453,1035],{"class":164},[158,1455,1382],{"class":243},[158,1457,1040],{"class":164},[158,1459,1387],{"class":179},[158,1461,1390],{"class":164},[158,1463,1393],{"class":179},[158,1465,442],{"class":164},[158,1467,1398],{"class":179},[158,1469,1401],{"class":164},[158,1471,1404],{"class":179},[158,1473,1046],{"class":164},[158,1475,1476,1478,1480],{"class":160,"line":457},[158,1477,225],{"class":164},[158,1479,169],{"class":243},[158,1481,183],{"class":164},[149,1483,1484],{"className":290,"code":1417,"language":291,"meta":154,"style":154},[10,1485,1486,1500,1508,1540],{"__ignoreMap":154},[158,1487,1488,1490,1492,1494,1496,1498],{"class":160,"line":161},[158,1489,165],{"class":164},[158,1491,169],{"class":243},[158,1493,173],{"class":172},[158,1495,176],{"class":249},[158,1497,180],{"class":179},[158,1499,183],{"class":164},[158,1501,1502,1504,1506],{"class":160,"line":186},[158,1503,189],{"class":164},[158,1505,1312],{"class":243},[158,1507,219],{"class":164},[158,1509,1510,1512,1514,1516,1518,1520,1522,1524,1526,1528,1530,1532,1534,1536,1538],{"class":160,"line":222},[158,1511,189],{"class":164},[158,1513,1321],{"class":243},[158,1515,1375],{"class":172},[158,1517,176],{"class":249},[158,1519,1035],{"class":164},[158,1521,1382],{"class":243},[158,1523,1040],{"class":164},[158,1525,1387],{"class":179},[158,1527,1390],{"class":164},[158,1529,1393],{"class":179},[158,1531,442],{"class":164},[158,1533,1398],{"class":179},[158,1535,1401],{"class":164},[158,1537,1404],{"class":179},[158,1539,1046],{"class":164},[158,1541,1542,1544,1546],{"class":160,"line":457},[158,1543,225],{"class":164},[158,1545,169],{"class":243},[158,1547,183],{"class":164},[149,1549,1551],{"className":396,"code":1550,"language":398,"meta":154,"style":154},"const shader = await createShader(canvas, {\n  components: [\n    { type: 'LinearGradient' },\n    {\n      type: 'Blur',\n      props: {\n        boundingBox: { x: 24, y: '1rem', width: '50vw', height: '40%', origin: 'bottom-right' }\n      }\n    }\n  ]\n})\n",[10,1552,1553,1567,1571,1581,1586,1597,1603,1630,1636,1642,1647],{"__ignoreMap":154},[158,1554,1555,1557,1559,1561,1563,1565],{"class":160,"line":161},[158,1556,405],{"class":249},[158,1558,408],{"class":243},[158,1560,411],{"class":249},[158,1562,414],{"class":249},[158,1564,417],{"class":172},[158,1566,420],{"class":164},[158,1568,1569],{"class":160,"line":186},[158,1570,425],{"class":164},[158,1572,1573,1575,1578],{"class":160,"line":222},[158,1574,430],{"class":164},[158,1576,1577],{"class":179},"'LinearGradient'",[158,1579,1580],{"class":164}," },\n",[158,1582,1583],{"class":160,"line":457},[158,1584,1585],{"class":164},"    {\n",[158,1587,1588,1591,1594],{"class":160,"line":463},[158,1589,1590],{"class":164},"      type: ",[158,1592,1593],{"class":179},"'Blur'",[158,1595,1596],{"class":164},",\n",[158,1598,1600],{"class":160,"line":1599},6,[158,1601,1602],{"class":164},"      props: {\n",[158,1604,1606,1609,1611,1613,1615,1617,1619,1621,1623,1625,1627],{"class":160,"line":1605},7,[158,1607,1608],{"class":164},"        boundingBox: { x: ",[158,1610,1382],{"class":243},[158,1612,1040],{"class":164},[158,1614,1387],{"class":179},[158,1616,1390],{"class":164},[158,1618,1393],{"class":179},[158,1620,442],{"class":164},[158,1622,1398],{"class":179},[158,1624,1401],{"class":164},[158,1626,1404],{"class":179},[158,1628,1629],{"class":164}," }\n",[158,1631,1633],{"class":160,"line":1632},8,[158,1634,1635],{"class":164},"      }\n",[158,1637,1639],{"class":160,"line":1638},9,[158,1640,1641],{"class":164},"    }\n",[158,1643,1645],{"class":160,"line":1644},10,[158,1646,460],{"class":164},[158,1648,1650],{"class":160,"line":1649},11,[158,1651,466],{"class":164},[139,1653,1654,1655,1658],{},"The blurred region sits 24px from the right edge and 16px from the bottom. See ",[1656,1657,41],"a",{"href":40}," for origins, rotation, and how each kind of layer fills its box.",[471,1660,1662],{"id":1661},"reading-bare-numbers-on-shape-props","Reading bare numbers on shape props",[139,1664,1665,1666,1669,1670,551],{},"On shape props, a bare number keeps its original meaning: a fraction of the canvas. ",[10,1667,1668],{},"radius: 0.5"," isn't 0.5px. Shape props worked this way before units existed, and changing it would move every shape already written with numbers. Add a unit when you want CSS behavior: ",[10,1671,1672],{},"radius=\"50cmin\"",[139,1674,1675,1676,1678,1679,1682,1683,1685],{},"In ",[10,1677,796],{},", a bare ",[10,1680,1681],{},"0"," is the left or top edge of the canvas, while ",[10,1684,550],{}," with a centered origin is the middle.",[471,1687,1689],{"id":1688},"resizing-and-animating-lengths","Resizing and animating lengths",[139,1691,1692,1693,1695],{},"Shaders recalculates every length when the canvas resizes, and recalculates viewport and ",[10,1694,687],{}," lengths when the window resizes. A recalculated length updates a uniform, a value the GPU reads every frame, so nothing recompiles.",[139,1697,1698,1701],{},[1656,1699,1700],{"href":28},"Dynamic prop"," ranges take lengths in the object form. This circle grows from 80px to 240px across:",[149,1703,1705],{"className":151,"code":1704,"language":153,"meta":154,"style":154},"\u003CCircle :radius=\"{\n  type: 'auto-animate',\n  mode: 'ping-pong',\n  outputMin: { value: 80, unit: 'px' },\n  outputMax: { value: 240, unit: 'px' }\n}\" \u002F>\n",[10,1706,1707,1720,1725,1730,1735,1740],{"__ignoreMap":154},[158,1708,1709,1711,1713,1715,1717],{"class":160,"line":161},[158,1710,165],{"class":164},[158,1712,494],{"class":168},[158,1714,537],{"class":172},[158,1716,176],{"class":164},[158,1718,1719],{"class":179},"\"{\n",[158,1721,1722],{"class":160,"line":186},[158,1723,1724],{"class":179},"  type: 'auto-animate',\n",[158,1726,1727],{"class":160,"line":222},[158,1728,1729],{"class":179},"  mode: 'ping-pong',\n",[158,1731,1732],{"class":160,"line":457},[158,1733,1734],{"class":179},"  outputMin: { value: 80, unit: 'px' },\n",[158,1736,1737],{"class":160,"line":463},[158,1738,1739],{"class":179},"  outputMax: { value: 240, unit: 'px' }\n",[158,1741,1742,1745],{"class":160,"line":1599},[158,1743,1744],{"class":179},"}\"",[158,1746,219],{"class":164},[139,1748,1749,1750,1752],{},"A range is converted to the canvas once, when the prop is set. Resizing the canvas or window doesn't update it, so a ",[10,1751,601],{}," range keeps the size it had at that moment.",[1754,1755,1756],"note",{},[139,1757,1758,1759,720,1761,1763],{},"The design editor offers ",[10,1760,601],{},[10,1762,588],{}," only. The other units work in code.",[471,1765,1767],{"id":1766},"next-steps","Next steps",[785,1769,1770,1775,1780],{},[788,1771,1772,1774],{},[1656,1773,41],{"href":40},": position, size, and rotate any layer with a bounding box.",[788,1776,1777,1779],{},[1656,1778,29],{"href":28},": animate props or drive them from the cursor without animation code.",[788,1781,1782,1784],{},[1656,1783,33],{"href":32},": size and place the canvas itself in your page.",[1786,1787,1788],"style",{},"html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}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 .snl16, html code.shiki .snl16{--shiki-default:#F97583}",{"title":154,"searchDepth":186,"depth":186,"links":1790},[1791,1792,1793,1794,1796,1797,1798,1799,1800],{"id":473,"depth":186,"text":474},{"id":554,"depth":186,"text":555},{"id":733,"depth":186,"text":734},{"id":845,"depth":186,"text":1795},"Using %",{"id":925,"depth":186,"text":926},{"id":1266,"depth":186,"text":1267},{"id":1661,"depth":186,"text":1662},{"id":1688,"depth":186,"text":1689},{"id":1766,"depth":186,"text":1767},"md","ruler-combined",{"type":1804},"guide",true,{"title":37,"description":38},"docs\u002Fguide\u002F07.sizing-and-units","StkfLztRN1zofeO5pGaEgiIb2WjXWLHZMS5VFlr_yZc"]