Skip to content

Commit f25965b

Browse files
committed
1 parent 468ad8b commit f25965b

File tree

11 files changed

+4875
-14
lines changed

11 files changed

+4875
-14
lines changed
File renamed without changes.

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
22
"private": true,
3-
"name": "croquis",
3+
"name": "croquis.js",
44
"version": "0.0.0",
55
"description": "drawing tool library",
66
"workspaces": [
77
"packages/*"
88
],
99
"scripts": {
10-
"test": "echo \"Error: no test specified\" && exit 1"
10+
"dev": "wsrun dev",
11+
"build": "wsrun -t build"
1112
},
1213
"repository": {
1314
"type": "git",
@@ -18,5 +19,8 @@
1819
"bugs": {
1920
"url": "https://github.com/disjukr/croquis.js/issues"
2021
},
21-
"homepage": "https://github.com/disjukr/croquis.js#readme"
22+
"homepage": "https://github.com/disjukr/croquis.js#readme",
23+
"dependencies": {
24+
"wsrun": "^5.2.0"
25+
}
2226
}

packages/croquis.js/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
{
2-
"name": "croquis",
2+
"name": "croquis.js",
33
"version": "1.0.0",
44
"description": "drawing tool library",
55
"main": "index.js",
66
"scripts": {
7+
"dev": "tsc --watch",
78
"build": "tsc",
89
"lint:fix": "prettier --write \"src/**/*.ts\""
910
},

packages/croquis.js/src/draw/brush.ts

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,35 @@ export interface BrushConfig {
4747
tangentSpread: number;
4848
}
4949

50+
type RequiredKeysOfBrushConfig = 'ctx' | 'draw' | 'size' | 'aspectRatio';
51+
export const defaultBrushConfig = Object.freeze<Omit<BrushConfig, RequiredKeysOfBrushConfig>>({
52+
spacing: 0,
53+
angle: 0,
54+
rotateToTangent: false,
55+
angleRandom: Math.random,
56+
angleSpread: 0,
57+
normalRandom: Math.random,
58+
normalSpread: 0,
59+
tangentRandom: Math.random,
60+
tangentSpread: 0,
61+
});
62+
63+
interface XY {
64+
x: number;
65+
y: number;
66+
}
67+
const id = <T>(x: T) => x;
68+
export function getBrushStrokeParams(e: PointerEvent, transformXy: (xy: XY) => XY = id) {
69+
return {
70+
...(transformXy({ x: e.x, y: e.y })),
71+
pressure: e.pressure,
72+
tangentialPressure: e.tangentialPressure,
73+
tiltX: e.tiltX,
74+
tiltY: e.tiltY,
75+
twist: e.twist,
76+
};
77+
}
78+
5079
export function getDrawCircleFn(ctx: CanvasRenderingContext2D, color: Color, flow: number) {
5180
return function drawCircle(width: number, height: number) {
5281
const halfWidth = width * 0.5;
@@ -107,11 +136,13 @@ export function stamp(config: BrushConfig, state: BrushStrokeState, params: Stam
107136
const normal = state.tangent + quarter;
108137
const spreadX = doSpread && cos(normal) * normalSpread + cos(state.tangent) * tangentSpread;
109138
const spreadY = doSpread && sin(normal) * normalSpread + sin(state.tangent) * tangentSpread;
139+
const x = params.x + spreadX;
140+
const y = params.y + spreadY;
110141
{
111142
// draw
112143
const ctx = config.ctx;
113144
ctx.save();
114-
ctx.translate(spreadX, spreadY);
145+
ctx.translate(x, y);
115146
ctx.rotate(angle);
116147
ctx.translate(-(width * 0.5), -(height * 0.5));
117148
config.draw(width, height);
@@ -122,16 +153,16 @@ export function stamp(config: BrushConfig, state: BrushStrokeState, params: Stam
122153
const br = state.boundingRect;
123154
const boundWidth = angle ? abs(height * sin(angle)) + abs(width * cos(angle)) : width;
124155
const boundHeight = angle ? abs(width * sin(angle)) + abs(height * cos(angle)) : height;
125-
const bx = spreadX - boundWidth * 0.5;
126-
const by = spreadY - boundHeight * 0.5;
127-
const x = min(br.x, bx);
128-
const y = min(br.y, by);
156+
const bx = x - boundWidth * 0.5;
157+
const by = y - boundHeight * 0.5;
158+
const rx = min(br.x, bx);
159+
const ry = min(br.y, by);
129160
const right = max(br.x + br.w, bx + boundWidth);
130161
const bottom = max(br.y + br.h, by + boundHeight);
131-
state.boundingRect.x = x;
132-
state.boundingRect.y = y;
133-
state.boundingRect.w = right - x;
134-
state.boundingRect.h = bottom - y;
162+
state.boundingRect.x = rx;
163+
state.boundingRect.y = ry;
164+
state.boundingRect.w = right - rx;
165+
state.boundingRect.h = bottom - ry;
135166
}
136167
state.lastStamp = params;
137168
}

packages/croquis.js/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"esModuleInterop": true,
1515
"allowSyntheticDefaultImports": true,
1616
"strict": true,
17-
"module": "esnext",
17+
"module": "commonjs",
1818
"moduleResolution": "node",
1919
"resolveJsonModule": true,
2020
"isolatedModules": true,

packages/website/.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.DS_Store
2+
3+
/node_modules
4+
/.next/
5+
/out/
6+
/build
7+
next-env.d.ts
8+
9+
npm-debug.log*
10+
yarn-debug.log*
11+
yarn-error.log*

packages/website/next.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
target: 'serverless',
3+
};

packages/website/package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"private": true,
3+
"name": "website",
4+
"version": "0.0.0",
5+
"scripts": {
6+
"dev": "next dev",
7+
"build": "next build",
8+
"start": "next start"
9+
},
10+
"dependencies": {
11+
"@types/node": "^13.9.8",
12+
"@types/react": "^16.9.31",
13+
"croquis.js": "^1.0.0",
14+
"next": "9.3.4",
15+
"react": "16.13.1",
16+
"react-dom": "16.13.1",
17+
"typescript": "^3.8.3"
18+
}
19+
}

packages/website/pages/index.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React, { useEffect, useRef, PointerEventHandler } from 'react';
2+
import {
3+
down,
4+
move,
5+
up,
6+
defaultBrushConfig,
7+
BrushConfig,
8+
getDrawCircleFn,
9+
BrushStrokeState,
10+
} from 'croquis.js/lib/draw/brush';
11+
12+
const Page = () => {
13+
const canvasRef = useRef<HTMLCanvasElement>(null);
14+
const brushConfigRef = useRef<BrushConfig>();
15+
const brushStateRef = useRef<BrushStrokeState>();
16+
useEffect(() => {
17+
const ctx = canvasRef.current!.getContext('2d')!;
18+
brushConfigRef.current = {
19+
...defaultBrushConfig,
20+
ctx,
21+
draw: getDrawCircleFn(ctx, '#000', 1),
22+
size: 30,
23+
aspectRatio: 1,
24+
};
25+
}, []);
26+
const downHandler: PointerEventHandler = e => {
27+
brushStateRef.current = down(brushConfigRef.current!, e.nativeEvent);
28+
};
29+
const moveHandler: PointerEventHandler = e => {
30+
if (!brushStateRef.current) return;
31+
if (e.nativeEvent.pressure !== 0.5) console.log(e.nativeEvent.pressure);
32+
move(brushConfigRef.current!, brushStateRef.current, e.nativeEvent);
33+
};
34+
const upHandler: PointerEventHandler = e => {
35+
if (!brushStateRef.current) return;
36+
up(brushConfigRef.current!, brushStateRef.current, e.nativeEvent);
37+
};
38+
return <canvas
39+
ref={canvasRef}
40+
onPointerDown={downHandler}
41+
onPointerMove={moveHandler}
42+
onPointerUp={upHandler}
43+
width={500}
44+
height={500}
45+
style={{ outline: '1px solid black' }}
46+
/>;
47+
}
48+
49+
export default Page;

packages/website/tsconfig.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"declaration": true,
5+
"lib": [
6+
"dom",
7+
"dom.iterable",
8+
"esnext"
9+
],
10+
"jsx": "preserve",
11+
"rootDir": "src",
12+
"outDir": "lib",
13+
"allowJs": true,
14+
"skipLibCheck": true,
15+
"esModuleInterop": true,
16+
"allowSyntheticDefaultImports": true,
17+
"strict": true,
18+
"module": "esnext",
19+
"moduleResolution": "node",
20+
"resolveJsonModule": true,
21+
"isolatedModules": true,
22+
"forceConsistentCasingInFileNames": true,
23+
"noEmit": true
24+
},
25+
"exclude": [
26+
"node_modules"
27+
],
28+
"include": [
29+
"next-env.d.ts",
30+
"**/*.ts",
31+
"**/*.tsx"
32+
]
33+
}

0 commit comments

Comments
 (0)