skills/storefront-ui/image-zoom-360/SKILL.md
Boost product confidence with high-res image zoom, 360-degree spin views, and inline video so shoppers can examine products closely before buying
npx skillsauth add finsilabs/awesome-ecommerce-skills image-zoom-360Install this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Implement a rich product media experience that includes high-resolution zoom on hover, touch-native pinch-to-zoom on mobile, 360-degree spin views from a sequence of images, and inline video playback. Richer media is associated with lower return rates and higher conversion for fashion, jewelry, electronics, and other detail-sensitive categories.
| Platform | Recommended Approach | Why | |----------|---------------------|-----| | Shopify | Use built-in media support in OS2.0 themes (Dawn, Sense) + Magic Zoom Plus app or Swiper Gallery for 360 | Dawn natively supports product images, video, and 3D models in the media gallery; Magic Zoom Plus ($69 one-time) adds hover zoom and 360 spin without theme edits | | WooCommerce | Install WooCommerce Product Gallery Slider or YITH WooCommerce Zoom Magnifier (free/premium) | WooCommerce includes a basic gallery; YITH Zoom Magnifier adds hover zoom and lightbox; Product Gallery Slider adds swipe, thumbnails, and video support | | BigCommerce | Use the Cornerstone theme's built-in zoom (hover zoom is enabled by default) + install Magic 360 or Sirv app for spin views | Cornerstone has native zoom; Sirv ($20+/mo) provides hosted 360 spin and zoom CDN with a Stencil widget | | Custom / Headless | Build a custom gallery component with CSS transform zoom, Pointer Events API for pinch-to-zoom, and frame-based spin viewer | Full control over performance and UX; see implementation below |
Built-in media gallery (no app required):
.glb files for 3D modelsFor 360-degree spin views — Magic Zoom Plus ($69 one-time):
product-001.jpg through product-036.jpg)Built-in zoom (no plugin required):
WooCommerce includes basic image zoom (powered by Zoom.js) by default on product pages. To configure it:
YITH WooCommerce Zoom Magnifier (free + premium):
Product Gallery Slider (free — WooCommerce.com):
For 360 views: Use WooCommerce 360° Image plugin (free, wordpress.org) — upload numbered spin frames as product images prefixed with 360_ and the plugin creates a drag-to-spin viewer.
Built-in zoom (Cornerstone theme):
Sirv (hosted 360 spin + zoom CDN):
Product videos:
CSS hover zoom (no JavaScript image loading):
// ZoomImage.jsx
import { useState, useRef } from 'react';
export function ZoomImage({ src, alt }) {
const [zoom, setZoom] = useState(null);
const containerRef = useRef(null);
function handleMouseMove(e) {
const rect = containerRef.current.getBoundingClientRect();
const x = ((e.clientX - rect.left) / rect.width) * 100;
const y = ((e.clientY - rect.top) / rect.height) * 100;
setZoom({ x, y });
}
return (
<div
ref={containerRef}
className="zoom-container"
onMouseMove={handleMouseMove}
onMouseLeave={() => setZoom(null)}
>
<img
src={src}
alt={alt}
className="zoom-image"
style={zoom ? {
transformOrigin: `${zoom.x}% ${zoom.y}%`,
transform: 'scale(2.5)',
} : {}}
draggable={false}
/>
</div>
);
}
.zoom-container { overflow: hidden; cursor: crosshair; aspect-ratio: 1/1; }
.zoom-image { width: 100%; height: 100%; object-fit: cover; transition: transform 0.05s linear; will-change: transform; }
360-degree spin viewer:
// SpinViewer.jsx — preloads all frames, switches on drag
export function SpinViewer({ frames, productName = 'Product' }) {
const [frameIndex, setFrameIndex] = useState(0);
const [loaded, setLoaded] = useState(false);
const dragStart = useRef(null);
useEffect(() => {
let count = 0;
frames.forEach(src => {
const img = new Image();
img.src = src;
img.onload = () => { if (++count === frames.length) setLoaded(true); };
});
}, [frames]);
function handleDragStart(e) { dragStart.current = e.clientX ?? e.touches?.[0]?.clientX; }
function handleDragMove(e) {
if (dragStart.current === null) return;
const clientX = e.clientX ?? e.touches?.[0]?.clientX;
const delta = Math.round((clientX - dragStart.current) / 8);
if (delta !== 0) {
setFrameIndex(i => ((i + delta) % frames.length + frames.length) % frames.length);
dragStart.current = clientX;
}
}
function handleDragEnd() { dragStart.current = null; }
if (!loaded) return <div aria-label="Loading 360 view">Loading...</div>;
return (
<div
onMouseDown={handleDragStart} onMouseMove={handleDragMove}
onMouseUp={handleDragEnd} onMouseLeave={handleDragEnd}
onTouchStart={handleDragStart} onTouchMove={handleDragMove} onTouchEnd={handleDragEnd}
aria-label="360 degree product view — drag to rotate"
role="img" style={{ cursor: 'ew-resize' }}
>
<img src={frames[frameIndex]} alt={`${productName}, frame ${frameIndex + 1} of ${frames.length}`} draggable={false} />
<span aria-hidden="true" style={{ fontSize: '0.75rem', color: '#666' }}>Drag to rotate</span>
</div>
);
}
Regardless of platform, follow these media guidelines:
fetchpriority="high" and loading="eager" to the first product image| Problem | Solution |
|---------|----------|
| Zoom CSS transform causes layout shift | Use will-change: transform and overflow: hidden on the container so the scaled image does not reflow siblings |
| 360 spin is jittery on mobile | Throttle frame updates to one per requestAnimationFrame; do not call setState on every touchmove event |
| Video does not autoplay on iOS | Add playsInline and muted attributes; iOS requires both for autoplay without user gesture |
| LCP score poor due to large hero image | Add fetchpriority="high" and loading="eager" to the main product image; verify with Lighthouse |
| 360 assets too large (36 × 500 KB) | Target 20–40 KB per frame at 800px wide using JPEG quality 75 through your CDN |
tools
Let shoppers save products to a wishlist, share it with friends, and get notified when saved items come back in stock or drop in price
development
Build a themeable storefront with design tokens and CSS custom properties that supports white-labeling, multi-brand variants, and dark mode
development
Speed up product discovery with instant search suggestions, fuzzy typo matching, and category-aware results powered by Algolia or Elasticsearch
development
Build a mobile-first storefront with thumb-friendly navigation, sticky add-to-cart buttons, and touch-optimized components for high mobile conversion