three-render-objects 1.28.6 → 1.29.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.
@@ -1,4 +1,4 @@
1
- // Version 1.28.6 three-render-objects - https://github.com/vasturiano/three-render-objects
1
+ // Version 1.29.1 three-render-objects - https://github.com/vasturiano/three-render-objects
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('three')) :
4
4
  typeof define === 'function' && define.amd ? define(['three'], factory) :
@@ -35,33 +35,47 @@
35
35
  var css_248z = ".scene-nav-info {\n bottom: 5px;\n width: 100%;\n text-align: center;\n color: slategrey;\n opacity: 0.7;\n font-size: 10px;\n}\n\n.scene-tooltip {\n top: 0;\n color: lavender;\n font-size: 15px;\n}\n\n.scene-nav-info, .scene-tooltip {\n position: absolute;\n font-family: sans-serif;\n pointer-events: none;\n user-select: none;\n}\n\n.scene-container canvas:focus {\n outline: none;\n}";
36
36
  styleInject(css_248z);
37
37
 
38
- function _iterableToArrayLimit$1(arr, i) {
39
- var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"];
40
- if (null != _i) {
41
- var _s,
42
- _e,
43
- _x,
44
- _r,
45
- _arr = [],
46
- _n = !0,
47
- _d = !1;
38
+ function _iterableToArrayLimit$1(r, l) {
39
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
40
+ if (null != t) {
41
+ var e,
42
+ n,
43
+ i,
44
+ u,
45
+ a = [],
46
+ f = !0,
47
+ o = !1;
48
48
  try {
49
- if (_x = (_i = _i.call(arr)).next, 0 === i) {
50
- if (Object(_i) !== _i) return;
51
- _n = !1;
52
- } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0);
53
- } catch (err) {
54
- _d = !0, _e = err;
49
+ if (i = (t = t.call(r)).next, 0 === l) {
50
+ if (Object(t) !== t) return;
51
+ f = !1;
52
+ } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
53
+ } catch (r) {
54
+ o = !0, n = r;
55
55
  } finally {
56
56
  try {
57
- if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return;
57
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
58
58
  } finally {
59
- if (_d) throw _e;
59
+ if (o) throw n;
60
60
  }
61
61
  }
62
- return _arr;
62
+ return a;
63
63
  }
64
64
  }
65
+ function _toPrimitive$1(t, r) {
66
+ if ("object" != typeof t || !t) return t;
67
+ var e = t[Symbol.toPrimitive];
68
+ if (void 0 !== e) {
69
+ var i = e.call(t, r || "default");
70
+ if ("object" != typeof i) return i;
71
+ throw new TypeError("@@toPrimitive must return a primitive value.");
72
+ }
73
+ return ("string" === r ? String : Number)(t);
74
+ }
75
+ function _toPropertyKey$1(t) {
76
+ var i = _toPrimitive$1(t, "string");
77
+ return "symbol" == typeof i ? i : String(i);
78
+ }
65
79
  function _defineProperty(obj, key, value) {
66
80
  key = _toPropertyKey$1(key);
67
81
  if (key in obj) {
@@ -110,20 +124,6 @@
110
124
  function _nonIterableRest$1() {
111
125
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
112
126
  }
113
- function _toPrimitive$1(input, hint) {
114
- if (typeof input !== "object" || input === null) return input;
115
- var prim = input[Symbol.toPrimitive];
116
- if (prim !== undefined) {
117
- var res = prim.call(input, hint || "default");
118
- if (typeof res !== "object") return res;
119
- throw new TypeError("@@toPrimitive must return a primitive value.");
120
- }
121
- return (hint === "string" ? String : Number)(input);
122
- }
123
- function _toPropertyKey$1(arg) {
124
- var key = _toPrimitive$1(arg, "string");
125
- return typeof key === "symbol" ? key : String(key);
126
- }
127
127
 
128
128
  const _changeEvent$2 = { type: 'change' };
129
129
  const _startEvent$1 = { type: 'start' };
@@ -953,6 +953,9 @@
953
953
  const _changeEvent$1 = { type: 'change' };
954
954
  const _startEvent = { type: 'start' };
955
955
  const _endEvent = { type: 'end' };
956
+ const _ray = new three$1.Ray();
957
+ const _plane = new three$1.Plane();
958
+ const TILT_LIMIT = Math.cos( 70 * three$1.MathUtils.DEG2RAD );
956
959
 
957
960
  class OrbitControls extends three$1.EventDispatcher {
958
961
 
@@ -970,6 +973,9 @@
970
973
  // "target" sets the location of focus, where the object orbits around
971
974
  this.target = new three$1.Vector3();
972
975
 
976
+ // Sets the 3D cursor (similar to Blender), from which the maxTargetRadius takes effect
977
+ this.cursor = new three$1.Vector3();
978
+
973
979
  // How far you can dolly in and out ( PerspectiveCamera only )
974
980
  this.minDistance = 0;
975
981
  this.maxDistance = Infinity;
@@ -978,6 +984,10 @@
978
984
  this.minZoom = 0;
979
985
  this.maxZoom = Infinity;
980
986
 
987
+ // Limit camera target within a spherical area around the cursor
988
+ this.minTargetRadius = 0;
989
+ this.maxTargetRadius = Infinity;
990
+
981
991
  // How far you can orbit vertically, upper and lower limits.
982
992
  // Range is 0 to Math.PI radians.
983
993
  this.minPolarAngle = 0; // radians
@@ -1007,6 +1017,7 @@
1007
1017
  this.panSpeed = 1.0;
1008
1018
  this.screenSpacePanning = true; // if false, pan orthogonal to world-space direction camera.up
1009
1019
  this.keyPanSpeed = 7.0; // pixels moved per arrow key push
1020
+ this.zoomToCursor = false;
1010
1021
 
1011
1022
  // Set to true to automatically rotate around the target
1012
1023
  // If auto-rotate is enabled, you must call controls.update() in your animation loop
@@ -1104,7 +1115,7 @@
1104
1115
 
1105
1116
  const twoPI = 2 * Math.PI;
1106
1117
 
1107
- return function update() {
1118
+ return function update( deltaTime = null ) {
1108
1119
 
1109
1120
  const position = scope.object.position;
1110
1121
 
@@ -1118,7 +1129,7 @@
1118
1129
 
1119
1130
  if ( scope.autoRotate && state === STATE.NONE ) {
1120
1131
 
1121
- rotateLeft( getAutoRotationAngle() );
1132
+ rotateLeft( getAutoRotationAngle( deltaTime ) );
1122
1133
 
1123
1134
  }
1124
1135
 
@@ -1165,11 +1176,6 @@
1165
1176
  spherical.makeSafe();
1166
1177
 
1167
1178
 
1168
- spherical.radius *= scale;
1169
-
1170
- // restrict radius to be between desired limits
1171
- spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
1172
-
1173
1179
  // move target to panned location
1174
1180
 
1175
1181
  if ( scope.enableDamping === true ) {
@@ -1182,6 +1188,23 @@
1182
1188
 
1183
1189
  }
1184
1190
 
1191
+ // Limit the target distance from the cursor to create a sphere around the center of interest
1192
+ scope.target.sub( scope.cursor );
1193
+ scope.target.clampLength( scope.minTargetRadius, scope.maxTargetRadius );
1194
+ scope.target.add( scope.cursor );
1195
+
1196
+ // adjust the camera position based on zoom only if we're not zooming to the cursor or if it's an ortho camera
1197
+ // we adjust zoom later in these cases
1198
+ if ( scope.zoomToCursor && performCursorZoom || scope.object.isOrthographicCamera ) {
1199
+
1200
+ spherical.radius = clampDistance( spherical.radius );
1201
+
1202
+ } else {
1203
+
1204
+ spherical.radius = clampDistance( spherical.radius * scale );
1205
+
1206
+ }
1207
+
1185
1208
  offset.setFromSpherical( spherical );
1186
1209
 
1187
1210
  // rotate offset back to "camera-up-vector-is-up" space
@@ -1206,7 +1229,96 @@
1206
1229
 
1207
1230
  }
1208
1231
 
1232
+ // adjust camera position
1233
+ let zoomChanged = false;
1234
+ if ( scope.zoomToCursor && performCursorZoom ) {
1235
+
1236
+ let newRadius = null;
1237
+ if ( scope.object.isPerspectiveCamera ) {
1238
+
1239
+ // move the camera down the pointer ray
1240
+ // this method avoids floating point error
1241
+ const prevRadius = offset.length();
1242
+ newRadius = clampDistance( prevRadius * scale );
1243
+
1244
+ const radiusDelta = prevRadius - newRadius;
1245
+ scope.object.position.addScaledVector( dollyDirection, radiusDelta );
1246
+ scope.object.updateMatrixWorld();
1247
+
1248
+ } else if ( scope.object.isOrthographicCamera ) {
1249
+
1250
+ // adjust the ortho camera position based on zoom changes
1251
+ const mouseBefore = new three$1.Vector3( mouse.x, mouse.y, 0 );
1252
+ mouseBefore.unproject( scope.object );
1253
+
1254
+ scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
1255
+ scope.object.updateProjectionMatrix();
1256
+ zoomChanged = true;
1257
+
1258
+ const mouseAfter = new three$1.Vector3( mouse.x, mouse.y, 0 );
1259
+ mouseAfter.unproject( scope.object );
1260
+
1261
+ scope.object.position.sub( mouseAfter ).add( mouseBefore );
1262
+ scope.object.updateMatrixWorld();
1263
+
1264
+ newRadius = offset.length();
1265
+
1266
+ } else {
1267
+
1268
+ console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - zoom to cursor disabled.' );
1269
+ scope.zoomToCursor = false;
1270
+
1271
+ }
1272
+
1273
+ // handle the placement of the target
1274
+ if ( newRadius !== null ) {
1275
+
1276
+ if ( this.screenSpacePanning ) {
1277
+
1278
+ // position the orbit target in front of the new camera position
1279
+ scope.target.set( 0, 0, - 1 )
1280
+ .transformDirection( scope.object.matrix )
1281
+ .multiplyScalar( newRadius )
1282
+ .add( scope.object.position );
1283
+
1284
+ } else {
1285
+
1286
+ // get the ray and translation plane to compute target
1287
+ _ray.origin.copy( scope.object.position );
1288
+ _ray.direction.set( 0, 0, - 1 ).transformDirection( scope.object.matrix );
1289
+
1290
+ // if the camera is 20 degrees above the horizon then don't adjust the focus target to avoid
1291
+ // extremely large values
1292
+ if ( Math.abs( scope.object.up.dot( _ray.direction ) ) < TILT_LIMIT ) {
1293
+
1294
+ object.lookAt( scope.target );
1295
+
1296
+ } else {
1297
+
1298
+ _plane.setFromNormalAndCoplanarPoint( scope.object.up, scope.target );
1299
+ _ray.intersectPlane( _plane, scope.target );
1300
+
1301
+ }
1302
+
1303
+ }
1304
+
1305
+ }
1306
+
1307
+ } else if ( scope.object.isOrthographicCamera ) {
1308
+
1309
+ zoomChanged = scale !== 1;
1310
+
1311
+ if ( zoomChanged ) {
1312
+
1313
+ scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / scale ) );
1314
+ scope.object.updateProjectionMatrix();
1315
+
1316
+ }
1317
+
1318
+ }
1319
+
1209
1320
  scale = 1;
1321
+ performCursorZoom = false;
1210
1322
 
1211
1323
  // update condition is:
1212
1324
  // min(camera displacement, camera rotation in radians)^2 > EPS
@@ -1223,8 +1335,6 @@
1223
1335
  lastQuaternion.copy( scope.object.quaternion );
1224
1336
  lastTargetPosition.copy( scope.target );
1225
1337
 
1226
- zoomChanged = false;
1227
-
1228
1338
  return true;
1229
1339
 
1230
1340
  }
@@ -1285,7 +1395,6 @@
1285
1395
 
1286
1396
  let scale = 1;
1287
1397
  const panOffset = new three$1.Vector3();
1288
- let zoomChanged = false;
1289
1398
 
1290
1399
  const rotateStart = new three$1.Vector2();
1291
1400
  const rotateEnd = new three$1.Vector2();
@@ -1299,18 +1408,33 @@
1299
1408
  const dollyEnd = new three$1.Vector2();
1300
1409
  const dollyDelta = new three$1.Vector2();
1301
1410
 
1411
+ const dollyDirection = new three$1.Vector3();
1412
+ const mouse = new three$1.Vector2();
1413
+ let performCursorZoom = false;
1414
+
1302
1415
  const pointers = [];
1303
1416
  const pointerPositions = {};
1304
1417
 
1305
- function getAutoRotationAngle() {
1418
+ let controlActive = false;
1419
+
1420
+ function getAutoRotationAngle( deltaTime ) {
1306
1421
 
1307
- return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
1422
+ if ( deltaTime !== null ) {
1423
+
1424
+ return ( 2 * Math.PI / 60 * scope.autoRotateSpeed ) * deltaTime;
1425
+
1426
+ } else {
1427
+
1428
+ return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
1429
+
1430
+ }
1308
1431
 
1309
1432
  }
1310
1433
 
1311
- function getZoomScale() {
1434
+ function getZoomScale( delta ) {
1312
1435
 
1313
- return Math.pow( 0.95, scope.zoomSpeed );
1436
+ const normalizedDelta = Math.abs( delta * 0.01 );
1437
+ return Math.pow( 0.95, scope.zoomSpeed * normalizedDelta );
1314
1438
 
1315
1439
  }
1316
1440
 
@@ -1409,16 +1533,10 @@
1409
1533
 
1410
1534
  function dollyOut( dollyScale ) {
1411
1535
 
1412
- if ( scope.object.isPerspectiveCamera ) {
1536
+ if ( scope.object.isPerspectiveCamera || scope.object.isOrthographicCamera ) {
1413
1537
 
1414
1538
  scale /= dollyScale;
1415
1539
 
1416
- } else if ( scope.object.isOrthographicCamera ) {
1417
-
1418
- scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );
1419
- scope.object.updateProjectionMatrix();
1420
- zoomChanged = true;
1421
-
1422
1540
  } else {
1423
1541
 
1424
1542
  console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
@@ -1430,16 +1548,10 @@
1430
1548
 
1431
1549
  function dollyIn( dollyScale ) {
1432
1550
 
1433
- if ( scope.object.isPerspectiveCamera ) {
1551
+ if ( scope.object.isPerspectiveCamera || scope.object.isOrthographicCamera ) {
1434
1552
 
1435
1553
  scale *= dollyScale;
1436
1554
 
1437
- } else if ( scope.object.isOrthographicCamera ) {
1438
-
1439
- scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );
1440
- scope.object.updateProjectionMatrix();
1441
- zoomChanged = true;
1442
-
1443
1555
  } else {
1444
1556
 
1445
1557
  console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
@@ -1449,6 +1561,35 @@
1449
1561
 
1450
1562
  }
1451
1563
 
1564
+ function updateZoomParameters( x, y ) {
1565
+
1566
+ if ( ! scope.zoomToCursor ) {
1567
+
1568
+ return;
1569
+
1570
+ }
1571
+
1572
+ performCursorZoom = true;
1573
+
1574
+ const rect = scope.domElement.getBoundingClientRect();
1575
+ const dx = x - rect.left;
1576
+ const dy = y - rect.top;
1577
+ const w = rect.width;
1578
+ const h = rect.height;
1579
+
1580
+ mouse.x = ( dx / w ) * 2 - 1;
1581
+ mouse.y = - ( dy / h ) * 2 + 1;
1582
+
1583
+ dollyDirection.set( mouse.x, mouse.y, 1 ).unproject( scope.object ).sub( scope.object.position ).normalize();
1584
+
1585
+ }
1586
+
1587
+ function clampDistance( dist ) {
1588
+
1589
+ return Math.max( scope.minDistance, Math.min( scope.maxDistance, dist ) );
1590
+
1591
+ }
1592
+
1452
1593
  //
1453
1594
  // event callbacks - update the object state
1454
1595
  //
@@ -1461,6 +1602,7 @@
1461
1602
 
1462
1603
  function handleMouseDownDolly( event ) {
1463
1604
 
1605
+ updateZoomParameters( event.clientX, event.clientX );
1464
1606
  dollyStart.set( event.clientX, event.clientY );
1465
1607
 
1466
1608
  }
@@ -1497,11 +1639,11 @@
1497
1639
 
1498
1640
  if ( dollyDelta.y > 0 ) {
1499
1641
 
1500
- dollyOut( getZoomScale() );
1642
+ dollyOut( getZoomScale( dollyDelta.y ) );
1501
1643
 
1502
1644
  } else if ( dollyDelta.y < 0 ) {
1503
1645
 
1504
- dollyIn( getZoomScale() );
1646
+ dollyIn( getZoomScale( dollyDelta.y ) );
1505
1647
 
1506
1648
  }
1507
1649
 
@@ -1527,13 +1669,15 @@
1527
1669
 
1528
1670
  function handleMouseWheel( event ) {
1529
1671
 
1672
+ updateZoomParameters( event.clientX, event.clientY );
1673
+
1530
1674
  if ( event.deltaY < 0 ) {
1531
1675
 
1532
- dollyIn( getZoomScale() );
1676
+ dollyIn( getZoomScale( event.deltaY ) );
1533
1677
 
1534
1678
  } else if ( event.deltaY > 0 ) {
1535
1679
 
1536
- dollyOut( getZoomScale() );
1680
+ dollyOut( getZoomScale( event.deltaY ) );
1537
1681
 
1538
1682
  }
1539
1683
 
@@ -1621,16 +1765,18 @@
1621
1765
 
1622
1766
  }
1623
1767
 
1624
- function handleTouchStartRotate() {
1768
+ function handleTouchStartRotate( event ) {
1625
1769
 
1626
1770
  if ( pointers.length === 1 ) {
1627
1771
 
1628
- rotateStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY );
1772
+ rotateStart.set( event.pageX, event.pageY );
1629
1773
 
1630
1774
  } else {
1631
1775
 
1632
- const x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX );
1633
- const y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY );
1776
+ const position = getSecondPointerPosition( event );
1777
+
1778
+ const x = 0.5 * ( event.pageX + position.x );
1779
+ const y = 0.5 * ( event.pageY + position.y );
1634
1780
 
1635
1781
  rotateStart.set( x, y );
1636
1782
 
@@ -1638,16 +1784,18 @@
1638
1784
 
1639
1785
  }
1640
1786
 
1641
- function handleTouchStartPan() {
1787
+ function handleTouchStartPan( event ) {
1642
1788
 
1643
1789
  if ( pointers.length === 1 ) {
1644
1790
 
1645
- panStart.set( pointers[ 0 ].pageX, pointers[ 0 ].pageY );
1791
+ panStart.set( event.pageX, event.pageY );
1646
1792
 
1647
1793
  } else {
1648
1794
 
1649
- const x = 0.5 * ( pointers[ 0 ].pageX + pointers[ 1 ].pageX );
1650
- const y = 0.5 * ( pointers[ 0 ].pageY + pointers[ 1 ].pageY );
1795
+ const position = getSecondPointerPosition( event );
1796
+
1797
+ const x = 0.5 * ( event.pageX + position.x );
1798
+ const y = 0.5 * ( event.pageY + position.y );
1651
1799
 
1652
1800
  panStart.set( x, y );
1653
1801
 
@@ -1655,10 +1803,12 @@
1655
1803
 
1656
1804
  }
1657
1805
 
1658
- function handleTouchStartDolly() {
1806
+ function handleTouchStartDolly( event ) {
1807
+
1808
+ const position = getSecondPointerPosition( event );
1659
1809
 
1660
- const dx = pointers[ 0 ].pageX - pointers[ 1 ].pageX;
1661
- const dy = pointers[ 0 ].pageY - pointers[ 1 ].pageY;
1810
+ const dx = event.pageX - position.x;
1811
+ const dy = event.pageY - position.y;
1662
1812
 
1663
1813
  const distance = Math.sqrt( dx * dx + dy * dy );
1664
1814
 
@@ -1666,19 +1816,19 @@
1666
1816
 
1667
1817
  }
1668
1818
 
1669
- function handleTouchStartDollyPan() {
1819
+ function handleTouchStartDollyPan( event ) {
1670
1820
 
1671
- if ( scope.enableZoom ) handleTouchStartDolly();
1821
+ if ( scope.enableZoom ) handleTouchStartDolly( event );
1672
1822
 
1673
- if ( scope.enablePan ) handleTouchStartPan();
1823
+ if ( scope.enablePan ) handleTouchStartPan( event );
1674
1824
 
1675
1825
  }
1676
1826
 
1677
- function handleTouchStartDollyRotate() {
1827
+ function handleTouchStartDollyRotate( event ) {
1678
1828
 
1679
- if ( scope.enableZoom ) handleTouchStartDolly();
1829
+ if ( scope.enableZoom ) handleTouchStartDolly( event );
1680
1830
 
1681
- if ( scope.enableRotate ) handleTouchStartRotate();
1831
+ if ( scope.enableRotate ) handleTouchStartRotate( event );
1682
1832
 
1683
1833
  }
1684
1834
 
@@ -1753,6 +1903,11 @@
1753
1903
 
1754
1904
  dollyStart.copy( dollyEnd );
1755
1905
 
1906
+ const centerX = ( event.pageX + position.x ) * 0.5;
1907
+ const centerY = ( event.pageY + position.y ) * 0.5;
1908
+
1909
+ updateZoomParameters( centerX, centerY );
1910
+
1756
1911
  }
1757
1912
 
1758
1913
  function handleTouchMoveDollyPan( event ) {
@@ -1824,18 +1979,32 @@
1824
1979
 
1825
1980
  removePointer( event );
1826
1981
 
1827
- if ( pointers.length === 0 ) {
1982
+ switch ( pointers.length ) {
1828
1983
 
1829
- scope.domElement.releasePointerCapture( event.pointerId );
1984
+ case 0:
1830
1985
 
1831
- scope.domElement.removeEventListener( 'pointermove', onPointerMove );
1832
- scope.domElement.removeEventListener( 'pointerup', onPointerUp );
1986
+ scope.domElement.releasePointerCapture( event.pointerId );
1833
1987
 
1834
- }
1988
+ scope.domElement.removeEventListener( 'pointermove', onPointerMove );
1989
+ scope.domElement.removeEventListener( 'pointerup', onPointerUp );
1835
1990
 
1836
- scope.dispatchEvent( _endEvent );
1991
+ scope.dispatchEvent( _endEvent );
1837
1992
 
1838
- state = STATE.NONE;
1993
+ state = STATE.NONE;
1994
+
1995
+ break;
1996
+
1997
+ case 1:
1998
+
1999
+ const pointerId = pointers[ 0 ];
2000
+ const position = pointerPositions[ pointerId ];
2001
+
2002
+ // minimal placeholder event - allows state correction on pointer-up
2003
+ onTouchStart( { pointerId: pointerId, pageX: position.x, pageY: position.y } );
2004
+
2005
+ break;
2006
+
2007
+ }
1839
2008
 
1840
2009
  }
1841
2010
 
@@ -1976,12 +2145,76 @@
1976
2145
 
1977
2146
  scope.dispatchEvent( _startEvent );
1978
2147
 
1979
- handleMouseWheel( event );
2148
+ handleMouseWheel( customWheelEvent( event ) );
1980
2149
 
1981
2150
  scope.dispatchEvent( _endEvent );
1982
2151
 
1983
2152
  }
1984
2153
 
2154
+ function customWheelEvent( event ) {
2155
+
2156
+ const mode = event.deltaMode;
2157
+
2158
+ // minimal wheel event altered to meet delta-zoom demand
2159
+ const newEvent = {
2160
+ clientX: event.clientX,
2161
+ clientY: event.clientY,
2162
+ deltaY: event.deltaY,
2163
+ };
2164
+
2165
+ switch ( mode ) {
2166
+
2167
+ case 1: // LINE_MODE
2168
+ newEvent.deltaY *= 16;
2169
+ break;
2170
+
2171
+ case 2: // PAGE_MODE
2172
+ newEvent.deltaY *= 100;
2173
+ break;
2174
+
2175
+ }
2176
+
2177
+ // detect if event was triggered by pinching
2178
+ if ( event.ctrlKey && ! controlActive ) {
2179
+
2180
+ newEvent.deltaY *= 10;
2181
+
2182
+ }
2183
+
2184
+ return newEvent;
2185
+
2186
+ }
2187
+
2188
+ function interceptControlDown( event ) {
2189
+
2190
+ if ( event.key === 'Control' ) {
2191
+
2192
+ controlActive = true;
2193
+
2194
+
2195
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
2196
+
2197
+ document.addEventListener( 'keyup', interceptControlUp, { passive: true, capture: true } );
2198
+
2199
+ }
2200
+
2201
+ }
2202
+
2203
+ function interceptControlUp( event ) {
2204
+
2205
+ if ( event.key === 'Control' ) {
2206
+
2207
+ controlActive = false;
2208
+
2209
+
2210
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
2211
+
2212
+ document.removeEventListener( 'keyup', interceptControlUp, { passive: true, capture: true } );
2213
+
2214
+ }
2215
+
2216
+ }
2217
+
1985
2218
  function onKeyDown( event ) {
1986
2219
 
1987
2220
  if ( scope.enabled === false || scope.enablePan === false ) return;
@@ -2004,7 +2237,7 @@
2004
2237
 
2005
2238
  if ( scope.enableRotate === false ) return;
2006
2239
 
2007
- handleTouchStartRotate();
2240
+ handleTouchStartRotate( event );
2008
2241
 
2009
2242
  state = STATE.TOUCH_ROTATE;
2010
2243
 
@@ -2014,7 +2247,7 @@
2014
2247
 
2015
2248
  if ( scope.enablePan === false ) return;
2016
2249
 
2017
- handleTouchStartPan();
2250
+ handleTouchStartPan( event );
2018
2251
 
2019
2252
  state = STATE.TOUCH_PAN;
2020
2253
 
@@ -2036,7 +2269,7 @@
2036
2269
 
2037
2270
  if ( scope.enableZoom === false && scope.enablePan === false ) return;
2038
2271
 
2039
- handleTouchStartDollyPan();
2272
+ handleTouchStartDollyPan( event );
2040
2273
 
2041
2274
  state = STATE.TOUCH_DOLLY_PAN;
2042
2275
 
@@ -2046,7 +2279,7 @@
2046
2279
 
2047
2280
  if ( scope.enableZoom === false && scope.enableRotate === false ) return;
2048
2281
 
2049
- handleTouchStartDollyRotate();
2282
+ handleTouchStartDollyRotate( event );
2050
2283
 
2051
2284
  state = STATE.TOUCH_DOLLY_ROTATE;
2052
2285
 
@@ -2138,7 +2371,7 @@
2138
2371
 
2139
2372
  function addPointer( event ) {
2140
2373
 
2141
- pointers.push( event );
2374
+ pointers.push( event.pointerId );
2142
2375
 
2143
2376
  }
2144
2377
 
@@ -2148,7 +2381,7 @@
2148
2381
 
2149
2382
  for ( let i = 0; i < pointers.length; i ++ ) {
2150
2383
 
2151
- if ( pointers[ i ].pointerId == event.pointerId ) {
2384
+ if ( pointers[ i ] == event.pointerId ) {
2152
2385
 
2153
2386
  pointers.splice( i, 1 );
2154
2387
  return;
@@ -2176,9 +2409,9 @@
2176
2409
 
2177
2410
  function getSecondPointerPosition( event ) {
2178
2411
 
2179
- const pointer = ( event.pointerId === pointers[ 0 ].pointerId ) ? pointers[ 1 ] : pointers[ 0 ];
2412
+ const pointerId = ( event.pointerId === pointers[ 0 ] ) ? pointers[ 1 ] : pointers[ 0 ];
2180
2413
 
2181
- return pointerPositions[ pointer.pointerId ];
2414
+ return pointerPositions[ pointerId ];
2182
2415
 
2183
2416
  }
2184
2417
 
@@ -2190,6 +2423,10 @@
2190
2423
  scope.domElement.addEventListener( 'pointercancel', onPointerUp );
2191
2424
  scope.domElement.addEventListener( 'wheel', onMouseWheel, { passive: false } );
2192
2425
 
2426
+ const document = scope.domElement.getRootNode(); // offscreen canvas compatibility
2427
+
2428
+ document.addEventListener( 'keydown', interceptControlDown, { passive: true, capture: true } );
2429
+
2193
2430
  // force an update at start
2194
2431
 
2195
2432
  this.update();
@@ -2380,6 +2617,29 @@
2380
2617
 
2381
2618
  };
2382
2619
 
2620
+ this.pointercancel = function () {
2621
+
2622
+ if ( this.enabled === false ) return;
2623
+
2624
+ if ( this.dragToLook ) {
2625
+
2626
+ this.status = 0;
2627
+
2628
+ this.moveState.yawLeft = this.moveState.pitchDown = 0;
2629
+
2630
+ } else {
2631
+
2632
+ this.moveState.forward = 0;
2633
+ this.moveState.back = 0;
2634
+
2635
+ this.updateMovementVector();
2636
+
2637
+ }
2638
+
2639
+ this.updateRotationVector();
2640
+
2641
+ };
2642
+
2383
2643
  this.contextMenu = function ( event ) {
2384
2644
 
2385
2645
  if ( this.enabled === false ) return;
@@ -2463,6 +2723,7 @@
2463
2723
  this.domElement.removeEventListener( 'pointerdown', _pointerdown );
2464
2724
  this.domElement.removeEventListener( 'pointermove', _pointermove );
2465
2725
  this.domElement.removeEventListener( 'pointerup', _pointerup );
2726
+ this.domElement.removeEventListener( 'pointercancel', _pointercancel );
2466
2727
 
2467
2728
  window.removeEventListener( 'keydown', _keydown );
2468
2729
  window.removeEventListener( 'keyup', _keyup );
@@ -2473,6 +2734,7 @@
2473
2734
  const _pointermove = this.pointermove.bind( this );
2474
2735
  const _pointerdown = this.pointerdown.bind( this );
2475
2736
  const _pointerup = this.pointerup.bind( this );
2737
+ const _pointercancel = this.pointercancel.bind( this );
2476
2738
  const _keydown = this.keydown.bind( this );
2477
2739
  const _keyup = this.keyup.bind( this );
2478
2740
 
@@ -2480,6 +2742,7 @@
2480
2742
  this.domElement.addEventListener( 'pointerdown', _pointerdown );
2481
2743
  this.domElement.addEventListener( 'pointermove', _pointermove );
2482
2744
  this.domElement.addEventListener( 'pointerup', _pointerup );
2745
+ this.domElement.addEventListener( 'pointercancel', _pointercancel );
2483
2746
 
2484
2747
  window.addEventListener( 'keydown', _keydown );
2485
2748
  window.addEventListener( 'keyup', _keyup );
@@ -2573,9 +2836,20 @@
2573
2836
 
2574
2837
  // https://github.com/mrdoob/three.js/pull/21358
2575
2838
 
2576
- const _geometry = new three$1.BufferGeometry();
2577
- _geometry.setAttribute( 'position', new three$1.Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );
2578
- _geometry.setAttribute( 'uv', new three$1.Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );
2839
+ class FullscreenTriangleGeometry extends three$1.BufferGeometry {
2840
+
2841
+ constructor() {
2842
+
2843
+ super();
2844
+
2845
+ this.setAttribute( 'position', new three$1.Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );
2846
+ this.setAttribute( 'uv', new three$1.Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );
2847
+
2848
+ }
2849
+
2850
+ }
2851
+
2852
+ const _geometry = new FullscreenTriangleGeometry();
2579
2853
 
2580
2854
  class FullScreenQuad {
2581
2855
 
@@ -2744,11 +3018,14 @@
2744
3018
  if ( this.clear ) renderer.clear();
2745
3019
  renderer.render( this.scene, this.camera );
2746
3020
 
2747
- // unlock color and depth buffer for subsequent rendering
3021
+ // unlock color and depth buffer and make them writable for subsequent rendering/clearing
2748
3022
 
2749
3023
  state.buffers.color.setLocked( false );
2750
3024
  state.buffers.depth.setLocked( false );
2751
3025
 
3026
+ state.buffers.color.setMask( true );
3027
+ state.buffers.depth.setMask( true );
3028
+
2752
3029
  // only render where stencil is set to 1
2753
3030
 
2754
3031
  state.buffers.stencil.setLocked( false );
@@ -2999,7 +3276,7 @@
2999
3276
 
3000
3277
  class RenderPass extends Pass {
3001
3278
 
3002
- constructor( scene, camera, overrideMaterial, clearColor, clearAlpha ) {
3279
+ constructor( scene, camera, overrideMaterial = null, clearColor = null, clearAlpha = null ) {
3003
3280
 
3004
3281
  super();
3005
3282
 
@@ -3009,7 +3286,7 @@
3009
3286
  this.overrideMaterial = overrideMaterial;
3010
3287
 
3011
3288
  this.clearColor = clearColor;
3012
- this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 0;
3289
+ this.clearAlpha = clearAlpha;
3013
3290
 
3014
3291
  this.clear = true;
3015
3292
  this.clearDepth = false;
@@ -3025,7 +3302,7 @@
3025
3302
 
3026
3303
  let oldClearAlpha, oldOverrideMaterial;
3027
3304
 
3028
- if ( this.overrideMaterial !== undefined ) {
3305
+ if ( this.overrideMaterial !== null ) {
3029
3306
 
3030
3307
  oldOverrideMaterial = this.scene.overrideMaterial;
3031
3308
 
@@ -3033,16 +3310,21 @@
3033
3310
 
3034
3311
  }
3035
3312
 
3036
- if ( this.clearColor ) {
3313
+ if ( this.clearColor !== null ) {
3037
3314
 
3038
3315
  renderer.getClearColor( this._oldClearColor );
3039
- oldClearAlpha = renderer.getClearAlpha();
3316
+ renderer.setClearColor( this.clearColor );
3040
3317
 
3041
- renderer.setClearColor( this.clearColor, this.clearAlpha );
3318
+ }
3319
+
3320
+ if ( this.clearAlpha !== null ) {
3321
+
3322
+ oldClearAlpha = renderer.getClearAlpha();
3323
+ renderer.setClearAlpha( this.clearAlpha );
3042
3324
 
3043
3325
  }
3044
3326
 
3045
- if ( this.clearDepth ) {
3327
+ if ( this.clearDepth == true ) {
3046
3328
 
3047
3329
  renderer.clearDepth();
3048
3330
 
@@ -3050,17 +3332,30 @@
3050
3332
 
3051
3333
  renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );
3052
3334
 
3053
- // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
3054
- if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
3335
+ if ( this.clear === true ) {
3336
+
3337
+ // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
3338
+ renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
3339
+
3340
+ }
3341
+
3055
3342
  renderer.render( this.scene, this.camera );
3056
3343
 
3057
- if ( this.clearColor ) {
3344
+ // restore
3345
+
3346
+ if ( this.clearColor !== null ) {
3347
+
3348
+ renderer.setClearColor( this._oldClearColor );
3349
+
3350
+ }
3351
+
3352
+ if ( this.clearAlpha !== null ) {
3058
3353
 
3059
- renderer.setClearColor( this._oldClearColor, oldClearAlpha );
3354
+ renderer.setClearAlpha( oldClearAlpha );
3060
3355
 
3061
3356
  }
3062
3357
 
3063
- if ( this.overrideMaterial !== undefined ) {
3358
+ if ( this.overrideMaterial !== null ) {
3064
3359
 
3065
3360
  this.scene.overrideMaterial = oldOverrideMaterial;
3066
3361
 
@@ -3116,35 +3411,28 @@
3116
3411
  }
3117
3412
 
3118
3413
  function _isNativeFunction(fn) {
3119
- return Function.toString.call(fn).indexOf("[native code]") !== -1;
3414
+ try {
3415
+ return Function.toString.call(fn).indexOf("[native code]") !== -1;
3416
+ } catch (e) {
3417
+ return typeof fn === "function";
3418
+ }
3120
3419
  }
3121
3420
 
3122
3421
  function _isNativeReflectConstruct() {
3123
- if (typeof Reflect === "undefined" || !Reflect.construct) return false;
3124
- if (Reflect.construct.sham) return false;
3125
- if (typeof Proxy === "function") return true;
3126
3422
  try {
3127
- Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
3128
- return true;
3129
- } catch (e) {
3130
- return false;
3131
- }
3423
+ var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
3424
+ } catch (t) {}
3425
+ return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {
3426
+ return !!t;
3427
+ })();
3132
3428
  }
3133
3429
 
3134
- function _construct(Parent, args, Class) {
3135
- if (_isNativeReflectConstruct()) {
3136
- _construct = Reflect.construct.bind();
3137
- } else {
3138
- _construct = function _construct(Parent, args, Class) {
3139
- var a = [null];
3140
- a.push.apply(a, args);
3141
- var Constructor = Function.bind.apply(Parent, a);
3142
- var instance = new Constructor();
3143
- if (Class) _setPrototypeOf(instance, Class.prototype);
3144
- return instance;
3145
- };
3146
- }
3147
- return _construct.apply(null, arguments);
3430
+ function _construct(t, e, r) {
3431
+ if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
3432
+ var o = [null];
3433
+ o.push.apply(o, e);
3434
+ var p = new (t.bind.apply(t, o))();
3435
+ return r && _setPrototypeOf(p, r.prototype), p;
3148
3436
  }
3149
3437
 
3150
3438
  function _wrapNativeSuper(Class) {
@@ -3175,7 +3463,6 @@
3175
3463
  }
3176
3464
 
3177
3465
  // based on https://github.com/styled-components/styled-components/blob/fcf6f3804c57a14dd7984dfab7bc06ee2edca044/src/utils/error.js
3178
-
3179
3466
  /**
3180
3467
  * Parse errors.md and turn it into a simple hash of code: message
3181
3468
  * @private
@@ -3260,84 +3547,71 @@
3260
3547
  "77": "remToPx expects a value in \"rem\" but you provided it in \"%s\".\n\n",
3261
3548
  "78": "base must be set in \"px\" or \"%\" but you set it in \"%s\".\n"
3262
3549
  };
3550
+
3263
3551
  /**
3264
3552
  * super basic version of sprintf
3265
3553
  * @private
3266
3554
  */
3267
-
3268
3555
  function format() {
3269
3556
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3270
3557
  args[_key] = arguments[_key];
3271
3558
  }
3272
-
3273
3559
  var a = args[0];
3274
3560
  var b = [];
3275
3561
  var c;
3276
-
3277
3562
  for (c = 1; c < args.length; c += 1) {
3278
3563
  b.push(args[c]);
3279
3564
  }
3280
-
3281
3565
  b.forEach(function (d) {
3282
3566
  a = a.replace(/%[a-z]/, d);
3283
3567
  });
3284
3568
  return a;
3285
3569
  }
3570
+
3286
3571
  /**
3287
3572
  * Create an error file out of errors.md for development and a simple web link to the full errors
3288
3573
  * in production mode.
3289
3574
  * @private
3290
3575
  */
3291
-
3292
-
3293
3576
  var PolishedError = /*#__PURE__*/function (_Error) {
3294
3577
  _inheritsLoose(PolishedError, _Error);
3295
-
3296
3578
  function PolishedError(code) {
3297
3579
  var _this;
3298
-
3299
3580
  if (process.env.NODE_ENV === 'production') {
3300
3581
  _this = _Error.call(this, "An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#" + code + " for more information.") || this;
3301
3582
  } else {
3302
3583
  for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
3303
3584
  args[_key2 - 1] = arguments[_key2];
3304
3585
  }
3305
-
3306
3586
  _this = _Error.call(this, format.apply(void 0, [ERRORS[code]].concat(args))) || this;
3307
3587
  }
3308
-
3309
3588
  return _assertThisInitialized(_this);
3310
3589
  }
3311
-
3312
3590
  return PolishedError;
3313
3591
  }( /*#__PURE__*/_wrapNativeSuper(Error));
3314
3592
 
3315
3593
  function colorToInt(color) {
3316
3594
  return Math.round(color * 255);
3317
3595
  }
3318
-
3319
3596
  function convertToInt(red, green, blue) {
3320
3597
  return colorToInt(red) + "," + colorToInt(green) + "," + colorToInt(blue);
3321
3598
  }
3322
-
3323
3599
  function hslToRgb(hue, saturation, lightness, convert) {
3324
3600
  if (convert === void 0) {
3325
3601
  convert = convertToInt;
3326
3602
  }
3327
-
3328
3603
  if (saturation === 0) {
3329
3604
  // achromatic
3330
3605
  return convert(lightness, lightness, lightness);
3331
- } // formulae from https://en.wikipedia.org/wiki/HSL_and_HSV
3332
-
3606
+ }
3333
3607
 
3608
+ // formulae from https://en.wikipedia.org/wiki/HSL_and_HSV
3334
3609
  var huePrime = (hue % 360 + 360) % 360 / 60;
3335
3610
  var chroma = (1 - Math.abs(2 * lightness - 1)) * saturation;
3336
3611
  var secondComponent = chroma * (1 - Math.abs(huePrime % 2 - 1));
3337
3612
  var red = 0;
3338
3613
  var green = 0;
3339
3614
  var blue = 0;
3340
-
3341
3615
  if (huePrime >= 0 && huePrime < 1) {
3342
3616
  red = chroma;
3343
3617
  green = secondComponent;
@@ -3357,7 +3631,6 @@
3357
3631
  red = chroma;
3358
3632
  blue = secondComponent;
3359
3633
  }
3360
-
3361
3634
  var lightnessModification = lightness - chroma / 2;
3362
3635
  var finalRed = red + lightnessModification;
3363
3636
  var finalGreen = green + lightnessModification;
@@ -3515,11 +3788,11 @@
3515
3788
  yellow: 'ff0',
3516
3789
  yellowgreen: '9acd32'
3517
3790
  };
3791
+
3518
3792
  /**
3519
3793
  * Checks if a string is a CSS named color and returns its equivalent hex value, otherwise returns the original color.
3520
3794
  * @private
3521
3795
  */
3522
-
3523
3796
  function nameToHex(color) {
3524
3797
  if (typeof color !== 'string') return color;
3525
3798
  var normalizedColorName = color.toLowerCase();
@@ -3534,6 +3807,7 @@
3534
3807
  var rgbaRegex = /^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i;
3535
3808
  var hslRegex = /^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i;
3536
3809
  var hslaRegex = /^hsl(?:a)?\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i;
3810
+
3537
3811
  /**
3538
3812
  * Returns an RgbColor or RgbaColor object. This utility function is only useful
3539
3813
  * if want to extract a color component. With the color util `toColorString` you
@@ -3545,14 +3819,11 @@
3545
3819
  * // Assigns `{ red: 92, green: 102, blue: 112, alpha: 0.75 }` to color2
3546
3820
  * const color2 = parseToRgb('hsla(210, 10%, 40%, 0.75)');
3547
3821
  */
3548
-
3549
3822
  function parseToRgb(color) {
3550
3823
  if (typeof color !== 'string') {
3551
3824
  throw new PolishedError(3);
3552
3825
  }
3553
-
3554
3826
  var normalizedColor = nameToHex(color);
3555
-
3556
3827
  if (normalizedColor.match(hexRegex)) {
3557
3828
  return {
3558
3829
  red: parseInt("" + normalizedColor[1] + normalizedColor[2], 16),
@@ -3560,7 +3831,6 @@
3560
3831
  blue: parseInt("" + normalizedColor[5] + normalizedColor[6], 16)
3561
3832
  };
3562
3833
  }
3563
-
3564
3834
  if (normalizedColor.match(hexRgbaRegex)) {
3565
3835
  var alpha = parseFloat((parseInt("" + normalizedColor[7] + normalizedColor[8], 16) / 255).toFixed(2));
3566
3836
  return {
@@ -3570,7 +3840,6 @@
3570
3840
  alpha: alpha
3571
3841
  };
3572
3842
  }
3573
-
3574
3843
  if (normalizedColor.match(reducedHexRegex)) {
3575
3844
  return {
3576
3845
  red: parseInt("" + normalizedColor[1] + normalizedColor[1], 16),
@@ -3578,10 +3847,8 @@
3578
3847
  blue: parseInt("" + normalizedColor[3] + normalizedColor[3], 16)
3579
3848
  };
3580
3849
  }
3581
-
3582
3850
  if (normalizedColor.match(reducedRgbaHexRegex)) {
3583
3851
  var _alpha = parseFloat((parseInt("" + normalizedColor[4] + normalizedColor[4], 16) / 255).toFixed(2));
3584
-
3585
3852
  return {
3586
3853
  red: parseInt("" + normalizedColor[1] + normalizedColor[1], 16),
3587
3854
  green: parseInt("" + normalizedColor[2] + normalizedColor[2], 16),
@@ -3589,9 +3856,7 @@
3589
3856
  alpha: _alpha
3590
3857
  };
3591
3858
  }
3592
-
3593
3859
  var rgbMatched = rgbRegex.exec(normalizedColor);
3594
-
3595
3860
  if (rgbMatched) {
3596
3861
  return {
3597
3862
  red: parseInt("" + rgbMatched[1], 10),
@@ -3599,9 +3864,7 @@
3599
3864
  blue: parseInt("" + rgbMatched[3], 10)
3600
3865
  };
3601
3866
  }
3602
-
3603
3867
  var rgbaMatched = rgbaRegex.exec(normalizedColor.substring(0, 50));
3604
-
3605
3868
  if (rgbaMatched) {
3606
3869
  return {
3607
3870
  red: parseInt("" + rgbaMatched[1], 10),
@@ -3610,44 +3873,32 @@
3610
3873
  alpha: parseFloat("" + rgbaMatched[4]) > 1 ? parseFloat("" + rgbaMatched[4]) / 100 : parseFloat("" + rgbaMatched[4])
3611
3874
  };
3612
3875
  }
3613
-
3614
3876
  var hslMatched = hslRegex.exec(normalizedColor);
3615
-
3616
3877
  if (hslMatched) {
3617
3878
  var hue = parseInt("" + hslMatched[1], 10);
3618
3879
  var saturation = parseInt("" + hslMatched[2], 10) / 100;
3619
3880
  var lightness = parseInt("" + hslMatched[3], 10) / 100;
3620
3881
  var rgbColorString = "rgb(" + hslToRgb(hue, saturation, lightness) + ")";
3621
3882
  var hslRgbMatched = rgbRegex.exec(rgbColorString);
3622
-
3623
3883
  if (!hslRgbMatched) {
3624
3884
  throw new PolishedError(4, normalizedColor, rgbColorString);
3625
3885
  }
3626
-
3627
3886
  return {
3628
3887
  red: parseInt("" + hslRgbMatched[1], 10),
3629
3888
  green: parseInt("" + hslRgbMatched[2], 10),
3630
3889
  blue: parseInt("" + hslRgbMatched[3], 10)
3631
3890
  };
3632
3891
  }
3633
-
3634
3892
  var hslaMatched = hslaRegex.exec(normalizedColor.substring(0, 50));
3635
-
3636
3893
  if (hslaMatched) {
3637
3894
  var _hue = parseInt("" + hslaMatched[1], 10);
3638
-
3639
3895
  var _saturation = parseInt("" + hslaMatched[2], 10) / 100;
3640
-
3641
3896
  var _lightness = parseInt("" + hslaMatched[3], 10) / 100;
3642
-
3643
3897
  var _rgbColorString = "rgb(" + hslToRgb(_hue, _saturation, _lightness) + ")";
3644
-
3645
3898
  var _hslRgbMatched = rgbRegex.exec(_rgbColorString);
3646
-
3647
3899
  if (!_hslRgbMatched) {
3648
3900
  throw new PolishedError(4, normalizedColor, _rgbColorString);
3649
3901
  }
3650
-
3651
3902
  return {
3652
3903
  red: parseInt("" + _hslRgbMatched[1], 10),
3653
3904
  green: parseInt("" + _hslRgbMatched[2], 10),
@@ -3655,10 +3906,82 @@
3655
3906
  alpha: parseFloat("" + hslaMatched[4]) > 1 ? parseFloat("" + hslaMatched[4]) / 100 : parseFloat("" + hslaMatched[4])
3656
3907
  };
3657
3908
  }
3658
-
3659
3909
  throw new PolishedError(5);
3660
3910
  }
3661
3911
 
3912
+ function rgbToHsl(color) {
3913
+ // make sure rgb are contained in a set of [0, 255]
3914
+ var red = color.red / 255;
3915
+ var green = color.green / 255;
3916
+ var blue = color.blue / 255;
3917
+ var max = Math.max(red, green, blue);
3918
+ var min = Math.min(red, green, blue);
3919
+ var lightness = (max + min) / 2;
3920
+ if (max === min) {
3921
+ // achromatic
3922
+ if (color.alpha !== undefined) {
3923
+ return {
3924
+ hue: 0,
3925
+ saturation: 0,
3926
+ lightness: lightness,
3927
+ alpha: color.alpha
3928
+ };
3929
+ } else {
3930
+ return {
3931
+ hue: 0,
3932
+ saturation: 0,
3933
+ lightness: lightness
3934
+ };
3935
+ }
3936
+ }
3937
+ var hue;
3938
+ var delta = max - min;
3939
+ var saturation = lightness > 0.5 ? delta / (2 - max - min) : delta / (max + min);
3940
+ switch (max) {
3941
+ case red:
3942
+ hue = (green - blue) / delta + (green < blue ? 6 : 0);
3943
+ break;
3944
+ case green:
3945
+ hue = (blue - red) / delta + 2;
3946
+ break;
3947
+ default:
3948
+ // blue case
3949
+ hue = (red - green) / delta + 4;
3950
+ break;
3951
+ }
3952
+ hue *= 60;
3953
+ if (color.alpha !== undefined) {
3954
+ return {
3955
+ hue: hue,
3956
+ saturation: saturation,
3957
+ lightness: lightness,
3958
+ alpha: color.alpha
3959
+ };
3960
+ }
3961
+ return {
3962
+ hue: hue,
3963
+ saturation: saturation,
3964
+ lightness: lightness
3965
+ };
3966
+ }
3967
+
3968
+ /**
3969
+ * Returns an HslColor or HslaColor object. This utility function is only useful
3970
+ * if want to extract a color component. With the color util `toColorString` you
3971
+ * can convert a HslColor or HslaColor object back to a string.
3972
+ *
3973
+ * @example
3974
+ * // Assigns `{ hue: 0, saturation: 1, lightness: 0.5 }` to color1
3975
+ * const color1 = parseToHsl('rgb(255, 0, 0)');
3976
+ * // Assigns `{ hue: 128, saturation: 1, lightness: 0.5, alpha: 0.75 }` to color2
3977
+ * const color2 = parseToHsl('hsla(128, 100%, 50%, 0.75)');
3978
+ */
3979
+ function parseToHsl(color) {
3980
+ // Note: At a later stage we can optimize this function as right now a hsl
3981
+ // color would be parsed converted to rgb values and converted back to hsl.
3982
+ return rgbToHsl(parseToRgb(color));
3983
+ }
3984
+
3662
3985
  /**
3663
3986
  * Reduces hex values if possible e.g. #ff8866 to #f86
3664
3987
  * @private
@@ -3667,10 +3990,8 @@
3667
3990
  if (value.length === 7 && value[1] === value[2] && value[3] === value[4] && value[5] === value[6]) {
3668
3991
  return "#" + value[1] + value[3] + value[5];
3669
3992
  }
3670
-
3671
3993
  return value;
3672
3994
  };
3673
-
3674
3995
  var reduceHexValue$1 = reduceHexValue;
3675
3996
 
3676
3997
  function numberToHex(value) {
@@ -3678,6 +3999,83 @@
3678
3999
  return hex.length === 1 ? "0" + hex : hex;
3679
4000
  }
3680
4001
 
4002
+ function colorToHex(color) {
4003
+ return numberToHex(Math.round(color * 255));
4004
+ }
4005
+ function convertToHex(red, green, blue) {
4006
+ return reduceHexValue$1("#" + colorToHex(red) + colorToHex(green) + colorToHex(blue));
4007
+ }
4008
+ function hslToHex(hue, saturation, lightness) {
4009
+ return hslToRgb(hue, saturation, lightness, convertToHex);
4010
+ }
4011
+
4012
+ /**
4013
+ * Returns a string value for the color. The returned result is the smallest possible hex notation.
4014
+ *
4015
+ * @example
4016
+ * // Styles as object usage
4017
+ * const styles = {
4018
+ * background: hsl(359, 0.75, 0.4),
4019
+ * background: hsl({ hue: 360, saturation: 0.75, lightness: 0.4 }),
4020
+ * }
4021
+ *
4022
+ * // styled-components usage
4023
+ * const div = styled.div`
4024
+ * background: ${hsl(359, 0.75, 0.4)};
4025
+ * background: ${hsl({ hue: 360, saturation: 0.75, lightness: 0.4 })};
4026
+ * `
4027
+ *
4028
+ * // CSS in JS Output
4029
+ *
4030
+ * element {
4031
+ * background: "#b3191c";
4032
+ * background: "#b3191c";
4033
+ * }
4034
+ */
4035
+ function hsl(value, saturation, lightness) {
4036
+ if (typeof value === 'number' && typeof saturation === 'number' && typeof lightness === 'number') {
4037
+ return hslToHex(value, saturation, lightness);
4038
+ } else if (typeof value === 'object' && saturation === undefined && lightness === undefined) {
4039
+ return hslToHex(value.hue, value.saturation, value.lightness);
4040
+ }
4041
+ throw new PolishedError(1);
4042
+ }
4043
+
4044
+ /**
4045
+ * Returns a string value for the color. The returned result is the smallest possible rgba or hex notation.
4046
+ *
4047
+ * @example
4048
+ * // Styles as object usage
4049
+ * const styles = {
4050
+ * background: hsla(359, 0.75, 0.4, 0.7),
4051
+ * background: hsla({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0,7 }),
4052
+ * background: hsla(359, 0.75, 0.4, 1),
4053
+ * }
4054
+ *
4055
+ * // styled-components usage
4056
+ * const div = styled.div`
4057
+ * background: ${hsla(359, 0.75, 0.4, 0.7)};
4058
+ * background: ${hsla({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0,7 })};
4059
+ * background: ${hsla(359, 0.75, 0.4, 1)};
4060
+ * `
4061
+ *
4062
+ * // CSS in JS Output
4063
+ *
4064
+ * element {
4065
+ * background: "rgba(179,25,28,0.7)";
4066
+ * background: "rgba(179,25,28,0.7)";
4067
+ * background: "#b3191c";
4068
+ * }
4069
+ */
4070
+ function hsla(value, saturation, lightness, alpha) {
4071
+ if (typeof value === 'number' && typeof saturation === 'number' && typeof lightness === 'number' && typeof alpha === 'number') {
4072
+ return alpha >= 1 ? hslToHex(value, saturation, lightness) : "rgba(" + hslToRgb(value, saturation, lightness) + "," + alpha + ")";
4073
+ } else if (typeof value === 'object' && saturation === undefined && lightness === undefined && alpha === undefined) {
4074
+ return value.alpha >= 1 ? hslToHex(value.hue, value.saturation, value.lightness) : "rgba(" + hslToRgb(value.hue, value.saturation, value.lightness) + "," + value.alpha + ")";
4075
+ }
4076
+ throw new PolishedError(2);
4077
+ }
4078
+
3681
4079
  /**
3682
4080
  * Returns a string value for the color. The returned result is the smallest possible hex notation.
3683
4081
  *
@@ -3707,124 +4105,605 @@
3707
4105
  } else if (typeof value === 'object' && green === undefined && blue === undefined) {
3708
4106
  return reduceHexValue$1("#" + numberToHex(value.red) + numberToHex(value.green) + numberToHex(value.blue));
3709
4107
  }
3710
-
3711
4108
  throw new PolishedError(6);
3712
4109
  }
3713
4110
 
3714
4111
  /**
3715
- * Returns a string value for the color. The returned result is the smallest possible rgba or hex notation.
3716
- *
3717
- * Can also be used to fade a color by passing a hex value or named CSS color along with an alpha value.
4112
+ * Returns a string value for the color. The returned result is the smallest possible rgba or hex notation.
4113
+ *
4114
+ * Can also be used to fade a color by passing a hex value or named CSS color along with an alpha value.
4115
+ *
4116
+ * @example
4117
+ * // Styles as object usage
4118
+ * const styles = {
4119
+ * background: rgba(255, 205, 100, 0.7),
4120
+ * background: rgba({ red: 255, green: 205, blue: 100, alpha: 0.7 }),
4121
+ * background: rgba(255, 205, 100, 1),
4122
+ * background: rgba('#ffffff', 0.4),
4123
+ * background: rgba('black', 0.7),
4124
+ * }
4125
+ *
4126
+ * // styled-components usage
4127
+ * const div = styled.div`
4128
+ * background: ${rgba(255, 205, 100, 0.7)};
4129
+ * background: ${rgba({ red: 255, green: 205, blue: 100, alpha: 0.7 })};
4130
+ * background: ${rgba(255, 205, 100, 1)};
4131
+ * background: ${rgba('#ffffff', 0.4)};
4132
+ * background: ${rgba('black', 0.7)};
4133
+ * `
4134
+ *
4135
+ * // CSS in JS Output
4136
+ *
4137
+ * element {
4138
+ * background: "rgba(255,205,100,0.7)";
4139
+ * background: "rgba(255,205,100,0.7)";
4140
+ * background: "#ffcd64";
4141
+ * background: "rgba(255,255,255,0.4)";
4142
+ * background: "rgba(0,0,0,0.7)";
4143
+ * }
4144
+ */
4145
+ function rgba(firstValue, secondValue, thirdValue, fourthValue) {
4146
+ if (typeof firstValue === 'string' && typeof secondValue === 'number') {
4147
+ var rgbValue = parseToRgb(firstValue);
4148
+ return "rgba(" + rgbValue.red + "," + rgbValue.green + "," + rgbValue.blue + "," + secondValue + ")";
4149
+ } else if (typeof firstValue === 'number' && typeof secondValue === 'number' && typeof thirdValue === 'number' && typeof fourthValue === 'number') {
4150
+ return fourthValue >= 1 ? rgb(firstValue, secondValue, thirdValue) : "rgba(" + firstValue + "," + secondValue + "," + thirdValue + "," + fourthValue + ")";
4151
+ } else if (typeof firstValue === 'object' && secondValue === undefined && thirdValue === undefined && fourthValue === undefined) {
4152
+ return firstValue.alpha >= 1 ? rgb(firstValue.red, firstValue.green, firstValue.blue) : "rgba(" + firstValue.red + "," + firstValue.green + "," + firstValue.blue + "," + firstValue.alpha + ")";
4153
+ }
4154
+ throw new PolishedError(7);
4155
+ }
4156
+
4157
+ var isRgb = function isRgb(color) {
4158
+ return typeof color.red === 'number' && typeof color.green === 'number' && typeof color.blue === 'number' && (typeof color.alpha !== 'number' || typeof color.alpha === 'undefined');
4159
+ };
4160
+ var isRgba = function isRgba(color) {
4161
+ return typeof color.red === 'number' && typeof color.green === 'number' && typeof color.blue === 'number' && typeof color.alpha === 'number';
4162
+ };
4163
+ var isHsl = function isHsl(color) {
4164
+ return typeof color.hue === 'number' && typeof color.saturation === 'number' && typeof color.lightness === 'number' && (typeof color.alpha !== 'number' || typeof color.alpha === 'undefined');
4165
+ };
4166
+ var isHsla = function isHsla(color) {
4167
+ return typeof color.hue === 'number' && typeof color.saturation === 'number' && typeof color.lightness === 'number' && typeof color.alpha === 'number';
4168
+ };
4169
+
4170
+ /**
4171
+ * Converts a RgbColor, RgbaColor, HslColor or HslaColor object to a color string.
4172
+ * This util is useful in case you only know on runtime which color object is
4173
+ * used. Otherwise we recommend to rely on `rgb`, `rgba`, `hsl` or `hsla`.
4174
+ *
4175
+ * @example
4176
+ * // Styles as object usage
4177
+ * const styles = {
4178
+ * background: toColorString({ red: 255, green: 205, blue: 100 }),
4179
+ * background: toColorString({ red: 255, green: 205, blue: 100, alpha: 0.72 }),
4180
+ * background: toColorString({ hue: 240, saturation: 1, lightness: 0.5 }),
4181
+ * background: toColorString({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0.72 }),
4182
+ * }
4183
+ *
4184
+ * // styled-components usage
4185
+ * const div = styled.div`
4186
+ * background: ${toColorString({ red: 255, green: 205, blue: 100 })};
4187
+ * background: ${toColorString({ red: 255, green: 205, blue: 100, alpha: 0.72 })};
4188
+ * background: ${toColorString({ hue: 240, saturation: 1, lightness: 0.5 })};
4189
+ * background: ${toColorString({ hue: 360, saturation: 0.75, lightness: 0.4, alpha: 0.72 })};
4190
+ * `
4191
+ *
4192
+ * // CSS in JS Output
4193
+ * element {
4194
+ * background: "#ffcd64";
4195
+ * background: "rgba(255,205,100,0.72)";
4196
+ * background: "#00f";
4197
+ * background: "rgba(179,25,25,0.72)";
4198
+ * }
4199
+ */
4200
+
4201
+ function toColorString(color) {
4202
+ if (typeof color !== 'object') throw new PolishedError(8);
4203
+ if (isRgba(color)) return rgba(color);
4204
+ if (isRgb(color)) return rgb(color);
4205
+ if (isHsla(color)) return hsla(color);
4206
+ if (isHsl(color)) return hsl(color);
4207
+ throw new PolishedError(8);
4208
+ }
4209
+
4210
+ // Type definitions taken from https://github.com/gcanti/flow-static-land/blob/master/src/Fun.js
4211
+ // eslint-disable-next-line no-unused-vars
4212
+ // eslint-disable-next-line no-unused-vars
4213
+ // eslint-disable-next-line no-redeclare
4214
+ function curried(f, length, acc) {
4215
+ return function fn() {
4216
+ // eslint-disable-next-line prefer-rest-params
4217
+ var combined = acc.concat(Array.prototype.slice.call(arguments));
4218
+ return combined.length >= length ? f.apply(this, combined) : curried(f, length, combined);
4219
+ };
4220
+ }
4221
+
4222
+ // eslint-disable-next-line no-redeclare
4223
+ function curry(f) {
4224
+ // eslint-disable-line no-redeclare
4225
+ return curried(f, f.length, []);
4226
+ }
4227
+
4228
+ /**
4229
+ * Changes the hue of the color. Hue is a number between 0 to 360. The first
4230
+ * argument for adjustHue is the amount of degrees the color is rotated around
4231
+ * the color wheel, always producing a positive hue value.
4232
+ *
4233
+ * @example
4234
+ * // Styles as object usage
4235
+ * const styles = {
4236
+ * background: adjustHue(180, '#448'),
4237
+ * background: adjustHue('180', 'rgba(101,100,205,0.7)'),
4238
+ * }
4239
+ *
4240
+ * // styled-components usage
4241
+ * const div = styled.div`
4242
+ * background: ${adjustHue(180, '#448')};
4243
+ * background: ${adjustHue('180', 'rgba(101,100,205,0.7)')};
4244
+ * `
4245
+ *
4246
+ * // CSS in JS Output
4247
+ * element {
4248
+ * background: "#888844";
4249
+ * background: "rgba(136,136,68,0.7)";
4250
+ * }
4251
+ */
4252
+ function adjustHue(degree, color) {
4253
+ if (color === 'transparent') return color;
4254
+ var hslColor = parseToHsl(color);
4255
+ return toColorString(_extends({}, hslColor, {
4256
+ hue: hslColor.hue + parseFloat(degree)
4257
+ }));
4258
+ }
4259
+
4260
+ // prettier-ignore
4261
+ curry /* ::<number | string, string, string> */(adjustHue);
4262
+
4263
+ function guard(lowerBoundary, upperBoundary, value) {
4264
+ return Math.max(lowerBoundary, Math.min(upperBoundary, value));
4265
+ }
4266
+
4267
+ /**
4268
+ * Returns a string value for the darkened color.
4269
+ *
4270
+ * @example
4271
+ * // Styles as object usage
4272
+ * const styles = {
4273
+ * background: darken(0.2, '#FFCD64'),
4274
+ * background: darken('0.2', 'rgba(255,205,100,0.7)'),
4275
+ * }
4276
+ *
4277
+ * // styled-components usage
4278
+ * const div = styled.div`
4279
+ * background: ${darken(0.2, '#FFCD64')};
4280
+ * background: ${darken('0.2', 'rgba(255,205,100,0.7)')};
4281
+ * `
4282
+ *
4283
+ * // CSS in JS Output
4284
+ *
4285
+ * element {
4286
+ * background: "#ffbd31";
4287
+ * background: "rgba(255,189,49,0.7)";
4288
+ * }
4289
+ */
4290
+ function darken(amount, color) {
4291
+ if (color === 'transparent') return color;
4292
+ var hslColor = parseToHsl(color);
4293
+ return toColorString(_extends({}, hslColor, {
4294
+ lightness: guard(0, 1, hslColor.lightness - parseFloat(amount))
4295
+ }));
4296
+ }
4297
+
4298
+ // prettier-ignore
4299
+ curry /* ::<number | string, string, string> */(darken);
4300
+
4301
+ /**
4302
+ * Decreases the intensity of a color. Its range is between 0 to 1. The first
4303
+ * argument of the desaturate function is the amount by how much the color
4304
+ * intensity should be decreased.
4305
+ *
4306
+ * @example
4307
+ * // Styles as object usage
4308
+ * const styles = {
4309
+ * background: desaturate(0.2, '#CCCD64'),
4310
+ * background: desaturate('0.2', 'rgba(204,205,100,0.7)'),
4311
+ * }
4312
+ *
4313
+ * // styled-components usage
4314
+ * const div = styled.div`
4315
+ * background: ${desaturate(0.2, '#CCCD64')};
4316
+ * background: ${desaturate('0.2', 'rgba(204,205,100,0.7)')};
4317
+ * `
4318
+ *
4319
+ * // CSS in JS Output
4320
+ * element {
4321
+ * background: "#b8b979";
4322
+ * background: "rgba(184,185,121,0.7)";
4323
+ * }
4324
+ */
4325
+ function desaturate(amount, color) {
4326
+ if (color === 'transparent') return color;
4327
+ var hslColor = parseToHsl(color);
4328
+ return toColorString(_extends({}, hslColor, {
4329
+ saturation: guard(0, 1, hslColor.saturation - parseFloat(amount))
4330
+ }));
4331
+ }
4332
+
4333
+ // prettier-ignore
4334
+ curry /* ::<number | string, string, string> */(desaturate);
4335
+
4336
+ /**
4337
+ * Returns a string value for the lightened color.
4338
+ *
4339
+ * @example
4340
+ * // Styles as object usage
4341
+ * const styles = {
4342
+ * background: lighten(0.2, '#CCCD64'),
4343
+ * background: lighten('0.2', 'rgba(204,205,100,0.7)'),
4344
+ * }
4345
+ *
4346
+ * // styled-components usage
4347
+ * const div = styled.div`
4348
+ * background: ${lighten(0.2, '#FFCD64')};
4349
+ * background: ${lighten('0.2', 'rgba(204,205,100,0.7)')};
4350
+ * `
4351
+ *
4352
+ * // CSS in JS Output
4353
+ *
4354
+ * element {
4355
+ * background: "#e5e6b1";
4356
+ * background: "rgba(229,230,177,0.7)";
4357
+ * }
4358
+ */
4359
+ function lighten(amount, color) {
4360
+ if (color === 'transparent') return color;
4361
+ var hslColor = parseToHsl(color);
4362
+ return toColorString(_extends({}, hslColor, {
4363
+ lightness: guard(0, 1, hslColor.lightness + parseFloat(amount))
4364
+ }));
4365
+ }
4366
+
4367
+ // prettier-ignore
4368
+ curry /* ::<number | string, string, string> */(lighten);
4369
+
4370
+ /**
4371
+ * Mixes the two provided colors together by calculating the average of each of the RGB components weighted to the first color by the provided weight.
4372
+ *
4373
+ * @example
4374
+ * // Styles as object usage
4375
+ * const styles = {
4376
+ * background: mix(0.5, '#f00', '#00f')
4377
+ * background: mix(0.25, '#f00', '#00f')
4378
+ * background: mix('0.5', 'rgba(255, 0, 0, 0.5)', '#00f')
4379
+ * }
4380
+ *
4381
+ * // styled-components usage
4382
+ * const div = styled.div`
4383
+ * background: ${mix(0.5, '#f00', '#00f')};
4384
+ * background: ${mix(0.25, '#f00', '#00f')};
4385
+ * background: ${mix('0.5', 'rgba(255, 0, 0, 0.5)', '#00f')};
4386
+ * `
4387
+ *
4388
+ * // CSS in JS Output
4389
+ *
4390
+ * element {
4391
+ * background: "#7f007f";
4392
+ * background: "#3f00bf";
4393
+ * background: "rgba(63, 0, 191, 0.75)";
4394
+ * }
4395
+ */
4396
+ function mix(weight, color, otherColor) {
4397
+ if (color === 'transparent') return otherColor;
4398
+ if (otherColor === 'transparent') return color;
4399
+ if (weight === 0) return otherColor;
4400
+ var parsedColor1 = parseToRgb(color);
4401
+ var color1 = _extends({}, parsedColor1, {
4402
+ alpha: typeof parsedColor1.alpha === 'number' ? parsedColor1.alpha : 1
4403
+ });
4404
+ var parsedColor2 = parseToRgb(otherColor);
4405
+ var color2 = _extends({}, parsedColor2, {
4406
+ alpha: typeof parsedColor2.alpha === 'number' ? parsedColor2.alpha : 1
4407
+ });
4408
+
4409
+ // The formula is copied from the original Sass implementation:
4410
+ // http://sass-lang.com/documentation/Sass/Script/Functions.html#mix-instance_method
4411
+ var alphaDelta = color1.alpha - color2.alpha;
4412
+ var x = parseFloat(weight) * 2 - 1;
4413
+ var y = x * alphaDelta === -1 ? x : x + alphaDelta;
4414
+ var z = 1 + x * alphaDelta;
4415
+ var weight1 = (y / z + 1) / 2.0;
4416
+ var weight2 = 1 - weight1;
4417
+ var mixedColor = {
4418
+ red: Math.floor(color1.red * weight1 + color2.red * weight2),
4419
+ green: Math.floor(color1.green * weight1 + color2.green * weight2),
4420
+ blue: Math.floor(color1.blue * weight1 + color2.blue * weight2),
4421
+ alpha: color1.alpha * parseFloat(weight) + color2.alpha * (1 - parseFloat(weight))
4422
+ };
4423
+ return rgba(mixedColor);
4424
+ }
4425
+
4426
+ // prettier-ignore
4427
+ var curriedMix = curry /* ::<number | string, string, string, string> */(mix);
4428
+ var mix$1 = curriedMix;
4429
+
4430
+ /**
4431
+ * Increases the opacity of a color. Its range for the amount is between 0 to 1.
4432
+ *
4433
+ *
4434
+ * @example
4435
+ * // Styles as object usage
4436
+ * const styles = {
4437
+ * background: opacify(0.1, 'rgba(255, 255, 255, 0.9)');
4438
+ * background: opacify(0.2, 'hsla(0, 0%, 100%, 0.5)'),
4439
+ * background: opacify('0.5', 'rgba(255, 0, 0, 0.2)'),
4440
+ * }
4441
+ *
4442
+ * // styled-components usage
4443
+ * const div = styled.div`
4444
+ * background: ${opacify(0.1, 'rgba(255, 255, 255, 0.9)')};
4445
+ * background: ${opacify(0.2, 'hsla(0, 0%, 100%, 0.5)')},
4446
+ * background: ${opacify('0.5', 'rgba(255, 0, 0, 0.2)')},
4447
+ * `
4448
+ *
4449
+ * // CSS in JS Output
4450
+ *
4451
+ * element {
4452
+ * background: "#fff";
4453
+ * background: "rgba(255,255,255,0.7)";
4454
+ * background: "rgba(255,0,0,0.7)";
4455
+ * }
4456
+ */
4457
+ function opacify(amount, color) {
4458
+ if (color === 'transparent') return color;
4459
+ var parsedColor = parseToRgb(color);
4460
+ var alpha = typeof parsedColor.alpha === 'number' ? parsedColor.alpha : 1;
4461
+ var colorWithAlpha = _extends({}, parsedColor, {
4462
+ alpha: guard(0, 1, (alpha * 100 + parseFloat(amount) * 100) / 100)
4463
+ });
4464
+ return rgba(colorWithAlpha);
4465
+ }
4466
+
4467
+ // prettier-ignore
4468
+ var curriedOpacify = curry /* ::<number | string, string, string> */(opacify);
4469
+ var curriedOpacify$1 = curriedOpacify;
4470
+
4471
+ /**
4472
+ * Increases the intensity of a color. Its range is between 0 to 1. The first
4473
+ * argument of the saturate function is the amount by how much the color
4474
+ * intensity should be increased.
4475
+ *
4476
+ * @example
4477
+ * // Styles as object usage
4478
+ * const styles = {
4479
+ * background: saturate(0.2, '#CCCD64'),
4480
+ * background: saturate('0.2', 'rgba(204,205,100,0.7)'),
4481
+ * }
4482
+ *
4483
+ * // styled-components usage
4484
+ * const div = styled.div`
4485
+ * background: ${saturate(0.2, '#FFCD64')};
4486
+ * background: ${saturate('0.2', 'rgba(204,205,100,0.7)')};
4487
+ * `
4488
+ *
4489
+ * // CSS in JS Output
4490
+ *
4491
+ * element {
4492
+ * background: "#e0e250";
4493
+ * background: "rgba(224,226,80,0.7)";
4494
+ * }
4495
+ */
4496
+ function saturate(amount, color) {
4497
+ if (color === 'transparent') return color;
4498
+ var hslColor = parseToHsl(color);
4499
+ return toColorString(_extends({}, hslColor, {
4500
+ saturation: guard(0, 1, hslColor.saturation + parseFloat(amount))
4501
+ }));
4502
+ }
4503
+
4504
+ // prettier-ignore
4505
+ curry /* ::<number | string, string, string> */(saturate);
4506
+
4507
+ /**
4508
+ * Sets the hue of a color to the provided value. The hue range can be
4509
+ * from 0 and 359.
4510
+ *
4511
+ * @example
4512
+ * // Styles as object usage
4513
+ * const styles = {
4514
+ * background: setHue(42, '#CCCD64'),
4515
+ * background: setHue('244', 'rgba(204,205,100,0.7)'),
4516
+ * }
4517
+ *
4518
+ * // styled-components usage
4519
+ * const div = styled.div`
4520
+ * background: ${setHue(42, '#CCCD64')};
4521
+ * background: ${setHue('244', 'rgba(204,205,100,0.7)')};
4522
+ * `
4523
+ *
4524
+ * // CSS in JS Output
4525
+ * element {
4526
+ * background: "#cdae64";
4527
+ * background: "rgba(107,100,205,0.7)";
4528
+ * }
4529
+ */
4530
+ function setHue(hue, color) {
4531
+ if (color === 'transparent') return color;
4532
+ return toColorString(_extends({}, parseToHsl(color), {
4533
+ hue: parseFloat(hue)
4534
+ }));
4535
+ }
4536
+
4537
+ // prettier-ignore
4538
+ curry /* ::<number | string, string, string> */(setHue);
4539
+
4540
+ /**
4541
+ * Sets the lightness of a color to the provided value. The lightness range can be
4542
+ * from 0 and 1.
4543
+ *
4544
+ * @example
4545
+ * // Styles as object usage
4546
+ * const styles = {
4547
+ * background: setLightness(0.2, '#CCCD64'),
4548
+ * background: setLightness('0.75', 'rgba(204,205,100,0.7)'),
4549
+ * }
4550
+ *
4551
+ * // styled-components usage
4552
+ * const div = styled.div`
4553
+ * background: ${setLightness(0.2, '#CCCD64')};
4554
+ * background: ${setLightness('0.75', 'rgba(204,205,100,0.7)')};
4555
+ * `
4556
+ *
4557
+ * // CSS in JS Output
4558
+ * element {
4559
+ * background: "#4d4d19";
4560
+ * background: "rgba(223,224,159,0.7)";
4561
+ * }
4562
+ */
4563
+ function setLightness(lightness, color) {
4564
+ if (color === 'transparent') return color;
4565
+ return toColorString(_extends({}, parseToHsl(color), {
4566
+ lightness: parseFloat(lightness)
4567
+ }));
4568
+ }
4569
+
4570
+ // prettier-ignore
4571
+ curry /* ::<number | string, string, string> */(setLightness);
4572
+
4573
+ /**
4574
+ * Sets the saturation of a color to the provided value. The saturation range can be
4575
+ * from 0 and 1.
4576
+ *
4577
+ * @example
4578
+ * // Styles as object usage
4579
+ * const styles = {
4580
+ * background: setSaturation(0.2, '#CCCD64'),
4581
+ * background: setSaturation('0.75', 'rgba(204,205,100,0.7)'),
4582
+ * }
4583
+ *
4584
+ * // styled-components usage
4585
+ * const div = styled.div`
4586
+ * background: ${setSaturation(0.2, '#CCCD64')};
4587
+ * background: ${setSaturation('0.75', 'rgba(204,205,100,0.7)')};
4588
+ * `
4589
+ *
4590
+ * // CSS in JS Output
4591
+ * element {
4592
+ * background: "#adad84";
4593
+ * background: "rgba(228,229,76,0.7)";
4594
+ * }
4595
+ */
4596
+ function setSaturation(saturation, color) {
4597
+ if (color === 'transparent') return color;
4598
+ return toColorString(_extends({}, parseToHsl(color), {
4599
+ saturation: parseFloat(saturation)
4600
+ }));
4601
+ }
4602
+
4603
+ // prettier-ignore
4604
+ curry /* ::<number | string, string, string> */(setSaturation);
4605
+
4606
+ /**
4607
+ * Shades a color by mixing it with black. `shade` can produce
4608
+ * hue shifts, where as `darken` manipulates the luminance channel and therefore
4609
+ * doesn't produce hue shifts.
4610
+ *
4611
+ * @example
4612
+ * // Styles as object usage
4613
+ * const styles = {
4614
+ * background: shade(0.25, '#00f')
4615
+ * }
4616
+ *
4617
+ * // styled-components usage
4618
+ * const div = styled.div`
4619
+ * background: ${shade(0.25, '#00f')};
4620
+ * `
4621
+ *
4622
+ * // CSS in JS Output
4623
+ *
4624
+ * element {
4625
+ * background: "#00003f";
4626
+ * }
4627
+ */
4628
+
4629
+ function shade(percentage, color) {
4630
+ if (color === 'transparent') return color;
4631
+ return mix$1(parseFloat(percentage), 'rgb(0, 0, 0)', color);
4632
+ }
4633
+
4634
+ // prettier-ignore
4635
+ curry /* ::<number | string, string, string> */(shade);
4636
+
4637
+ /**
4638
+ * Tints a color by mixing it with white. `tint` can produce
4639
+ * hue shifts, where as `lighten` manipulates the luminance channel and therefore
4640
+ * doesn't produce hue shifts.
3718
4641
  *
3719
4642
  * @example
3720
4643
  * // Styles as object usage
3721
4644
  * const styles = {
3722
- * background: rgba(255, 205, 100, 0.7),
3723
- * background: rgba({ red: 255, green: 205, blue: 100, alpha: 0.7 }),
3724
- * background: rgba(255, 205, 100, 1),
3725
- * background: rgba('#ffffff', 0.4),
3726
- * background: rgba('black', 0.7),
4645
+ * background: tint(0.25, '#00f')
3727
4646
  * }
3728
4647
  *
3729
4648
  * // styled-components usage
3730
4649
  * const div = styled.div`
3731
- * background: ${rgba(255, 205, 100, 0.7)};
3732
- * background: ${rgba({ red: 255, green: 205, blue: 100, alpha: 0.7 })};
3733
- * background: ${rgba(255, 205, 100, 1)};
3734
- * background: ${rgba('#ffffff', 0.4)};
3735
- * background: ${rgba('black', 0.7)};
4650
+ * background: ${tint(0.25, '#00f')};
3736
4651
  * `
3737
4652
  *
3738
4653
  * // CSS in JS Output
3739
4654
  *
3740
4655
  * element {
3741
- * background: "rgba(255,205,100,0.7)";
3742
- * background: "rgba(255,205,100,0.7)";
3743
- * background: "#ffcd64";
3744
- * background: "rgba(255,255,255,0.4)";
3745
- * background: "rgba(0,0,0,0.7)";
4656
+ * background: "#bfbfff";
3746
4657
  * }
3747
4658
  */
3748
- function rgba(firstValue, secondValue, thirdValue, fourthValue) {
3749
- if (typeof firstValue === 'string' && typeof secondValue === 'number') {
3750
- var rgbValue = parseToRgb(firstValue);
3751
- return "rgba(" + rgbValue.red + "," + rgbValue.green + "," + rgbValue.blue + "," + secondValue + ")";
3752
- } else if (typeof firstValue === 'number' && typeof secondValue === 'number' && typeof thirdValue === 'number' && typeof fourthValue === 'number') {
3753
- return fourthValue >= 1 ? rgb(firstValue, secondValue, thirdValue) : "rgba(" + firstValue + "," + secondValue + "," + thirdValue + "," + fourthValue + ")";
3754
- } else if (typeof firstValue === 'object' && secondValue === undefined && thirdValue === undefined && fourthValue === undefined) {
3755
- return firstValue.alpha >= 1 ? rgb(firstValue.red, firstValue.green, firstValue.blue) : "rgba(" + firstValue.red + "," + firstValue.green + "," + firstValue.blue + "," + firstValue.alpha + ")";
3756
- }
3757
-
3758
- throw new PolishedError(7);
3759
- }
3760
-
3761
- // Type definitions taken from https://github.com/gcanti/flow-static-land/blob/master/src/Fun.js
3762
- // eslint-disable-next-line no-unused-vars
3763
- // eslint-disable-next-line no-unused-vars
3764
- // eslint-disable-next-line no-redeclare
3765
- function curried(f, length, acc) {
3766
- return function fn() {
3767
- // eslint-disable-next-line prefer-rest-params
3768
- var combined = acc.concat(Array.prototype.slice.call(arguments));
3769
- return combined.length >= length ? f.apply(this, combined) : curried(f, length, combined);
3770
- };
3771
- } // eslint-disable-next-line no-redeclare
3772
-
3773
4659
 
3774
- function curry(f) {
3775
- // eslint-disable-line no-redeclare
3776
- return curried(f, f.length, []);
4660
+ function tint(percentage, color) {
4661
+ if (color === 'transparent') return color;
4662
+ return mix$1(parseFloat(percentage), 'rgb(255, 255, 255)', color);
3777
4663
  }
3778
4664
 
3779
- function guard(lowerBoundary, upperBoundary, value) {
3780
- return Math.max(lowerBoundary, Math.min(upperBoundary, value));
3781
- }
4665
+ // prettier-ignore
4666
+ curry /* ::<number | string, string, string> */(tint);
3782
4667
 
3783
4668
  /**
3784
- * Increases the opacity of a color. Its range for the amount is between 0 to 1.
4669
+ * Decreases the opacity of a color. Its range for the amount is between 0 to 1.
3785
4670
  *
3786
4671
  *
3787
4672
  * @example
3788
4673
  * // Styles as object usage
3789
4674
  * const styles = {
3790
- * background: opacify(0.1, 'rgba(255, 255, 255, 0.9)');
3791
- * background: opacify(0.2, 'hsla(0, 0%, 100%, 0.5)'),
3792
- * background: opacify('0.5', 'rgba(255, 0, 0, 0.2)'),
4675
+ * background: transparentize(0.1, '#fff'),
4676
+ * background: transparentize(0.2, 'hsl(0, 0%, 100%)'),
4677
+ * background: transparentize('0.5', 'rgba(255, 0, 0, 0.8)'),
3793
4678
  * }
3794
4679
  *
3795
4680
  * // styled-components usage
3796
4681
  * const div = styled.div`
3797
- * background: ${opacify(0.1, 'rgba(255, 255, 255, 0.9)')};
3798
- * background: ${opacify(0.2, 'hsla(0, 0%, 100%, 0.5)')},
3799
- * background: ${opacify('0.5', 'rgba(255, 0, 0, 0.2)')},
4682
+ * background: ${transparentize(0.1, '#fff')};
4683
+ * background: ${transparentize(0.2, 'hsl(0, 0%, 100%)')};
4684
+ * background: ${transparentize('0.5', 'rgba(255, 0, 0, 0.8)')};
3800
4685
  * `
3801
4686
  *
3802
4687
  * // CSS in JS Output
3803
4688
  *
3804
4689
  * element {
3805
- * background: "#fff";
3806
- * background: "rgba(255,255,255,0.7)";
3807
- * background: "rgba(255,0,0,0.7)";
4690
+ * background: "rgba(255,255,255,0.9)";
4691
+ * background: "rgba(255,255,255,0.8)";
4692
+ * background: "rgba(255,0,0,0.3)";
3808
4693
  * }
3809
4694
  */
3810
-
3811
- function opacify(amount, color) {
4695
+ function transparentize(amount, color) {
3812
4696
  if (color === 'transparent') return color;
3813
4697
  var parsedColor = parseToRgb(color);
3814
4698
  var alpha = typeof parsedColor.alpha === 'number' ? parsedColor.alpha : 1;
3815
-
3816
4699
  var colorWithAlpha = _extends({}, parsedColor, {
3817
- alpha: guard(0, 1, (alpha * 100 + parseFloat(amount) * 100) / 100)
4700
+ alpha: guard(0, 1, +(alpha * 100 - parseFloat(amount) * 100).toFixed(2) / 100)
3818
4701
  });
3819
-
3820
4702
  return rgba(colorWithAlpha);
3821
- } // prettier-ignore
3822
-
4703
+ }
3823
4704
 
3824
- var curriedOpacify = /*#__PURE__*/curry
3825
- /* ::<number | string, string, string> */
3826
- (opacify);
3827
- var curriedOpacify$1 = curriedOpacify;
4705
+ // prettier-ignore
4706
+ curry /* ::<number | string, string, string> */(transparentize);
3828
4707
 
3829
4708
  /**
3830
4709
  * The Ease class provides a collection of easing functions for use with tween.js.
@@ -4041,7 +4920,7 @@
4041
4920
  },
4042
4921
  });
4043
4922
 
4044
- var now$2 = function () { return performance.now(); };
4923
+ var now$1 = function () { return performance.now(); };
4045
4924
 
4046
4925
  /**
4047
4926
  * Controlling groups of tweens
@@ -4072,7 +4951,7 @@
4072
4951
  delete this._tweensAddedDuringUpdate[tween.getId()];
4073
4952
  };
4074
4953
  Group.prototype.update = function (time, preserve) {
4075
- if (time === void 0) { time = now$2(); }
4954
+ if (time === void 0) { time = now$1(); }
4076
4955
  if (preserve === void 0) { preserve = false; }
4077
4956
  var tweenIds = Object.keys(this._tweens);
4078
4957
  if (tweenIds.length === 0) {
@@ -4241,18 +5120,21 @@
4241
5120
  Tween.prototype.isPaused = function () {
4242
5121
  return this._isPaused;
4243
5122
  };
5123
+ Tween.prototype.getDuration = function () {
5124
+ return this._duration;
5125
+ };
4244
5126
  Tween.prototype.to = function (target, duration) {
4245
5127
  if (duration === void 0) { duration = 1000; }
4246
5128
  if (this._isPlaying)
4247
5129
  throw new Error('Can not call Tween.to() while Tween is already started or paused. Stop the Tween first.');
4248
5130
  this._valuesEnd = target;
4249
5131
  this._propertiesAreSetUp = false;
4250
- this._duration = duration;
5132
+ this._duration = duration < 0 ? 0 : duration;
4251
5133
  return this;
4252
5134
  };
4253
5135
  Tween.prototype.duration = function (duration) {
4254
5136
  if (duration === void 0) { duration = 1000; }
4255
- this._duration = duration;
5137
+ this._duration = duration < 0 ? 0 : duration;
4256
5138
  return this;
4257
5139
  };
4258
5140
  Tween.prototype.dynamic = function (dynamic) {
@@ -4261,7 +5143,7 @@
4261
5143
  return this;
4262
5144
  };
4263
5145
  Tween.prototype.start = function (time, overrideStartingValues) {
4264
- if (time === void 0) { time = now$2(); }
5146
+ if (time === void 0) { time = now$1(); }
4265
5147
  if (overrideStartingValues === void 0) { overrideStartingValues = false; }
4266
5148
  if (this._isPlaying) {
4267
5149
  return this;
@@ -4399,7 +5281,7 @@
4399
5281
  return this;
4400
5282
  };
4401
5283
  Tween.prototype.pause = function (time) {
4402
- if (time === void 0) { time = now$2(); }
5284
+ if (time === void 0) { time = now$1(); }
4403
5285
  if (this._isPaused || !this._isPlaying) {
4404
5286
  return this;
4405
5287
  }
@@ -4410,7 +5292,7 @@
4410
5292
  return this;
4411
5293
  };
4412
5294
  Tween.prototype.resume = function (time) {
4413
- if (time === void 0) { time = now$2(); }
5295
+ if (time === void 0) { time = now$1(); }
4414
5296
  if (!this._isPaused || !this._isPlaying) {
4415
5297
  return this;
4416
5298
  }
@@ -4501,12 +5383,13 @@
4501
5383
  * it is still playing, just paused).
4502
5384
  */
4503
5385
  Tween.prototype.update = function (time, autoStart) {
4504
- if (time === void 0) { time = now$2(); }
5386
+ var _this = this;
5387
+ var _a;
5388
+ if (time === void 0) { time = now$1(); }
4505
5389
  if (autoStart === void 0) { autoStart = true; }
4506
5390
  if (this._isPaused)
4507
5391
  return true;
4508
5392
  var property;
4509
- var elapsed;
4510
5393
  var endTime = this._startTime + this._duration;
4511
5394
  if (!this._goToEnd && !this._isPlaying) {
4512
5395
  if (time > endTime)
@@ -4530,18 +5413,37 @@
4530
5413
  }
4531
5414
  this._onEveryStartCallbackFired = true;
4532
5415
  }
4533
- elapsed = (time - this._startTime) / this._duration;
4534
- elapsed = this._duration === 0 || elapsed > 1 ? 1 : elapsed;
5416
+ var elapsedTime = time - this._startTime;
5417
+ var durationAndDelay = this._duration + ((_a = this._repeatDelayTime) !== null && _a !== void 0 ? _a : this._delayTime);
5418
+ var totalTime = this._duration + this._repeat * durationAndDelay;
5419
+ var calculateElapsedPortion = function () {
5420
+ if (_this._duration === 0)
5421
+ return 1;
5422
+ if (elapsedTime > totalTime) {
5423
+ return 1;
5424
+ }
5425
+ var timesRepeated = Math.trunc(elapsedTime / durationAndDelay);
5426
+ var timeIntoCurrentRepeat = elapsedTime - timesRepeated * durationAndDelay;
5427
+ // TODO use %?
5428
+ // const timeIntoCurrentRepeat = elapsedTime % durationAndDelay
5429
+ var portion = Math.min(timeIntoCurrentRepeat / _this._duration, 1);
5430
+ if (portion === 0 && elapsedTime === _this._duration) {
5431
+ return 1;
5432
+ }
5433
+ return portion;
5434
+ };
5435
+ var elapsed = calculateElapsedPortion();
4535
5436
  var value = this._easingFunction(elapsed);
4536
5437
  // properties transformations
4537
5438
  this._updateProperties(this._object, this._valuesStart, this._valuesEnd, value);
4538
5439
  if (this._onUpdateCallback) {
4539
5440
  this._onUpdateCallback(this._object, elapsed);
4540
5441
  }
4541
- if (elapsed === 1) {
5442
+ if (this._duration === 0 || elapsedTime >= this._duration) {
4542
5443
  if (this._repeat > 0) {
5444
+ var completeCount = Math.min(Math.trunc((elapsedTime - this._duration) / durationAndDelay) + 1, this._repeat);
4543
5445
  if (isFinite(this._repeat)) {
4544
- this._repeat--;
5446
+ this._repeat -= completeCount;
4545
5447
  }
4546
5448
  // Reassign starting values, restart by making startTime = now
4547
5449
  for (property in this._valuesStartRepeat) {
@@ -4559,12 +5461,7 @@
4559
5461
  if (this._yoyo) {
4560
5462
  this._reversed = !this._reversed;
4561
5463
  }
4562
- if (this._repeatDelayTime !== undefined) {
4563
- this._startTime = time + this._repeatDelayTime;
4564
- }
4565
- else {
4566
- this._startTime = time + this._delayTime;
4567
- }
5464
+ this._startTime += durationAndDelay * completeCount;
4568
5465
  if (this._onRepeatCallback) {
4569
5466
  this._onRepeatCallback(this._object);
4570
5467
  }
@@ -4666,23 +5563,101 @@
4666
5563
  };
4667
5564
  }); // constant
4668
5565
 
5566
+ /**
5567
+ * Checks if `value` is the
5568
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
5569
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
5570
+ *
5571
+ * @static
5572
+ * @memberOf _
5573
+ * @since 0.1.0
5574
+ * @category Lang
5575
+ * @param {*} value The value to check.
5576
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
5577
+ * @example
5578
+ *
5579
+ * _.isObject({});
5580
+ * // => true
5581
+ *
5582
+ * _.isObject([1, 2, 3]);
5583
+ * // => true
5584
+ *
5585
+ * _.isObject(_.noop);
5586
+ * // => true
5587
+ *
5588
+ * _.isObject(null);
5589
+ * // => false
5590
+ */
5591
+ function isObject(value) {
5592
+ var type = typeof value;
5593
+ return value != null && (type == 'object' || type == 'function');
5594
+ }
5595
+
4669
5596
  /** Detect free variable `global` from Node.js. */
4670
5597
  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
4671
5598
 
4672
- var freeGlobal$1 = freeGlobal;
4673
-
4674
5599
  /** Detect free variable `self`. */
4675
5600
  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
4676
5601
 
4677
5602
  /** Used as a reference to the global object. */
4678
- var root = freeGlobal$1 || freeSelf || Function('return this')();
5603
+ var root = freeGlobal || freeSelf || Function('return this')();
4679
5604
 
4680
- var root$1 = root;
5605
+ /**
5606
+ * Gets the timestamp of the number of milliseconds that have elapsed since
5607
+ * the Unix epoch (1 January 1970 00:00:00 UTC).
5608
+ *
5609
+ * @static
5610
+ * @memberOf _
5611
+ * @since 2.4.0
5612
+ * @category Date
5613
+ * @returns {number} Returns the timestamp.
5614
+ * @example
5615
+ *
5616
+ * _.defer(function(stamp) {
5617
+ * console.log(_.now() - stamp);
5618
+ * }, _.now());
5619
+ * // => Logs the number of milliseconds it took for the deferred invocation.
5620
+ */
5621
+ var now = function() {
5622
+ return root.Date.now();
5623
+ };
4681
5624
 
4682
- /** Built-in value references. */
4683
- var Symbol$1 = root$1.Symbol;
5625
+ /** Used to match a single whitespace character. */
5626
+ var reWhitespace = /\s/;
5627
+
5628
+ /**
5629
+ * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
5630
+ * character of `string`.
5631
+ *
5632
+ * @private
5633
+ * @param {string} string The string to inspect.
5634
+ * @returns {number} Returns the index of the last non-whitespace character.
5635
+ */
5636
+ function trimmedEndIndex(string) {
5637
+ var index = string.length;
5638
+
5639
+ while (index-- && reWhitespace.test(string.charAt(index))) {}
5640
+ return index;
5641
+ }
5642
+
5643
+ /** Used to match leading whitespace. */
5644
+ var reTrimStart = /^\s+/;
5645
+
5646
+ /**
5647
+ * The base implementation of `_.trim`.
5648
+ *
5649
+ * @private
5650
+ * @param {string} string The string to trim.
5651
+ * @returns {string} Returns the trimmed string.
5652
+ */
5653
+ function baseTrim(string) {
5654
+ return string
5655
+ ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
5656
+ : string;
5657
+ }
4684
5658
 
4685
- var Symbol$2 = Symbol$1;
5659
+ /** Built-in value references. */
5660
+ var Symbol$1 = root.Symbol;
4686
5661
 
4687
5662
  /** Used for built-in method references. */
4688
5663
  var objectProto$1 = Object.prototype;
@@ -4698,7 +5673,7 @@
4698
5673
  var nativeObjectToString$1 = objectProto$1.toString;
4699
5674
 
4700
5675
  /** Built-in value references. */
4701
- var symToStringTag$1 = Symbol$2 ? Symbol$2.toStringTag : undefined;
5676
+ var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
4702
5677
 
4703
5678
  /**
4704
5679
  * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
@@ -4753,7 +5728,7 @@
4753
5728
  undefinedTag = '[object Undefined]';
4754
5729
 
4755
5730
  /** Built-in value references. */
4756
- var symToStringTag = Symbol$2 ? Symbol$2.toStringTag : undefined;
5731
+ var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined;
4757
5732
 
4758
5733
  /**
4759
5734
  * The base implementation of `getTag` without fallbacks for buggy environments.
@@ -4824,70 +5799,6 @@
4824
5799
  (isObjectLike(value) && baseGetTag(value) == symbolTag);
4825
5800
  }
4826
5801
 
4827
- /** Used to match a single whitespace character. */
4828
- var reWhitespace = /\s/;
4829
-
4830
- /**
4831
- * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
4832
- * character of `string`.
4833
- *
4834
- * @private
4835
- * @param {string} string The string to inspect.
4836
- * @returns {number} Returns the index of the last non-whitespace character.
4837
- */
4838
- function trimmedEndIndex(string) {
4839
- var index = string.length;
4840
-
4841
- while (index-- && reWhitespace.test(string.charAt(index))) {}
4842
- return index;
4843
- }
4844
-
4845
- /** Used to match leading whitespace. */
4846
- var reTrimStart = /^\s+/;
4847
-
4848
- /**
4849
- * The base implementation of `_.trim`.
4850
- *
4851
- * @private
4852
- * @param {string} string The string to trim.
4853
- * @returns {string} Returns the trimmed string.
4854
- */
4855
- function baseTrim(string) {
4856
- return string
4857
- ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
4858
- : string;
4859
- }
4860
-
4861
- /**
4862
- * Checks if `value` is the
4863
- * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
4864
- * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
4865
- *
4866
- * @static
4867
- * @memberOf _
4868
- * @since 0.1.0
4869
- * @category Lang
4870
- * @param {*} value The value to check.
4871
- * @returns {boolean} Returns `true` if `value` is an object, else `false`.
4872
- * @example
4873
- *
4874
- * _.isObject({});
4875
- * // => true
4876
- *
4877
- * _.isObject([1, 2, 3]);
4878
- * // => true
4879
- *
4880
- * _.isObject(_.noop);
4881
- * // => true
4882
- *
4883
- * _.isObject(null);
4884
- * // => false
4885
- */
4886
- function isObject(value) {
4887
- var type = typeof value;
4888
- return value != null && (type == 'object' || type == 'function');
4889
- }
4890
-
4891
5802
  /** Used as references for various `Number` constants. */
4892
5803
  var NAN = 0 / 0;
4893
5804
 
@@ -4947,28 +5858,6 @@
4947
5858
  : (reIsBadHex.test(value) ? NAN : +value);
4948
5859
  }
4949
5860
 
4950
- /**
4951
- * Gets the timestamp of the number of milliseconds that have elapsed since
4952
- * the Unix epoch (1 January 1970 00:00:00 UTC).
4953
- *
4954
- * @static
4955
- * @memberOf _
4956
- * @since 2.4.0
4957
- * @category Date
4958
- * @returns {number} Returns the timestamp.
4959
- * @example
4960
- *
4961
- * _.defer(function(stamp) {
4962
- * console.log(_.now() - stamp);
4963
- * }, _.now());
4964
- * // => Logs the number of milliseconds it took for the deferred invocation.
4965
- */
4966
- var now = function() {
4967
- return root$1.Date.now();
4968
- };
4969
-
4970
- var now$1 = now;
4971
-
4972
5861
  /** Error message constants. */
4973
5862
  var FUNC_ERROR_TEXT = 'Expected a function';
4974
5863
 
@@ -5094,7 +5983,7 @@
5094
5983
  }
5095
5984
 
5096
5985
  function timerExpired() {
5097
- var time = now$1();
5986
+ var time = now();
5098
5987
  if (shouldInvoke(time)) {
5099
5988
  return trailingEdge(time);
5100
5989
  }
@@ -5123,11 +6012,11 @@
5123
6012
  }
5124
6013
 
5125
6014
  function flush() {
5126
- return timerId === undefined ? result : trailingEdge(now$1());
6015
+ return timerId === undefined ? result : trailingEdge(now());
5127
6016
  }
5128
6017
 
5129
6018
  function debounced() {
5130
- var time = now$1(),
6019
+ var time = now(),
5131
6020
  isInvoking = shouldInvoke(time);
5132
6021
 
5133
6022
  lastArgs = arguments;
@@ -5155,31 +6044,31 @@
5155
6044
  return debounced;
5156
6045
  }
5157
6046
 
5158
- function _iterableToArrayLimit(arr, i) {
5159
- var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"];
5160
- if (null != _i) {
5161
- var _s,
5162
- _e,
5163
- _x,
5164
- _r,
5165
- _arr = [],
5166
- _n = !0,
5167
- _d = !1;
6047
+ function _iterableToArrayLimit(r, l) {
6048
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
6049
+ if (null != t) {
6050
+ var e,
6051
+ n,
6052
+ i,
6053
+ u,
6054
+ a = [],
6055
+ f = !0,
6056
+ o = !1;
5168
6057
  try {
5169
- if (_x = (_i = _i.call(arr)).next, 0 === i) {
5170
- if (Object(_i) !== _i) return;
5171
- _n = !1;
5172
- } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0);
5173
- } catch (err) {
5174
- _d = !0, _e = err;
6058
+ if (i = (t = t.call(r)).next, 0 === l) {
6059
+ if (Object(t) !== t) return;
6060
+ f = !1;
6061
+ } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
6062
+ } catch (r) {
6063
+ o = !0, n = r;
5175
6064
  } finally {
5176
6065
  try {
5177
- if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return;
6066
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
5178
6067
  } finally {
5179
- if (_d) throw _e;
6068
+ if (o) throw n;
5180
6069
  }
5181
6070
  }
5182
- return _arr;
6071
+ return a;
5183
6072
  }
5184
6073
  }
5185
6074
  function _classCallCheck(instance, Constructor) {
@@ -5420,6 +6309,9 @@
5420
6309
  objects: {
5421
6310
  "default": []
5422
6311
  },
6312
+ lights: {
6313
+ "default": []
6314
+ },
5423
6315
  enablePointerInteraction: {
5424
6316
  "default": true,
5425
6317
  onChange: function onChange(_, state) {
@@ -5501,7 +6393,6 @@
5501
6393
  }
5502
6394
  update(); // update camera animation tweens
5503
6395
  }
5504
-
5505
6396
  return this;
5506
6397
  },
5507
6398
  getPointerPos: function getPointerPos(state) {
@@ -5563,7 +6454,6 @@
5563
6454
  camera.lookAt(lookAtVect); // note: lookAt may be overridden by other controls in some cases
5564
6455
  }
5565
6456
  }
5566
-
5567
6457
  function getLookAt() {
5568
6458
  return Object.assign(new three.Vector3(0, 0, -1000).applyQuaternion(camera.quaternion).add(camera.position));
5569
6459
  }
@@ -5662,7 +6552,6 @@
5662
6552
  return state.controls;
5663
6553
  } // to be deprecated
5664
6554
  },
5665
-
5666
6555
  stateInit: function stateInit() {
5667
6556
  return {
5668
6557
  scene: new three.Scene(),
@@ -5753,14 +6642,12 @@
5753
6642
  state.isPointerDragging = false;
5754
6643
  if (!state.clickAfterDrag) return; // don't trigger onClick after pointer drag (camera motion via controls)
5755
6644
  }
5756
-
5757
6645
  requestAnimationFrame(function () {
5758
6646
  // trigger click events asynchronously, to allow hoverObj to be set (on frame)
5759
6647
  if (ev.button === 0) {
5760
6648
  // left-click
5761
6649
  state.onClick(state.hoverObj || null, ev, state.intersectionPoint); // trigger background clicks with null
5762
6650
  }
5763
-
5764
6651
  if (ev.button === 2 && state.onRightClick) {
5765
6652
  // right-click
5766
6653
  state.onRightClick(state.hoverObj || null, ev, state.intersectionPoint);
@@ -5880,6 +6767,14 @@
5880
6767
  }
5881
6768
  }
5882
6769
  changedProps.hasOwnProperty('showNavInfo') && (state.navInfo.style.display = state.showNavInfo ? null : 'none');
6770
+ if (changedProps.hasOwnProperty('lights')) {
6771
+ (changedProps.lights || []).forEach(function (light) {
6772
+ return state.scene.remove(light);
6773
+ }); // Clear the place
6774
+ state.lights.forEach(function (light) {
6775
+ return state.scene.add(light);
6776
+ }); // Add to scene
6777
+ }
5883
6778
  if (changedProps.hasOwnProperty('objects')) {
5884
6779
  (changedProps.objects || []).forEach(function (obj) {
5885
6780
  return state.scene.remove(obj);