Interactive Components System

Project Overview

The Interactive Post Elements framework is a custom JavaScript system built for the QED website to make mathematical concepts more accessible through interactive visualizations, simulations, and games embedded directly within educational articles. The goal is to help readers understand complex topics through animations and hands-on interaction rather than relying solely on static text and images.

Each interactive element is a self-contained JavaScript class that can be instantiated multiple times on a page. The framework uses a plugin architecture where new element types can be added without modifying the core code.

Core Capabilities & Lifecycle Management

The framework manages the entire lifecycle of interactive elements, from initialization to cleanup.

Script Evaluation & Registration

The system parses JavaScript strings using extractAndEvaluateScripts, identifies class definitions, and maps them to a global window.interactiveElements registry. This allows dynamic loading while maintaining namespace isolation.

Lifecycle Stages

Each interactive element follows a specific lifecycle:

  1. Initialization (start): Elements are activated by placeholders (.interactive-placeholder) containing data-script, data-params, data-instance-name, and data-options attributes. The start method is async, allowing elements to load assets or fetch data before starting. It receives the container DOM element, initialization parameters, and optional saved state.

  2. Execution Loop: If a class defines a main() method, the framework calls it repeatedly using setTimeout with 10ms intervals (100 FPS), providing smooth animations while remaining CPU-friendly.

  3. Pause/Resume: Elements can be paused automatically when scrolled out of view or manually via user controls. The framework tracks whether a pause is user-initiated or automatic.

  4. Reset: Re-runs start() with original parameters and fresh state.

  5. Stop: Deletes the instance from the window object and removes DOM nodes, preventing memory leaks.

Instance Isolation

Each element instance stores its state in window[instanceName], preventing conflicts when multiple instances of the same type exist on a page.

Configuration System

Authors configure elements using data attributes and comma-separated options.

Available Options

OptionDescription
autoPlayStarts immediately without requiring user interaction
autoPauseOnScrollPauses when element is outside viewport to save CPU/battery
allowPauseAdds manual pause/resume controls
allowFullscreenEnables fullscreen mode with cross-browser support
saveStatesSaves progress to localStorage across sessions
noControlsHides the control bar entirely
noStopRemoves the stop button
openControlsShows controls panel by default
h=XSets explicit container height (converted to rem)

Performance Optimizations

Mathematical simulations, especially fractals, are computationally expensive. The framework uses several strategies to maintain performance:

Viewport-Aware Execution

The framework uses getBoundingClientRect and scroll listeners with 100px margins to detect element visibility. When autoPauseOnScroll is enabled, the execution loop stops when elements leave the viewport, preventing unnecessary CPU usage. This is particularly effective on pages with multiple interactive elements.

Memory Management

When an element stops, the framework explicitly deletes its instance from the global namespace and removes all DOM nodes. This prevents memory leaks even when users interact with many elements in a single session.

Computation Caching

Complex computations cache their results to avoid redundant calculations. For example, ComplexFractal stores iteration results in a 2D array (this.cache), allowing instant re-rendering during resize operations or color changes without recalculating Mandelbrot/Julia set iterations.

Grid Snapping

Draggable elements use grid-based positioning to minimize continuous coordinate updates. Collision detection uses Set lookups and breadth-first search for finding closest free positions, maintaining O(n) performance.

Design Philosophy & UI/UX

The interface is designed to stay out of the way and not distract from the mathematical content.

Theme Integration

The system uses a centralized color palette that automatically adapts to the website’s light/dark mode:

  • Background: gray-100 / gray-700
  • Main: gray-300 / gray-500
  • Contrast: blue-600 / blue-200

SVG lines, grid patterns, and UI buttons use these colors to remain legible and consistent. Visual elements respond to theme changes via CSS custom properties and class-based styling.

Interactive Overlays

Elements show a play button overlay before activation, preventing scripts from running until the user clicks. This reduces initial page load and gives users control over when resources are used. A loading animation provides feedback during initialization.

Responsive Scaling

Every element handles window resize events. The framework recalculates canvas dimensions, SVG viewboxes, and grid layouts to maintain correct rendering on different screen sizes. For example, the Esther Klein simulation dynamically repositions points when the viewport changes.

Internationalization

Button labels are localized based on the page language (detected from #current-lang-icon). Currently supports English and Spanish for stop, reset, pause, resume, and clear data controls.

Accessibility & Keyboard Navigation

Interactive puzzles like crosswords, KenKen, and Numbrix support arrow key navigation for moving between cells without a mouse. Touch targets are at least 20px for mobile usability. Semantic HTML helps screen readers, and high contrast colors work in both light and dark themes.

Collapsible Controls

The control panel uses CSS transitions for smooth height changes. An arrow icon rotates 180° when toggling. Controls are generated dynamically based on enabled options, reducing clutter.

Fullscreen Support

The framework implements the fullscreen API with vendor prefixes for Firefox, Chrome, Safari, and IE/Edge. SVG icons switch between enter/exit states, and border radius adjusts to maintain visual consistency.

State Management

LocalStorage Persistence

When saveStates is enabled, elements can save user progress across sessions using this structure:

{
  "article-url": {
    "ElementClassName": {
      "instanceName": savedStateData
    }
  }
}

The framework provides saveData(data) and clearData() methods, handling nested object updates and automatic cleanup when entries become empty.

State Recovery

On initialization, if saved state exists for the current URL, script name, and instance name, it’s passed to the element’s start() method. This allows puzzles like crosswords to resume from where users left off. Language-dependant elements like crosswords can have different instance names for each language, while elements that don’t depend on language like Esther Klein can share the same insteance name, allowing data transfer.

Extensibility

New interactive elements implement this interface:

class CustomElement {
    async start(container, params, savedState) {
        // Initialize DOM, parse parameters, restore state
        // Set up event listeners and create structure
    }

    async main() {
        // Called every ~10ms when running
        // Update animations, physics, or game state
    }
}

The framework automatically provides:

  • Lifecycle management (pause/resume/reset/stop)
  • Control generation
  • Theme integration through color constants
  • State persistence API
  • Fullscreen capabilities
  • Viewport visibility detection

Sub-Projects in this Folder

JavaScript
Tailwind CSS

KenKen Logic Puzzle

An implementation of the KenKen mathematical puzzle requiring logic and arithmetic operations.

JavaScript
Tailwind CSS

Numbrix Path Puzzle

A sequential logic puzzle where players must complete a path of consecutive numbers.

JavaScript

Bach Raised to Twelve

An exploration of mathematical music theory through audio synthesis.

JavaScript
Tailwind CSS

Interactive Crossword

A dynamic crossword puzzle engine featuring real-time validation and grid management.

JavaScript
Tailwind CSS

Esther Klein Theorem

Visualizing the Happy Ending problem in computational geometry.

JavaScript
Tailwind CSS
WebGL

The Fractal Dimension

A comprehensive suite of fractal generators including Cantor, Sierpinski, and Koch curves.

Technologies used

JavaScript
Tailwind CSS
WebGL