laborb/bunny-stream
Laravel package for Bunny Stream: upload, manage, and play videos via Bunny.net's streaming API with an Eloquent-friendly interface for models, tokens, and playback URLs.
This addon gives Statamic assets a focal point fieldtype so editors can pick the point of interest on an image, and front-end/control-panel previews crop around it instead of always centre-cropping.
composer require <vendor>/<package> then php artisan vendor:publish --tag=<package>-config if you need to tweak defaults (usually you don't — 1.1.2 explicitly requires no config changes).php artisan config:clear && php artisan cache:clear
php artisan statamic:stache:clear
resources/blueprints/assets/images.yaml:
tabs:
main:
sections:
- fields:
- handle: focal_point
field:
type: focal_point
display: Focal Point
It belongs on the asset container, not on an entry blueprint — the value is stored on the asset's meta.glide output at 16:9 and 4:5 crops both keep the face in frame without hand-cropping per breakpoint.Where to look first: the README's templating section (how the focal point is passed into Glide), the published config (preview/thumbnail sizes), and the addon's fieldtype Vue component if you need to understand what the CP preview is doing. For 1.1.2 specifically, skim the changelog note about isolating the control-panel bundle — it tells you the addon now loads its CP JS in a scope that doesn't touch window.
Blueprint-first rollout. Add the field only to containers that actually need it (heroes, cards, editorial images). Putting it on every container adds a CP panel to every asset edit screen and confuses editors on icons/logos where it's meaningless.
Front-end rendering. The focal point exists to feed Glide's crop. Typical Antlers:
{{ glide:url width="1200" height="675" fit="crop_focal" }}
<img src="{{ url }}" alt="{{ alt }}">
{{ /glide:url }}
If your version of the addon exposes a modifier/param instead of relying on Statamic's native crop_focal fit, use theirs — but do not mix both, or you'll apply the point twice and get an off-centre crop. Pick one convention per project and document it in the repo.
Responsive sets. Generate one URL per breakpoint in a loop or via a partial, and let every size derive from the same focal point:
{{ glide:generate width="480" height="270" fit="crop_focal" }}
{{ glide:generate width="960" height="540" fit="crop_focal" }}
Because the focal point is stored on the asset, changing it once invalidates all derived sizes at once — usually what you want, but see the Glide-cache gotcha below.
Programmatic access. Read the value from asset meta when you need it outside templates (API resources, sitemap generators, headless front ends):
$point = $asset->get('focal_point'); // typically ['x' => 50, 'y' => 35] style percentages
Normalise percentages to your image library (Intervention/Glide take either percentages or pixels depending on the call) in one helper rather than in five controllers.
Editorial workflow. Pair the field with a CP hint in the blueprint (instructions:) telling editors to place the point on the subject's eyes for portraits. The CP preview is the whole value proposition — if the preview doesn't render, editors place the point blind and your crops get worse, not better.
Multi-site. Focal point is asset-level, not site-level, so a photo used on both a de and en site shares one point. If localisation matters, store per-site overrides via an entry-level field or an asset localizable meta field and fall back to the asset value.
CI / upgrade testing. Run a matrix with one Statamic 5 site and one Statamic 6 site. 1.1.2 changes only the Statamic 6 CP path, so a 5.x smoke test confirms "unchanged behaviour" and the 6.x job covers the regression you just fixed.
window.* assignments in your own resources/js/cp.js) can still interfere. If previews regress after adding another addon, check the browser console for duplicate-library warnings and load order before filing a bug here.php artisan glide:clear (or your configured equivalent) and purge the CDN — otherwise editors "fix" a crop and see the old one, then file duplicate tickets.php artisan statamic:stache:clear plus a hard browser reload. Blueprint YAML edits are cached per-request in some setups.focal_point in the asset's data explicitly — an unsaved Asset instance won't carry the field through the CP.auth middleware on /img or a strict CSP img-src, previews silently fall back to a broken image even though front-end rendering works fine. Test the CP as a non-super user before shipping.crop_focal output.AssetSaved/AssetUploaded to push the resolved focal point into an external DAM or image service that does its own cropping. If you need custom behaviour in the picker itself, override the fieldtype's Vue component in your own resources/js rather than patching vendor/.x/y, (4) is the Glide cache stale, (5) is another CP asset leaking globals (Statamic 6). Working that list in order resolves most reports without touching the addon source.How can I help you explore Laravel packages today?