redhotmagma-graphics-editor 1.26.5 → 1.27.2

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/package.json CHANGED
@@ -1,14 +1,11 @@
1
1
  {
2
2
  "name": "redhotmagma-graphics-editor",
3
- "version": "1.26.5",
3
+ "version": "1.27.2",
4
4
  "license": "UNLICENSED",
5
5
  "private": false,
6
6
  "main": "./lib/index.js",
7
7
  "files": [
8
- "CanvasAdapters",
9
- "CanvasInterface",
10
- "Components",
11
- "Utils",
8
+ "lib",
12
9
  "src",
13
10
  "scripts",
14
11
  ".babelrc"
@@ -88,6 +88,7 @@ export class Canvas extends AbstractCanvas {
88
88
  this._view.center = new paper.Point(this._view.size.divide(2));
89
89
  this._view.viewSize = size;
90
90
  this._maskHandler && this._maskHandler.updateOutline();
91
+ this.updateObjectConstraints();
91
92
  }
92
93
 
93
94
  saveViewBox() {
@@ -174,7 +175,7 @@ export class Canvas extends AbstractCanvas {
174
175
  }
175
176
 
176
177
  onMouseDrag(event) {
177
- if (this.selectedObject) {
178
+ if (this.selectedObject && !this.selectedObject.locked && !this.selectedObject.autoFit) {
178
179
  const { x: dx, y: dy } = event.delta;
179
180
  const o = this.selectedObject;
180
181
  o.x += dx;
@@ -1,4 +1,5 @@
1
1
  import debounce from 'lodash/debounce';
2
+ import isInteger from 'lodash/isInteger';
2
3
  import { CanvasObject } from './CanvasObject';
3
4
  import { TextInterface } from '../../../CanvasInterface/Objects/Text';
4
5
  import { Logger } from '../../../Utils/Logger';
@@ -40,7 +41,10 @@ export class Text extends CanvasObject implements TextInterface {
40
41
  const scaling = this.scaling;
41
42
  if (scaling !== 1) {
42
43
  this._scaling = 1;
43
- this.fontSize = Math.floor(this._fontSize * scaling);
44
+ const fontSize = Math.floor(this._fontSize * scaling);
45
+ if (isInteger(fontSize)) {
46
+ this.fontSize = fontSize;
47
+ }
44
48
  }
45
49
  }, 500);
46
50
 
@@ -86,6 +90,9 @@ export class Text extends CanvasObject implements TextInterface {
86
90
  if (!fontSize) {
87
91
  throw new Error('The given value is not a number!');
88
92
  }
93
+ if (fontSize === this._fontSize) {
94
+ return;
95
+ }
89
96
  this._fontSize = Math.max(this._fontSizeMin, fontSize);
90
97
  this.build();
91
98
  this.triggerChangeEvent(prevState);
@@ -166,6 +166,12 @@ export abstract class AbstractCanvas {
166
166
  return this;
167
167
  }
168
168
 
169
+ updateObjectConstraints(): void {
170
+ for (const o of this.objects) {
171
+ o.updateConstraints();
172
+ }
173
+ }
174
+
169
175
  update() {
170
176
  return this;
171
177
  }
@@ -198,9 +204,10 @@ export abstract class AbstractCanvas {
198
204
  }
199
205
 
200
206
  getState(): any {
201
- const { selectedObject } = this;
207
+ const { selectedObject, size } = this;
202
208
  return {
203
209
  selectedObject: selectedObject ? selectedObject.getState() : null,
210
+ size,
204
211
  };
205
212
  }
206
213
 
@@ -32,7 +32,11 @@ export abstract class AbstractCanvasObject {
32
32
  // technical properties
33
33
  protected _wrappedObject: any = null;
34
34
  protected _selected = false;
35
+ protected _locked = false;
36
+ protected _autoFit = false;
35
37
  protected _grabbed = false;
38
+ protected _activeAction = '';
39
+ protected _userData = {};
36
40
  protected _canvas: AbstractCanvas = null;
37
41
  protected _observable: Observable = new Observable(this);
38
42
 
@@ -41,6 +45,7 @@ export abstract class AbstractCanvasObject {
41
45
 
42
46
  constructor(options?: any) {
43
47
  this.initOptions(options);
48
+ this._observable.on(CanvasObjectEvents.OnChange, this.updateConstraints.bind(this));
44
49
  }
45
50
 
46
51
  initOptions(options?: any) {
@@ -75,6 +80,9 @@ export abstract class AbstractCanvasObject {
75
80
  }
76
81
 
77
82
  set x(x: number) {
83
+ if (x === this._x) {
84
+ return;
85
+ }
78
86
  this._x = x;
79
87
  this.setPosition(this._x, this._y);
80
88
  this._observable.triggerEvent(CanvasObjectEvents.OnChange);
@@ -84,7 +92,10 @@ export abstract class AbstractCanvasObject {
84
92
  return this._x;
85
93
  }
86
94
 
87
- set y(y: number): AbstractCanvasObject {
95
+ set y(y: number) {
96
+ if (y === this._y) {
97
+ return;
98
+ }
88
99
  this._y = y;
89
100
  this.setPosition(this._x, this._y);
90
101
  this._observable.triggerEvent(CanvasObjectEvents.OnChange);
@@ -95,7 +106,11 @@ export abstract class AbstractCanvasObject {
95
106
  }
96
107
 
97
108
  set rotation(rotation: number) {
98
- this._rotation = (360 + rotation) % 360;
109
+ const rot = (360 + rotation) % 360;
110
+ if (rot === this._rotation) {
111
+ return;
112
+ }
113
+ this._rotation = rot;
99
114
  this.setRotation(this._rotation);
100
115
  this._observable.triggerEvent(CanvasObjectEvents.OnChange);
101
116
  }
@@ -105,6 +120,9 @@ export abstract class AbstractCanvasObject {
105
120
  }
106
121
 
107
122
  set scaling(scaling: number) {
123
+ if (scaling === this._scaling || !Number.isFinite(scaling)) {
124
+ return;
125
+ }
108
126
  this._scaling = scaling;
109
127
  this.setScalingWithFactor(scaling);
110
128
  this._observable.triggerEvent(CanvasObjectEvents.OnChange);
@@ -116,7 +134,6 @@ export abstract class AbstractCanvasObject {
116
134
 
117
135
  set wrappedObject(object: any) {
118
136
  this._wrappedObject = object;
119
- //this.initOptions(this.getOptionsFromWrappedObject());
120
137
  this.setOptionsFromObject(this.toObject());
121
138
  this.initObjectEvents();
122
139
  }
@@ -140,6 +157,33 @@ export abstract class AbstractCanvasObject {
140
157
  return this._selected;
141
158
  }
142
159
 
160
+ set locked(locked: boolean) {
161
+ this._locked = locked;
162
+ this._observable.triggerEvent(CanvasObjectEvents.OnChange);
163
+ }
164
+
165
+ get locked(): boolean {
166
+ return this._locked;
167
+ }
168
+
169
+ set autoFit(autoFit: boolean) {
170
+ this._autoFit = autoFit;
171
+ this._observable.triggerEvent(CanvasObjectEvents.OnChange);
172
+ }
173
+
174
+ get autoFit(): boolean {
175
+ return this._autoFit;
176
+ }
177
+
178
+ get userData(): Record<string, unknown> {
179
+ return this._userData;
180
+ }
181
+
182
+ set userData(userDataObject: Record<string, unknown>) {
183
+ this._userData = userDataObject;
184
+ this._observable.triggerEvent(CanvasObjectEvents.OnChange);
185
+ }
186
+
143
187
  set grabbed(grabbed) {
144
188
  this._grabbed = grabbed;
145
189
  this._observable.triggerEvent(CanvasObjectEvents.OnChange);
@@ -149,6 +193,15 @@ export abstract class AbstractCanvasObject {
149
193
  return this._grabbed;
150
194
  }
151
195
 
196
+ set activeAction(action: string) {
197
+ this._activeAction = action;
198
+ this._observable.triggerEvent(CanvasObjectEvents.OnChange);
199
+ }
200
+
201
+ get activeAction(): string {
202
+ return this._activeAction;
203
+ }
204
+
152
205
  set canvas(canvas: AbstractCanvas) {
153
206
  this._canvas = canvas;
154
207
  }
@@ -183,6 +236,8 @@ export abstract class AbstractCanvasObject {
183
236
 
184
237
  abstract setSelected(selected: boolean): void;
185
238
 
239
+ abstract setLocked(locked: boolean): void;
240
+
186
241
  abstract initObjectEvents(): void;
187
242
 
188
243
  abstract getTransformedRect(): any;
@@ -202,13 +257,15 @@ export abstract class AbstractCanvasObject {
202
257
  }
203
258
 
204
259
  getState() {
205
- const { selected, grabbed, isFirst, isLast } = this;
260
+ const { selected, grabbed, isFirst, isLast, locked, autoFit } = this;
206
261
  return {
207
262
  ...this.toObject(),
208
263
  selected,
209
264
  grabbed,
210
265
  isFirst,
211
266
  isLast,
267
+ locked,
268
+ autoFit,
212
269
  };
213
270
  }
214
271
 
@@ -232,13 +289,16 @@ export abstract class AbstractCanvasObject {
232
289
  }
233
290
 
234
291
  toObject(includeWrappedObject = false) {
235
- const { type, x, y, rotation, scaling, uuid } = this;
292
+ const { type, x, y, rotation, scaling, locked, autoFit, userData, uuid } = this;
236
293
  const obj = {
237
294
  type,
238
295
  x,
239
296
  y,
240
297
  rotation,
241
298
  scaling,
299
+ locked,
300
+ autoFit,
301
+ userData,
242
302
  uuid,
243
303
  };
244
304
  if (includeWrappedObject) {
@@ -306,4 +366,8 @@ export abstract class AbstractCanvasObject {
306
366
  height: oh * scaling,
307
367
  };
308
368
  }
369
+
370
+ updateConstraints() {
371
+ this.autoFit && this.fitCanvas(true, true);
372
+ }
309
373
  }
@@ -38,6 +38,7 @@ export class Editor extends React.Component {
38
38
  canvas: PropTypes.instanceOf(AbstractCanvas).isRequired,
39
39
  classes: PropTypes.object.isRequired,
40
40
  containerClassName: PropTypes.string,
41
+ renderInCanvasContainer: PropTypes.func,
41
42
  };
42
43
 
43
44
  static defaultProps = {
@@ -163,6 +164,7 @@ export class Editor extends React.Component {
163
164
  Rulers,
164
165
  SelectionToolbox,
165
166
  StandardToolbox,
167
+ renderInCanvasContainer,
166
168
  } = props;
167
169
  if (typeof children === 'function') {
168
170
  return children({
@@ -222,6 +224,7 @@ export class Editor extends React.Component {
222
224
  Rulers,
223
225
  },
224
226
  })}
227
+ {renderInCanvasContainer && renderInCanvasContainer()}
225
228
  </CanvasContainer>
226
229
  </EditorContainer>
227
230
  {this.renderSelectionToolbox({
@@ -75,6 +75,8 @@ class InlineToolBox extends React.Component {
75
75
  return;
76
76
  }
77
77
 
78
+ selectedObject.activeAction = 'scale';
79
+
78
80
  const clientPosition = this.getClientPositionFromEvent(evt);
79
81
 
80
82
  let iDistance = selectedObject.getDistanceToCenter(clientPosition.x, clientPosition.y);
@@ -99,6 +101,7 @@ class InlineToolBox extends React.Component {
99
101
  this.updateToolbarTransform();
100
102
  };
101
103
  const mouseUp = evt => {
104
+ selectedObject.activeAction = '';
102
105
  const clientPosition = this.getClientPositionFromEvent(evt);
103
106
  evt.preventDefault();
104
107
  document.removeEventListener(clientPosition.isTouchEvent ? 'touchmove' : 'mousemove', mouseMove, {
@@ -118,6 +121,8 @@ class InlineToolBox extends React.Component {
118
121
  return;
119
122
  }
120
123
 
124
+ selectedObject.activeAction = 'rotate';
125
+
121
126
  const clientPosition = this.getClientPositionFromEvent(evt);
122
127
 
123
128
  // const { canvasPosition } = this.props;
@@ -140,6 +145,7 @@ class InlineToolBox extends React.Component {
140
145
  this.updateToolbarTransform();
141
146
  };
142
147
  const mouseUp = evt => {
148
+ selectedObject.activeAction = '';
143
149
  const clientPosition = this.getClientPositionFromEvent(evt);
144
150
  evt.preventDefault();
145
151
 
@@ -263,26 +269,34 @@ class InlineToolBox extends React.Component {
263
269
  },
264
270
  });
265
271
  }
272
+ if (!selectedObject) {
273
+ return null;
274
+ }
266
275
  switch (positionName) {
267
276
  case 'topRight':
268
277
  return (
269
- <InlineToolboxButton
270
- style={{
271
- background: 'red',
272
- }}
273
- onTouchStart={onRotationChange}
274
- onMouseDown={onRotationChange}
275
- />
278
+ !selectedObject.locked && (
279
+ <InlineToolboxButton
280
+ style={{
281
+ background: 'red',
282
+ }}
283
+ onTouchStart={onRotationChange}
284
+ onMouseDown={onRotationChange}
285
+ />
286
+ )
276
287
  );
277
288
  case 'bottomRight':
278
289
  return (
279
- <InlineToolboxButton
280
- style={{
281
- background: 'green',
282
- }}
283
- onTouchStart={onScalingChange}
284
- onMouseDown={onScalingChange}
285
- />
290
+ !selectedObject.locked &&
291
+ !selectedObject.autoFit && (
292
+ <InlineToolboxButton
293
+ style={{
294
+ background: 'green',
295
+ }}
296
+ onTouchStart={onScalingChange}
297
+ onMouseDown={onScalingChange}
298
+ />
299
+ )
286
300
  );
287
301
  case 'bottomLeft':
288
302
  return (
@@ -72,6 +72,22 @@ export class SelectionToolbox extends React.Component {
72
72
  }
73
73
  };
74
74
 
75
+ onLockChange = evt => {
76
+ const { canvas } = this.props;
77
+ const { selectedObject } = canvas;
78
+ if (selectedObject) {
79
+ selectedObject.locked = evt.target.checked;
80
+ }
81
+ };
82
+
83
+ onAutoFitChange = evt => {
84
+ const { canvas } = this.props;
85
+ const { selectedObject } = canvas;
86
+ if (selectedObject) {
87
+ selectedObject.autoFit = evt.target.checked;
88
+ }
89
+ };
90
+
75
91
  renderObjectTools(renderObj) {
76
92
  const { renderObjectTools } = this.props;
77
93
  if (renderObjectTools) {
@@ -85,6 +101,8 @@ export class SelectionToolbox extends React.Component {
85
101
  onScalingChange,
86
102
  onMoveUpClick,
87
103
  onMoveDownClick,
104
+ onLockChange,
105
+ onAutoFitChange,
88
106
  } = renderObj;
89
107
  return (
90
108
  <React.Fragment>
@@ -108,6 +126,28 @@ export class SelectionToolbox extends React.Component {
108
126
  Down
109
127
  </button>
110
128
  </ToolboxRow>
129
+ <ToolboxRow>
130
+ <label htmlFor="lock">
131
+ Lock element
132
+ <input
133
+ type="checkbox"
134
+ id="lock"
135
+ name="autoFit"
136
+ checked={selectedObject.locked}
137
+ onChange={onLockChange}
138
+ />
139
+ </label>
140
+ <label htmlFor="autoFit">
141
+ Auto fit
142
+ <input
143
+ type="checkbox"
144
+ id="autoFit"
145
+ name="autoFit"
146
+ checked={selectedObject.autoFit}
147
+ onChange={onAutoFitChange}
148
+ />
149
+ </label>
150
+ </ToolboxRow>
111
151
  </React.Fragment>
112
152
  );
113
153
  }
@@ -127,7 +167,16 @@ export class SelectionToolbox extends React.Component {
127
167
 
128
168
  render() {
129
169
  logger.log('render SelectionToolbox');
130
- const { props, onRotationChange, onScalingChange, onMoveUpClick, onMoveDownClick, state } = this;
170
+ const {
171
+ props,
172
+ onRotationChange,
173
+ onScalingChange,
174
+ onMoveUpClick,
175
+ onMoveDownClick,
176
+ onLockChange,
177
+ onAutoFitChange,
178
+ state,
179
+ } = this;
131
180
  const { children, selectedObject, canvas, classes } = props;
132
181
  if (selectedObject) {
133
182
  if (typeof children === 'function') {
@@ -140,6 +189,8 @@ export class SelectionToolbox extends React.Component {
140
189
  onScalingChange,
141
190
  onMoveUpClick,
142
191
  onMoveDownClick,
192
+ onLockChange,
193
+ onAutoFitChange,
143
194
  components: {
144
195
  ToolboxContainer,
145
196
  ToolboxRow,
@@ -158,6 +209,8 @@ export class SelectionToolbox extends React.Component {
158
209
  onScalingChange,
159
210
  onMoveUpClick,
160
211
  onMoveDownClick,
212
+ onLockChange,
213
+ onAutoFitChange,
161
214
  components: {
162
215
  ToolboxRow,
163
216
  },