All skills
freshtechbro avatar

/lightweight-3d-effects

@1da73fe

Lightweight 3D effects for decorative elements and micro-interactions using Zdog, Vanta.js, and Vanilla-Tilt.js. Use this skill when adding pseudo-3D illustrations, animated backgrounds, parallax tilt effects, decorative 3D elements, or subtle depth effects without heavy frameworks. Triggers on tasks involving Zdog pseudo-3D, Vanta.js backgrounds, Vanilla-Tilt parallax, card tilt effects, hero section animations, or lightweight landing page visuals. Ideal for performance-focused designs.

Use this Skill: https://skilld.dev/gh/freshtechbro/claudedesignskills/lightweight-3d-effects

This session only. Nothing lands on disk.

referenceszdog_api.md

≈5.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Zdog API Reference

Complete API documentation for Zdog - a pseudo-3D engine for canvas and SVG.

Version: 1.1.3 License: MIT CDN: https://unpkg.com/zdog@1/dist/zdog.dist.min.js


Table of Contents

  1. Core Classes
  2. Shape Types
  3. Properties
  4. Methods
  5. Animation
  6. Advanced Techniques

Core Classes

Zdog.Illustration

The root display object that manages the scene and rendering.

let illo = new Zdog.Illustration({
  element: '.zdog-canvas',  // CSS selector or DOM element
  zoom: 4,                  // Scale multiplier
  dragRotate: false,        // Enable drag-to-rotate
  resize: false,            // Auto-resize to element
  centered: true,           // Center origin
  onDragStart: function() {},
  onDragMove: function() {},
  onDragEnd: function() {},
  onResize: function(width, height) {}
});
Properties
Property Type Default Description
element String|Element Required Canvas or SVG element
zoom Number 1 Scale multiplier
dragRotate Boolean|Zdog.Anchor false Enable drag rotation
resize Boolean false Auto-resize to fit element
centered Boolean true Center scene at origin
rotate Zdog.Vector {x:0,y:0,z:0} Rotation in radians
translate Zdog.Vector {x:0,y:0,z:0} Position offset
Methods
// Render scene
illo.updateRenderGraph();

// Update size
illo.setSize(width, height);

Zdog.Anchor

Group container for organizing and transforming child shapes.

let group = new Zdog.Anchor({
  addTo: illo,
  translate: { x: 0, y: 0, z: 0 },
  rotate: { x: 0, y: 0, z: 0 },
  scale: 1
});
Properties
Property Type Default Description
addTo Zdog.Anchor null Parent object
translate Object {x:0,y:0,z:0} Position
rotate Object {x:0,y:0,z:0} Rotation (radians)
scale Number|Object 1 Uniform or {x,y,z} scale
Methods
// Add child
group.addChild(shape);

// Remove child
group.removeChild(shape);

// Remove from parent
group.remove();

// Copy all properties
let copy = group.copy();

// Copy with options
let copy = group.copyGraph({
  translate: { x: 10 }
});

Zdog.Shape

Base class for all rendered shapes (usually not used directly).

let shape = new Zdog.Shape({
  addTo: group,
  stroke: 1,
  fill: false,
  color: '#333',
  visible: true,
  backface: true
});
Common Shape Properties
Property Type Default Description
stroke Number 1 Line thickness
fill Boolean false Fill shape interior
color String '#333' CSS color value
visible Boolean true Render visibility
backface Boolean|String true Show back face / color
front Object {z:0} Front face offset
closed Boolean true Close path

Shape Types

Ellipse

Circle or ellipse shape.

new Zdog.Ellipse({
  addTo: illo,
  diameter: 80,        // Circle
  // OR
  width: 80,           // Ellipse width
  height: 40,          // Ellipse height
  quarters: 4,         // Number of curve segments
  stroke: 20,
  color: '#636',
  fill: true
});
Properties
Property Type Default Description
diameter Number 1 Circle diameter
width Number diameter Ellipse width
height Number diameter Ellipse height
quarters Number 4 Bezier curve segments (4 = smooth)

Rect

Rectangle shape.

new Zdog.Rect({
  addTo: illo,
  width: 80,
  height: 60,
  stroke: 2,
  color: '#E62',
  fill: true
});
Properties
Property Type Default Description
width Number 1 Rectangle width
height Number 1 Rectangle height

RoundedRect

Rectangle with rounded corners.

