Socket
Socket
Sign inDemoInstall

@dldc/canvas

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@dldc/canvas - npm Package Compare versions

Comparing version 1.2.5 to 1.2.6

dist/mod.cjs

230

dist/mod.d.ts

@@ -38,16 +38,28 @@ import * as _dldc_stack from '@dldc/stack';

interface IScreduler {
/**
* Simple abstraction on top of requestAnimationFrame
*/
interface IScheduler {
/**
* Start the animation loop and reset the time
*/
start(): void;
/**
* Get the time relative to the start of the animation loop
* This value is updated on each frame.
*/
time(): number;
start(): void;
stop(): void;
}
declare const Screduler: {
create: (onFrame: (t: number) => void) => IScreduler;
declare const Scheduler: {
create: (onFrame: (t: number) => void) => IScheduler;
};
declare class Tools extends Stack {
static create(ctx: CanvasRenderingContext2D, scheduler: IScreduler): Tools;
static create(view: IFrame, scheduler: IScheduler): Tools;
static CtxKey: _dldc_stack.TKey<CanvasRenderingContext2D, false>;
static SchedulerKey: _dldc_stack.TKey<IScreduler, false>;
static SchedulerKey: _dldc_stack.TKey<IScheduler, false>;
static FrameKey: _dldc_stack.TKey<IFrame, false>;
get ctx(): CanvasRenderingContext2D;
get frame(): IFrame;
time(): number;

@@ -57,6 +69,38 @@ protected instantiate(stackCore: TStackCoreValue): this;

/**
* This is a layer
*/
interface ILayer {
readonly ref: ILayerRef;
readonly mount: TMountLayerFn;
}
declare const INTERNAL: unique symbol;
type TMountLayerFn = (tools: Tools) => ILayerLifecycles;
interface ILayerLifecycles {
/**
* Called when the pointers are updated (added, removed, moved)
* Return the pointers that should be passed to the children
*/
readonly pointers?: TPointersLifecycle;
/**
* Called when an event is triggered
* When an event handled, it should return true
* This is used in merged to stop propagation to sibling layers
*/
readonly event?: TEventLifecycle;
/**
* Run on each frame, return an array of rects that need to be redrawn (or null)
*/
readonly update?: TUpdateLifecycle;
/**
* Is called for each rect returned by update
*/
readonly draw?: TDrawLifecycle;
/**
* Cleanup is called when the layer is unmounted
*/
readonly cleanup?: TCleanupLifecycle;
}
type TLayerLifecyclesMutable = Mutable<ILayerLifecycles>;
type Mutable<Type> = {
-readonly [Key in keyof Type]: Type[Key];
};
interface IUpdateParams {

@@ -112,29 +156,22 @@ t: number;

type TPointersLifecycle = (pointers: IPointers) => IPointers;
interface ILayerLifecyclesMutable {
pointers?: TPointersLifecycle;
event?: TEventLifecycle;
update?: TUpdateLifecycle;
draw?: TDrawLifecycle;
cleanup?: TCleanupLifecycle;
/**
*
*/
interface IBoxLayer<Child extends ILayer> extends ILayer {
readonly children: Child;
width: number;
height: number;
x: number;
y: number;
}
type ILayerLifecycles = Readonly<ILayerLifecyclesMutable>;
type ILayerFn = (tools: Tools) => ILayerLifecycles;
interface ILayerRef {
[INTERNAL]: ILayerFn;
interface IBoxLayerOptions<Child extends ILayer> {
children: Child;
width?: number;
height?: number;
x?: number;
y?: number;
}
declare const Layer: {
createRef: (fn: ILayerFn) => ILayerRef;
mount: (ref: ILayerRef, tools: Tools) => ILayerLifecycles;
merge: (...layersLifecycles: ILayerLifecycles[]) => ILayerLifecycles;
};
declare function BoxLayer<Child extends ILayer>({ children, x, y, height, width, }: IBoxLayerOptions<Child>): IBoxLayer<Child>;
interface IEventManager {
getPointers(): ReadonlyArray<IPointer>;
flushEvents(): ReadonlyArray<IEventAny>;
destroy(): void;
}
declare const EventManager: {
create: (el: HTMLElement | Window) => IEventManager;
};
interface IGroup<Child extends ILayer> extends ILayer {

@@ -153,69 +190,35 @@ readonly children: ReadonlyArray<Child>;

interface IHitDrawParams {
ctx: CanvasRenderingContext2D;
rect: IRect;
}
type THitDraw = (params: IHitDrawParams) => void;
interface IHitResponder extends ILayerLifecycles {
setDraw(draw: THitDraw): void;
onPointerMove: SubscribeMethod<IEvent<'PointerMove'>>;
onPointerEnter: SubscribeMethod<IEvent<'PointerEnter'>>;
onPointerLeave: SubscribeMethod<IEvent<'PointerLeave'>>;
}
declare const HitResponder: {
create: () => IHitResponder;
};
/**
* Apply pixelRation to canvas scale and view
*/
declare function PixelRatio(child: ILayer): ILayer;
type TUnregister = () => void;
interface IHitObject<T> {
register(value: T): TUnregister;
responders: Set<T>;
color: string;
/**
* A value that meant to be commited on update
*/
interface IVariable<T> {
value: T;
commit(): boolean;
}
interface IHitView {
readonly canvas: HTMLCanvasElement;
readonly context: CanvasRenderingContext2D;
prepare(x: number, y: number): void;
getHitColor(): string | null;
}
declare const HitView: {
create: () => IHitView;
};
declare function Variable<T>(init: T): IVariable<T>;
/**
* Array witgh some extra methods
* A value that meant to be commited on update
*/
interface IList<T> {
readonly raw: Array<T>;
readonly size: number;
at(index: number): T | undefined;
push(value: T): void;
remove(value: T): T | undefined;
insertAt(index: number, value: T): void;
removeAt(index: number): void;
has(value: T): boolean;
forEach(fn: (value: T, index: number) => void): void;
map<U>(fn: (value: T, index: number) => U): Array<U>;
forEachSafe(fn: (value: T, index: number) => void): void;
mapSafe<U>(fn: (value: T, index: number) => U): Array<U>;
interface IVariables<T extends Record<string, any>> {
get<K extends keyof T>(key: K): T[K];
set<K extends keyof T>(key: K, value: T[K]): void;
commit(): boolean;
}
declare const List: {
create: <T>(init?: Iterable<T> | undefined) => IList<T>;
};
declare function Variables<T extends Record<string, any>>(init: T): IVariables<T>;
type TReleasePointer = () => void;
interface IPointerCaptureManager<Target> {
capturePointer(target: Target, pointerId: number): TReleasePointer;
hasCapture(pointerId: number): boolean;
getCapture(pointerId: number): Target | undefined;
interface IEventManager {
getPointers(): ReadonlyArray<IPointer>;
flushEvents(): ReadonlyArray<IEventAny>;
destroy(): void;
}
declare const PointerCaptureManager: {
create: <Target>() => IPointerCaptureManager<Target>;
declare const EventManager: {
create: (el: HTMLElement | Window) => IEventManager;
};
declare const Random: {
sequenceOfUniqueColor: () => () => string;
sequenceOfUnique: (intermediateOffset: number, seedBase?: number) => () => number;
};
interface Options {

@@ -228,5 +231,15 @@ name?: string;

*/
interface IView {
interface IFrame {
/**
* Canvas size and position in the page
*/
readonly outerSize: ISize;
/**
* View inside the canvas. Origin is always 0,0. Size is outerSize * pixelRatio
*/
readonly view: IRect;
/**
* Pixel ratio of the canvas
*/
readonly pixelRatio: number;
readonly container: HTMLElement;

@@ -236,11 +249,33 @@ readonly canvas: HTMLCanvasElement;

update(): boolean;
prepare(): void;
destroy(): void;
}
declare const View: ({ target, name }: Options) => IView;
declare const Frame: ({ target, name }: Options) => IFrame;
interface IHitDrawParams {
ctx: CanvasRenderingContext2D;
rect: IRect;
}
type THitDraw = (params: IHitDrawParams) => void;
interface IHitResponder extends ILayerLifecycles {
setDraw(draw: THitDraw): void;
onPointerMove: SubscribeMethod<IEvent<'PointerMove'>>;
onPointerEnter: SubscribeMethod<IEvent<'PointerEnter'>>;
onPointerLeave: SubscribeMethod<IEvent<'PointerLeave'>>;
}
declare const HitResponder: {
create: () => IHitResponder;
};
declare const Layer: {
merge: (...layersLifecycles: ILayerLifecycles[]) => ILayerLifecycles;
};
/**
* Connect everything together
* - Create a View
*/
interface IRenderer<RootLayer extends ILayer> {
readonly layer: RootLayer;
readonly scheduler: IScreduler;
readonly view: IView;
readonly scheduler: IScheduler;
readonly view: IFrame;
destroy(): void;

@@ -259,2 +294,7 @@ }

export { EventManager, Geometry, Group, HitResponder, HitView, IBox, IDrawParams, IEvent, IEventAny, IEventManager, IEventName, IGroup, IGroupOptions, IHitDrawParams, IHitObject, IHitResponder, IHitView, ILayer, ILayerFn, ILayerLifecycles, ILayerLifecyclesMutable, ILayerRef, IList, IPointer, IPointerCaptureManager, IPointers, IPosition, IRect, IRenderer, IRendererOptions, IScreduler, ISize, IUpdateParams, IView, Layer, List, PointerCaptureManager, Random, Renderer, Screduler, TCleanupLifecycle, TDrawLifecycle, TEventLifecycle, THandled, THitDraw, TPointersLifecycle, TReleasePointer, TUnregister, TUpdateLifecycle, Tools, View };
declare const Random: {
sequenceOfUniqueColor: () => () => string;
sequenceOfUnique: (intermediateOffset: number, seedBase?: number) => () => number;
};
export { BoxLayer, EventManager, Frame, Geometry, Group, HitResponder, type IBox, type IBoxLayer, type IBoxLayerOptions, type IDrawParams, type IEvent, type IEventAny, type IEventManager, type IEventName, type IFrame, type IGroup, type IGroupOptions, type IHitDrawParams, type IHitResponder, type ILayer, type ILayerLifecycles, type IPointer, type IPointers, type IPosition, type IRect, type IRenderer, type IRendererOptions, type IScheduler, type ISize, type IUpdateParams, type IVariable, type IVariables, Layer, type Mutable, PixelRatio, Random, Renderer, Scheduler, type TCleanupLifecycle, type TDrawLifecycle, type TEventLifecycle, type THandled, type THitDraw, type TLayerLifecyclesMutable, type TMountLayerFn, type TPointersLifecycle, type TUpdateLifecycle, Tools, Variable, Variables };

@@ -1,42 +0,291 @@

"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
// src/base/Variables.ts
function Variables(init) {
let current = { ...init };
let next = { ...init };
return {
get(key) {
return next[key];
},
set(key, value) {
next[key] = value;
},
commit() {
if (current !== next) {
current = { ...next };
next = { ...next };
return true;
}
return false;
}
};
}
// src/base/BoxLayer.ts
function BoxLayer({
children,
x = 0,
y = 0,
height = 100,
width = 100
}) {
const $coords = Variables({ x, y, width, height });
return {
children,
get x() {
return $coords.get("x");
},
set x(value) {
$coords.set("x", value);
},
get y() {
return $coords.get("y");
},
set y(value) {
$coords.set("y", value);
},
get width() {
return $coords.get("width");
},
set width(value) {
$coords.set("width", value);
},
get height() {
return $coords.get("height");
},
set height(value) {
$coords.set("height", value);
},
mount(tools) {
const childLifecycles = children.mount(tools);
return {
...childLifecycles,
update: ({ view, t }) => {
const changed = $coords.commit();
const subView = [$coords.get("x"), $coords.get("y"), $coords.get("width"), $coords.get("height")];
const childRects = childLifecycles.update?.({ view: subView, t }) ?? null;
return changed ? [view, ...childRects ?? []] : childRects;
},
draw({ view, ...rest }) {
const subView = [$coords.get("x"), $coords.get("y"), $coords.get("width"), $coords.get("height")];
childLifecycles.draw?.({ ...rest, view: subView });
}
};
}
};
}
// src/core/Layer.ts
var Layer = /* @__PURE__ */ (() => {
return { merge };
function merge(...layersLifecycles) {
const merged = {};
const events = layersLifecycles.map((l) => l.event).filter(isNotNil).reverse();
if (events.length > 0) {
merged.event = (event) => events.reduce((acc, e) => !acc && e(event), false);
}
const pointersLifecycles = layersLifecycles.map((l) => l.pointers).filter(isNotNil).reverse();
if (pointersLifecycles.length > 0) {
merged.pointers = (pointers) => pointersLifecycles.reduce((pointers2, fn) => fn(pointers2), pointers);
}
const updates = layersLifecycles.map((l) => l.update).filter(isNotNil);
if (updates.length > 0) {
merged.update = (params) => {
const rects = updates.map((u) => u(params)).filter(isNotNil).flat();
if (rects.length === 0) {
return null;
}
return rects;
};
}
const draws = layersLifecycles.map((l) => l.draw).filter(isNotNil);
if (draws.length > 0) {
merged.draw = (params) => draws.forEach((d) => d(params));
}
const cleanups = layersLifecycles.map((l) => l.cleanup).filter(isNotNil);
if (cleanups.length > 0) {
merged.cleanup = () => cleanups.forEach((c) => c());
}
return merged;
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
function isNotNil(v) {
return v !== null && v !== void 0;
}
})();
// src/mod.ts
var mod_exports = {};
__export(mod_exports, {
EventManager: () => EventManager,
Geometry: () => Geometry,
Group: () => Group,
HitResponder: () => HitResponder,
HitView: () => HitView,
Layer: () => Layer,
List: () => List,
PointerCaptureManager: () => PointerCaptureManager,
Random: () => Random,
Renderer: () => Renderer,
Screduler: () => Screduler,
Tools: () => Tools,
View: () => View
});
module.exports = __toCommonJS(mod_exports);
// src/utils/List.ts
var List = /* @__PURE__ */ (() => {
return { create };
function create(init) {
const data = init ? Array.from(init) : [];
return {
raw: data,
get size() {
return data.length;
},
at,
push,
insertAt,
has,
remove,
removeAt,
forEach,
map,
forEachSafe,
mapSafe
};
function at(index) {
return data[index];
}
function push(value) {
data.push(value);
}
function insertAt(index, value) {
data.splice(index, 0, value);
}
function has(value) {
return data.includes(value);
}
function remove(value) {
const index = data.indexOf(value);
if (index >= 0) {
data.splice(index, 1);
return value;
}
return void 0;
}
function removeAt(index) {
data.splice(index, 1);
}
function forEach(fn) {
data.forEach(fn);
}
function map(fn) {
return data.map(fn);
}
function forEachSafe(fn) {
data.slice().forEach(fn);
}
function mapSafe(fn) {
return data.slice().map(fn);
}
}
})();
// src/EventManager.ts
var EventManager = (() => {
// src/base/Group.ts
var Group = /* @__PURE__ */ (() => {
return { create };
function create({ children: initialChildren } = {}) {
const children = List.create(initialChildren ?? []);
const mountedChildren = /* @__PURE__ */ new WeakMap();
let mounted = null;
let mergedLifecycles = {};
const layerGroup = {
mount,
children: children.raw,
appendChild,
removeChild,
hasChild
};
return layerGroup;
function mount(tools) {
if (mounted) {
throw new Error("Group already mounted");
}
mounted = tools;
children.forEachSafe((child) => {
mountChild(child, tools);
});
updateMergeLifecycles();
return {
pointers: (pointers) => mergedLifecycles.pointers?.(pointers) ?? pointers,
event: (event) => mergedLifecycles.event?.(event) ?? false,
update: (params) => mergedLifecycles.update?.(params) ?? null,
draw: (params) => mergedLifecycles.draw?.(params),
cleanup: () => mergedLifecycles.cleanup?.()
};
}
function updateMergeLifecycles() {
mergedLifecycles = Layer.merge(...children.mapSafe((child) => mountedChildren.get(child) ?? {}));
}
function mountChild(child, tools) {
const lifecycles = child.mount(tools);
if (lifecycles) {
mountedChildren.set(child, lifecycles);
}
}
function unmountChild(child) {
const lifecycles = mountedChildren.get(child);
if (lifecycles) {
lifecycles.cleanup?.();
mountedChildren.delete(child);
}
}
function appendChild(child) {
children.push(child);
if (mounted) {
mountChild(child, mounted);
}
updateMergeLifecycles();
}
function removeChild(child) {
const removed = children.remove(child);
if (removed) {
if (mounted) {
unmountChild(child);
}
updateMergeLifecycles();
}
}
function hasChild(child) {
return children.has(child);
}
}
})();
// src/base/PixelRatio.ts
function PixelRatio(child) {
return {
mount: (tools) => {
const childLifecycles = child.mount(tools);
const frame = tools.frame;
return {
...childLifecycles,
update({ view, t }) {
return childLifecycles.update?.({ view: Geometry.Rect.scale(view, 1 / frame.pixelRatio), t }) ?? null;
},
draw({ ctx, view, ...rest }) {
ctx.save();
ctx.scale(frame.pixelRatio, frame.pixelRatio);
childLifecycles.draw?.({ ...rest, ctx, view: Geometry.Rect.scale(view, 1 / frame.pixelRatio) });
ctx.restore();
}
};
}
};
}
// src/base/Variable.ts
function Variable(init) {
let current = init;
let next = init;
return {
get value() {
return next;
},
set value(value) {
next = value;
},
commit() {
if (current !== next) {
current = next;
return true;
}
return false;
}
};
}
// src/core/EventManager.ts
var EventManager = /* @__PURE__ */ (() => {
return { create };
function create(el) {

@@ -139,4 +388,4 @@ const pointers = [];

// src/Geometry.ts
var Geometry = (() => {
// src/utils/Geometry.ts
var Geometry = /* @__PURE__ */ (() => {
return {

@@ -253,182 +502,75 @@ Rect: {

// src/Layer.ts
var INTERNAL = Symbol.for("DRAAW_INTERNAL");
var Layer = (() => {
return { createRef, mount, merge };
function createRef(fn) {
return { [INTERNAL]: fn };
}
function mount(ref, tools) {
return ref[INTERNAL](tools);
}
function merge(...layersLifecycles) {
const merged = {};
const events = layersLifecycles.map((l) => l.event).filter(isNotNil).reverse();
if (events.length > 0) {
merged.event = (event) => events.reduce((acc, e) => !acc && e(event), false);
// src/core/Frame.ts
var VALID_POSITIONS = ["relative", "absolute", "fixed", "sticky"];
var Frame = /* @__PURE__ */ (() => {
return create;
function create({ target, name }) {
validateTargetPosition();
const canvas = document.createElement("canvas");
Object.assign(canvas.style, { padding: "0", margin: "0", border: "0" });
Object.assign(canvas.style, { background: "transparent", position: "absolute", top: "0", left: "0" });
if (name) {
canvas.setAttribute("data-name", name);
}
const pointersLifecycles = layersLifecycles.map((l) => l.pointers).filter(isNotNil).reverse();
if (pointersLifecycles.length > 0) {
merged.pointers = (pointers) => pointersLifecycles.reduce((pointers2, fn) => fn(pointers2), pointers);
}
const updates = layersLifecycles.map((l) => l.update).filter(isNotNil);
if (updates.length > 0) {
merged.update = (params) => {
const rects = updates.map((u) => u(params)).filter(isNotNil).flat();
if (rects.length === 0) {
return null;
}
return rects;
};
}
const draws = layersLifecycles.map((l) => l.draw).filter(isNotNil);
if (draws.length > 0) {
merged.draw = (params) => draws.forEach((d) => d(params));
}
const cleanups = layersLifecycles.map((l) => l.cleanup).filter(isNotNil);
if (cleanups.length > 0) {
merged.cleanup = () => cleanups.forEach((c) => c());
}
return merged;
}
function isNotNil(v) {
return v !== null && v !== void 0;
}
})();
// src/List.ts
var List = (() => {
return { create };
function create(init) {
const data = init ? Array.from(init) : [];
const context = canvas.getContext("2d");
let elemSize = [0, 0];
let pixelRatio = 1;
let view = [0, 0, 0, 0];
let outerSize = [0, 0];
update();
target.appendChild(canvas);
return {
raw: data,
get size() {
return data.length;
get outerSize() {
return outerSize;
},
at,
push,
insertAt,
has,
remove,
removeAt,
forEach,
map,
forEachSafe,
mapSafe
get view() {
return view;
},
get pixelRatio() {
return pixelRatio;
},
container: target,
canvas,
context,
update,
destroy
};
function at(index) {
return data[index];
function destroy() {
target.removeChild(canvas);
}
function push(value) {
data.push(value);
}
function insertAt(index, value) {
data.splice(index, 0, value);
}
function has(value) {
return data.includes(value);
}
function remove(value) {
const index = data.indexOf(value);
if (index >= 0) {
data.splice(index, 1);
return value;
function update() {
const nextElemSize = Geometry.Size.fromDomRect(target.getBoundingClientRect());
const nextPixelRatio = window.devicePixelRatio;
if (Geometry.Size.equal(nextElemSize, elemSize) && nextPixelRatio === pixelRatio) {
return false;
}
return void 0;
pixelRatio = nextPixelRatio;
elemSize = nextElemSize;
const innerSize = Geometry.Size.round(Geometry.Size.scale(elemSize, pixelRatio));
outerSize = Geometry.Size.scale(innerSize, 1 / pixelRatio);
const [outerWidth, outerHeight] = outerSize;
const [innerWidth, innerHeight] = innerSize;
view = [0, 0, innerWidth, innerHeight];
canvas.style.width = outerWidth + "px";
canvas.style.height = outerHeight + "px";
canvas.width = innerWidth;
canvas.height = innerHeight;
return true;
}
function removeAt(index) {
data.splice(index, 1);
}
function forEach(fn) {
data.forEach(fn);
}
function map(fn) {
return data.map(fn);
}
function forEachSafe(fn) {
data.slice().forEach(fn);
}
function mapSafe(fn) {
return data.slice().map(fn);
}
}
})();
// src/Group.ts
var Group = (() => {
return { create };
function create({ children: initialChildren } = {}) {
const children = List.create(initialChildren ?? []);
const mountedChildren = /* @__PURE__ */ new WeakMap();
let mounted = null;
let mergedLifecycles = {};
const layerGroup = {
ref: Layer.createRef(mount),
children: children.raw,
appendChild,
removeChild,
hasChild
};
return layerGroup;
function mount(tools) {
if (mounted) {
throw new Error("Group already mounted");
function validateTargetPosition() {
const elemStyles = window.getComputedStyle(target);
if (!VALID_POSITIONS.includes(elemStyles.position)) {
throw new Error(
`Element should have one of the following position ${VALID_POSITIONS.join(", ")} ! It currently has ${elemStyles.position}`
);
}
mounted = tools;
children.forEachSafe((child) => {
mountChild(child, tools);
});
updateMergeLifecycles();
return {
pointers: (pointers) => mergedLifecycles.pointers?.(pointers) ?? pointers,
event: (event) => mergedLifecycles.event?.(event) ?? false,
update: (params) => mergedLifecycles.update?.(params) ?? null,
draw: (params) => mergedLifecycles.draw?.(params),
cleanup: () => mergedLifecycles.cleanup?.()
};
}
function updateMergeLifecycles() {
mergedLifecycles = Layer.merge(...children.mapSafe((child) => mountedChildren.get(child) ?? {}));
}
function mountChild(child, tools) {
const lifecycles = Layer.mount(child.ref, tools);
if (lifecycles) {
mountedChildren.set(child, lifecycles);
}
}
function unmountChild(child) {
const lifecycles = mountedChildren.get(child);
if (lifecycles) {
lifecycles.cleanup?.();
mountedChildren.delete(child);
}
}
function appendChild(child) {
children.push(child);
if (mounted) {
mountChild(child, mounted);
}
updateMergeLifecycles();
}
function removeChild(child) {
const removed = children.remove(child);
if (removed) {
if (mounted) {
unmountChild(child);
}
updateMergeLifecycles();
}
}
function hasChild(child) {
return children.has(child);
}
}
})();
// src/HitResponder.ts
var import_pubsub = require("@dldc/pubsub");
// src/core/HitResponder.ts
import { PubSub } from "@dldc/pubsub";
// src/HitView.ts
var HitView = (() => {
// src/core/HitView.ts
var HitView = /* @__PURE__ */ (() => {
return { create };

@@ -460,4 +602,4 @@ function create() {

// src/HitResponder.ts
var HitResponder = (() => {
// src/core/HitResponder.ts
var HitResponder = /* @__PURE__ */ (() => {
return { create };

@@ -469,5 +611,5 @@ function create() {

let draw = null;
const pointerMoveSub = import_pubsub.Suub.createSubscription();
const pointerEnterSub = import_pubsub.Suub.createSubscription();
const pointerLeaveSub = import_pubsub.Suub.createSubscription();
const pointerMoveSub = PubSub.createSubscription();
const pointerEnterSub = PubSub.createSubscription();
const pointerLeaveSub = PubSub.createSubscription();
return {

@@ -524,71 +666,5 @@ event,

// src/PointerCaptureManager.ts
var PointerCaptureManager = (() => {
// src/core/Scheduler.ts
var Scheduler = /* @__PURE__ */ (() => {
return { create };
function create() {
const captures = /* @__PURE__ */ new Map();
return {
capturePointer,
getCapture,
hasCapture
};
function capturePointer(target, pointerId) {
if (captures.has(pointerId)) {
throw new Error(`Pointer ${pointerId} already captured`);
}
captures.set(pointerId, target);
return () => releaseCapture(pointerId);
}
function releaseCapture(pointerId) {
captures.delete(pointerId);
}
function hasCapture(pointerId) {
return captures.has(pointerId);
}
function getCapture(pointerId) {
return captures.get(pointerId);
}
}
})();
// src/Random.ts
var Random = (() => {
return {
sequenceOfUniqueColor,
sequenceOfUnique
};
function sequenceOfUnique(intermediateOffset, seedBase = 1) {
let index = permuteQPR(permuteQPR(seedBase) + 6827777);
function permuteQPR(x) {
const prime = 16777199;
const halfPrime = 8388599;
if (x >= prime)
return x;
const residue = x * x % prime;
return x <= halfPrime ? residue : prime - residue;
}
function getNth(n) {
return permuteQPR((permuteQPR(n) + intermediateOffset ^ 6025270) >>> 0);
}
return () => {
const res = getNth(index);
index++;
return res;
};
}
function sequenceOfUniqueColor() {
const gen = sequenceOfUnique(Math.floor(Math.random() * 1e4));
return () => {
let num = gen().toString(16);
while (num.length < 6) {
num = "0" + num;
}
return "#" + num;
};
}
})();
// src/Scheduler.ts
var Screduler = (() => {
return { create };
function create(onFrame) {

@@ -611,4 +687,12 @@ let startTime = performance.now();

startTime = performance.now();
currentTime = startTime;
loop();
}
function stop() {
if (requestedFrameId === null) {
return;
}
cancelAnimationFrame(requestedFrameId);
requestedFrameId = null;
}
function loop() {

@@ -623,13 +707,21 @@ const t = performance.now() - startTime;

// src/Tools.ts
var import_stack = require("@dldc/stack");
var Tools = class _Tools extends import_stack.Stack {
static create(ctx, scheduler) {
return new _Tools().with(_Tools.CtxKey.Provider(ctx), _Tools.SchedulerKey.Provider(scheduler));
// src/core/Tools.ts
import { Key, Stack } from "@dldc/stack";
var Tools = class _Tools extends Stack {
static create(view, scheduler) {
return new _Tools().with(
_Tools.FrameKey.Provider(view),
_Tools.CtxKey.Provider(view.context),
_Tools.SchedulerKey.Provider(scheduler)
);
}
static CtxKey = import_stack.Key.create("Ctx");
static SchedulerKey = import_stack.Key.create("Screduler");
static CtxKey = Key.create("Ctx");
static SchedulerKey = Key.create("Screduler");
static FrameKey = Key.create("View");
get ctx() {
return this.getOrFail(_Tools.CtxKey.Consumer);
}
get frame() {
return this.getOrFail(_Tools.FrameKey.Consumer);
}
time() {

@@ -643,74 +735,4 @@ return this.getOrFail(_Tools.SchedulerKey.Consumer).time();

// src/View.ts
var VALID_POSITIONS = ["relative", "absolute", "fixed", "sticky"];
var View = (() => {
return create;
function create({ target, name }) {
validateTargetPosition();
const canvas = document.createElement("canvas");
Object.assign(canvas.style, { padding: "0", margin: "0", border: "0" });
Object.assign(canvas.style, { background: "transparent", position: "absolute", top: "0", left: "0" });
if (name) {
canvas.setAttribute("data-name", name);
}
const context = canvas.getContext("2d");
let elemSize = [0, 0];
let pixelRatio = 0;
let view = [0, 0, 0, 0];
let outerSize = [0, 0];
update();
target.appendChild(canvas);
return {
get outerSize() {
return outerSize;
},
get view() {
return view;
},
container: target,
canvas,
context,
update,
prepare,
destroy
};
function destroy() {
target.removeChild(canvas);
}
function update() {
const nextElemSize = Geometry.Size.fromDomRect(target.getBoundingClientRect());
const nextPixelRatio = window.devicePixelRatio;
if (Geometry.Size.equal(nextElemSize, elemSize) && nextPixelRatio === pixelRatio) {
return false;
}
pixelRatio = nextPixelRatio;
elemSize = nextElemSize;
const innerSize = Geometry.Size.round(Geometry.Size.scale(elemSize, pixelRatio));
outerSize = Geometry.Size.scale(innerSize, 1 / pixelRatio);
const [outerWidth, outerHeight] = outerSize;
const [innerWidth, innerHeight] = innerSize;
view = [0, 0, innerWidth, innerHeight];
canvas.style.width = outerWidth + "px";
canvas.style.height = outerHeight + "px";
canvas.width = innerWidth;
canvas.height = innerHeight;
return true;
}
function prepare() {
context.resetTransform();
context.scale(pixelRatio, pixelRatio);
}
function validateTargetPosition() {
const elemStyles = window.getComputedStyle(target);
if (!VALID_POSITIONS.includes(elemStyles.position)) {
throw new Error(
`Element should have one of the following position ${VALID_POSITIONS.join(", ")} ! It currently has ${elemStyles.position}`
);
}
}
}
})();
// src/Renderer.ts
var Renderer = (() => {
// src/core/Renderer.ts
var Renderer = /* @__PURE__ */ (() => {
return { create };

@@ -724,7 +746,7 @@ function create({

}) {
const view = View({ target, name });
const scheduler = Screduler.create(onFrame);
const tools = Tools.create(view.context, scheduler);
const frame = Frame({ target, name });
const scheduler = Scheduler.create(onFrame);
const tools = Tools.create(frame, scheduler);
const rootLayer = layer;
const rootLayerLifecycles = Layer.mount(rootLayer.ref, tools);
const rootLayerLifecycles = rootLayer.mount(tools);
const eventManager = EventManager.create(eventsTarget);

@@ -734,7 +756,7 @@ if (autoStart) {

}
return { layer: rootLayer, scheduler, view, destroy };
return { layer: rootLayer, scheduler, view: frame, destroy };
function destroy() {
scheduler.stop();
rootLayerLifecycles.cleanup?.();
view.destroy();
frame.destroy();
eventManager.destroy();

@@ -747,9 +769,8 @@ }

});
const resized = view.update();
view.prepare();
const currentView = view.view;
const resized = frame.update();
const currentView = frame.view;
const renderRects = rootLayerLifecycles.update?.({ t, view: currentView }) ?? [];
const actualRenderRects = resized ? [currentView] : renderRects;
actualRenderRects.forEach((renderRect) => {
rootLayerLifecycles.draw?.({ t, view: currentView, rect: renderRect, ctx: view.context });
rootLayerLifecycles.draw?.({ t, view: currentView, rect: renderRect, ctx: frame.context });
});

@@ -759,17 +780,54 @@ }

})();
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
// src/utils/Random.ts
var Random = /* @__PURE__ */ (() => {
return {
sequenceOfUniqueColor,
sequenceOfUnique
};
function sequenceOfUnique(intermediateOffset, seedBase = 1) {
let index = permuteQPR(permuteQPR(seedBase) + 6827777);
function permuteQPR(x) {
const prime = 16777199;
const halfPrime = 8388599;
if (x >= prime)
return x;
const residue = x * x % prime;
return x <= halfPrime ? residue : prime - residue;
}
function getNth(n) {
return permuteQPR((permuteQPR(n) + intermediateOffset ^ 6025270) >>> 0);
}
return () => {
const res = getNth(index);
index++;
return res;
};
}
function sequenceOfUniqueColor() {
const gen = sequenceOfUnique(Math.floor(Math.random() * 1e4));
return () => {
let num = gen().toString(16);
while (num.length < 6) {
num = "0" + num;
}
return "#" + num;
};
}
})();
export {
BoxLayer,
EventManager,
Frame,
Geometry,
Group,
HitResponder,
HitView,
Layer,
List,
PointerCaptureManager,
PixelRatio,
Random,
Renderer,
Screduler,
Scheduler,
Tools,
View
});
Variable,
Variables
};
{
"name": "@dldc/canvas",
"version": "1.2.5",
"version": "1.2.6",
"description": "A 2D Canvas engine",

@@ -17,6 +17,7 @@ "keywords": [],

"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./dist/mod.mjs",
"require": "./dist/mod.js",
"import": "./dist/mod.js",
"require": "./dist/mod.cjs",
"types": "./dist/mod.d.ts"

@@ -26,3 +27,2 @@ }

"main": "./dist/mod.js",
"module": "./dist/mod.mjs",
"types": "./dist/mod.d.ts",

@@ -33,4 +33,4 @@ "files": [

"scripts": {
"build": "rimraf dist && tsup --format cjs,esm src/mod.ts --dts src/mod.ts",
"build:watch": "tsup --watch --format cjs,esm src/mod.ts --dts src/mod.ts",
"build": "rimraf dist && tsup --format cjs,esm src/mod.ts --dts",
"build:watch": "tsup --watch --format cjs,esm src/mod.ts --dts",
"changelog": "auto-changelog --stdout --hide-credit true --commit-limit false -u --template https://raw.githubusercontent.com/release-it/release-it/main/templates/changelog-compact.hbs",

@@ -88,23 +88,23 @@ "example:run": "vite example",

"dependencies": {
"@dldc/pubsub": "^5.2.5",
"@dldc/stack": "^4.1.1"
"@dldc/pubsub": "^6.0.1",
"@dldc/stack": "^4.1.5"
},
"devDependencies": {
"@dldc/humpf": "^4.0.5",
"@types/node": "^20.8.3",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"@vitest/coverage-v8": "^0.34.6",
"@dldc/humpf": "^5.0.1",
"@types/node": "^20.10.4",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"@vitest/coverage-v8": "^1.0.4",
"auto-changelog": "^2.4.0",
"eslint": "^8.51.0",
"eslint-config-prettier": "^9.0.0",
"prettier": "^3.0.3",
"release-it": "^16.2.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"prettier": "^3.1.1",
"release-it": "^17.0.1",
"rimraf": "^5.0.5",
"tsup": "^7.2.0",
"typescript": "^5.2.2",
"vite": "^4.4.11",
"vitest": "^0.34.6"
"tsup": "^8.0.1",
"typescript": "^5.3.3",
"vite": "^5.0.10",
"vitest": "^1.0.4"
},
"packageManager": "pnpm@8.6.1",
"packageManager": "pnpm@8.9.0",
"publishConfig": {

@@ -111,0 +111,0 @@ "access": "public",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc