Skip to content

Commit

Permalink
feat: finish coordinate
Browse files Browse the repository at this point in the history
  • Loading branch information
manyyuri committed May 21, 2024
1 parent ddba787 commit 440cdbf
Show file tree
Hide file tree
Showing 14 changed files with 234 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .eslintcache

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ module.exports = {
'no-sequences': 0,
'no-loop-func': 0,
'no-nested-ternary': 0,
'no-bitwise': 0,
},
};
18 changes: 18 additions & 0 deletions __tests__/coordinate/cartesian.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {
createCoordinate, cartesian,
} from '../../src/coordinate';

describe('cartesian', () => {
test('cartesian()', () => {
const c = createCoordinate({
width: 200,
height: 300,
x: 0,
y: 0,
transforms: [cartesian()],
});
expect(c([0.5, 0.5])).toEqual([100, 150]);
expect(c.isPolar()).toBeFalsy();
expect(c.isTranspose()).toBeFalsy();
});
});
14 changes: 14 additions & 0 deletions __tests__/coordinate/coordinate.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {
createCoordinate,
} from '../../src/coordinate';

describe('coordinate', () => {
test('createCoordinate(options) returns a identity function without transforms', () => {
const c = createCoordinate({
transforms: [],
});

expect(c(1)).toBe(1);
expect(c(2)).toBe(2);
});
});
44 changes: 44 additions & 0 deletions __tests__/coordinate/polar.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
createCoordinate, cartesian, polar,
} from '../../src/coordinate';

describe('polar', () => {
test('polar()', () => {
const c1 = createCoordinate({
width: 300,
height: 200,
x: 0,
y: 0,
transforms: [polar({
startAngle: -Math.PI / 2,
endAngle: (Math.PI / 2) * 3,
innerRadius: 0,
outerRadius: 1,
}), cartesian()],
});

expect(c1([0, 1])).toEqual([150, 100]);
expect(c1.isPolar()).toBeTruthy();
expect(c1.isTranspose()).toBeFalsy();

const c2 = createCoordinate({
width: 200,
height: 400,
x: 0,
y: 0,
transforms: [
polar(
{
startAngle: Math.PI / 2,
endAngle: (Math.PI * 3) / 2,
innerRadius: 0.2,
outerRadius: 0.8,
},
),
cartesian(),
],
});

expect(c2([0, 0])).toEqual([100, 280]);
});
});
20 changes: 20 additions & 0 deletions __tests__/coordinate/transpose.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {
createCoordinate, cartesian, transpose,
} from '../../src/coordinate';

describe('transpose', () => {
test('transpose()', () => {
const c = createCoordinate({
width: 200,
height: 300,
x: 0,
y: 0,
transforms: [transpose(), cartesian()],
});

expect(c([0.5, 1])).toEqual([0, 150]);
expect(c([0.4, 1])).toEqual([0, 120]);
expect(c.isPolar()).toBeFalsy();
expect(c.isTranspose()).toBeTruthy();
});
});
14 changes: 14 additions & 0 deletions src/coordinate/cartesian.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { curry } from '../utils';
import { scale, translate } from './transform';

function coordinate(transformOptions, canvasOptions) {
const {
x, y, width, height,
} = canvasOptions;
return [
scale(width, height),
translate(x, y),
];
}

export const cartesian = curry(coordinate);
19 changes: 19 additions & 0 deletions src/coordinate/coordinate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { compose } from '../utils';

export function createCoordinate({
transforms: coordinates = [],
...canvasOptions
}) {
const transforms = coordinates.flatMap((coordinate) => coordinate(canvasOptions));
const types = transforms.map((d) => d.type());
const output = compose(...transforms);
const {
x, y, width, height,
} = canvasOptions;

output.isPolar = () => types.indexOf('polar') !== -1;
output.isTranspose = () => types.reduce((is, type) => is ^ (type === 'transpose'), false);
output.center = () => [x + width / 2, y + height / 2];

return output;
}
4 changes: 4 additions & 0 deletions src/coordinate/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { createCoordinate } from './coordinate';
export { cartesian } from './cartesian';
export { polar } from './polar';
export { transpose } from './transpose';
30 changes: 30 additions & 0 deletions src/coordinate/polar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {
translate, scale, reflectY, polar as polarT,
} from './transform';
import { curry } from '../utils/helper';

function coordinate(transformOptions, canvasOptions) {
const { width, height } = canvasOptions;
const {
innerRadius = 0,
outerRadius = 1,
startAngle = -Math.PI / 2,
endAngle = (Math.PI / 2) * 3,
} = transformOptions;
const aspect = width / height;
const sx = aspect > 1 ? 1 / aspect : 1;
const sy = aspect > 1 ? 1 : aspect;
return [
translate(0, -0.5),
reflectY(),
translate(0, 0.5),
scale(endAngle - startAngle, outerRadius - innerRadius),
translate(startAngle, innerRadius),
polarT(),
scale(sx, sy),
scale(0.5, 0.5),
translate(0.5, 0.5),
];
}

export const polar = curry(coordinate);
36 changes: 36 additions & 0 deletions src/coordinate/transform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export function transpose() {
return transform('transpose', ([px, py]) => [py, px]);
}

export function translate(tx = 0, ty = 0) {
return transform('translate', ([px, py]) => [px + tx, py + ty]);
}

export function scale(sx = 1, sy = 1) {
return transform('scale', ([px, py]) => [px * sx, py * sy]);
}

export function reflect() {
return transform('reflect', scale(-1, -1));
}

export function reflectX() {
return transform('reflectX', scale(-1, 1));
}

export function reflectY() {
return transform('reflectY', scale(1, -1));
}

export function polar() {
return transform('polar', ([theta, radius]) => {
const x = radius * Math.cos(theta);
const y = radius * Math.sin(theta);
return [x, y];
});
}

function transform(type, transformer) {
transformer.type = () => type;
return transformer;
}
14 changes: 14 additions & 0 deletions src/coordinate/transpose.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { curry } from '../utils';
import { reflectX, translate, transpose as transposeT } from './transform';

// eslint-disable-next-line no-unused-vars
function coordinate(transformOptions, canvasOptions) {
return [
transposeT(),
translate(-0.5, -0.5),
reflectX(),
translate(0.5, 0.5),
];
}

export const transpose = curry(coordinate);
16 changes: 16 additions & 0 deletions src/utils/helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export function identity(x) {
return x;
}

export function compose(...fns) {
return fns.reduce((total, cur) => (x) => cur(total(x)), identity);
}

export function curry(fn) {
const arity = fn.length;
return function curried(...args) {
const newArgs = args.length === 0 ? [undefined] : args;
if (newArgs.length >= arity) return fn(...newArgs);
return curried.bind(null, ...newArgs);
};
}
3 changes: 3 additions & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { curry, compose } from './helper';

export { curry, compose };

0 comments on commit 440cdbf

Please sign in to comment.