new Zdog.RoundedRect({
  addTo: illo,
  width: 80,
  height: 60,
  cornerRadius: 10,
  stroke: 2,
  color: '#E62',
  fill: true
});
Properties
Property Type Default Description
width Number 1 Rectangle width
height Number 1 Rectangle height
cornerRadius Number 0 Corner curve radius

Polygon

Multi-sided polygon shape.

// Triangle
new Zdog.Polygon({
  addTo: illo,
  sides: 3,
  radius: 40,
  stroke: 2,
  color: '#EA0',
  fill: true
});

// Pentagon
new Zdog.Polygon({
  sides: 5,
  radius: 40
});

// Star (using path hack)
new Zdog.Polygon({
  sides: 5,
  radius: 40,
  rotate: { z: -Math.PI/2 }
});
Properties
Property Type Default Description
sides Number 3 Number of sides
radius Number 1 Distance from center

Line

Straight line segment.

new Zdog.Shape({
  addTo: illo,
  path: [
    { x: -40, y: 0, z: 0 },  // Start point
    { x: 40, y: 0, z: 0 }    // End point
  ],
  stroke: 4,
  color: '#636'
});

Bezier

Bezier curve path.

new Zdog.Shape({
  addTo: illo,
  path: [
    { x: -40, y: 0 },           // Start
    {
      bezier: [
        { x: -20, y: -40 },     // Control point 1
        { x: 20, y: -40 },      // Control point 2
        { x: 40, y: 0 }         // End point
      ]
    }
  ],
  stroke: 4,
  color: '#E62'
});

Hemisphere

Half-sphere shape.

new Zdog.Hemisphere({
  addTo: illo,
  diameter: 80,
  stroke: 5,
  color: '#EA0',
  fill: true,
  // Render semi-circles
});
Properties
Property Type Default Description
diameter Number 1 Sphere diameter

Cylinder

Cylindrical shape.

new Zdog.Cylinder({
  addTo: illo,
  diameter: 80,
  length: 120,
  stroke: 5,
  color: '#636',
  fill: true,
  frontFace: '#EA0',   // Front cap color
  backface: '#E62'     // Back cap color
});
Properties
Property Type Default Description
diameter Number 1 Cylinder diameter
length Number 1 Cylinder length (depth)
frontFace String|Boolean true Front cap color

Cone

Conical shape.

new Zdog.Cone({
  addTo: illo,
  diameter: 80,
  length: 120,
  stroke: 5,
  color: '#636',
  fill: true,
  backface: '#E62'
});
Properties
Property Type Default Description
diameter Number 1 Base diameter
length Number 1 Cone height

Box

3D box shape (composed of rectangles).

new Zdog.Box({
  addTo: illo,
  width: 80,
  height: 100,
  depth: 60,
  stroke: 2,
  color: '#C25',
  fill: true,
  frontFace: '#EA0',
  rearFace: '#E62',
  leftFace: '#636',
  rightFace: '#C25',
  topFace: '#EA0',
  bottomFace: '#E62'
});
Properties
Property Type Default Description
width Number 1 Box width (x-axis)
height Number 1 Box height (y-axis)
depth Number 1 Box depth (z-axis)
frontFace String|Boolean true Front face color
rearFace String|Boolean true Rear face color
leftFace String|Boolean true Left face color
rightFace String|Boolean true Right face color
topFace String|Boolean true Top face color
bottomFace String|Boolean true Bottom face color

Properties

Transform Properties

Available on all Zdog.Anchor and Zdog.Shape objects.

translate

Position in 3D space.

shape.translate = { x: 0, y: 0, z: 0 };
shape.translate.x = 10;
shape.translate.y += 5;
rotate

Rotation in radians around each axis.

shape.rotate = { x: 0, y: 0, z: 0 };
shape.rotate.y = Math.PI / 4;  // 45 degrees
shape.rotate.z += 0.03;        // Incremental

Helper: Convert degrees to radians

const TAU = Math.PI * 2;
let degrees = 90;
let radians = degrees / 360 * TAU;
scale

Uniform or per-axis scaling.

// Uniform scale
shape.scale = 2;

// Per-axis scale
shape.scale = { x: 1, y: 2, z: 1 };

Appearance Properties

color

CSS color string.

shape.color = '#E62';
shape.color = 'rgb(255, 100, 50)';
shape.color = 'hsl(200, 100%, 50%)';
stroke

Line thickness.

shape.stroke = 10;
fill

