@molecule/app-image-crop-cropperjs 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -0
- package/package.json +6 -4
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
3
|
+
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
|
+
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
|
+
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
+
Generated: 2026-08-04T01:51:05.744Z
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
# @molecule/app-image-crop-cropperjs
|
|
10
|
+
|
|
11
|
+
> **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
|
|
12
|
+
> It is written to be read by coding agents as much as by people, and is generated from this
|
|
13
|
+
> package's source — edit `src/index.ts` JSDoc, not this file.
|
|
14
|
+
|
|
15
|
+
Cropper.js image-crop provider for `@molecule/app-image-crop` — a REAL
|
|
16
|
+
implementation backed by cropperjs v1. `createCropper({ src })` mounts a live
|
|
17
|
+
`Cropper` on an image element and every instance method delegates to the
|
|
18
|
+
corresponding cropperjs call, so `getCroppedCanvas()` returns the actual
|
|
19
|
+
cropped `<canvas>` (call `.toBlob()` / `.toDataURL()` on it to export) — not a
|
|
20
|
+
placeholder object.
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { provider } from '@molecule/app-image-crop-cropperjs'
|
|
26
|
+
import { setProvider, requireProvider } from '@molecule/app-image-crop'
|
|
27
|
+
|
|
28
|
+
setProvider(provider) // once, at app startup (bonds.ts)
|
|
29
|
+
|
|
30
|
+
const cropper = requireProvider().createCropper({ src: '/avatar.jpg', aspectRatio: 1 })
|
|
31
|
+
const canvas = cropper.getCroppedCanvas({ width: 200, height: 200 })
|
|
32
|
+
canvas.toBlob((blob) => uploadAvatar(blob), 'image/png')
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Type
|
|
36
|
+
|
|
37
|
+
`provider`
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install @molecule/app-image-crop-cropperjs @molecule/app-image-crop cropperjs
|
|
43
|
+
npm install -D @types/cropperjs
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## API
|
|
47
|
+
|
|
48
|
+
### Interfaces
|
|
49
|
+
|
|
50
|
+
#### `CropperjsConfig`
|
|
51
|
+
|
|
52
|
+
Provider-level defaults applied to every cropper created by the provider.
|
|
53
|
+
|
|
54
|
+
These map onto cropperjs constructor options. Per-cropper `CropperOptions`
|
|
55
|
+
(e.g. `guides`) take precedence over the matching field here.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
interface CropperjsConfig {
|
|
59
|
+
/**
|
|
60
|
+
* Whether to show the dashed crop guide lines by default. Overridden per-cropper
|
|
61
|
+
* by `CropperOptions.guides`. Defaults to `true`.
|
|
62
|
+
*/
|
|
63
|
+
guides?: boolean
|
|
64
|
+
|
|
65
|
+
/** Whether to render the checkerboard background behind the image. Defaults to `true`. */
|
|
66
|
+
background?: boolean
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* cropperjs view mode (0-3) constraining the crop box relative to the canvas /
|
|
70
|
+
* container. `1` restricts the crop box within the canvas. Defaults to `1`.
|
|
71
|
+
*/
|
|
72
|
+
viewMode?: 0 | 1 | 2 | 3
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Functions
|
|
77
|
+
|
|
78
|
+
#### `createProvider(config)`
|
|
79
|
+
|
|
80
|
+
Creates a Cropper.js-based image crop provider.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
function createProvider(config?: CropperjsConfig): ImageCropProvider
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
- `config` — Optional provider-level defaults (`guides`, `background`, `viewMode`).
|
|
87
|
+
|
|
88
|
+
**Returns:** A configured `ImageCropProvider` backed by real cropperjs instances.
|
|
89
|
+
|
|
90
|
+
### Constants
|
|
91
|
+
|
|
92
|
+
#### `provider`
|
|
93
|
+
|
|
94
|
+
Default Cropper.js provider instance.
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
const provider: ImageCropProvider
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Namespaces
|
|
101
|
+
|
|
102
|
+
#### `Cropper`
|
|
103
|
+
|
|
104
|
+
## Core Interface
|
|
105
|
+
|
|
106
|
+
Implements `@molecule/app-image-crop` interface.
|
|
107
|
+
|
|
108
|
+
## Bond Wiring
|
|
109
|
+
|
|
110
|
+
Setup function to register this provider with the core interface:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { setProvider } from '@molecule/app-image-crop'
|
|
114
|
+
import { provider } from '@molecule/app-image-crop-cropperjs'
|
|
115
|
+
|
|
116
|
+
export function setupImageCropCropperjs(): void {
|
|
117
|
+
setProvider(provider)
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Injection Notes
|
|
122
|
+
|
|
123
|
+
### Requirements
|
|
124
|
+
|
|
125
|
+
Peer dependencies:
|
|
126
|
+
|
|
127
|
+
- `@molecule/app-image-crop` ^1.0.1
|
|
128
|
+
|
|
129
|
+
### Runtime Dependencies
|
|
130
|
+
|
|
131
|
+
- `@molecule/app-image-crop`
|
|
132
|
+
- `cropperjs`
|
|
133
|
+
|
|
134
|
+
- **Import cropperjs's stylesheet yourself** — this package does NOT:
|
|
135
|
+
`import 'cropperjs/dist/cropper.css'`. Without it the crop box, handles, and
|
|
136
|
+
drag guides render unstyled (an invisible/broken cropper), the same way Quill
|
|
137
|
+
needs its theme CSS.
|
|
138
|
+
- **Browser-only.** `createCropper()` calls `document.createElement('img')` and
|
|
139
|
+
`new Cropper(...)`; construct it in a client-only effect under SSR.
|
|
140
|
+
- **cropperjs initializes on the image's `load` event.** Reading `getCropData()`
|
|
141
|
+
or `getCroppedCanvas()` before the source has loaded returns empty/degenerate
|
|
142
|
+
data — drive them after load, or set the region explicitly with `setCropData()`
|
|
143
|
+
in natural-image coordinates first.
|
|
144
|
+
- **`circular` is a UI concern, not a pixel op.** cropperjs has no circular
|
|
145
|
+
pixel output; for a round avatar, style the crop box round in CSS
|
|
146
|
+
(`.cropper-view-box, .cropper-face { border-radius: 50% }`) and draw the
|
|
147
|
+
returned canvas into a rounded canvas before upload.
|
|
148
|
+
- **`OutputOptions.quality` applies at encode time**, not to canvas generation —
|
|
149
|
+
pass it to `canvas.toBlob(cb, 'image/jpeg', quality)` / `toDataURL(type, quality)`.
|
|
150
|
+
- Provider defaults (`guides`, `background`, `viewMode`) come from
|
|
151
|
+
`createProvider(config)`; per-cropper `CropperOptions.guides` wins over the
|
|
152
|
+
config default. `maxWidth`/`maxHeight` are enforced on output (cropperjs has no
|
|
153
|
+
max-crop-box constructor option).
|
|
154
|
+
- **Wire it** with `setProvider()` from `@molecule/app-image-crop` or
|
|
155
|
+
`bond('image-crop', provider)` from `@molecule/app-bond` — both route through
|
|
156
|
+
the shared registry; `requireProvider()` throws until one has run.
|
|
157
|
+
|
|
158
|
+
## E2E Tests
|
|
159
|
+
|
|
160
|
+
Integration checklist — drive the real UI (live preview, no mocks), adapt each
|
|
161
|
+
item to this app's actual crop screen (avatar/photo upload, etc.), and check
|
|
162
|
+
every box off one by one. A box you can't check is an integration bug to fix —
|
|
163
|
+
not a skip. The cropper is headless, so verify the UI YOU rendered:
|
|
164
|
+
|
|
165
|
+
- [ ] Opening the crop screen loads the source image (`createCropper({ src })`)
|
|
166
|
+
and renders it with a visible crop-box overlay + drag handles drawn from
|
|
167
|
+
`getCropData()` — not a blank or full-bleed image with no selection.
|
|
168
|
+
- [ ] Dragging/resizing the crop box feeds the gesture into `setCropData()`,
|
|
169
|
+
`getCropData()` reflects the new x/y/width/height, and the on-page preview
|
|
170
|
+
(the `getCroppedCanvas()` output drawn into the page) updates to show ONLY
|
|
171
|
+
the selected area, not the whole image.
|
|
172
|
+
- [ ] With an aspect-ratio lock (e.g. `aspectRatio: 1` for an avatar) the crop
|
|
173
|
+
box stays that ratio while you resize — `getCropData()` width == height for
|
|
174
|
+
1:1 — and `circular: true` clips the preview to a circle.
|
|
175
|
+
- [ ] `rotate()` / `zoom()` transform the source and the crop overlay follows:
|
|
176
|
+
`getCropData().rotate` / `scaleX` change and the preview re-renders the
|
|
177
|
+
transformed region — the selection isn't stranded on the old orientation.
|
|
178
|
+
- [ ] Applying the crop OUTPUTS the cropped image: `getCroppedCanvas()` pixels
|
|
179
|
+
match the selected region (not the full source), and downstream the SAVED
|
|
180
|
+
file is the cropped Blob (`canvas.toBlob` → upload) — re-fetch and render the
|
|
181
|
+
stored image and confirm it shows the crop, never the original.
|
|
182
|
+
- [ ] Min/max crop size is enforced — you cannot drag the box smaller than
|
|
183
|
+
`minWidth`/`minHeight` or larger than `maxWidth`/`maxHeight`.
|
|
184
|
+
- [ ] Cancel/close discards without mutating the source: the original image is
|
|
185
|
+
unchanged and no cropped result is saved.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/app-image-crop-cropperjs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Cropper.js provider for @molecule/app-image-crop",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
|
-
"dist"
|
|
20
|
+
"dist",
|
|
21
|
+
"README.md"
|
|
21
22
|
],
|
|
22
23
|
"keywords": [
|
|
23
24
|
"molecule",
|
|
@@ -28,13 +29,14 @@
|
|
|
28
29
|
"license": "Apache-2.0",
|
|
29
30
|
"repository": {
|
|
30
31
|
"type": "git",
|
|
32
|
+
"url": "https://github.com/molecule-dev/molecule.git",
|
|
31
33
|
"directory": "packages/app/bonds/image-crop/cropperjs"
|
|
32
34
|
},
|
|
33
35
|
"peerDependencies": {
|
|
34
|
-
"@molecule/app-image-crop": "^1.0.
|
|
36
|
+
"@molecule/app-image-crop": "^1.0.1"
|
|
35
37
|
},
|
|
36
38
|
"devDependencies": {
|
|
37
|
-
"@molecule/app-image-crop": "1.0.
|
|
39
|
+
"@molecule/app-image-crop": "1.0.1",
|
|
38
40
|
"@types/cropperjs": "1.3.3",
|
|
39
41
|
"@types/node": "26.1.2",
|
|
40
42
|
"typescript": "6.0.3",
|