Glaze for WP (and for BricksBuilder)
HereUpdateis1.2.0:comprehensivePreviewdocumentation forof the Presets directly in the WP backend now possible.
What It Is
Glaze for WP / Bricks plugin (v 1.1.1).
Overview
Glaze for WP / Bricks is a WordPress plugin that brings Tailwind-style, declarative GSAPattribute-driven animations to any WordPress site,site (with first-classspecial supportaffinity for Bricks Builder) using GSAP under the Bricks page builder.hood. Instead of writing JavaScript animationfor code,every animated element, you describesimply animationsadd directly in HTML usinga data-animate attributesattribute (or a CSS classes),class, if you prefer class-based syntax) containing a compact animation string, and the plugin's runtime translatesscript thoseparses stringsit intoand drives GSAP callsautomatically.
The Technology Behind It
GSAP (GreenSock Animation Platform) is the actual animation engine — it handles all the tweening, easing, timelines, and (optionally) scroll-triggered behavior via theits lightweightScrollTrigger ~3kb GlazeJS library.
Everything the plugin needs — settings, presets, breakpoints, and downloaded libraries — is stored in flat files inside the plugin directory (/config and /lib). No custom database tables, options, transients, or custom post types are created, and every trace is removed cleanly on uninstall.
GlazeJS is a small ES module that sits between your HTML and GSAP. It scans the DOM for commercialelements use.
the
Coreconfigured Concept
attribute A(default Glazedata-animate) animationor isclass expressedprefix as(default aglaze-), parses the pipe-separated animation string inon aneach HTMLone attribute:
<div data-animate="from:opacity-0|y-50|30|duration-1"></div>0.6), and Thistranslates is parsedthat into the equivalent GSAP call:
.from()/.to()/timeline gsap.from(element,calls {— opacity:including 0,support y:for 50,staggered duration: 1 });
The animation string follows the anatomy [breakpoint][selector]:state:properties, where:
from:to:gsap.fromgsap.togsap.fromTo|-@name:@tablet:from:opacity-0[&>div]*]:...), [&_path]:...), transform origins, easing functions, and scroll-trigger properties.
This plugin is the elementWordPress itself.
preset-nameGSAP and Thea fullsmall syntaxruntime script (runtime.js). Everything is documentedstored in theflat bundled glaze-opus-docs-2.0.md "skill" file, which also serves as an AI-readable reference for generating presets via "Vibe Coding."
Installation & Activation
glaze-wp-bricks/wp-content/plugins/On activation (glaze_wpb_activate in glaze-wp-bricks.php), the plugin:
/config/libindex.php<?php // Silence is golden..htaccessDeny from all/config/config/settings.json, /lib/*.js) rather than the Glaze_WPB_Settings::defaults()and Getting
AStarted
new
sidebar
(superhero icon).
TheThe settingsadmin screen ishas afive self-contained single-page app rendered by Glaze_WPB_Admin::render(). The PHP outputs only a skeleton — a header withtabs: ResetLibraries, General, Breakpoints & Defaults, Presets, and Mappings.
<section>admin.jswindow.GlazeWPBAdminconfigwindow.GlazeWPBStrings
Tab-by-Tab all UI labels and hint text (from admin-strings.js), keeping copy separate from logic.
The interface is styled by admin.css in a dark theme scoped under .glaze-wpb, using CSS custom properties for colors, radius, and accents. It also darkens the surrounding WordPress chrome (#wpwrap, #wpbody-content).
The five tabs are:
1. Libraries
Controls how GSAPGSAP, ScrollTrigger, and GlazeJS are loaded:loaded on the front end.
- Library mode
—:CDN(loadsjsDelivr/esm.shfrom—jsDelivrfastest/toesm.sh,setzeroup,setup)but relies on external requests) orLocal(serves self-hosted copies from the plugin's/libfolder)folder — no third-party requests, but you must download each library first). - Use existing global GSAP:
—Enablewhenifenabled, theanother plugindoesornotyourloadthemeitsalreadyownloads GSAPandglobally,insteadso Glaze reusesan existingwindow.gsap(e.g.insteadfromof loading adedicated GSAP WordPress plugin), avoidingduplicatescripts and version conflicts.copy. ALocal librariescardsection:listsFor eachregisteredlibrary (GSAP core, ScrollTrigger, GlazeJS),gsapscrolltrigger,youglaze)canwithDownload (fetch abadge showing whether afresh localcopy exists, pluscopy),Download/Refreshand(re-download an existing one, e.g. after an update), or Removebuttons.(delete the local copy, falling back to CDN until re-downloaded).
Library operations are handled by AJAX (glaze_wpb_lib) and delegated to Glaze_WPB_Libs (see Technical Processes below).
2. General
AttributesData attribute:—Thethe dataHTML attributenameGlaze scans for animation strings (defaultdata-animate).GlazeOnlyscans,changeandthistheifclassit conflicts with another plugin/theme.
glazeglaze), class="glaze-from:opacity-0".
Enable ScrollTrigger: scrollTrigger.* properties).
Force GPU (force3D): Watch DOM & re-animate: Run inside Bricks builder: Verbose console logging: 3. Breakpoints & Defaults
- Breakpoints:
—Namedname/media-querymediapairsqueriesthatusedpowerfor responsive prefixes like@tablet:from:opacity-0. Thespecialname is what you reference in animation strings; the value is the actual CSS media query.defaultname is usedapplies when nobreakpoint@breakpoint:prefix isgiven.used. - Global defaults:
—Baselinesettings applied automatically everywhere.element - Element defaults:
(appliedFallbackaspropertiesa fallback tofor every animatedelement,element (e.g.duration-0.6|ease-power2.out)and—overriddentltimelineby anything set directly in an element's own attribute.
defaults:ease-power2.outscrollTrigger.trigger4. Presets
Reusable animation strings organizedreferenced intoby namedname categoriesinside data-animate (Fades,e.g. Scale,fadeIn) Slide,or Zoom,as Bounce,a SVGclass Draw, Stagger, etc.(glaze-preset-fadeIn). Categories exist only to organize the admin UI — they have no front-end effecteffect, and are flattened into a single map before delivery. Presetpreset names must be unique across all categories.categories Yousince referencethey're flattened into one list at runtime.
preset-name/config/settings.json glaze-preset-nameopus-docs-2.0.md file in 5. Mappings
AutomaticAutomatically class mappings attachattaches an animation to every element matching a CSS class/selectorclass or selector, without editingneeding eachto element'sadd markupdata-animate manually — useful for markup you don't control directly (e.g. Bricks-generated icon wrappers)wrappers Bricks generates).
.fv-a-icon or fv-a-icon).
preset-nameto apply.
Saving,Writing Resetting,Animation and Data FlowStrings
WhenAnimation youstrings clickare Savepipe-separated changes,(|) key-value pairs, e.g.:
from:opacity-0|y-30|duration-0.6|ease-power2.out
Common patterns:
from: / admin.jscollect()to: glaze_wpb_savetween Glaze_WPB_Admin::ajax_save()guard()y-30, scale-0.8, rotate-[-45] (brackets allow negative/complex values).
duration-, delay-, ease-, stagger-, repeat-, yoyo- control timing/behavior.
[&>*]: prefix applies the array_replace_recursive()[&_path]: [&_line]: prefix targets nested SVG elements.
scrollTrigger.trigger-[&], scrollTrigger.start-[top_85%], scrollTrigger.scrub-1, etc. wire the @breakpoint: Glaze_WPB_Settings::save(@tablet:from:opacity-0)/config/settings.jsonReset
Practical (glaze_wpb_reset)Notes
defaults()to to Glaze_WPB_Settings::get()always reads the file and merges it onto the defaults, so a corrupt or partial file safely fallsfall back to defaults.
for
Thethat Front-Endlibrary Runtime
until you Glaze_WPB_Frontend::enqueue()runsdownload on wp_enqueue_scripts (priority 20) and orchestrates loading:
loadInBuilderbricks_is_builder()useExternalGsapDOM Glaze_WPB_Libs::url()runtime.jswindow.GlazeWPBricksFirefox-safe, wp_add_inline_script(..., 'before')runtime.js then executes this flow:
DOMContentLoadedgsapforce3DapplyAnimationMappings()MutationObserver — prepareSVGs()getTotalLength()strokeDasharraystrokeDashoffsetglazeUrlglaze(glazeConfig)glazeReadyglazegsapreinitThe Firefox "looping" safeguard
A key technical detail: Glaze's own native watch mode is deliberately never enabled. Its internal observer reacts to attribute mutations, and sincewhen GSAP rewrites inline styles on every tick, native watch would re-trigger Glaze on its own output — a mutate → re-init → mutate loop that Firefox renders as endlessly restarting animations.
Instead, the Watch DOM & re-animate toggle drives a custom, Firefox-safe MutationObserver that listens for childList changes only (never attributes). When new nodes appear, it checks whether they are SVGs or match any mapping, and if so schedules a debounced re-init (re-preparing SVGs, re-running Glaze, and refreshing ScrollTrigger). When the toggle is off, no observer is attached at all. Either way, scheduleReinit remains exposed through the glazeReady event for manual re-runs.
Technical Processes in Detail
Library management (Glaze_WPB_Libs)
A static registry() defines each library's runtime CDN URL, download URL, local filename, and type (script vs module):
gsapgsap.min.jsscrolltriggerScrollTrigger.min.jsglazeglaze.module.jsesm.sh/glazejs?bundle&target=es2020url($key, $mode) returns the local /lib URL when mode is local and a local copy exists, otherwise the CDN URL. is_local() simply checks whether the local file exists.
download($key) fetches the source via wp_remote_get() (30s timeout, following redirects), validates the HTTP status and non-empty body, and writes it into /lib.
ESM import rewriting — a notable subtlety: esm.sh often returns a thin ESM shim whose specifiers are root-relative (e.g. export * from "/glazejs@2.0.1/es2020/glazejs.bundle.mjs";). Those only resolve against the CDN's origin. Since the plugin serves the file from your own WordPress domain, absolutize_root_relative_imports() uses a regex to rewrite from/import specifiers that begin with / into fully-qualified URLs pointing back at the CDN origin, so the locally-served module still resolves its dependencies correctly.
delete($key) unlinks the local file (returning true if it was already absent).
Preset flattening
Glaze_WPB_Settings::flatten_presets() collapses the categorized preset structure (category → { name → string }) into a single flat name → string map, which is what Glaze actually consumes at runtime. This is why preset names must be globally unique.
Security
guard()manage_optionsglaze_wpb_nonce/config.htaccessindex.phpadmin.jsescHtml()escAttr()innerHTMLUninstall
uninstall.php runs glaze_wpb_rrmdir() to recursively delete the /config and /lib directories and everything inside them. Because the plugin never touches the options table, transients, or custom post types, nothing else needs cleanup — the removal is complete.
Writing Animations: Quick Reference
Once configured, add animations directly in your markup or Bricks elements:
<!-- Simple fade up -->
<div data-animate="from:opacity-0|y-30|duration-0.6"></div>
<!-- Using a preset -->
<div data-animate="preset-fadeInUp"></div>
<!-- Responsive: only on tablet and up -->
<div data-animate="@tablet:from:opacity-0|scale-0.9"></div>
<!-- Staggered children -->
<div data-animate="[&>*]:from:opacity-0|y-20|stagger-0.1|duration-0.5">
<div>One</div><div>Two</div><div>Three</div>
</div>
<!-- Scroll-triggered -->
<div data-animate="from:opacity-0|y-40|scrollTrigger.trigger-[&]|scrollTrigger.start-[top_85%]"></div>
<!-- SVG line-drawing -->
<svg class="glaze-preset-svgDrawIn"> ... </svg>
Syntax notes: use [-50] for negative/literal values, underscores for values with spaces ([top_center]), dots for nested props (scale.x-2), and tl to make an element a timeline container. Consult the bundled glaze-opus-docs-2.0.md for the exhaustive syntax reference.
Bricks-Specific Notes
Troubleshooting
[Glaze] GSAP detecteduseExternalGsapurl()/configlive /config/settings.json, /lib/*.js) — nothing is scrollTrigger.trigger-[&]glazeReadyreinit