Fill interior of closed shapes.

shape.fill = true;
visible

Control rendering visibility.

shape.visible = false;  // Hidden but still in scene
backface

Control back face rendering.

// Show back face with same color
shape.backface = true;

// Hide back face
shape.backface = false;

// Different back face color
shape.backface = '#EA0';

Methods

Rendering

updateRenderGraph()

Update and render the entire scene graph.

function animate() {
  illo.rotate.y += 0.03;
  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}

Important: Must call on root Illustration, not individual shapes.


Hierarchy

addChild(shape)

Add a child shape to an anchor.

let group = new Zdog.Anchor({ addTo: illo });
let shape = new Zdog.Ellipse({ diameter: 40 });
group.addChild(shape);
removeChild(shape)

Remove a child from an anchor.

group.removeChild(shape);
remove()

Remove shape from its parent.

shape.remove();

Copying

copy(options)

Create a duplicate of a shape.

let original = new Zdog.Ellipse({
  addTo: illo,
  diameter: 40,
  color: '#636'
});

let duplicate = original.copy({
  translate: { x: 50 },
  color: '#E62'
});
copyGraph(options)

Copy shape including all children.

let group = new Zdog.Anchor({ addTo: illo });
// ... add children ...

let groupCopy = group.copyGraph({
  translate: { x: 100 }
});

Animation

Basic Animation Loop

let illo = new Zdog.Illustration({
  element: '.zdog-canvas'
});

let shape = new Zdog.Ellipse({
  addTo: illo,
  diameter: 80,
  stroke: 20,
  color: '#636'
});

function animate() {
  // Update properties
  shape.rotate.y += 0.03;

  // Render
  illo.updateRenderGraph();

  // Loop
  requestAnimationFrame(animate);
}

animate();

Rotation Animation

// Continuous rotation
function animate() {
  illo.rotate.y += 0.03;
  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}

// Rotate specific shape
function animate() {
  shape.rotate.z += 0.05;
  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}

// Multi-axis rotation
function animate() {
  shape.rotate.x += 0.02;
  shape.rotate.y += 0.03;
  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}

Position Animation

let time = 0;

function animate() {
  time += 0.05;

  // Sine wave motion
  shape.translate.y = Math.sin(time) * 40;

  // Circular motion
  shape.translate.x = Math.cos(time) * 50;
  shape.translate.y = Math.sin(time) * 50;

  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}

Scale Animation

let time = 0;

function animate() {
  time += 0.05;

  // Pulsing scale
  let scale = 1 + Math.sin(time) * 0.3;
  shape.scale = scale;

  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}

Color Animation

Zdog doesn't support direct color interpolation. Use external libraries or manual RGB interpolation.

// Manual RGB interpolation
function lerpColor(color1, color2, t) {
  let r1 = parseInt(color1.substr(1,2), 16);
  let g1 = parseInt(color1.substr(3,2), 16);
  let b1 = parseInt(color1.substr(5,2), 16);

  let r2 = parseInt(color2.substr(1,2), 16);
  let g2 = parseInt(color2.substr(3,2), 16);
  let b2 = parseInt(color2.substr(5,2), 16);

  let r = Math.round(r1 + (r2 - r1) * t);
  let g = Math.round(g1 + (g2 - g1) * t);
  let b = Math.round(b1 + (b2 - b1) * t);

  return `#${r.toString(16).padStart(2,'0')}${g.toString(16).padStart(2,'0')}${b.toString(16).padStart(2,'0')}`;
}

let time = 0;
function animate() {
  time += 0.05;
  let t = (Math.sin(time) + 1) / 2;  // 0 to 1
  shape.color = lerpColor('#636', '#E62', t);

  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}

Easing

Use easing functions for smooth animations.

// Easing functions
const easing = {
  linear: t => t,
  easeInOut: t => t < 0.5
    ? 2 * t * t
    : -1 + (4 - 2 * t) * t,
  easeOut: t => t * (2 - t),
  easeIn: t => t * t
};

// Animate with easing
let progress = 0;
function animate() {
  progress += 0.01;
  if (progress > 1) progress = 0;

  let eased = easing.easeInOut(progress);
  shape.translate.x = eased * 100 - 50;

  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}

Interactive Animation

let isDragging = false;

let illo = new Zdog.Illustration({
  element: '.zdog-canvas',
  dragRotate: true,
  onDragStart: function() {
    isDragging = true;
  },
  onDragEnd: function() {
    isDragging = false;
  }
});

