react-scratchingcard 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 CHANGED
@@ -35,7 +35,7 @@ yarn add react-scratchingcard
35
35
 
36
36
  ```tsx
37
37
  import React, { useRef } from 'react';
38
- import ScratchCard from 'react-scratchcard-v2';
38
+ import ScratchCard from 'react-scratchingcard';
39
39
 
40
40
  import * as IMG from './img.jpg';
41
41
 
@@ -100,7 +100,7 @@ const App = () => {
100
100
  or you can use CUSTOM_BRUSH_PRESET object
101
101
 
102
102
  ```tsx
103
- import { CUSTOM_BRUSH_PRESET } from 'react-scratchcard-v2';
103
+ import { CUSTOM_BRUSH_PRESET } from 'react-scratchingcard';
104
104
 
105
105
  const App = () => {
106
106
  return (
@@ -128,7 +128,8 @@ const App = () => {
128
128
  |-------------------|-----------------|-------------|
129
129
  | width | number | |
130
130
  | height | number | |
131
- | image | File or Base64 | |
131
+ | image | File \| string \| {src?: string, default?: string} | |
132
+ | imageCrossOrigin | ?'' \| 'anonymous' \| 'use-credentials' | 'anonymous' |
132
133
  | finishPercent | ?number | 70 |
133
134
  | brushSize | ?number | 20 |
134
135
  | fadeOutOnComplete | ?boolean | true |
@@ -136,6 +137,21 @@ const App = () => {
136
137
  | customBrush | ?CustomBrush | |
137
138
  | customCheckZone | ?CustomCheckZone| |
138
139
 
140
+ ### Remote URL
141
+
142
+ ```tsx
143
+ <ScratchCard
144
+ width={320}
145
+ height={226}
146
+ image='https://cdn.example.com/scratch-cover.jpg'
147
+ imageCrossOrigin='anonymous'
148
+ >
149
+ <h1>Scratch card</h1>
150
+ </ScratchCard>
151
+ ```
152
+
153
+ Note: pour calculer le pourcentage gratté (`finishPercent`) avec une image distante, le serveur distant doit autoriser CORS.
154
+
139
155
  ### CustomBrush
140
156
 
141
157
  | **name** | **type** |
package/dist/index.d.ts CHANGED
@@ -8,6 +8,10 @@ declare type CustomBrush = {
8
8
  width: number;
9
9
  height: number;
10
10
  };
11
+ declare type ImageSource = string | File | {
12
+ src?: string;
13
+ default?: string;
14
+ };
11
15
  declare type CustomCheckZone = {
12
16
  x: number;
13
17
  y: number;
@@ -17,7 +21,8 @@ declare type CustomCheckZone = {
17
21
  interface Props {
18
22
  width: number;
19
23
  height: number;
20
- image: any;
24
+ image: ImageSource;
25
+ imageCrossOrigin?: '' | 'anonymous' | 'use-credentials';
21
26
  finishPercent?: number;
22
27
  onComplete?: () => void;
23
28
  brushSize?: number;
@@ -37,8 +42,14 @@ declare class Scratch extends Component<Props, State> {
37
42
  canvas: HTMLCanvasElement;
38
43
  brushImage?: any;
39
44
  image: HTMLImageElement;
45
+ objectUrl: string | null;
40
46
  isFinished: boolean;
41
47
  constructor(props: Props);
48
+ componentDidUpdate(prevProps: Props): void;
49
+ componentWillUnmount(): void;
50
+ revokeObjectUrl(): void;
51
+ resolveImageSource(image: ImageSource): string;
52
+ loadImage(): void;
42
53
  componentDidMount(): void;
43
54
  reset: () => void;
44
55
  getFilledInPixels(stride: number): number;
package/dist/index.js CHANGED
@@ -28,6 +28,7 @@ var Scratch = /*#__PURE__*/function (_Component) {
28
28
  _this = _Component.call(this, props) || this;
29
29
  _this.isDrawing = false;
30
30
  _this.lastPoint = null;
31
+ _this.objectUrl = null;
31
32
  _this.isFinished = false;
32
33
 
33
34
  _this.reset = function () {
@@ -93,24 +94,75 @@ var Scratch = /*#__PURE__*/function (_Component) {
93
94
 
94
95
  var _proto = Scratch.prototype;
95
96
 
96
- _proto.componentDidMount = function componentDidMount() {
97
+ _proto.componentDidUpdate = function componentDidUpdate(prevProps) {
98
+ if (prevProps.image !== this.props.image) {
99
+ this.loadImage();
100
+ }
101
+ };
102
+
103
+ _proto.componentWillUnmount = function componentWillUnmount() {
104
+ this.revokeObjectUrl();
105
+ };
106
+
107
+ _proto.revokeObjectUrl = function revokeObjectUrl() {
108
+ if (this.objectUrl) {
109
+ URL.revokeObjectURL(this.objectUrl);
110
+ this.objectUrl = null;
111
+ }
112
+ };
113
+
114
+ _proto.resolveImageSource = function resolveImageSource(image) {
115
+ this.revokeObjectUrl();
116
+
117
+ if (typeof image === 'string') {
118
+ return image;
119
+ }
120
+
121
+ if (image instanceof File) {
122
+ this.objectUrl = URL.createObjectURL(image);
123
+ return this.objectUrl;
124
+ }
125
+
126
+ if (image && typeof image.src === 'string') {
127
+ return image.src;
128
+ }
129
+
130
+ if (image && typeof image["default"] === 'string') {
131
+ return image["default"];
132
+ }
133
+
134
+ return '';
135
+ };
136
+
137
+ _proto.loadImage = function loadImage() {
97
138
  var _this2 = this;
98
139
 
99
- this.isDrawing = false;
100
- this.lastPoint = null;
101
- this.ctx = this.canvas.getContext('2d');
102
140
  this.image = new Image();
103
- this.image.crossOrigin = 'Anonymous';
141
+ this.image.crossOrigin = this.props.imageCrossOrigin === undefined ? 'anonymous' : this.props.imageCrossOrigin;
104
142
 
105
143
  this.image.onload = function () {
144
+ _this2.ctx.globalCompositeOperation = 'source-over';
145
+
146
+ _this2.ctx.clearRect(0, 0, _this2.props.width, _this2.props.height);
147
+
106
148
  _this2.ctx.drawImage(_this2.image, 0, 0, _this2.props.width, _this2.props.height);
107
149
 
150
+ _this2.isFinished = false;
151
+
108
152
  _this2.setState({
109
- loaded: true
153
+ loaded: true,
154
+ finished: false
110
155
  });
111
156
  };
112
157
 
113
- this.image.src = this.props.image;
158
+ this.image.src = this.resolveImageSource(this.props.image);
159
+ };
160
+
161
+ _proto.componentDidMount = function componentDidMount() {
162
+ this.isDrawing = false;
163
+ this.lastPoint = null;
164
+ this.ctx = this.canvas.getContext('2d');
165
+ this.loadImage();
114
166
 
115
167
  if (this.props.customBrush) {
116
168
  this.brushImage = new Image(this.props.customBrush.width, this.props.customBrush.height);