paper 0.13.0 → 0.14.0

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +16 -13
  3. package/dist/docs/assets/js/paper.js +434 -128
  4. package/dist/docs/classes/ChangeFlag.html +384 -0
  5. package/dist/docs/classes/Color.html +1 -1
  6. package/dist/docs/classes/CompoundPath.html +58 -4
  7. package/dist/docs/classes/Curve.html +1 -1
  8. package/dist/docs/classes/CurveLocation.html +1 -1
  9. package/dist/docs/classes/Event.html +1 -1
  10. package/dist/docs/classes/Gradient.html +1 -1
  11. package/dist/docs/classes/GradientStop.html +1 -1
  12. package/dist/docs/classes/Group.html +89 -4
  13. package/dist/docs/classes/HitResult.html +3 -2
  14. package/dist/docs/classes/HostItem.html +6721 -0
  15. package/dist/docs/classes/Item.html +58 -4
  16. package/dist/docs/classes/Key.html +1 -1
  17. package/dist/docs/classes/KeyEvent.html +1 -1
  18. package/dist/docs/classes/Layer.html +89 -4
  19. package/dist/docs/classes/Matrix.html +1 -1
  20. package/dist/docs/classes/MouseEvent.html +1 -1
  21. package/dist/docs/classes/PaperScope.html +2 -1
  22. package/dist/docs/classes/PaperScript.html +2 -1
  23. package/dist/docs/classes/Path.html +59 -5
  24. package/dist/docs/classes/PathItem.html +58 -4
  25. package/dist/docs/classes/Point.html +1 -1
  26. package/dist/docs/classes/PointText.html +58 -4
  27. package/dist/docs/classes/Project.html +188 -1
  28. package/dist/docs/classes/Raster.html +58 -4
  29. package/dist/docs/classes/Rectangle.html +1 -1
  30. package/dist/docs/classes/Segment.html +1 -1
  31. package/dist/docs/classes/Shape.html +58 -4
  32. package/dist/docs/classes/Size.html +1 -1
  33. package/dist/docs/classes/Style.html +2 -2
  34. package/dist/docs/classes/SymbolDefinition.html +1 -1
  35. package/dist/docs/classes/SymbolItem.html +58 -4
  36. package/dist/docs/classes/TextItem.html +58 -4
  37. package/dist/docs/classes/Tool.html +126 -1
  38. package/dist/docs/classes/ToolEvent.html +1 -1
  39. package/dist/docs/classes/Tween.html +1 -1
  40. package/dist/docs/classes/View.html +144 -2
  41. package/dist/docs/classes/global.html +1 -1
  42. package/dist/docs/classes/index.html +2 -2
  43. package/dist/docs/index.html +1 -1
  44. package/dist/paper-core.js +425 -123
  45. package/dist/paper-core.min.js +3 -3
  46. package/dist/paper-full.js +434 -128
  47. package/dist/paper-full.min.js +3 -3
  48. package/dist/paper-sourced.js +18631 -0
  49. package/dist/paper.d.ts +284 -7
  50. package/package.json +6 -10
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Paper.js v0.13.0 - The Swiss Army Knife of Vector Graphics Scripting.
2
+ * Paper.js v0.14.0 - The Swiss Army Knife of Vector Graphics Scripting.
3
3
  * http://paperjs.org/
4
4
  *
5
5
  * Copyright (c) 2011 - 2020, Jürg Lehni & Jonathan Puckey
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * All rights reserved.
11
11
  *
12
- * Date: Mon Oct 19 15:31:53 2026 +0200
12
+ * Date: Tue Oct 20 01:20:31 2026 +0200
13
13
  *
14
14
  ***
15
15
  *
@@ -780,7 +780,8 @@ var PaperScope = Base.extend({
780
780
  applyMatrix: true,
781
781
  insertItems: true,
782
782
  handleSize: 4,
783
- hitTolerance: 0
783
+ hitTolerance: 0,
784
+ scaleStrokes: false
784
785
  });
785
786
  this.project = null;
786
787
  this.projects = [];
@@ -824,7 +825,7 @@ var PaperScope = Base.extend({
824
825
  }
825
826
  },
826
827
 
827
- version: "0.13.0",
828
+ version: "0.14.0",
828
829
 
829
830
  getView: function() {
830
831
  var project = this.project;
@@ -848,9 +849,10 @@ var PaperScope = Base.extend({
848
849
  }
849
850
  });
850
851
  });
851
- for (var key in this)
852
- if (!/^_/.test(key) && this[key])
852
+ for (var key in this) {
853
+ if (!/^_/.test(key) && this[key] && !(key in scope))
853
854
  scope[key] = this[key];
855
+ }
854
856
  },
855
857
 