// Auto-rotate when not dragging
function animate() {
  if (!isDragging) {
    illo.rotate.y += 0.01;
  }
  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}

Advanced Techniques

Custom Paths

Create complex shapes using path arrays.

new Zdog.Shape({
  addTo: illo,
  path: [
    { x: 0, y: -40 },           // Start point
    { x: 40, y: 0 },            // Line to
    { x: 0, y: 40 },            // Line to
    { x: -40, y: 0 },           // Line to
  ],
  closed: true,
  stroke: 4,
  color: '#636',
  fill: true
});

Bezier Curves

new Zdog.Shape({
  addTo: illo,
  path: [
    { x: -60, y: 0 },
    {
      bezier: [
        { x: -30, y: -60 },    // Control 1
        { x: 30, y: -60 },     // Control 2
        { x: 60, y: 0 }        // End point
      ]
    },
    {
      bezier: [
        { x: 30, y: 60 },
        { x: -30, y: 60 },
        { x: -60, y: 0 }
      ]
    }
  ],
  closed: true,
  stroke: 4,
  color: '#E62',
  fill: true
});

Arc Curves

new Zdog.Shape({
  addTo: illo,
  path: [
    { x: -40, y: 0 },
    {
      arc: [
        { x: 0, y: -40 },      // Corner
        { x: 40, y: 0 }        // End
      ]
    }
  ],
  stroke: 4,
  color: '#636'
});

Complex Models

Build complex 3D objects using groups.

// Robot example
let robot = new Zdog.Anchor({
  addTo: illo,
  translate: { y: -40 }
});

// Head
new Zdog.Box({
  addTo: robot,
  width: 40,
  height: 40,
  depth: 40,
  stroke: 2,
  color: '#636',
  topFace: '#EA0',
  bottomFace: '#E62'
});

// Body
new Zdog.Box({
  addTo: robot,
  translate: { y: 50 },
  width: 50,
  height: 60,
  depth: 40,
  stroke: 2,
  color: '#636'
});

// Arms (group for symmetry)
[-1, 1].forEach(xSide => {
  new Zdog.Box({
    addTo: robot,
    translate: { x: xSide * 40, y: 50 },
    width: 20,
    height: 60,
    depth: 20,
    stroke: 2,
    color: '#C25'
  });
});

// Legs
[-1, 1].forEach(xSide => {
  new Zdog.Box({
    addTo: robot,
    translate: { x: xSide * 15, y: 100 },
    width: 20,
    height: 60,
    depth: 20,
    stroke: 2,
    color: '#C25'
  });
});

// Animate
function animate() {
  robot.rotate.y += 0.03;
  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}
animate();

Instancing

Efficiently create multiple copies.

// Create template
let sphere = new Zdog.Hemisphere({
  diameter: 20,
  stroke: 2,
  color: '#636',
  fill: true
});

// Instance grid
for (let x = -100; x <= 100; x += 40) {
  for (let y = -100; y <= 100; y += 40) {
    sphere.copy({
      addTo: illo,
      translate: { x, y },
      color: `hsl(${(x+100)/2}, 70%, 50%)`
    });
  }
}

Responsive Sizing

Make Zdog canvas responsive to container.

let illo = new Zdog.Illustration({
  element: '.zdog-canvas',
  resize: true,
  onResize: function(width, height) {
    // Adjust zoom based on size
    this.zoom = Math.min(width, height) / 200;
  }
});

// Manual resize handling
function handleResize() {
  let container = document.querySelector('.zdog-container');
  illo.setSize(container.offsetWidth, container.offsetHeight);
}

window.addEventListener('resize', handleResize);
handleResize();

Performance Optimization

1. Limit Update Frequency

let needsUpdate = false;

element.addEventListener('mousemove', () => {
  needsUpdate = true;
});

function animate() {
  if (needsUpdate) {
    illo.updateRenderGraph();
    needsUpdate = false;
  }
  requestAnimationFrame(animate);
}

2. Use Visibility

// Hide off-screen objects
shapes.forEach(shape => {
  shape.visible = isInView(shape);
});

3. Throttle Drag Rotation

let lastUpdate = 0;

let illo = new Zdog.Illustration({
  element: '.zdog-canvas',
  dragRotate: true,
  onDragMove: function() {
    const now = Date.now();
    if (now - lastUpdate > 16) {  // ~60fps
      this.updateRenderGraph();
      lastUpdate = now;
    }
  }
});

