fCanvas Library

website·Indexed 30 days ago

https://fcanvas.js.org

A powerful 2D canvas library designed for minimal rendering and diverse shapes. It features a hierarchical structure using Stage, Layer, Group, and Shape classes, and incorporates a reactivity system with computed properties and watchers similar to Vue. The library includes a variety of built-in shapes such as Arc, Circle, Line, and Text, as well as plugins for animations (@fcanvas/animate), WebWorker support (@fcanvas/worker), and Node.js integration (@fcanvas/node).

Tokens
21.3K
Snippets
147
Records
167
Agent score
48%

What's inside fCanvas

  1. Overview of fCanvas features

    fCanvas is a 2D canvas library optimized for high-performance animations, transitions, and event handling for desktop and mobile applications. It supports layering, filtering, caching, and independent transformation (moving, scaling, rotating) of shapes. Unlike Konva.js and Fabric.js, fCanvas automatically stops redrawing when no changes are detected to increase performance and reduces the API surface to minimize package size (approximately 80kB, or 60kB when used with Vue).
  2. Overview of fCanvas 2D Canvas Library

    fCanvas is a high-performance 2D canvas library designed for minimal rendering and diverse shape support. It is a rewrite of KonvaJS aimed at reducing redundant APIs and improving redrawing performance. Key capabilities include high-performance animations, transitions, button nesting, layering, filtering, caching, and event handling for both desktop and mobile applications. It supports independent moving, scaling, and rotating of shapes, maintaining performance even with thousands of objects on stage. A primary performance optimization is that it automatically stops redrawing when no changes have occurred.
  3. Overview of the fcanvas 2D library

    fcanvas is a powerful 2D canvas JavaScript library designed for minimal rendering and providing a diverse set of shapes. It is built to be approachable by using options that closely align with CSS standards. To optimize performance and minimize redraws, it leverages the reactive capabilities of @vue/reactivity.
  4. Use watch to monitor specific reactive sources

    watch() is lazy by default and only invokes the callback when the specified source changes. Unlike watchEffect, it allows you to be specific about which state triggers the effect and provides access to both the new and old values.

    Supported sources:

    • A ref
    • A getter function returning a value
    • A reactive object (automatically enables deep: true)
    • An array of the above

    The callback receives: (newValue, oldValue, onCleanup). If watching multiple sources, newValue and oldValue are arrays corresponding to the source array.

    const state = reactive({ count: 0 })
    const countRef = ref(0)
    
    // 1. Watching a getter
    watch(() => state.count, (newVal, oldVal) => {
      console.log(`Count changed from ${oldVal} to ${newVal}`)
    })
    
    // 2. Watching a ref
    watch(countRef, (newVal, oldVal) => { /* ... */ })
    
    // 3. Watching multiple sources
    watch([countRef, () => state.count], ([newCount, newStateCount], [oldCount, oldStateCount]) => {
      /* ... */
    })
  5. Group shapes for simultaneous display and caching

    The Group class allows you to group multiple Shape objects together. It shares a similar API to Shape but includes .add(node: Shape) and .delete(node: Shape) methods, similar to those found in Layer. Grouping static elements is recommended to improve performance by avoiding continuous redrawing of elements that do not change.
    import { Stage, Layer, Group, Circle } from "fcanvas"
    
    const stage = new Stage().mount("#app")
    const layer = new Layer().addTo(stage)
    
    const group = new Group().addTo(layer)
    const circle = new Circle({ x: 20, y: 20, radius: 20, fill: "red" }).addTo(
      group
    )
  6. Understand the Shape base class

    The Shape class serves as the base for all display elements in fcanvas, including Arc and Rect. All child elements inherit the methods and properties defined in the Shape class.
  7. Understand the fcanvas node hierarchy

    fcanvas uses a virtual node hierarchy similar to the DOM. The root is the Stage, which contains one or more Layer objects. Each Layer can contain shapes, groups of shapes, or nested groups.

    Every Layer manages two <canvas> renderers: a scene renderer (visible to the user) and a hit graph renderer (a hidden canvas used for high-performance event detection).

  8. Handle high-resolution (HiDPI) displays to prevent blurriness

    To prevent canvas items from appearing blurry on high-resolution displays, scale the canvas internal dimensions by the device pixel ratio (DPR) while maintaining the CSS display size.
    // Get the DPR and size of the canvas
    const dpr = window.devicePixelRatio;
    const rect = canvas.getBoundingClientRect();
    
    // Set the "actual" size of the canvas
    canvas.width = rect.width * dpr;
    canvas.height = rect.height * dpr;
    
    // Scale the context to ensure correct drawing operations
    ctx.scale(dpr, dpr);
    
    // Set the "drawn" size of the canvas
    canvas.style.width = `${rect.width}px`;
    canvas.style.height = `${rect.height}px`;
  9. Install and initialize @fcanvas/animate

    The @fcanvas/animate plugin provides animation capabilities for fcanvas by integrating GSAP. To use it, install the plugin along with fcanvas and gsap, then call installAnimate(Stage) to enable the Animate class and its .to() method.
    pnpm add fcanvas @fcanvas/animate gsap
    import { Stage } from "fcanvas"
    import { installAnimate } from "@fcanvas/animate"
    
    installAnimate(Stage)
  10. Use reactive state to control fcanvas shapes

    fcanvas components such as Stage, Layer, and Shape (e.g., Circle) accept values as either standard primitives or reactive wrappers from the fcanvas API, such as ref, reactive, and computed. When a reactive value is updated, the corresponding property on the canvas object updates automatically.
    import { ref, computed, Circle } from "fcanvas"
    
    // Define reactive state
    const x = ref(0)
    
    // Define a computed value based on state
    const y = computed(() => x.value * 2)
    
    // Pass reactive refs/computed values to the Shape constructor
    const circle = new Circle({
      x,
      y
    })
    
    // Updating the ref value automatically updates the circle's position
    x.value = 50
  11. Optimize static backgrounds using CSS

    For static background images, avoid rendering them on the canvas every tick. Instead, use a plain <div> element with the CSS background property and position it behind the canvas element.
  12. Use reactive and computed values in fcanvas components

    fcanvas components (such as Stage, Layer, and Shape) accept property values as either primitives or reactive return values from APIs like ref, reactive, and computed. When a reactive dependency changes, the component property updates automatically.
    import { ref, computed, Circle } from "fcanvas"
    
    const x = ref(0)
    const y = computed(() => x.value * 2)
    
    // The Circle component accepts reactive refs and computed values
    const circle = new Circle({
      x,
      y
    })
    
    // Updating x.value will automatically update the circle's x and y positions
    x.value = 50