856
858
  setup: function(element) {
@@ -927,6 +929,10 @@ var PaperScopeItem = Base.extend(Emitter, {
927
929
  return this._scope[this._reference] === this;
928
930
  },
929
931
 
932
+ getScope: function() {
933
+ return this._scope;
934
+ },
935
+
930
936
  remove: function() {
931
937
  if (this._index == null)
932
938
  return false;
@@ -2643,6 +2649,10 @@ var Matrix = Base.extend({
2643
2649
  return det && !isNaN(det) && isFinite(this._tx) && isFinite(this._ty);
2644
2650
  },
2645
2651
 
2652
+ _getMeanScale: function() {
2653
+ return Math.sqrt(Math.abs(this._a * this._d - this._b * this._c));
2654
+ },
2655
+
2646
2656
  isSingular: function() {
2647
2657
  return !this.isInvertible();
2648
2658
  },
@@ -2931,6 +2941,48 @@ var Line = Base.extend({
2931
2941
  }
2932
2942
  });
2933
2943
 
2944
+ var ChangeFlag = {
2945
+ APPEARANCE: 0x1,
2946
+
2947
+ CHILDREN: 0x2,
2948
+
2949
+ INSERTION: 0x4,
2950
+
2951
+ GEOMETRY: 0x8,
2952
+
2953
+ MATRIX: 0x10,
2954
+
2955
+ SEGMENTS: 0x20,
2956
+
2957
+ STROKE: 0x40,
2958
+
2959
+ STYLE: 0x80,
2960
+
2961
+ ATTRIBUTE: 0x100,
2962
+
2963
+ CONTENT: 0x200,
2964
+
2965
+ PIXELS: 0x400,
2966
+
2967
+ CLIPPING: 0x800,
2968
+
2969
+ VIEW: 0x1000
2970
+ };
2971
+
2972
+ var Change = {
2973
+ CHILDREN: ChangeFlag.CHILDREN | ChangeFlag.GEOMETRY | ChangeFlag.APPEARANCE,
2974
+ INSERTION: ChangeFlag.INSERTION | ChangeFlag.APPEARANCE,
2975
+ GEOMETRY: ChangeFlag.GEOMETRY | ChangeFlag.APPEARANCE,
2976
+ MATRIX: ChangeFlag.MATRIX | ChangeFlag.GEOMETRY | ChangeFlag.APPEARANCE,
2977
+ SEGMENTS: ChangeFlag.SEGMENTS | ChangeFlag.GEOMETRY | ChangeFlag.APPEARANCE,
2978
+ STROKE: ChangeFlag.STROKE | ChangeFlag.STYLE | ChangeFlag.APPEARANCE,
2979
+ STYLE: ChangeFlag.STYLE | ChangeFlag.APPEARANCE,
2980
+ ATTRIBUTE: ChangeFlag.ATTRIBUTE | ChangeFlag.APPEARANCE,
2981
+ CONTENT: ChangeFlag.CONTENT | ChangeFlag.GEOMETRY | ChangeFlag.APPEARANCE,
2982
+ PIXELS: ChangeFlag.PIXELS | ChangeFlag.APPEARANCE,
2983
+ VIEW: ChangeFlag.VIEW | ChangeFlag.APPEARANCE
2984
+ };
2985
+
2934
2986
  var Project = PaperScopeItem.extend({
2935
2987
  _class: 'Project',
2936
2988
  _list: 'projects',
@@ -2964,7 +3016,7 @@ var Project = PaperScopeItem.extend({
2964
3016
  }
2965
3017
  }
2966
3018
  var changes = this._changes;
2967
- if (changes && item) {
3019
+ if (changes && item && item.isInserted()) {
2968
3020
  var changesById = this._changesById,
2969
3021
  id = item._id,
2970
3022
  entry = changesById[id];
@@ -2976,6 +3028,26 @@ var Project = PaperScopeItem.extend({
2976
3028
  }
2977
3029
  },
2978
3030
 
3031
+ getTrackChanges: function() {
3032
+ return !!this._changes;
3033
+ },
3034
+
3035
+ setTrackChanges: function(trackChanges) {
3036
+ if (!this._changes ^ !trackChanges) {
3037
+ this._changes = trackChanges ? [] : null;
3038
+ this._changesById = trackChanges ? {} : null;
3039
+ }
3040
+ },
3041
+
3042
+ takeChanges: function() {
3043
+ var changes = this._changes;
3044
+ if (changes) {
3045
+ this._changes = [];
3046
+ this._changesById = {};
3047
+ }
3048
+ return changes || null;
3049
+ },
3050
+
2979
3051
  clear: function() {
2980
3052
  var children = this._children;
2981
3053
  for (var i = children.length - 1; i >= 0; i--)
@@ -3271,6 +3343,10 @@ new function() {
3271
3343
  matrix = this._matrix = new Matrix(),
3272
3344
  project = hasProps && props.project || paper.project,
3273
3345
  settings = paper.settings;
3346
+ if (!project) {
3347
+ throw new Error('Unable to create an item without a project. '
3348
+ + 'Call paper.setup() or create a Project first.');
3349
+ }
3274
3350
  this._id = internal ? null : UID.get();
3275
3351
  this._parent = this._index = null;
3276
3352
  this._applyMatrix = this._canApplyMatrix && settings.applyMatrix;
@@ -3804,6 +3880,10 @@ new function() {
3804
3880
  return this._project._view;
3805
3881
  },
3806
3882
 
3883
+ getScope: function() {
3884
+ return this._project._scope;
3885
+ },
3886
+
3807
3887
  _installEvents: function _installEvents(install) {
3808
3888
  _installEvents.base.call(this, install);
3809
3889
  if (this._selection)
@@ -4076,7 +4156,7 @@ new function() {
4076
4156
 
4077
4157
  _hitTest: function(point, options, parentViewMatrix) {
4078
4158
  if (this._locked || !this._visible || this._guide && !options.guides
4079
- || this.isEmpty()) {
4159
+ || !this._shell && this.isEmpty()) {
4080
4160
  return null;
4081
4161
  }
4082
4162
 
@@ -4091,7 +4171,7 @@ new function() {
4091
4171
  .prepended(this.getView()._matrix.inverted())
4092
4172
  ._shiftless().invert()));
4093
4173
  point = pointMatrix._inverseTransform(point);
4094
- if (!point || !this._children &&
4174
+ if (!point || (this._shell || !this._children) &&
4095
4175
  !this.getBounds({ internal: true, stroke: true, handle: true })
4096
4176
  .expand(tolerancePadding.multiply(2))._containsPoint(point)) {
4097
4177
  return null;
@@ -4107,10 +4187,21 @@ new function() {
4107
4187
  res;
4108
4188
 
4109
4189
  function filter(hit) {
4190
+ if (Array.isArray(hit)) {
4191
+ var first = null;
4192
+ for (var i = 0, l = hit.length; i < l; i++) {
4193
+ var res = filter(hit[i]);
4194
+ first = first || res;
4195
+ }
4196
+ return first;
4197
+ }
4110
4198
  if (hit && match && !match(hit))
4111
4199
  hit = null;
4112
- if (hit && options.all)
4200
+ if (hit && options.all) {
4201
+ if (hit.point)
4202
+ hit.point = that.getGlobalMatrix().transform(hit.point);
4113
4203
  options.all.push(hit);
4204
+ }
4114
4205
  return hit;
4115
4206
  }
4116
4207
 
@@ -4154,14 +4245,14 @@ new function() {
4154
4245
  : viewMatrix._shiftless().invert()))
4155
4246
  || null;
4156
4247
  }
4157
- if (res && res.point) {
4248
+ if (res && res.point && !options.all) {
4158
4249
  res.point = pointMatrix.transform(res.point);
4159
4250
  }
4160
4251
  return res;
4161
4252
  },
4162
4253
 
4163
4254
  _hitTestSelf: function(point, options) {
4164
- if (options.fill && this.hasFill() && this._contains(point))
4255
+ if (options.fill && this.getFillColor() && this._contains(point))
4165
4256
  return new HitResult('fill', this);
4166
4257
  },
4167
4258
 
@@ -4284,6 +4375,19 @@ new function() {
4284
4375
  }, {
4285
4376
 
4286
4377
  importJSON: function(json) {
4378
+ json = typeof json === 'string' ? JSON.parse(json) : json;
4379
+ var props = json && json[0] === this._class && json[1];
4380
+ if (Base.isPlainObject(props)) {
4381
+ var item = new this.constructor(Item.NO_INSERT),
4382
+ fields = Base.set({}, this._serializeFields,
4383
+ this instanceof Group ? null : this._style._defaults),
4384
+ defaults = {};
4385
+ for (var key in fields) {
4386
+ if (!(key in props) && !Base.equals(this[key], item[key]))
4387
+ defaults[key] = item[key];
4388
+ }
4389
+ this.set(defaults);
4390
+ }
4287
4391
  var res = Base.importJSON(json, this);
4288
4392
  return res !== this ? this.addChild(res) : res;
4289
4393
  },
@@ -4430,14 +4534,14 @@ new function() {
4430
4534
  if (this._name)
4431
4535
  this._removeNamed();
4432
4536
  this._installEvents(false);
4537
+ if (notifySelf && project._changes)
4538
+ this._changed(5);
4433
4539
  if (index != null) {
4434
4540
  if (project._activeLayer === this)
4435
4541
  project._activeLayer = this.getNextSibling()
4436
4542
  || this.getPreviousSibling();
4437
4543
  Base.splice(owner._children, null, index, 1);
4438
4544
  }
4439
- if (notifySelf && project._changes)
4440
- this._changed(5);
4441
4545
  if (notifyParent)
4442
4546
  owner._changed(11, this);
4443
4547
  this._parent = null;
@@ -4796,7 +4900,7 @@ new function() {
4796
4900
  opacity = Numerical.clamp(this._opacity, 0, 1),
4797
4901
  normalBlend = blendMode === 'normal',
4798
4902
  nativeBlend = BlendMode.nativeModes[blendMode],
4799
- direct = normalBlend && opacity === 1
4903
+ direct = normalBlend && opacity === 1 && !this._isolated
4800
4904
  || param.dontStart
4801
4905
  || param.clip
4802
4906
  || (nativeBlend || normalBlend && opacity < 1)
@@ -5012,8 +5116,10 @@ var Group = Item.extend({
5012
5116
  _selectBounds: false,
5013
5117
  _selectChildren: true,
5014
5118
  _serializeFields: {
5119
+ isolated: false,
5015
5120
  children: []
5016
5121
  },
5122
+ _isolated: false,
5017
5123
 
5018
5124
  initialize: function Group(arg) {
5019
5125
  this._children = [];
@@ -5055,6 +5161,15 @@ var Group = Item.extend({
5055
5161
  child.setClipMask(clipped);
5056
5162
  },
5057
5163
 
5164
+ isIsolated: function() {
5165
+ return this._isolated;
5166
+ },
5167
+
5168
+ setIsolated: function(isolated) {
5169
+ this._isolated = !!isolated;
5170
+ this._changed(257);
5171
+ },
5172
+
5058
5173
  _getBounds: function _getBounds(matrix, options) {
5059
5174
  var clipItem = this._getClipItem();
5060
5175
  return clipItem
@@ -5399,7 +5514,7 @@ new function() {
5399
5514
  var hit = false,
5400
5515
  style = this._style,
5401
5516
  hitStroke = options.stroke && style.hasStroke(),
5402
- hitFill = options.fill && style.hasFill();
5517
+ hitFill = options.fill && !!style.getFillColor();
5403
5518
  if (hitStroke || hitFill) {
5404
5519
  var type = this._type,
5405
5520
  radius = this._radius,
@@ -5489,6 +5604,7 @@ var Raster = Item.extend({
5489
5604
  _boundsOptions: { stroke: false, handle: false },
5490
5605
  _serializeFields: {
5491
5606
  crossOrigin: null,
5607
+ size: new Size(),
5492
5608
  source: null
5493
5609
  },
5494
5610
  _prioritize: ['crossOrigin'],
@@ -5638,6 +5754,14 @@ var Raster = Item.extend({
5638
5754
  }
5639
5755
  },
5640
5756
 
5757
+ set: function set(props, exclude) {
5758
+ if (props && props.source && props.size) {
5759
+ this._size = new Size(props.size);
5760
+ exclude = Base.set({ size: true }, exclude);
5761
+ }
5762
+ return set.base.call(this, props, exclude);
5763
+ },
5764
+
5641
5765
  _setImage: function(image) {
5642
5766
  if (this._canvas)
5643
5767
  CanvasProvider.release(this._canvas);
@@ -5650,9 +5774,11 @@ var Raster = Item.extend({
5650
5774
  this._canvas = null;
5651
5775
  this._loaded = !!(image && image.src && image.complete);
5652
5776
  }
5653
- this._size = new Size(
5654
- image ? image.naturalWidth || image.width : 0,
5655
- image ? image.naturalHeight || image.height : 0);
5777
+ this._size = image && !this._loaded
5778
+ ? this._size || new Size()
5779
+ : new Size(
5780
+ image ? image.naturalWidth || image.width : 0,
5781
+ image ? image.naturalHeight || image.height : 0);
5656
5782
  this._context = null;
5657
5783
  this._changed(1033);
5658
5784
  },
@@ -8227,6 +8353,15 @@ var PathItem = Item.extend({
8227
8353
  initialize: function PathItem() {
8228
8354
  },
8229
8355
 
8356
+ _scaleStroke: function(matrix) {
8357
+ var style = this._style;
8358
+ if (this._project._scope.settings.scaleStrokes
8359
+ && style.getStrokeScaling()) {
8360
+ style.setStrokeWidth(style.getStrokeWidth()
8361
+ * matrix._getMeanScale());
8362
+ }
8363
+ },
8364
+
8230
8365
  statics: {
8231
8366
  create: function(arg) {
8232
8367
  var data,
@@ -8695,6 +8830,7 @@ var Path = PathItem.extend({
8695
8830
  coords = new Array(6);
8696
8831
  for (var i = 0, l = segments.length; i < l; i++)
8697
8832
  segments[i]._transformCoordinates(matrix, coords, true);
8833
+ this._scaleStroke(matrix);
8698
8834
  return true;
8699
8835
  },
8700
8836
 
@@ -9325,8 +9461,9 @@ var Path = PathItem.extend({
9325
9461
  strokePadding = tolerancePadding,
9326
9462
  join, cap, miterLimit,
9327
9463
  area, loc, res,
9464
+ hits = options.all && [],
9328
9465
  hitStroke = options.stroke && style.hasStroke(),
9329
- hitFill = options.fill && style.hasFill(),
9466
+ hitFill = options.fill && !!style.getFillColor(),
9330
9467
  hitCurves = options.curves,
9331
9468
  strokeRadius = hitStroke
9332
9469
  ? style.getStrokeWidth() / 2
@@ -9354,10 +9491,13 @@ var Path = PathItem.extend({
9354
9491
  if (pt !== anchor)
9355
9492
  pt = pt.add(anchor);
9356
9493
  if (isCloseEnough(pt, strokePadding)) {
9357
- return new HitResult(name, that, {
9494
+ var hit = new HitResult(name, that, {
9358
9495
  segment: seg,
9359
9496
  point: pt
9360
9497
  });
9498
+ if (!hits)
9499
+ return hit;
9500
+ hits.push(hit);
9361
9501
  }
9362
9502
  }
9363
9503
  }
@@ -9431,7 +9571,7 @@ var Path = PathItem.extend({
9431
9571
  }
9432
9572
  }
9433
9573
  }
9434
- return !loc && hitFill && this._contains(point)
9574
+ res = !loc && hitFill && this._contains(point)
9435
9575
  || loc && !hitStroke && !hitCurves
9436
9576
  ? new HitResult('fill', this)
9437
9577
  : loc
@@ -9440,6 +9580,16 @@ var Path = PathItem.extend({
9440
9580
  point: loc.getPoint()
9441
9581
  })
9442
9582
  : null;
9583
+ if (hits) {
9584
+ hits.sort(function(hit1, hit2) {
9585
+ return hit1.point.getDistance(point)
9586
+ - hit2.point.getDistance(point);
9587
+ });
9588
+ if (res)
9589
+ hits.push(res);
9590
+ return hits;
9591
+ }
9592
+ return res;
9443
9593
  }
9444
9594
 
9445
9595
  }, Base.each(Curve._evaluateMethods,
@@ -10231,10 +10381,9 @@ Path.inject({ statics: new function() {
10231
10381
  center = Point.readNamed(args, 'center'),
10232
10382
  sides = Base.readNamed(args, 'sides'),
10233
10383
  radius = Base.readNamed(args, 'radius'),
10234
- step = 360 / sides,
10235
- three = sides % 3 === 0,
10236
- vector = new Point(0, three ? -radius : radius),
10237
- offset = three ? -1 : 0.5,
10384
+ step = -360 / sides,
10385
+ offset = sides % 2 ? 0 : -0.5,
10386
+ vector = new Point(0, -radius),
10238
10387
  segments = new Array(sides);
10239
10388
  for (var i = 0; i < sides; i++)
10240
10389
  segments[i] = new Segment(center.add(
@@ -10278,6 +10427,11 @@ var CompoundPath = PathItem.extend({
10278
10427
  }
10279
10428
  },
10280
10429
 
10430
+ _transformContent: function _transformContent(matrix) {
10431
+ this._scaleStroke(matrix);
10432
+ return _transformContent.base.apply(this, arguments);
10433
+ },
10434
+
10281
10435
  insertChildren: function insertChildren(index, items) {
10282
10436
  var list = items,
10283
10437
  first = list[0];
@@ -11765,6 +11919,16 @@ var PointText = TextItem.extend({
11765
11919
  hasStroke = style.hasStroke(),
11766
11920
  leading = style.getLeading(),
11767
11921
  shadowColor = ctx.shadowColor;
11922
+ if (hasStroke && !style.getStrokeScaling()) {
11923
+ var scale = viewMatrix._getMeanScale();
11924
+ ctx.lineWidth /= scale;
11925
+ if ('setLineDash' in ctx) {
11926
+ ctx.setLineDash(ctx.getLineDash().map(function(dash) {
11927
+ return dash / scale;
11928
+ }));
11929
+ ctx.lineDashOffset /= scale;
11930
+ }
11931
+ }
11768
11932
  ctx.font = style.getFontStyle();
11769
11933
  ctx.textAlign = style.getJustification();
11770
11934
  ctx.letterSpacing = style.getTrackingStyle();
@@ -11802,7 +11966,7 @@ var PointText = TextItem.extend({
11802
11966
  },
11803
11967
 
11804
11968
  _hitTestSelf: function(point, options) {
11805
- if (options.fill && this.hasFill()) {
11969
+ if (options.fill && this.getFillColor()) {
11806
11970
  var bounds = this.getInternalBounds(),
11807
11971
  closest = point.clamp(bounds.getTopLeft(true),
11808
11972
  bounds.getBottomRight(true));
@@ -13002,8 +13166,12 @@ DomEvent.requestAnimationFrame = new function() {
13002
13166
  for (var i = 0, l = functions.length; i < l; i++)
13003
13167
  functions[i]();
13004
13168
  requested = nativeRequest && callbacks.length;
13005
- if (requested)
13169
+ if (requested) {
13006
13170
  nativeRequest(handleCallbacks);
13171
+ } else if (timer && !callbacks.length) {
13172
+ clearInterval(timer);
13173
+ timer = null;
13174
+ }
13007
13175
  }
13008
13176
 
13009
13177
  return function(callback) {
@@ -13029,7 +13197,7 @@ var View = Base.extend(Emitter, {
13029
13197
  }
13030
13198
 
13031
13199
  function getCanvasSize() {
13032
- var size = DomElement.getSize(element);
13200
+ var size = new Size(element.offsetWidth, element.offsetHeight);
13033
13201
  return size.isNaN() || size.isZero()
13034
13202
  ? new Size(getSize('width'), getSize('height'))
13035
13203
  : size.subtract(DomElement.getInsets(element));
@@ -13160,7 +13328,8 @@ var View = Base.extend(Emitter, {
13160
13328
  if (that._animate) {
13161
13329
  that.requestUpdate();
13162
13330
  var element = that._element;
13163
- if ((!DomElement.getPrefixed(document, 'hidden')
13331
+ if (!element
13332
+ || (!DomElement.getPrefixed(document, 'hidden')
13164
13333
  || PaperScope.getAttribute(element, 'keepalive')
13165
13334
  === 'true') && DomElement.isInView(element)) {
13166
13335
  that._handleFrame();
@@ -13237,6 +13406,10 @@ var View = Base.extend(Emitter, {
13237
13406
  return this._project;
13238
13407
  },
13239
13408
 
13409
+ getScope: function() {
13410
+ return this._scope;
13411
+ },
13412
+
13240
13413
  getPixelRatio: function() {
13241
13414
  return this._pixelRatio;
13242
13415
  },
@@ -13457,8 +13630,6 @@ var View = Base.extend(Emitter, {
13457
13630
  }
13458
13631
  },
13459
13632
  new function() {
13460
- if (!window)
13461
- return;
13462
13633
  var prevFocus,
13463
13634
  tempFocus,
13464
13635
  dragging = false,
@@ -13486,26 +13657,28 @@ new function() {
13486
13657
  view._handleMouseEvent('mousemove', event, point);
13487
13658
  }
13488
13659
 
13489
- var navigator = window.navigator,
13490
- mousedown, mousemove, mouseup;
13491
- if (navigator.pointerEnabled || navigator.msPointerEnabled) {
13492
- mousedown = 'pointerdown MSPointerDown';
13493
- mousemove = 'pointermove MSPointerMove';
13494
- mouseup = 'pointerup pointercancel MSPointerUp MSPointerCancel';
13495
- } else {
13496
- mousedown = 'touchstart';
13497
- mousemove = 'touchmove';
13498
- mouseup = 'touchend touchcancel';
13499
- if (!('ontouchstart' in window && navigator.userAgent.match(
13500
- /mobile|tablet|ip(ad|hone|od)|android|silk/i))) {
13501
- mousedown += ' mousedown';
13502
- mousemove += ' mousemove';
13503
- mouseup += ' mouseup';
13660
+ var viewEvents = {};
13661
+
13662
+ if (window) {
13663
+ var navigator = window.navigator,
13664
+ mousedown, mousemove, mouseup;
13665
+ if (navigator.pointerEnabled || navigator.msPointerEnabled) {
13666
+ mousedown = 'pointerdown MSPointerDown';
13667
+ mousemove = 'pointermove MSPointerMove';
13668
+ mouseup = 'pointerup pointercancel MSPointerUp MSPointerCancel';
13669
+ } else {
13670
+ mousedown = 'touchstart';
13671
+ mousemove = 'touchmove';
13672
+ mouseup = 'touchend touchcancel';
13673
+ if (!('ontouchstart' in window && navigator.userAgent.match(
13674
+ /mobile|tablet|ip(ad|hone|od)|android|silk/i))) {
13675
+ mousedown += ' mousedown';
13676
+ mousemove += ' mousemove';
13677
+ mouseup += ' mouseup';
13678
+ }
13504
13679
  }
13505
- }
13506
13680
 
13507
- var viewEvents = {},
13508
- docEvents = {
13681
+ var docEvents = {
13509
13682
  mouseout: function(event) {
13510
13683
  var view = View._focused,
13511
13684
  target = DomEvent.getRelatedTarget(event);
@@ -13516,54 +13689,55 @@ new function() {
13516
13689
  scroll: updateFocus
13517
13690
  };
13518
13691
 
13519
- viewEvents[mousedown] = function(event) {
13520
- var view = View._focused = getView(event);
13521
- if (!dragging) {
13522
- dragging = true;
13523
- view._handleMouseEvent('mousedown', event);
13524
- }
13525
- };
13692
+ viewEvents[mousedown] = function(event) {
13693
+ var view = View._focused = getView(event);
13694
+ if (!dragging) {
13695
+ dragging = true;
13696
+ view._handleMouseEvent('mousedown', event);
13697
+ }
13698
+ };
13526
13699
 
13527
- docEvents[mousemove] = function(event) {
13528
- var view = View._focused;
13529
- if (!mouseDown) {
13530
- var target = getView(event);
13531
- if (target) {
13532
- if (view !== target) {
13533
- if (view)
13534
- handleMouseMove(view, event);
13535
- if (!prevFocus)
13536
- prevFocus = view;
13537
- view = View._focused = tempFocus = target;
13538
- }
13539
- } else if (tempFocus && tempFocus === view) {
13540
- if (prevFocus && !prevFocus.isInserted())
13700
+ docEvents[mousemove] = function(event) {
13701
+ var view = View._focused;
13702
+ if (!mouseDown) {
13703
+ var target = getView(event);
13704
+ if (target) {
13705
+ if (view !== target) {
13706
+ if (view)
13707
+ handleMouseMove(view, event);
13708
+ if (!prevFocus)
13709
+ prevFocus = view;
13710
+ view = View._focused = tempFocus = target;
13711
+ }
13712
+ } else if (tempFocus && tempFocus === view) {
13713
+ if (prevFocus && !prevFocus.isInserted())
13714
+ prevFocus = null;
13715
+ view = View._focused = prevFocus;
13541
13716
  prevFocus = null;
13542
- view = View._focused = prevFocus;
13543
- prevFocus = null;
13544
- updateFocus();
13717
+ updateFocus();
13718
+ }
13545
13719
  }
13546
- }
13547
- if (view)
13548
- handleMouseMove(view, event);
13549
- };
13720
+ if (view)
13721
+ handleMouseMove(view, event);
13722
+ };
13550
13723
 
13551
- docEvents[mousedown] = function() {
13552
- mouseDown = true;
13553
- };
13724
+ docEvents[mousedown] = function() {
13725
+ mouseDown = true;
13726
+ };
13554
13727
 
13555
- docEvents[mouseup] = function(event) {
13556
- var view = View._focused;
13557
- if (view && dragging)
13558
- view._handleMouseEvent('mouseup', event);
13559
- mouseDown = dragging = false;
13560
- };
13728
+ docEvents[mouseup] = function(event) {
13729
+ var view = View._focused;
13730
+ if (view && dragging)
13731
+ view._handleMouseEvent('mouseup', event);
13732
+ mouseDown = dragging = false;
13733
+ };
13561
13734
 
13562
- DomEvent.add(document, docEvents);
13735
+ DomEvent.add(document, docEvents);
13563
13736
 
13564
- DomEvent.add(window, {
13565
- load: updateFocus
13566
- });
13737
+ DomEvent.add(window, {
13738
+ load: updateFocus
13739
+ });
13740
+ }
13567
13741
 
13568
13742
  var called = false,
13569
13743
  prevented = false,
@@ -13629,9 +13803,27 @@ new function() {
13629
13803
  point, prevPoint));
13630
13804
  }
13631
13805
 
13806
+ function createEvent(type, options) {
13807
+ if (options.modifiers)
13808
+ Key.modifiers.set(options.modifiers);
13809
+ return {
13810
+ type: type,
13811
+ timeStamp: options.timeStamp != null ? options.timeStamp
13812
+ : Date.now(),
13813
+ button: options.button || 0,
13814
+ cancelable: true,
13815
+ defaultPrevented: false,
13816
+ preventDefault: function() {
13817
+ this.defaultPrevented = true;
13818
+ },
13819
+ stopPropagation: function() {}
13820
+ };
13821
+ }
13822
+
13632
13823
  var itemEventsMap = {
13633
13824
  mousedown: {
13634
13825
  mousedown: 1,
13826
+ mouseup: 1,
13635
13827
  mousedrag: 1,
13636
13828
  click: 1,
13637
13829
  doubleclick: 1
@@ -13653,6 +13845,28 @@ new function() {
13653
13845
  return {
13654
13846
  _viewEvents: viewEvents,
13655
13847
 
13848
+ dispatchMouseEvent: function(type, point, options) {
13849
+ if (!/^mouse(down|move|up)$/.test(type))
13850
+ throw new Error('Unknown mouse event type: \'' + type + '\'.');
13851
+ var event = createEvent(type, options || {});
13852
+ if (type === 'mousedown') {
13853
+ View._focused = this;
13854
+ mouseDown = dragging = true;
13855
+ }
13856
+ this._handleMouseEvent(type, event, new Point(point));
13857
+ if (type === 'mouseup')
13858
+ mouseDown = dragging = false;
13859
+ return event.defaultPrevented;
13860
+ },
13861
+
13862
+ dispatchKeyEvent: function(type, key, options) {
13863
+ if (!/^key(down|up)$/.test(type))
13864
+ throw new Error('Unknown key event type: \'' + type + '\'.');
13865
+ options = options || {};
13866
+ Key._handleKey(type === 'keydown', key, options.character,
13867
+ createEvent(type, options), this);
13868
+ },
13869
+
13656
13870
  _handleMouseEvent: function(type, event, point) {
13657
13871
  var itemEvents = this._itemEvents,
13658
13872
  hitItems = itemEvents.native[type],
@@ -13665,12 +13879,37 @@ new function() {
13665
13879
  || tool && tool.responds(type);
13666
13880
  }
13667
13881
 
13882
+ function needsUp(hitItem) {
13883
+ if (view.responds('mouseup')
13884
+ || tool && tool.responds('mouseup'))
13885
+ return true;
13886
+ for (var item = hitItem; item; item = item._parent) {
13887
+ for (var key in itemEventsMap.mouseup) {
13888
+ if (item.responds(key))
13889
+ return true;
13890
+ }
13891
+ }
13892
+ return false;
13893
+ }
13894
+
13895
+ if (event.shiftKey !== undefined) {
13896
+ Key.modifiers.set({
13897
+ shift: event.shiftKey,
13898
+ control: event.ctrlKey,
13899
+ alt: event.altKey,
13900
+ meta: event.metaKey
13901
+ });
13902
+ }
13668
13903
  if (nativeMove && dragging && responds('mousedrag'))
13669
13904
  type = 'mousedrag';
13670
13905
  if (!point)
13671
13906
  point = this.getEventPoint(event);
13672
13907
 
13673
- var inView = this.getBounds().contains(point),
13908
+ var target = DomEvent.getTarget(event),
13909
+ isCovered = nativeMove && !dragging && target
13910
+ && target.nodeType === 1
13911
+ && !target.contains(this._element),
13912
+ inView = !isCovered && this.getBounds().contains(point),
13674
13913
  hit = hitItems && inView && view._project.hitTest(point, {
13675
13914
  tolerance: 0,
13676
13915
  fill: true,
@@ -13737,7 +13976,7 @@ new function() {
13737
13976
 
13738
13977
  if (
13739
13978
  event.cancelable !== false
13740
- && (called && !mouse.move || mouse.down && responds('mouseup'))
13979
+ && (called && !mouse.move || mouse.down && needsUp(hitItem))
13741
13980
  ) {
13742
13981
  event.preventDefault();
13743
13982
  }
@@ -13756,11 +13995,9 @@ new function() {
13756
13995
  }
13757
13996
  }
13758
13997
 
13759
- if (this.isVisible()) {
13760
- emit(this);
13761
- if (tool && tool.responds(type))
13762
- emit(tool);
13763
- }
13998
+ emit(this);
13999
+ if (tool && tool.responds(type))
14000
+ emit(tool);
13764
14001
  },
13765
14002
 
13766
14003
  _countItemEvent: function(type, sign) {
@@ -13818,20 +14055,20 @@ var CanvasView = View.extend({
13818
14055
  },
13819
14056
 
13820
14057
  _setElementSize: function _setElementSize(width, height) {
13821
- var pixelRatio = this._pixelRatio;
14058
+ var pixelRatio = this._pixelRatio,
14059
+ element = this._element;
13822
14060
  _setElementSize.base.call(this, width * pixelRatio, height * pixelRatio);
14061
+ if (!PaperScope.hasAttribute(element, 'resize')) {
14062
+ var style = element.style,
14063
+ insets = DomElement.getStyles(element).boxSizing
14064
+ === 'border-box'
14065
+ ? DomElement.getInsets(element)
14066
+ : new Size();
14067
+ style.width = (width + insets.width) + 'px';
14068
+ style.height = (height + insets.height) + 'px';
14069
+ }
13823
14070
  if (pixelRatio !== 1) {
13824
- var element = this._element,
13825
- ctx = this._context;
13826
- if (!PaperScope.hasAttribute(element, 'resize')) {
13827
- var style = element.style,
13828
- insets = DomElement.getStyles(element).boxSizing
13829
- === 'border-box'
13830
- ? DomElement.getInsets(element)
13831
- : new Size();
13832
- style.width = (width + insets.width) + 'px';
13833
- style.height = (height + insets.height) + 'px';
13834
- }
14071
+ var ctx = this._context;
13835
14072
  ctx.restore();
13836
14073
  ctx.save();
13837
14074
  ctx.scale(pixelRatio, pixelRatio);
@@ -13997,11 +14234,16 @@ var Key = new function() {
13997
14234
  (key.length > 1 ? Base.hyphenate(key) : key.toLowerCase());
13998
14235
  }
13999
14236
 
14000
- function handleKey(down, key, character, event) {
14001
- View.updateFocus();
14002
- var type = down ? 'keydown' : 'keyup',
14003
- view = View._focused,
14004
- name;
14237
+ function handleKey(down, key, character, event, view) {
14238
+ if (!view) {
14239
+ View.updateFocus();
14240
+ view = View._focused;
14241
+ if (view && !view.isVisible())
14242
+ view = null;
14243
+ }
14244
+ if (character == null)
14245
+ character = down ? key.length > 1 ? '' : key : charMap[key] || '';
14246
+ var name;
14005
14247
  keyMap[key] = down;
14006
14248
  if (down) {
14007
14249
  charMap[key] = character;
@@ -14017,7 +14259,7 @@ var Key = new function() {
14017
14259
  } else {
14018
14260
  for (var k in metaFixMap) {
14019
14261
  if (k in charMap)
14020
- handleKey(false, k, metaFixMap[k], event);
14262
+ handleKey(false, k, metaFixMap[k], event, view);
14021
14263
  }
14022
14264
  metaFixMap = null;
14023
14265
  }
@@ -14072,6 +14314,8 @@ var Key = new function() {
14072
14314
  });
14073
14315
 
14074
14316
  return {
14317
+ _handleKey: handleKey,
14318
+
14075
14319
  modifiers: modifiers,
14076
14320
 
14077
14321
  isDown: function(key) {
@@ -14238,6 +14482,14 @@ var Tool = PaperScopeItem.extend({
14238
14482
  }
14239
14483
  },
14240
14484
 
14485
+ getEventInterval: function() {
14486
+ return this._eventInterval;
14487
+ },
14488
+
14489
+ setEventInterval: function(interval) {
14490
+ this._eventInterval = interval;
14491
+ },
14492
+
14241
14493
  getFixedDistance: function() {
14242
14494
  return this._minDistance == this._maxDistance
14243
14495
  ? this._minDistance : null;
@@ -14294,7 +14546,24 @@ var Tool = PaperScopeItem.extend({
14294
14546
  if (mouse.down) {
14295
14547
  update();
14296
14548
  emit();
14549
+ if (this._eventInterval > 0) {
14550
+ clearInterval(this._timer);
14551
+ this._timer = setInterval(function() {
14552
+ if (tool.isActive()) {
14553
+ paper = tool._scope;
14554
+ tool._lastPoint = tool._point;
14555
+ tool._moveCount++;
14556
+ if (tool.responds('mousedrag')) {
14557
+ tool.emit('mousedrag',
14558
+ new ToolEvent(tool, 'mousedrag', event));
14559
+ }
14560
+ } else {
14561
+ clearInterval(tool._timer);
14562
+ }
14563
+ }, this._eventInterval);
14564
+ }
14297
14565
  } else if (mouse.up) {
14566
+ clearInterval(this._timer);
14298
14567
  update(null, this._maxDistance);
14299
14568
  emit();
14300
14569
  } else if (responds) {
@@ -14671,8 +14940,9 @@ var CanvasProvider = Base.exports.CanvasProvider = {
14671
14940
  release: function(obj) {
14672
14941
  var canvas = obj && obj.canvas ? obj.canvas : obj;
14673
14942
  if (canvas && canvas.getContext) {
14674
- canvas.getContext('2d').restore();
14675
- this.canvases.push(canvas);
14943
+ canvas.width = canvas.height = 0;
14944
+ if (this.canvases.length < 8)
14945
+ this.canvases.push(canvas);
14676
14946
  }
14677
14947
  }
14678
14948
  };
@@ -15004,7 +15274,7 @@ var SvgStyles = Base.each({
15004
15274
  dashArray: ['stroke-dasharray', 'array'],
15005
15275
  dashOffset: ['stroke-dashoffset', 'number'],
15006
15276
  fontFamily: ['font-family', 'string'],
15007
- fontWeight: ['font-weight', 'string'],
15277
+ fontWeight: ['font-weight', 'font'],
15008
15278
  fontSize: ['font-size', 'number'],
15009
15279
  tracking: ['letter-spacing', 'tracking'],
15010
15280
  justification: ['text-anchor', 'lookup', {
@@ -15326,6 +15596,13 @@ new function() {
15326
15596
  PointText: exportText
15327
15597
  };
15328
15598
 
15599
+ var cssBlendModes = Base.each(['normal', 'multiply', 'screen', 'overlay',
15600
+ 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light',
15601
+ 'soft-light', 'difference', 'exclusion', 'hue', 'saturation',
15602
+ 'color', 'luminosity'], function(mode) {
15603
+ this[mode] = true;
15604
+ }, {});
15605
+
15329
15606
  function applyStyle(item, node, options, isRoot) {
15330
15607
  var attrs = {},
15331
15608
  parent = !isRoot && item.getParent(),
@@ -15352,7 +15629,19 @@ new function() {
15352
15629
  attrs[entry.attribute + '-opacity'] = alpha;
15353
15630
  }
15354
15631
  if (type === 'style') {
15355
- style.push(entry.attribute + ': ' + value);
15632
+ if (cssBlendModes[value]) {
15633
+ style.push(entry.attribute + ': ' + value);
15634
+ } else {
15635
+ attrs['data-paper-blend-mode'] = value;
15636
+ }
15637
+ } else if (type === 'font') {
15638
+ var font = ('' + value).match(
15639
+ /^(.*?)\s*\b(italic|oblique)\b\s*(.*)$/i);
15640
+ attrs[entry.attribute] = font
15641
+ ? (font[1] + ' ' + font[3]).trim() || 'normal'
15642
+ : value;
15643
+ if (font)
15644
+ attrs['font-style'] = font[2].toLowerCase();
15356
15645
  } else {
15357
15646
  attrs[entry.attribute] = value == null ? 'none'
15358
15647
  : type === 'color' ? value.gradient
@@ -15865,6 +16154,20 @@ new function() {
15865
16154
  item.setVisible(value !== null);
15866
16155
  },
15867
16156
 
16157
+ 'data-paper-blend-mode': function(item, value) {
16158
+ if (item.setBlendMode)
16159
+ item.setBlendMode(value);
16160
+ },
16161
+
16162
+ 'font-style': function(item, value) {
16163
+ if (item.setFontWeight && /^(italic|oblique)$/.test(value)) {
16164
+ var weight = ('' + item.getFontWeight())
16165
+ .replace(/\s*\b(italic|oblique)\b/gi, '');
16166
+ item.setFontWeight(/^(normal|400)$/.test(weight) ? value
16167
+ : weight + ' ' + value);
16168
+ }
16169
+ },
16170
+
15868
16171
  'letter-spacing': function(item, value) {
15869
16172
  if (item.setTracking) {
15870
16173
  var amount = parseFloat(value) || 0;
@@ -16141,14 +16444,13 @@ new function() {
16141
16444
  var paper = new (PaperScope.inject(Base.exports, {
16142
16445
  Base: Base,
16143
16446
  Numerical: Numerical,
16447
+ ChangeFlag: ChangeFlag,
16144
16448
  Key: Key,
16145
16449
  DomEvent: DomEvent,
16146
16450
  DomElement: DomElement,
16147
16451
  document: document,
16148
16452
  window: window,
16149
- PlacedSymbol: SymbolItem
16150
- }).inject({
16151
- enumerable: false,
16453
+ PlacedSymbol: SymbolItem,
16152
16454
  Symbol: SymbolDefinition
16153
16455
  }))();
16154
16456