SVG vs Canvas

Canvas (default):

  • Better performance
  • Smaller file size
  • Rasterized output
let illo = new Zdog.Illustration({
  element: 'canvas'  // Canvas element
});

SVG:

  • Vector output (scalable)
  • Accessible/indexable
  • Slower performance
let illo = new Zdog.Illustration({
  element: 'svg'  // SVG element
});

Coordinate System

Zdog uses a right-handed coordinate system:

  • X-axis: Right (+) / Left (-)
  • Y-axis: Down (+) / Up (-)
  • Z-axis: Forward (+) / Back (-)
// Move right
shape.translate.x = 50;

// Move up
shape.translate.y = -50;

// Move forward
shape.translate.z = 50;

Rotation Order

Rotations apply in ZYX order (z-axis first, then y, then x).

shape.rotate = {
  x: Math.PI / 4,   // Pitch (applied last)
  y: Math.PI / 6,   // Yaw (applied second)
  z: Math.PI / 8    // Roll (applied first)
};

Common Patterns

Clickable Shapes

Zdog doesn't have built-in click detection. Use canvas coordinates.

let canvas = document.querySelector('canvas');

canvas.addEventListener('click', (event) => {
  let rect = canvas.getBoundingClientRect();
  let x = event.clientX - rect.left;
  let y = event.clientY - rect.top;

  // Check if click is near shape (approximate)
  let shapeX = shape.translate.x * illo.zoom + canvas.width / 2;
  let shapeY = shape.translate.y * illo.zoom + canvas.height / 2;

  let distance = Math.sqrt(
    Math.pow(x - shapeX, 2) +
    Math.pow(y - shapeY, 2)
  );

  if (distance < 50) {
    console.log('Shape clicked!');
  }
});

Sprite Sheets

Animate through multiple Zdog illustrations.

let frames = [];

// Create frames
for (let i = 0; i < 10; i++) {
  let illo = new Zdog.Illustration({
    element: '.canvas',
    zoom: 4
  });

  let shape = new Zdog.Ellipse({
    addTo: illo,
    diameter: 20,
    rotate: { y: i * Math.PI / 10 }
  });

  illo.updateRenderGraph();
  frames.push(illo);
}

// Play frames
let currentFrame = 0;
function animate() {
  currentFrame = (currentFrame + 1) % frames.length;
  frames[currentFrame].updateRenderGraph();
  requestAnimationFrame(animate);
}

Particle Systems

Create simple particle effects.

let particles = [];

for (let i = 0; i < 50; i++) {
  particles.push({
    shape: new Zdog.Ellipse({
      addTo: illo,
      diameter: 4,
      stroke: 2,
      color: '#636'
    }),
    velocity: {
      x: (Math.random() - 0.5) * 4,
      y: (Math.random() - 0.5) * 4
    }
  });
}

function animate() {
  particles.forEach(p => {
    p.shape.translate.x += p.velocity.x;
    p.shape.translate.y += p.velocity.y;

    // Bounce off edges
    if (Math.abs(p.shape.translate.x) > 100) {
      p.velocity.x *= -1;
    }
    if (Math.abs(p.shape.translate.y) > 100) {
      p.velocity.y *= -1;
    }
  });

  illo.updateRenderGraph();
  requestAnimationFrame(animate);
}

TypeScript Support

Zdog includes TypeScript definitions.

import Zdog from 'zdog';

const illo: Zdog.Illustration = new Zdog.Illustration({
  element: '.zdog-canvas',
  zoom: 4
});

const shape: Zdog.Ellipse = new Zdog.Ellipse({
  addTo: illo,
  diameter: 80,
  stroke: 20,
  color: '#636'
});

Browser Support

  • Chrome: ✅ Full support
  • Firefox: ✅ Full support
  • Safari: ✅ Full support
  • Edge: ✅ Full support
  • IE11: ⚠️ Requires polyfills

Resources


License

MIT License - Free for commercial and personal use.

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill provides a suite of templates and scripts for creating lightweight 3D web effects. No malicious behaviors were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    11 files scanned · No issues

  • ZeroLeaks5mo

    1 finding · Score: 86/100

Signed by skilld at 1da73fe. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 11 months ago

README badge

README badge for freshtechbro/claudedesignskills/lightweight-3d-effects