big updat:
- update dependencies - add webp support and webp conversion for profile images
This commit is contained in:
parent
19c3dbb42d
commit
95aaaa69ea
244 changed files with 121382 additions and 86 deletions
21
node_modules/super-image-cropper/LICENSE
generated
vendored
Normal file
21
node_modules/super-image-cropper/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 陌小路
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
246
node_modules/super-image-cropper/README.md
generated
vendored
Normal file
246
node_modules/super-image-cropper/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
<div align="center">
|
||||
|
||||
# 🖼️ Super Image Cropper
|
||||
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
|
||||
A powerful JavaScript image cropping library that supports GIF animations, PNG, JPG and other image formats.
|
||||
|
||||
[](https://www.npmjs.com/package/super-image-cropper) [](https://www.npmjs.com/package/super-image-cropper) [](https://github.com/STDSuperman/super-image-cropper/blob/master/LICENSE) [](https://github.com/STDSuperman/super-image-cropper/stargazers) [](https://github.com/STDSuperman/super-image-cropper/issues) [](https://www.typescriptlang.org/)
|
||||
|
||||
[🌟 Live Demo](https://gif-cropper-stdsuperman.vercel.app/) | [📖 Documentation](#documentation) | [🇨🇳 中文文档](../../docs/README_zh.md)
|
||||
|
||||
</div>
|
||||
|
||||
## ✨ Features
|
||||
|
||||
- 🎬 **GIF Animation Support** - Crop animated GIFs while preserving animation
|
||||
- 🖼️ **Multiple Formats** - Support for PNG, JPG, JPEG, and GIF formats
|
||||
- 🔧 **CropperJS Integration** - Seamless integration with popular CropperJS library
|
||||
- 🎨 **Flexible Output** - Multiple output formats: Base64, Blob, or Blob URL
|
||||
- ⚡ **High Performance** - Optimized for handling large images and animations
|
||||
- 🎯 **Precise Control** - Fine-grained control over cropping parameters
|
||||
- 📱 **Cross-Platform** - Works in all modern browsers
|
||||
- 🔄 **Transform Support** - Rotation and scaling transformations
|
||||
|
||||
## 🎯 Live Demo
|
||||
|
||||
- **[Online Demo](https://gif-cropper-stdsuperman.vercel.app/)** - Try it out in your browser
|
||||
- **[CodeSandbox](https://codesandbox.io/p/github/STDSuperman/codesandbox-super-image-cropper/master?workspaceId=6d860bca-a1bd-4c35-9131-07f0c5450764)** - Interactive example with CropperJS
|
||||
|
||||
### Preview
|
||||
|
||||
#### GIF Animation Cropping
|
||||
<img src="https://blog-images-1257398419.cos.ap-nanjing.myqcloud.com/github/gif-transparent.png" width="657" alt="GIF Cropping Preview">
|
||||
|
||||
#### Static Image Cropping
|
||||
<img src="https://s4.ax1x.com/2022/02/23/bPUoIf.png" width="657" alt="Static Image Cropping Preview">
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
npm install super-image-cropper
|
||||
```
|
||||
|
||||
```bash
|
||||
yarn add super-image-cropper
|
||||
```
|
||||
|
||||
```bash
|
||||
pnpm add super-image-cropper
|
||||
```
|
||||
|
||||
### Basic Usage
|
||||
|
||||
#### With CropperJS (Recommended)
|
||||
|
||||
```html
|
||||
<img id="image" src="your-image.gif" alt="Image to crop">
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { SuperImageCropper } from 'super-image-cropper';
|
||||
import Cropper from 'cropperjs';
|
||||
|
||||
// Initialize CropperJS
|
||||
const image = document.getElementById('image') as HTMLImageElement;
|
||||
const cropperInstance = new Cropper(image, {
|
||||
aspectRatio: 16 / 9,
|
||||
autoCrop: false,
|
||||
autoCropArea: 1,
|
||||
minCropBoxHeight: 10,
|
||||
minCropBoxWidth: 10,
|
||||
viewMode: 1,
|
||||
initialAspectRatio: 1,
|
||||
responsive: false,
|
||||
guides: true
|
||||
});
|
||||
|
||||
// Create cropper instance
|
||||
const imageCropper = new SuperImageCropper();
|
||||
|
||||
// Crop the image
|
||||
imageCropper.crop({
|
||||
cropperInstance: cropperInstance,
|
||||
src: 'your-image.gif',
|
||||
outputType: 'blobURL' // optional, default is blobURL
|
||||
}).then(blobUrl => {
|
||||
const img = document.createElement('img');
|
||||
img.src = blobUrl;
|
||||
document.body.appendChild(img);
|
||||
});
|
||||
```
|
||||
|
||||
#### Standalone Usage
|
||||
|
||||
```typescript
|
||||
import { SuperImageCropper } from 'super-image-cropper';
|
||||
|
||||
const imageCropper = new SuperImageCropper();
|
||||
|
||||
imageCropper.crop({
|
||||
src: 'your-image.gif',
|
||||
cropperJsOpts: {
|
||||
width: 400,
|
||||
height: 240,
|
||||
rotate: 45,
|
||||
x: 0,
|
||||
y: 0,
|
||||
scaleX: 1,
|
||||
scaleY: 1
|
||||
},
|
||||
outputType: 'base64'
|
||||
}).then(result => {
|
||||
console.log('Cropped image:', result);
|
||||
});
|
||||
```
|
||||
|
||||
## 📖 API Reference
|
||||
|
||||
### SuperImageCropper
|
||||
|
||||
#### Methods
|
||||
|
||||
##### `crop(options: CropOptions): Promise<string | Blob>`
|
||||
|
||||
Crops an image based on the provided options.
|
||||
|
||||
#### CropOptions
|
||||
|
||||
| Property | Type | Required | Description |
|
||||
|----------|------|----------|-------------|
|
||||
| `src` | `string` | Yes | Image URL or path |
|
||||
| `crossOrigin` | `string` | No | CORS strategy for image loading |
|
||||
| `cropperInstance` | `Cropper` | No | CropperJS instance (when used with CropperJS) |
|
||||
| `cropperJsOpts` | `CropperJsOptions` | No | Manual cropping parameters |
|
||||
| `gifJsOptions` | `object` | No | [gif.js](https://github.com/jnordberg/gif.js) configuration |
|
||||
| `outputType` | `'base64' \| 'blob' \| 'blobURL'` | No | Output format (default: `'blobURL'`) |
|
||||
|
||||
#### CropperJsOptions
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `x` | `number` | Left offset of the cropped area |
|
||||
| `y` | `number` | Top offset of the cropped area |
|
||||
| `width` | `number` | Width of the cropped area |
|
||||
| `height` | `number` | Height of the cropped area |
|
||||
| `rotate` | `number` | Rotation angle in degrees |
|
||||
| `scaleX` | `number` | Horizontal scaling factor |
|
||||
| `scaleY` | `number` | Vertical scaling factor |
|
||||
| `background` | `string` | Background color for GIF (optional) |
|
||||
|
||||
### Output Types
|
||||
|
||||
- **`base64`** - Returns a base64 encoded string
|
||||
- **`blob`** - Returns a Blob object
|
||||
- **`blobURL`** - Returns a blob URL (e.g., `blob:http://localhost:3000/8a583ca5...`)
|
||||
|
||||
## 🔧 Examples
|
||||
|
||||
### React Integration
|
||||
|
||||
Check out our [React example](../../example/crop-gif-with-cropper) for a complete implementation with React and CropperJS.
|
||||
|
||||
### Advanced Usage
|
||||
|
||||
```typescript
|
||||
import { SuperImageCropper } from 'super-image-cropper';
|
||||
|
||||
const cropper = new SuperImageCropper();
|
||||
|
||||
// Crop with custom GIF options
|
||||
await cropper.crop({
|
||||
src: 'animated.gif',
|
||||
cropperJsOpts: {
|
||||
x: 100,
|
||||
y: 100,
|
||||
width: 300,
|
||||
height: 200,
|
||||
rotate: 90,
|
||||
background: '#ffffff'
|
||||
},
|
||||
gifJsOptions: {
|
||||
quality: 10,
|
||||
workers: 2,
|
||||
workerScript: 'gif.worker.js'
|
||||
},
|
||||
outputType: 'blob'
|
||||
});
|
||||
```
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
We welcome contributions! Please see our [Contributing Guide](../../CONTRIBUTING.md) for details.
|
||||
|
||||
### Development Setup
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/STDSuperman/super-image-cropper.git
|
||||
|
||||
# Install dependencies
|
||||
pnpm install
|
||||
|
||||
# Build the project
|
||||
pnpm build
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
super-image-cropper/
|
||||
├── packages/
|
||||
│ ├── super-image-cropper/ # Main library
|
||||
│ └── gif-worker-js/ # GIF processing worker
|
||||
├── example/ # Example applications
|
||||
├── docs/ # Documentation
|
||||
└── scripts/ # Build and release scripts
|
||||
```
|
||||
|
||||
## 📄 License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
## 🙏 Acknowledgments
|
||||
|
||||
- [CropperJS](https://github.com/fengyuanchen/cropperjs) - Excellent image cropping library
|
||||
- [gif.js](https://github.com/jnordberg/gif.js) - GIF encoding library
|
||||
- All our [contributors](https://github.com/STDSuperman/super-image-cropper/graphs/contributors)
|
||||
|
||||
## 📞 Support
|
||||
|
||||
- 🐛 [Report Issues](https://github.com/STDSuperman/super-image-cropper/issues)
|
||||
- 💬 [Discussions](https://github.com/STDSuperman/super-image-cropper/discussions)
|
||||
- ⭐ Star this project if it helps you!
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
Made with ❤️ by [STDSuperman](https://github.com/STDSuperman)
|
||||
|
||||
</div>
|
||||
76
node_modules/super-image-cropper/dist/index.d.ts
generated
vendored
Normal file
76
node_modules/super-image-cropper/dist/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import type Cropper from 'cropperjs';
|
||||
export interface CustomCropper extends Cropper {
|
||||
url: '';
|
||||
cropBoxData: Cropper.ImageData;
|
||||
canvasData: Cropper.ImageData;
|
||||
cropper?: HTMLDivElement;
|
||||
}
|
||||
export declare enum OutputType {
|
||||
BASE64 = "base64",
|
||||
BLOB = "blob",
|
||||
BLOB_URL = "blobURL"
|
||||
}
|
||||
export type IOutputTypeUnion = `${OutputType}`;
|
||||
export interface ICropperOptions {
|
||||
cropperInstance?: CustomCropper | Cropper;
|
||||
src?: string;
|
||||
crossOrigin?: '' | 'anonymous' | 'use-credentials';
|
||||
cropperJsOpts?: ICropOpts;
|
||||
gifJsOptions?: IGifOpts;
|
||||
outputType?: IOutputTypeUnion;
|
||||
}
|
||||
export interface IGifOpts {
|
||||
repeat?: number;
|
||||
quality?: number;
|
||||
workers?: number;
|
||||
workerScript?: string;
|
||||
background?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
transparent?: string | null;
|
||||
dither?: boolean;
|
||||
debug?: boolean;
|
||||
}
|
||||
export interface ICropOpts {
|
||||
width?: number;
|
||||
height?: number;
|
||||
scaleX?: number;
|
||||
scaleY?: number;
|
||||
x?: number;
|
||||
y?: number;
|
||||
background?: string;
|
||||
rotate?: number;
|
||||
left?: number;
|
||||
top?: number;
|
||||
}
|
||||
export interface IImageData {
|
||||
width: number;
|
||||
height: number;
|
||||
naturalWidth: number;
|
||||
naturalHeight: number;
|
||||
}
|
||||
export interface ICommonCropOptions {
|
||||
cropperJsOpts: Required<ICropOpts>;
|
||||
imageData: IImageData;
|
||||
cropBoxData: Cropper.CropBoxData;
|
||||
}
|
||||
export declare class SuperImageCropper {
|
||||
private cropperJsInstance?;
|
||||
private parsedFrameInfo;
|
||||
private commonCropOptions;
|
||||
private frameCropperInstance;
|
||||
private inputCropperOptions;
|
||||
private imageTypeInfo;
|
||||
crop(inputCropperOptions: ICropperOptions): Promise<string | Blob>;
|
||||
private init;
|
||||
private cleanUserInput;
|
||||
private userInputValidator;
|
||||
private normalizeRotate;
|
||||
private imageDataFormat;
|
||||
private decodeGIF;
|
||||
private ensureFrameCropperExist;
|
||||
private cropFrames;
|
||||
private saveGif;
|
||||
private checkIsStaticImage;
|
||||
private handleStaticImage;
|
||||
}
|
||||
2
node_modules/super-image-cropper/dist/index.js
generated
vendored
Normal file
2
node_modules/super-image-cropper/dist/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";var t,e=require("./lib/decoder.js"),r=require("./lib/synthetic-gif.js"),s=require("./lib/cropper.js"),p=require("./lib/helper.js");exports.OutputType=void 0,(t=exports.OutputType||(exports.OutputType={})).BASE64="base64",t.BLOB="blob",t.BLOB_URL="blobURL";exports.SuperImageCropper=class{cropperJsInstance;parsedFrameInfo;commonCropOptions;frameCropperInstance;inputCropperOptions;imageTypeInfo=null;async crop(t){this.userInputValidator(t),this.inputCropperOptions=this.cleanUserInput(t),await this.init(),await this.decodeGIF();const e=await this.checkIsStaticImage();if(e.isStatic)return this.handleStaticImage(e.imageInfo.imageInstance);{const t=await this.cropFrames();return this.saveGif(t,this.parsedFrameInfo?.delays||[])}}async init(){this.cropperJsInstance=this.inputCropperOptions.cropperInstance;const t=Object.assign({width:100,height:100,scaleX:1,scaleY:1,x:0,y:0,rotate:0,left:0,top:0},this.inputCropperOptions.cropperJsOpts||{},this.cropperJsInstance?.getData()||{}),e=this.cropperJsInstance?.getImageData()||await p.getImageInfo({src:this.inputCropperOptions.src,crossOrigin:this.inputCropperOptions.crossOrigin})||{};this.commonCropOptions={cropperJsOpts:this.imageDataFormat(t,e),imageData:e,cropBoxData:this.cropperJsInstance?.getCropBoxData()||t},this.commonCropOptions.cropperJsOpts.rotate=this.normalizeRotate(this.commonCropOptions.cropperJsOpts.rotate)}cleanUserInput(t){const{cropperInstance:e}=t;return e&&(delete t.cropperJsOpts,delete t.src),t}userInputValidator(t){const{cropperInstance:e,cropperJsOpts:r,src:s}=t;if(!e){if(!r)throw new Error("If cropperInstance is not specified, cropperJsOpts must be specified.");if(!s)throw new Error("If cropperInstance is not specified, src must be specified.")}}normalizeRotate(t){return t<0?360+t%360:t}imageDataFormat(t,e){return t.left=t.x,t.top=t.y,t.width=t.width||e.naturalWidth,t.height=t.height||e.naturalHeight,t}async decodeGIF(){const t=new e.Decoder(this.inputCropperOptions.src||this.cropperJsInstance?.url||""),r=await t.decompressFrames();this.parsedFrameInfo=r}ensureFrameCropperExist(){this.frameCropperInstance||(this.frameCropperInstance=new s.FrameCropper({commonCropOptions:this.commonCropOptions}))}async cropFrames(){return this.ensureFrameCropperExist(),this.frameCropperInstance.init({commonCropOptions:this.commonCropOptions}),this.frameCropperInstance.cropGif(this.parsedFrameInfo)}async saveGif(t,e){return new r.SyntheticGIF({frames:t,commonCropOptions:this.commonCropOptions,frameDelays:e,gifJsOptions:this.inputCropperOptions.gifJsOptions,outputType:this.inputCropperOptions.outputType}).bootstrap()}async checkIsStaticImage(){const t=this.cropperJsInstance?.url??this.inputCropperOptions?.src,e=await p.loadImage({src:t,crossOrigin:this.inputCropperOptions.crossOrigin});return{isStatic:"image/gif"!==e?.imageType?.mime,imageInfo:e}}async handleStaticImage(t){const e=document.createElement("canvas"),r=e.getContext("2d");e.width=t.width,e.height=t.height,r?.drawImage(t,0,0),this.ensureFrameCropperExist(),this.frameCropperInstance.init({commonCropOptions:this.commonCropOptions});const s=await this.frameCropperInstance.cropStaticImage(e);return r?.clearRect(0,0,e.width,e.height),e.width=s.width,e.height=s.height,r?.putImageData(s,0,0),new Promise(((t,r)=>{const{outputType:s=exports.OutputType.BLOB_URL}=this.inputCropperOptions;s===exports.OutputType.BASE64?t(e.toDataURL(this.imageTypeInfo?.mime)):e.toBlob((e=>{if(!e)return r(null);if(s===exports.OutputType.BLOB)t(e);else{const r=window.URL.createObjectURL(e);t(r)}}),this.imageTypeInfo?.mime)}))}};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/super-image-cropper/dist/index.js.map
generated
vendored
Normal file
1
node_modules/super-image-cropper/dist/index.js.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
31
node_modules/super-image-cropper/dist/lib/cropper.d.ts
generated
vendored
Normal file
31
node_modules/super-image-cropper/dist/lib/cropper.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { ICommonCropOptions } from '../index';
|
||||
import type { IParsedFrameInfo } from './decoder';
|
||||
export interface IFrameCropperProps {
|
||||
commonCropOptions: ICommonCropOptions;
|
||||
}
|
||||
export declare class FrameCropper {
|
||||
private frames;
|
||||
private parsedFrames;
|
||||
private commonCropOptions;
|
||||
private convertorCanvas;
|
||||
private containerCanvas;
|
||||
private convertCtx;
|
||||
private containerCtx;
|
||||
private cropperJsOpts;
|
||||
private offsetX;
|
||||
private offsetY;
|
||||
private containerCenterX;
|
||||
private containerCenterY;
|
||||
private resultFrames;
|
||||
constructor(props: IFrameCropperProps);
|
||||
init({ commonCropOptions }: IFrameCropperProps): void;
|
||||
cropGif(parsedFrameInfo: IParsedFrameInfo): Promise<ImageData[]>;
|
||||
cropStaticImage(canvasImageContainer: HTMLCanvasElement): ImageData;
|
||||
private transformFrame;
|
||||
private drawImgDataToCanvas;
|
||||
private ifDebugRun;
|
||||
private renderEachFrame;
|
||||
private setupCanvas;
|
||||
private setCanvasWH;
|
||||
private frameToImgData;
|
||||
}
|
||||
2
node_modules/super-image-cropper/dist/lib/cropper.js
generated
vendored
Normal file
2
node_modules/super-image-cropper/dist/lib/cropper.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";exports.FrameCropper=class{frames;parsedFrames;commonCropOptions;convertorCanvas;containerCanvas;convertCtx;containerCtx;cropperJsOpts;offsetX=0;offsetY=0;containerCenterX=0;containerCenterY=0;resultFrames=[];constructor(t){this.init(t)}init({commonCropOptions:t}){this.commonCropOptions=t,this.cropperJsOpts=t.cropperJsOpts,this.resultFrames=[],this.containerCanvas&&this.convertorCanvas||this.setupCanvas(),this.setCanvasWH()}async cropGif(t){const{frames:s,parsedFrames:e}=t;this.frames=s,this.parsedFrames=e;let a=0;for(;a<this.frames.length;){const t=this.frames[a];if(1!==this.parsedFrames[a].disposalType&&this.containerCtx.clearRect(0,0,this.containerCanvas.width,this.containerCanvas.height),this.containerCtx.globalCompositeOperation&&this.cropperJsOpts?.background&&(this.containerCtx.fillStyle=this.cropperJsOpts?.background||"",this.containerCtx.globalCompositeOperation="destination-over",this.containerCtx.fillRect(0,0,this.containerCanvas.width,this.containerCanvas.height),this.containerCtx.globalCompositeOperation="source-over"),!t)continue;const s=this.transformFrame(this.drawImgDataToCanvas(t,a));this.resultFrames.push(s),this.ifDebugRun(s,a),a++}return this.resultFrames}cropStaticImage(t){return this.transformFrame(t)}transformFrame(t){this.containerCtx.save(),this.containerCtx.translate(this.containerCenterX,this.containerCenterY),this.containerCtx.rotate(this.cropperJsOpts.rotate*Math.PI/180),this.containerCtx.scale(this.cropperJsOpts.scaleX,this.cropperJsOpts.scaleY),this.containerCtx.drawImage(t,-this.convertorCanvas.width/2,-this.convertorCanvas.height/2),this.containerCtx.restore();return this.containerCtx.getImageData(1*this.cropperJsOpts.x+this.offsetX,1*this.cropperJsOpts.y+this.offsetY,this.cropperJsOpts.width,this.cropperJsOpts.height)}drawImgDataToCanvas(t,s){const e=this.parsedFrames[s]?.dims;return this.convertCtx.clearRect(0,0,this.convertorCanvas.width,this.convertorCanvas.height),this.convertCtx.putImageData(t,e.left,e.top),this.convertorCanvas}ifDebugRun(t,s){location.search.includes("isCropDebug=true")&&s&&this.renderEachFrame(t,s)}renderEachFrame(t,s){const e=this.parsedFrames[s]?.dims,a=document.createElement("canvas");a.width=this.convertorCanvas.width,a.height=this.convertorCanvas.height;const r=a.getContext("2d");r&&(r?.putImageData(t,e.left,e.top),r.fillStyle="red",r.strokeStyle="blue",r.lineWidth=5,r.save(),r.beginPath(),r.font="70px orbitron",r.fillText(String(s),10,50),r.restore(),r.closePath(),document.body.appendChild(a))}setupCanvas(){const t=this.containerCanvas=document.createElement("canvas"),s=this.convertorCanvas=document.createElement("canvas");t.className="containerCanvas",s.className="convertorCanvas",t.style.display="none",s.style.display="none";const e=t.getContext("2d",{willReadFrequently:!0}),a=s.getContext("2d");e&&(this.containerCtx=e),a&&(this.convertCtx=a),document.body.appendChild(s),document.body.appendChild(t)}setCanvasWH(){Math.PI,this.cropperJsOpts.rotate;const t=this.commonCropOptions.imageData,s=t.naturalWidth,e=t.naturalHeight;this.offsetX=-Math.min(this.cropperJsOpts.x,0),this.offsetY=-Math.min(this.cropperJsOpts.y,0),this.containerCenterX=this.offsetX+s/2,this.containerCenterY=this.offsetY+e/2,this.containerCanvas.width=Math.max(this.offsetX+s,this.offsetX+this.cropperJsOpts.width,this.cropperJsOpts.x+this.cropperJsOpts.width),this.containerCanvas.height=Math.max(this.offsetY+e,this.offsetY+this.cropperJsOpts.height,this.cropperJsOpts.y+this.cropperJsOpts.height),this.convertorCanvas.width=t.naturalWidth,this.convertorCanvas.height=t.naturalHeight,this.containerCtx.clearRect(0,0,this.containerCanvas.width,this.containerCanvas.height),this.convertCtx.clearRect(0,0,this.convertorCanvas.width,this.convertorCanvas.height)}frameToImgData(t,s){if(!t)return;const e=s.pixels.length,a=t.createImageData(s.dims.width,s.dims.height),r=a.data;for(let t=0;t<e;t++){const e=4*t,a=s.pixels[t],n=s.colorTable[a];r[e]=n[0],r[e+1]=n[1],r[e+2]=n[2],r[e+3]=a!==s.transparentIndex?255:0}return a}};
|
||||
//# sourceMappingURL=cropper.js.map
|
||||
1
node_modules/super-image-cropper/dist/lib/cropper.js.map
generated
vendored
Normal file
1
node_modules/super-image-cropper/dist/lib/cropper.js.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"cropper.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
38
node_modules/super-image-cropper/dist/lib/decoder.d.ts
generated
vendored
Normal file
38
node_modules/super-image-cropper/dist/lib/decoder.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { ParsedGif, ParsedFrame } from 'gifuct-js';
|
||||
import { GetArrTypeUnion } from './helper';
|
||||
export type IFrames = Pick<ParsedGif, 'frames'>['frames'];
|
||||
export type IFrame = GetArrTypeUnion<IFrames>;
|
||||
export interface IParsedFrameInfo {
|
||||
frames: ImageData[];
|
||||
delays: number[];
|
||||
parsedFrames: ParsedFrame[];
|
||||
}
|
||||
export declare class Decoder {
|
||||
private url;
|
||||
private parseGIF;
|
||||
constructor(url: string);
|
||||
decode(): Promise<ParsedGif>;
|
||||
decompressFrames(): Promise<IParsedFrameInfo>;
|
||||
/**
|
||||
* Validates and fixes frames that have lost pixels.
|
||||
* @param gif
|
||||
*/
|
||||
private validateAndFixFrame;
|
||||
/**
|
||||
* Generates ImageData objects from parsed frames.
|
||||
* @param frames
|
||||
*/
|
||||
private generate2ImageData;
|
||||
/**
|
||||
* Generates ImageData objects from frames with modified pixels.
|
||||
* @param frames
|
||||
*/
|
||||
private generate2ImageDataWithPixelsModified;
|
||||
/**
|
||||
* @param {string} url
|
||||
* @returns
|
||||
*/
|
||||
private fetchImageData;
|
||||
private handlePixels;
|
||||
private putPixels;
|
||||
}
|
||||
2
node_modules/super-image-cropper/dist/lib/decoder.js
generated
vendored
Normal file
2
node_modules/super-image-cropper/dist/lib/decoder.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";var e=require("gifuct-js");exports.Decoder=class{url;parseGIF;constructor(e){this.url=e}async decode(){const t=await this.fetchImageData(this.url);return this.parseGIF=e.parseGIF(t),this.validateAndFixFrame(this.parseGIF),this.parseGIF}async decompressFrames(){this.parseGIF||await this.decode();const t=await e.decompressFrames(this.parseGIF,!0);return{frames:this.generate2ImageData(t),delays:t.map((e=>e.delay)),parsedFrames:t}}validateAndFixFrame=e=>{let t=null;for(const r of e.frames)t=r.gce?r.gce:t,"image"in r&&!("gce"in r)&&(r.gce=t)};generate2ImageData(e){return e.map((e=>{const t=e?.dims,r=new ImageData(t.width,t.height);return r.data.set(e.patch),r}))}generate2ImageDataWithPixelsModified(e,t){return e.map(((e,r)=>{t[r];const a=this.parseGIF.lsd,s=new ImageData(a.width,a.height);return s.data.set(new Uint8ClampedArray(e)),s}))}fetchImageData(e){return new Promise(((t,r)=>{const a=new XMLHttpRequest;a.open("GET",e,!0),a.responseType="arraybuffer",a.onload=e=>{if(!(e.target instanceof XMLHttpRequest))return;if(200!==e.target.status&&304!==e.target.status)return void r("Status Error: "+e.target.status);let a=e.target.response;a.toString().indexOf("ArrayBuffer")>0&&(a=new Uint8Array(a)),t(a)},a.onerror=e=>{r(e)},a.send()}))}handlePixels(e){const t=this.parseGIF.lsd,r=t.width*t.height*4,a=[];for(let s=0;s<e.length;++s){const i=e[s],n=0===s||2===e[s-1].disposalType?new Uint8ClampedArray(r):a[s-1].slice();a.push(this.putPixels(n,i,t))}return a}putPixels(e,t,r){if(!t.dims)return e;const{width:a,height:s,top:i,left:n}=t.dims,o=i*r.width+n;for(let i=0;i<s;i++)for(let s=0;s<a;s++){const n=i*a+s,d=t.pixels[n],h=o+i*r.width+s,p=t.colorTable[d]||[0,0,0];d===t.transparentIndex?(e[4*h]=0,e[4*h+1]=0,e[4*h+2]=0,e[4*h+3]=0):(e[4*h]=p[0],e[4*h+1]=p[1],e[4*h+2]=p[2],e[4*h+3]=255)}return e}};
|
||||
//# sourceMappingURL=decoder.js.map
|
||||
1
node_modules/super-image-cropper/dist/lib/decoder.js.map
generated
vendored
Normal file
1
node_modules/super-image-cropper/dist/lib/decoder.js.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"decoder.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
20
node_modules/super-image-cropper/dist/lib/helper.d.ts
generated
vendored
Normal file
20
node_modules/super-image-cropper/dist/lib/helper.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { IImageData } from '../index';
|
||||
export type GetArrTypeUnion<T extends any[]> = T extends (infer I)[] ? I : never;
|
||||
export type IImageLoadData = {
|
||||
imageInstance: HTMLImageElement;
|
||||
data: Event;
|
||||
imageType: IImageTypeInfo | null;
|
||||
};
|
||||
export interface IImageTypeInfo {
|
||||
ext: string;
|
||||
mime: string;
|
||||
}
|
||||
export interface IGetImageParams {
|
||||
src?: string;
|
||||
crossOrigin?: '' | 'anonymous' | 'use-credentials';
|
||||
}
|
||||
export declare const getImageInfo: (params: IGetImageParams) => Promise<IImageData>;
|
||||
export declare const getImageType: (imageBufferData: ArrayBuffer) => Promise<IImageTypeInfo | null>;
|
||||
export declare const loadImage: (params: IGetImageParams) => Promise<IImageLoadData>;
|
||||
export declare const transformImageData2ArrayBuffer: (image: HTMLImageElement) => ArrayBufferLike;
|
||||
export declare const getImageBufferFromRemote: (url?: string) => Promise<ArrayBuffer>;
|
||||
2
node_modules/super-image-cropper/dist/lib/helper.js
generated
vendored
Normal file
2
node_modules/super-image-cropper/dist/lib/helper.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";var e=require("image-type");const t=async t=>e(new Uint8Array(t)),a=async e=>{const{src:a="",crossOrigin:n}=e;return{...await new Promise(((e,t)=>{const r=new Image;void 0!==n&&(r.crossOrigin=n),r.onload=async t=>{e({imageInstance:r,data:t})},r.src=a,r.onerror=t})),imageType:await t(await r(a))}},r=(e="")=>new Promise(((t,a)=>{const r=new XMLHttpRequest;r.open("GET",e),r.responseType="arraybuffer",r.onload=()=>{t(r.response)},r.onerror=a,r.send()}));exports.getImageBufferFromRemote=r,exports.getImageInfo=async e=>{const{src:t=""}=e;if(!t)return{width:0,height:0,naturalWidth:0,naturalHeight:0};const{imageInstance:r}=await a(e);return{width:r.width,height:r.height,naturalWidth:r.naturalWidth,naturalHeight:r.naturalHeight}},exports.getImageType=t,exports.loadImage=a;
|
||||
//# sourceMappingURL=helper.js.map
|
||||
1
node_modules/super-image-cropper/dist/lib/helper.js.map
generated
vendored
Normal file
1
node_modules/super-image-cropper/dist/lib/helper.js.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"helper.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
19
node_modules/super-image-cropper/dist/lib/synthetic-gif.d.ts
generated
vendored
Normal file
19
node_modules/super-image-cropper/dist/lib/synthetic-gif.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { ICommonCropOptions, ICropperOptions } from '../index';
|
||||
import { IOutputTypeUnion } from '../index';
|
||||
export interface IFrameCropperProps {
|
||||
commonCropOptions: ICommonCropOptions;
|
||||
frames: ImageData[];
|
||||
frameDelays: number[];
|
||||
gifJsOptions?: ICropperOptions['gifJsOptions'];
|
||||
outputType?: IOutputTypeUnion;
|
||||
}
|
||||
export declare class SyntheticGIF {
|
||||
private cropperJsOpts;
|
||||
private frames;
|
||||
private frameDelays;
|
||||
private gifJsOptions;
|
||||
private outputType;
|
||||
constructor({ frames, commonCropOptions, frameDelays, gifJsOptions, outputType }: IFrameCropperProps);
|
||||
bootstrap(): Promise<string | Blob>;
|
||||
private convertBlob2Base64;
|
||||
}
|
||||
2
node_modules/super-image-cropper/dist/lib/synthetic-gif.js
generated
vendored
Normal file
2
node_modules/super-image-cropper/dist/lib/synthetic-gif.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
"use strict";var e=require("gif-build-worker-js"),t=require("gif.js"),s=require("../index.js");exports.SyntheticGIF=class{cropperJsOpts;frames;frameDelays;gifJsOptions;outputType;constructor({frames:e,commonCropOptions:t,frameDelays:s,gifJsOptions:r={},outputType:i}){this.cropperJsOpts=t.cropperJsOpts,this.frames=e,this.frameDelays=s,this.gifJsOptions=r,this.outputType=i}bootstrap(){return new Promise(((r,i)=>{const o=e.transformToUrl(),p=Object.assign({workers:2,quality:10,workerScript:o,width:this.cropperJsOpts.width,height:this.cropperJsOpts.height,transparent:"transparent"},this.gifJsOptions||{}),a=new t(p);a.on("finished",(e=>{if(this.outputType===s.OutputType.BLOB)r(e);else if(this.outputType===s.OutputType.BASE64)r(this.convertBlob2Base64(e));else{const t=window.URL.createObjectURL(e);r(t)}})),this.frames.forEach(((e,t)=>{a.addFrame(e,{delay:this.frameDelays[t],copy:!0})})),a.render()}))}convertBlob2Base64(e){return new Promise(((t,s)=>{const r=new FileReader;r.onload=function(e){t(e?.target?.result)},r.onerror=e=>{s(e)},r.readAsDataURL(e)}))}};
|
||||
//# sourceMappingURL=synthetic-gif.js.map
|
||||
1
node_modules/super-image-cropper/dist/lib/synthetic-gif.js.map
generated
vendored
Normal file
1
node_modules/super-image-cropper/dist/lib/synthetic-gif.js.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"synthetic-gif.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
1
node_modules/super-image-cropper/dist/utils/index.d.ts
generated
vendored
Normal file
1
node_modules/super-image-cropper/dist/utils/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
export declare const renderImageData2Canvas: (imageData: ImageData) => void;
|
||||
76
node_modules/super-image-cropper/esm/index.d.ts
generated
vendored
Normal file
76
node_modules/super-image-cropper/esm/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import type Cropper from 'cropperjs';
|
||||
export interface CustomCropper extends Cropper {
|
||||
url: '';
|
||||
cropBoxData: Cropper.ImageData;
|
||||
canvasData: Cropper.ImageData;
|
||||
cropper?: HTMLDivElement;
|
||||
}
|
||||
export declare enum OutputType {
|
||||
BASE64 = "base64",
|
||||
BLOB = "blob",
|
||||
BLOB_URL = "blobURL"
|
||||
}
|
||||
export type IOutputTypeUnion = `${OutputType}`;
|
||||
export interface ICropperOptions {
|
||||
cropperInstance?: CustomCropper | Cropper;
|
||||
src?: string;
|
||||
crossOrigin?: '' | 'anonymous' | 'use-credentials';
|
||||
cropperJsOpts?: ICropOpts;
|
||||
gifJsOptions?: IGifOpts;
|
||||
outputType?: IOutputTypeUnion;
|
||||
}
|
||||
export interface IGifOpts {
|
||||
repeat?: number;
|
||||
quality?: number;
|
||||
workers?: number;
|
||||
workerScript?: string;
|
||||
background?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
transparent?: string | null;
|
||||
dither?: boolean;
|
||||
debug?: boolean;
|
||||
}
|
||||
export interface ICropOpts {
|
||||
width?: number;
|
||||
height?: number;
|
||||
scaleX?: number;
|
||||
scaleY?: number;
|
||||
x?: number;
|
||||
y?: number;
|
||||
background?: string;
|
||||
rotate?: number;
|
||||
left?: number;
|
||||
top?: number;
|
||||
}
|
||||
export interface IImageData {
|
||||
width: number;
|
||||
height: number;
|
||||
naturalWidth: number;
|
||||
naturalHeight: number;
|
||||
}
|
||||
export interface ICommonCropOptions {
|
||||
cropperJsOpts: Required<ICropOpts>;
|
||||
imageData: IImageData;
|
||||
cropBoxData: Cropper.CropBoxData;
|
||||
}
|
||||
export declare class SuperImageCropper {
|
||||
private cropperJsInstance?;
|
||||
private parsedFrameInfo;
|
||||
private commonCropOptions;
|
||||
private frameCropperInstance;
|
||||
private inputCropperOptions;
|
||||
private imageTypeInfo;
|
||||
crop(inputCropperOptions: ICropperOptions): Promise<string | Blob>;
|
||||
private init;
|
||||
private cleanUserInput;
|
||||
private userInputValidator;
|
||||
private normalizeRotate;
|
||||
private imageDataFormat;
|
||||
private decodeGIF;
|
||||
private ensureFrameCropperExist;
|
||||
private cropFrames;
|
||||
private saveGif;
|
||||
private checkIsStaticImage;
|
||||
private handleStaticImage;
|
||||
}
|
||||
2
node_modules/super-image-cropper/esm/index.js
generated
vendored
Normal file
2
node_modules/super-image-cropper/esm/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import{Decoder as t}from"./lib/decoder.js";import{SyntheticGIF as e}from"./lib/synthetic-gif.js";import{FrameCropper as r}from"./lib/cropper.js";import{getImageInfo as s,loadImage as i}from"./lib/helper.js";var o;!function(t){t.BASE64="base64",t.BLOB="blob",t.BLOB_URL="blobURL"}(o||(o={}));class p{cropperJsInstance;parsedFrameInfo;commonCropOptions;frameCropperInstance;inputCropperOptions;imageTypeInfo=null;async crop(t){this.userInputValidator(t),this.inputCropperOptions=this.cleanUserInput(t),await this.init(),await this.decodeGIF();const e=await this.checkIsStaticImage();if(e.isStatic)return this.handleStaticImage(e.imageInfo.imageInstance);{const t=await this.cropFrames();return this.saveGif(t,this.parsedFrameInfo?.delays||[])}}async init(){this.cropperJsInstance=this.inputCropperOptions.cropperInstance;const t=Object.assign({width:100,height:100,scaleX:1,scaleY:1,x:0,y:0,rotate:0,left:0,top:0},this.inputCropperOptions.cropperJsOpts||{},this.cropperJsInstance?.getData()||{}),e=this.cropperJsInstance?.getImageData()||await s({src:this.inputCropperOptions.src,crossOrigin:this.inputCropperOptions.crossOrigin})||{};this.commonCropOptions={cropperJsOpts:this.imageDataFormat(t,e),imageData:e,cropBoxData:this.cropperJsInstance?.getCropBoxData()||t},this.commonCropOptions.cropperJsOpts.rotate=this.normalizeRotate(this.commonCropOptions.cropperJsOpts.rotate)}cleanUserInput(t){const{cropperInstance:e}=t;return e&&(delete t.cropperJsOpts,delete t.src),t}userInputValidator(t){const{cropperInstance:e,cropperJsOpts:r,src:s}=t;if(!e){if(!r)throw new Error("If cropperInstance is not specified, cropperJsOpts must be specified.");if(!s)throw new Error("If cropperInstance is not specified, src must be specified.")}}normalizeRotate(t){return t<0?360+t%360:t}imageDataFormat(t,e){return t.left=t.x,t.top=t.y,t.width=t.width||e.naturalWidth,t.height=t.height||e.naturalHeight,t}async decodeGIF(){const e=new t(this.inputCropperOptions.src||this.cropperJsInstance?.url||""),r=await e.decompressFrames();this.parsedFrameInfo=r}ensureFrameCropperExist(){this.frameCropperInstance||(this.frameCropperInstance=new r({commonCropOptions:this.commonCropOptions}))}async cropFrames(){return this.ensureFrameCropperExist(),this.frameCropperInstance.init({commonCropOptions:this.commonCropOptions}),this.frameCropperInstance.cropGif(this.parsedFrameInfo)}async saveGif(t,r){return new e({frames:t,commonCropOptions:this.commonCropOptions,frameDelays:r,gifJsOptions:this.inputCropperOptions.gifJsOptions,outputType:this.inputCropperOptions.outputType}).bootstrap()}async checkIsStaticImage(){const t=this.cropperJsInstance?.url??this.inputCropperOptions?.src,e=await i({src:t,crossOrigin:this.inputCropperOptions.crossOrigin});return{isStatic:"image/gif"!==e?.imageType?.mime,imageInfo:e}}async handleStaticImage(t){const e=document.createElement("canvas"),r=e.getContext("2d");e.width=t.width,e.height=t.height,r?.drawImage(t,0,0),this.ensureFrameCropperExist(),this.frameCropperInstance.init({commonCropOptions:this.commonCropOptions});const s=await this.frameCropperInstance.cropStaticImage(e);return r?.clearRect(0,0,e.width,e.height),e.width=s.width,e.height=s.height,r?.putImageData(s,0,0),new Promise(((t,r)=>{const{outputType:s=o.BLOB_URL}=this.inputCropperOptions;s===o.BASE64?t(e.toDataURL(this.imageTypeInfo?.mime)):e.toBlob((e=>{if(!e)return r(null);if(s===o.BLOB)t(e);else{const r=window.URL.createObjectURL(e);t(r)}}),this.imageTypeInfo?.mime)}))}}export{o as OutputType,p as SuperImageCropper};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/super-image-cropper/esm/index.js.map
generated
vendored
Normal file
1
node_modules/super-image-cropper/esm/index.js.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
31
node_modules/super-image-cropper/esm/lib/cropper.d.ts
generated
vendored
Normal file
31
node_modules/super-image-cropper/esm/lib/cropper.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { ICommonCropOptions } from '../index';
|
||||
import type { IParsedFrameInfo } from './decoder';
|
||||
export interface IFrameCropperProps {
|
||||
commonCropOptions: ICommonCropOptions;
|
||||
}
|
||||
export declare class FrameCropper {
|
||||
private frames;
|
||||
private parsedFrames;
|
||||
private commonCropOptions;
|
||||
private convertorCanvas;
|
||||
private containerCanvas;
|
||||
private convertCtx;
|
||||
private containerCtx;
|
||||
private cropperJsOpts;
|
||||
private offsetX;
|
||||
private offsetY;
|
||||
private containerCenterX;
|
||||
private containerCenterY;
|
||||
private resultFrames;
|
||||
constructor(props: IFrameCropperProps);
|
||||
init({ commonCropOptions }: IFrameCropperProps): void;
|
||||
cropGif(parsedFrameInfo: IParsedFrameInfo): Promise<ImageData[]>;
|
||||
cropStaticImage(canvasImageContainer: HTMLCanvasElement): ImageData;
|
||||
private transformFrame;
|
||||
private drawImgDataToCanvas;
|
||||
private ifDebugRun;
|
||||
private renderEachFrame;
|
||||
private setupCanvas;
|
||||
private setCanvasWH;
|
||||
private frameToImgData;
|
||||
}
|
||||
2
node_modules/super-image-cropper/esm/lib/cropper.js
generated
vendored
Normal file
2
node_modules/super-image-cropper/esm/lib/cropper.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
class t{frames;parsedFrames;commonCropOptions;convertorCanvas;containerCanvas;convertCtx;containerCtx;cropperJsOpts;offsetX=0;offsetY=0;containerCenterX=0;containerCenterY=0;resultFrames=[];constructor(t){this.init(t)}init({commonCropOptions:t}){this.commonCropOptions=t,this.cropperJsOpts=t.cropperJsOpts,this.resultFrames=[],this.containerCanvas&&this.convertorCanvas||this.setupCanvas(),this.setCanvasWH()}async cropGif(t){const{frames:s,parsedFrames:e}=t;this.frames=s,this.parsedFrames=e;let a=0;for(;a<this.frames.length;){const t=this.frames[a];if(1!==this.parsedFrames[a].disposalType&&this.containerCtx.clearRect(0,0,this.containerCanvas.width,this.containerCanvas.height),this.containerCtx.globalCompositeOperation&&this.cropperJsOpts?.background&&(this.containerCtx.fillStyle=this.cropperJsOpts?.background||"",this.containerCtx.globalCompositeOperation="destination-over",this.containerCtx.fillRect(0,0,this.containerCanvas.width,this.containerCanvas.height),this.containerCtx.globalCompositeOperation="source-over"),!t)continue;const s=this.transformFrame(this.drawImgDataToCanvas(t,a));this.resultFrames.push(s),this.ifDebugRun(s,a),a++}return this.resultFrames}cropStaticImage(t){return this.transformFrame(t)}transformFrame(t){this.containerCtx.save(),this.containerCtx.translate(this.containerCenterX,this.containerCenterY),this.containerCtx.rotate(this.cropperJsOpts.rotate*Math.PI/180),this.containerCtx.scale(this.cropperJsOpts.scaleX,this.cropperJsOpts.scaleY),this.containerCtx.drawImage(t,-this.convertorCanvas.width/2,-this.convertorCanvas.height/2),this.containerCtx.restore();return this.containerCtx.getImageData(1*this.cropperJsOpts.x+this.offsetX,1*this.cropperJsOpts.y+this.offsetY,this.cropperJsOpts.width,this.cropperJsOpts.height)}drawImgDataToCanvas(t,s){const e=this.parsedFrames[s]?.dims;return this.convertCtx.clearRect(0,0,this.convertorCanvas.width,this.convertorCanvas.height),this.convertCtx.putImageData(t,e.left,e.top),this.convertorCanvas}ifDebugRun(t,s){location.search.includes("isCropDebug=true")&&s&&this.renderEachFrame(t,s)}renderEachFrame(t,s){const e=this.parsedFrames[s]?.dims,a=document.createElement("canvas");a.width=this.convertorCanvas.width,a.height=this.convertorCanvas.height;const r=a.getContext("2d");r&&(r?.putImageData(t,e.left,e.top),r.fillStyle="red",r.strokeStyle="blue",r.lineWidth=5,r.save(),r.beginPath(),r.font="70px orbitron",r.fillText(String(s),10,50),r.restore(),r.closePath(),document.body.appendChild(a))}setupCanvas(){const t=this.containerCanvas=document.createElement("canvas"),s=this.convertorCanvas=document.createElement("canvas");t.className="containerCanvas",s.className="convertorCanvas",t.style.display="none",s.style.display="none";const e=t.getContext("2d",{willReadFrequently:!0}),a=s.getContext("2d");e&&(this.containerCtx=e),a&&(this.convertCtx=a),document.body.appendChild(s),document.body.appendChild(t)}setCanvasWH(){Math.PI,this.cropperJsOpts.rotate;const t=this.commonCropOptions.imageData,s=t.naturalWidth,e=t.naturalHeight;this.offsetX=-Math.min(this.cropperJsOpts.x,0),this.offsetY=-Math.min(this.cropperJsOpts.y,0),this.containerCenterX=this.offsetX+s/2,this.containerCenterY=this.offsetY+e/2,this.containerCanvas.width=Math.max(this.offsetX+s,this.offsetX+this.cropperJsOpts.width,this.cropperJsOpts.x+this.cropperJsOpts.width),this.containerCanvas.height=Math.max(this.offsetY+e,this.offsetY+this.cropperJsOpts.height,this.cropperJsOpts.y+this.cropperJsOpts.height),this.convertorCanvas.width=t.naturalWidth,this.convertorCanvas.height=t.naturalHeight,this.containerCtx.clearRect(0,0,this.containerCanvas.width,this.containerCanvas.height),this.convertCtx.clearRect(0,0,this.convertorCanvas.width,this.convertorCanvas.height)}frameToImgData(t,s){if(!t)return;const e=s.pixels.length,a=t.createImageData(s.dims.width,s.dims.height),r=a.data;for(let t=0;t<e;t++){const e=4*t,a=s.pixels[t],n=s.colorTable[a];r[e]=n[0],r[e+1]=n[1],r[e+2]=n[2],r[e+3]=a!==s.transparentIndex?255:0}return a}}export{t as FrameCropper};
|
||||
//# sourceMappingURL=cropper.js.map
|
||||
1
node_modules/super-image-cropper/esm/lib/cropper.js.map
generated
vendored
Normal file
1
node_modules/super-image-cropper/esm/lib/cropper.js.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"cropper.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
38
node_modules/super-image-cropper/esm/lib/decoder.d.ts
generated
vendored
Normal file
38
node_modules/super-image-cropper/esm/lib/decoder.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { ParsedGif, ParsedFrame } from 'gifuct-js';
|
||||
import { GetArrTypeUnion } from './helper';
|
||||
export type IFrames = Pick<ParsedGif, 'frames'>['frames'];
|
||||
export type IFrame = GetArrTypeUnion<IFrames>;
|
||||
export interface IParsedFrameInfo {
|
||||
frames: ImageData[];
|
||||
delays: number[];
|
||||
parsedFrames: ParsedFrame[];
|
||||
}
|
||||
export declare class Decoder {
|
||||
private url;
|
||||
private parseGIF;
|
||||
constructor(url: string);
|
||||
decode(): Promise<ParsedGif>;
|
||||
decompressFrames(): Promise<IParsedFrameInfo>;
|
||||
/**
|
||||
* Validates and fixes frames that have lost pixels.
|
||||
* @param gif
|
||||
*/
|
||||
private validateAndFixFrame;
|
||||
/**
|
||||
* Generates ImageData objects from parsed frames.
|
||||
* @param frames
|
||||
*/
|
||||
private generate2ImageData;
|
||||
/**
|
||||
* Generates ImageData objects from frames with modified pixels.
|
||||
* @param frames
|
||||
*/
|
||||
private generate2ImageDataWithPixelsModified;
|
||||
/**
|
||||
* @param {string} url
|
||||
* @returns
|
||||
*/
|
||||
private fetchImageData;
|
||||
private handlePixels;
|
||||
private putPixels;
|
||||
}
|
||||
2
node_modules/super-image-cropper/esm/lib/decoder.js
generated
vendored
Normal file
2
node_modules/super-image-cropper/esm/lib/decoder.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import{parseGIF as e,decompressFrames as t}from"gifuct-js";class a{url;parseGIF;constructor(e){this.url=e}async decode(){const t=await this.fetchImageData(this.url);return this.parseGIF=e(t),this.validateAndFixFrame(this.parseGIF),this.parseGIF}async decompressFrames(){this.parseGIF||await this.decode();const e=await t(this.parseGIF,!0);return{frames:this.generate2ImageData(e),delays:e.map((e=>e.delay)),parsedFrames:e}}validateAndFixFrame=e=>{let t=null;for(const a of e.frames)t=a.gce?a.gce:t,"image"in a&&!("gce"in a)&&(a.gce=t)};generate2ImageData(e){return e.map((e=>{const t=e?.dims,a=new ImageData(t.width,t.height);return a.data.set(e.patch),a}))}generate2ImageDataWithPixelsModified(e,t){return e.map(((e,a)=>{t[a];const r=this.parseGIF.lsd,s=new ImageData(r.width,r.height);return s.data.set(new Uint8ClampedArray(e)),s}))}fetchImageData(e){return new Promise(((t,a)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.responseType="arraybuffer",r.onload=e=>{if(!(e.target instanceof XMLHttpRequest))return;if(200!==e.target.status&&304!==e.target.status)return void a("Status Error: "+e.target.status);let r=e.target.response;r.toString().indexOf("ArrayBuffer")>0&&(r=new Uint8Array(r)),t(r)},r.onerror=e=>{a(e)},r.send()}))}handlePixels(e){const t=this.parseGIF.lsd,a=t.width*t.height*4,r=[];for(let s=0;s<e.length;++s){const i=e[s],n=0===s||2===e[s-1].disposalType?new Uint8ClampedArray(a):r[s-1].slice();r.push(this.putPixels(n,i,t))}return r}putPixels(e,t,a){if(!t.dims)return e;const{width:r,height:s,top:i,left:n}=t.dims,o=i*a.width+n;for(let i=0;i<s;i++)for(let s=0;s<r;s++){const n=i*r+s,d=t.pixels[n],h=o+i*a.width+s,l=t.colorTable[d]||[0,0,0];d===t.transparentIndex?(e[4*h]=0,e[4*h+1]=0,e[4*h+2]=0,e[4*h+3]=0):(e[4*h]=l[0],e[4*h+1]=l[1],e[4*h+2]=l[2],e[4*h+3]=255)}return e}}export{a as Decoder};
|
||||
//# sourceMappingURL=decoder.js.map
|
||||
1
node_modules/super-image-cropper/esm/lib/decoder.js.map
generated
vendored
Normal file
1
node_modules/super-image-cropper/esm/lib/decoder.js.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"decoder.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
20
node_modules/super-image-cropper/esm/lib/helper.d.ts
generated
vendored
Normal file
20
node_modules/super-image-cropper/esm/lib/helper.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { IImageData } from '../index';
|
||||
export type GetArrTypeUnion<T extends any[]> = T extends (infer I)[] ? I : never;
|
||||
export type IImageLoadData = {
|
||||
imageInstance: HTMLImageElement;
|
||||
data: Event;
|
||||
imageType: IImageTypeInfo | null;
|
||||
};
|
||||
export interface IImageTypeInfo {
|
||||
ext: string;
|
||||
mime: string;
|
||||
}
|
||||
export interface IGetImageParams {
|
||||
src?: string;
|
||||
crossOrigin?: '' | 'anonymous' | 'use-credentials';
|
||||
}
|
||||
export declare const getImageInfo: (params: IGetImageParams) => Promise<IImageData>;
|
||||
export declare const getImageType: (imageBufferData: ArrayBuffer) => Promise<IImageTypeInfo | null>;
|
||||
export declare const loadImage: (params: IGetImageParams) => Promise<IImageLoadData>;
|
||||
export declare const transformImageData2ArrayBuffer: (image: HTMLImageElement) => ArrayBufferLike;
|
||||
export declare const getImageBufferFromRemote: (url?: string) => Promise<ArrayBuffer>;
|
||||
2
node_modules/super-image-cropper/esm/lib/helper.js
generated
vendored
Normal file
2
node_modules/super-image-cropper/esm/lib/helper.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import t from"image-type";const n=async t=>{const{src:n=""}=t;if(!n)return{width:0,height:0,naturalWidth:0,naturalHeight:0};const{imageInstance:a}=await e(t);return{width:a.width,height:a.height,naturalWidth:a.naturalWidth,naturalHeight:a.naturalHeight}},a=async n=>t(new Uint8Array(n)),e=async t=>{const{src:n="",crossOrigin:e}=t;return{...await new Promise(((t,a)=>{const r=new Image;void 0!==e&&(r.crossOrigin=e),r.onload=async n=>{t({imageInstance:r,data:n})},r.src=n,r.onerror=a})),imageType:await a(await r(n))}},r=(t="")=>new Promise(((n,a)=>{const e=new XMLHttpRequest;e.open("GET",t),e.responseType="arraybuffer",e.onload=()=>{n(e.response)},e.onerror=a,e.send()}));export{r as getImageBufferFromRemote,n as getImageInfo,a as getImageType,e as loadImage};
|
||||
//# sourceMappingURL=helper.js.map
|
||||
1
node_modules/super-image-cropper/esm/lib/helper.js.map
generated
vendored
Normal file
1
node_modules/super-image-cropper/esm/lib/helper.js.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"helper.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
19
node_modules/super-image-cropper/esm/lib/synthetic-gif.d.ts
generated
vendored
Normal file
19
node_modules/super-image-cropper/esm/lib/synthetic-gif.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { ICommonCropOptions, ICropperOptions } from '../index';
|
||||
import { IOutputTypeUnion } from '../index';
|
||||
export interface IFrameCropperProps {
|
||||
commonCropOptions: ICommonCropOptions;
|
||||
frames: ImageData[];
|
||||
frameDelays: number[];
|
||||
gifJsOptions?: ICropperOptions['gifJsOptions'];
|
||||
outputType?: IOutputTypeUnion;
|
||||
}
|
||||
export declare class SyntheticGIF {
|
||||
private cropperJsOpts;
|
||||
private frames;
|
||||
private frameDelays;
|
||||
private gifJsOptions;
|
||||
private outputType;
|
||||
constructor({ frames, commonCropOptions, frameDelays, gifJsOptions, outputType }: IFrameCropperProps);
|
||||
bootstrap(): Promise<string | Blob>;
|
||||
private convertBlob2Base64;
|
||||
}
|
||||
2
node_modules/super-image-cropper/esm/lib/synthetic-gif.js
generated
vendored
Normal file
2
node_modules/super-image-cropper/esm/lib/synthetic-gif.js
generated
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
import{transformToUrl as t}from"gif-build-worker-js";import s from"gif.js";import{OutputType as e}from"../index.js";class r{cropperJsOpts;frames;frameDelays;gifJsOptions;outputType;constructor({frames:t,commonCropOptions:s,frameDelays:e,gifJsOptions:r={},outputType:o}){this.cropperJsOpts=s.cropperJsOpts,this.frames=t,this.frameDelays=e,this.gifJsOptions=r,this.outputType=o}bootstrap(){return new Promise(((r,o)=>{const i=t(),p=Object.assign({workers:2,quality:10,workerScript:i,width:this.cropperJsOpts.width,height:this.cropperJsOpts.height,transparent:"transparent"},this.gifJsOptions||{}),a=new s(p);a.on("finished",(t=>{if(this.outputType===e.BLOB)r(t);else if(this.outputType===e.BASE64)r(this.convertBlob2Base64(t));else{const s=window.URL.createObjectURL(t);r(s)}})),this.frames.forEach(((t,s)=>{a.addFrame(t,{delay:this.frameDelays[s],copy:!0})})),a.render()}))}convertBlob2Base64(t){return new Promise(((s,e)=>{const r=new FileReader;r.onload=function(t){s(t?.target?.result)},r.onerror=t=>{e(t)},r.readAsDataURL(t)}))}}export{r as SyntheticGIF};
|
||||
//# sourceMappingURL=synthetic-gif.js.map
|
||||
1
node_modules/super-image-cropper/esm/lib/synthetic-gif.js.map
generated
vendored
Normal file
1
node_modules/super-image-cropper/esm/lib/synthetic-gif.js.map
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"synthetic-gif.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
||||
1
node_modules/super-image-cropper/esm/utils/index.d.ts
generated
vendored
Normal file
1
node_modules/super-image-cropper/esm/utils/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
export declare const renderImageData2Canvas: (imageData: ImageData) => void;
|
||||
11
node_modules/super-image-cropper/esm/utils/index.js
generated
vendored
Normal file
11
node_modules/super-image-cropper/esm/utils/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
export const renderImageData2Canvas = (imageData) => {
|
||||
const tempCanvas = document.createElement('canvas');
|
||||
const tempCtx = tempCanvas.getContext('2d');
|
||||
const targetCanvas = document.createElement('canvas');
|
||||
const targetCtx = targetCanvas.getContext('2d');
|
||||
document.body.appendChild(targetCanvas);
|
||||
tempCanvas.width = imageData.width;
|
||||
tempCanvas.height = imageData.height;
|
||||
tempCtx?.putImageData(imageData, 0, 0);
|
||||
targetCtx?.drawImage(tempCanvas, 0, 0);
|
||||
};
|
||||
91
node_modules/super-image-cropper/package.json
generated
vendored
Normal file
91
node_modules/super-image-cropper/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
"name": "super-image-cropper",
|
||||
"version": "1.0.27",
|
||||
"description": "A powerful JavaScript image cropping library that supports GIF animations, PNG, JPG and other formats with CropperJS integration. Perfect for web developers who need to crop animated GIFs while preserving animation quality.",
|
||||
"main": "dist/index.js",
|
||||
"module": "esm/index.js",
|
||||
"type": "module",
|
||||
"types": "esm/index.d.ts",
|
||||
"keywords": [
|
||||
"image",
|
||||
"cropper",
|
||||
"gif",
|
||||
"animation",
|
||||
"crop",
|
||||
"cropperjs",
|
||||
"image-processing",
|
||||
"canvas",
|
||||
"javascript",
|
||||
"typescript",
|
||||
"web",
|
||||
"browser",
|
||||
"png",
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"image-editor",
|
||||
"image-manipulation",
|
||||
"frontend",
|
||||
"react",
|
||||
"vue",
|
||||
"angular",
|
||||
"gif-cropper",
|
||||
"animated-gif",
|
||||
"image-cropping",
|
||||
"photo-editor",
|
||||
"web-components"
|
||||
],
|
||||
"homepage": "https://gif-cropper-stdsuperman.vercel.app/",
|
||||
"bugs": {
|
||||
"url": "https://github.com/STDSuperman/super-image-cropper/issues"
|
||||
},
|
||||
"exports": {
|
||||
"import": {
|
||||
"types": "./esm/index.d.ts",
|
||||
"default": "./esm/index.js"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"esm",
|
||||
"package.json"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/STDSuperman/super-image-cropper.git"
|
||||
},
|
||||
"author": "STDSuperman <2750556766@qq.com>",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/cropperjs": "^1.3.0",
|
||||
"@types/gif.js": "^0.2.2",
|
||||
"@types/minimist": "^1.2.2",
|
||||
"conventional-changelog-cli": "^2.2.2",
|
||||
"esbuild": "^0.14.23",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-import": "^2.24.2",
|
||||
"prettier": "^2.3.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^4.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"cropperjs": "^1.5.12",
|
||||
"gif.js": "^0.2.0",
|
||||
"gifuct-js": "^2.1.2",
|
||||
"image-type": "^4.1.0",
|
||||
"rollup": "^4.24.0",
|
||||
"gif-build-worker-js": "1.0.3"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"prebuild": "npm run clean",
|
||||
"build": "rollup -c",
|
||||
"dev": "tsc --watch",
|
||||
"check": "tsc --noEmit",
|
||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue