Fix horizontalLine being one pixel short, add canvas center support

main
Shad Amethyst 2 years ago
parent a9b894d066
commit 5121ffddfa

4
package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "@shadryx/pptk",
"version": "0.1.7",
"version": "0.1.8",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@shadryx/pptk",
"version": "0.1.7",
"version": "0.1.8",
"license": "MIT",
"devDependencies": {
"solid-js": "^1.6.2",

@ -1,6 +1,6 @@
{
"name": "@shadryx/pptk",
"version": "0.1.7",
"version": "0.1.8",
"description": "Pixel-Perfect ToolKit, a library to help make pixel-perfect applications on high-DPI devices",
"keywords": [
"pixel-perfect",
@ -44,8 +44,7 @@
"dev:solid": "vite dev test/solid",
"dev:vanilla": "vite dev test/vanilla",
"build": "npm run prepare-dev && vite build && tsc && cp src/index.d.ts dist/types/index.d.ts",
"clean": "rm -rf dist/ src/index.d.ts",
"publish": "npm i && npm run build && npm publish --access public"
"clean": "rm -rf dist/ src/index.d.ts"
},
"repository": {
"type": "git",

@ -358,7 +358,7 @@ export class Pannable {
}
/** @private **/
_getValues(touches) {
_getValues(touches, cx = 0, cy = 0) {
// First-order moments of touches.x and touches.y
let mx = 0;
let my = 0;
@ -375,14 +375,14 @@ export class Pannable {
const n = touches.size;
if (n <= 1) {
return [mx, my, 1];
return [mx - cx, my - cy, 1];
}
// Unbiased sample variance, from https://en.wikipedia.org/wiki/Bessel%27s_correction#Formula
const sx = mx2 / (n - 1) - (mx * mx) / (n * (n - 1));
const sy = my2 / (n - 1) - (my * my) / (n * (n - 1));
return [mx / n, my / n, Math.sqrt(sx + sy)];
return [mx / n - cx, my / n - cy, Math.sqrt(sx + sy)];
}
/** @returns {number} **/
@ -409,8 +409,8 @@ export class Pannable {
/**
* @param {Map<number, Touch>} touches
**/
move(touches) {
const currentValues = this._getValues(touches);
move(touches, cx = 0, cy = 0) {
const currentValues = this._getValues(touches, cx, cy);
let deltaLogScale = Math.log2(currentValues[2] / this.lastValues[2]);
if (Number.isNaN(deltaLogScale) || !Number.isFinite(deltaLogScale)) {
deltaLogScale = 0;
@ -443,8 +443,8 @@ export class Pannable {
/**
* @param {Map<number, Touch>} touches
**/
update(touches) {
this.lastValues = this._getValues(touches);
update(touches, cx = 0, cy = 0) {
this.lastValues = this._getValues(touches, cx, cy);
}
}
@ -794,10 +794,10 @@ export class PixelPerfectContext2D {
if (y2 < y1) {
this.context.moveTo(this._unscaleX(x1 + dx), this._unscaleY(y2 + dy));
this.context.lineTo(this._unscaleX(x1 + dx), this._unscaleY(y1 - dy));
this.context.lineTo(this._unscaleX(x1 + dx), this._unscaleY(y1 - dy) - 1);
} else {
this.context.moveTo(this._unscaleX(x1 + dx), this._unscaleY(y1 + dy));
this.context.lineTo(this._unscaleX(x1 + dx), this._unscaleY(y2 - dy));
this.context.lineTo(this._unscaleX(x1 + dx), this._unscaleY(y2 - dy) + 1);
}
this.context.stroke();
@ -830,10 +830,10 @@ export class PixelPerfectContext2D {
if (x2 < x1) {
this.context.moveTo(this._unscaleX(x2 + dx), this._unscaleY(y1 + dy));
this.context.lineTo(this._unscaleX(x1 - dx), this._unscaleY(y1 + dy));
this.context.lineTo(this._unscaleX(x1 - dx) - 1, this._unscaleY(y1 + dy));
} else {
this.context.moveTo(this._unscaleX(x1 + dx), this._unscaleY(y1 + dy));
this.context.lineTo(this._unscaleX(x2 - dx), this._unscaleY(y1 + dy));
this.context.lineTo(this._unscaleX(x2 - dx) + 1, this._unscaleY(y1 + dy));
}
this.context.stroke();

@ -1,26 +1,40 @@
import { createSignal } from "solid-js";
import { Pannable, PannableOptions, PannableState, Touch } from "../index.js";
export function usePannable(config: PannableOptions) {
export type UsePannableOptions = {
center?: () => [x: number, y: number],
};
export function usePannable(config: PannableOptions & UsePannableOptions) {
const pannable = new Pannable(config);
const [state, setState] = createSignal<PannableState>(pannable.getState());
const center = config.center ?? (() => [0, 0]);
return {
update(touches: Map<number, Touch>) {
pannable.update(touches);
pannable.update(touches, ...center());
},
move(touches: Map<number, Touch>) {
pannable.move(touches);
pannable.move(touches, ...center());
const newState = pannable.getState();
setState(newState);
return newState;
},
zoom(amount: number, clientX?: number, clientY?: number) {
pannable.zoom(amount, clientX, clientY);
const [cx, cy] = center();
pannable.zoom(amount, (clientX ?? 0) - cx, (clientY ?? 0) - cy);
const newState = pannable.getState();
setState(newState);
return newState;
},
getState: state,
getState: () => {
const result = state();
const [cx, cy] = center();
return {
...result,
dx: result.dx + cx,
dy: result.dy + cy,
};
}
};
}

Loading…
Cancel
Save