plotboilerplate 1.12.9 → 1.15.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 (113) hide show
  1. package/README.md +5 -1
  2. package/changelog.md +34 -0
  3. package/dist/index.esm.js +435 -92
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.esm.min.js +1 -1
  6. package/dist/index.esm.min.js.map +1 -1
  7. package/dist/plotboilerplate.browser.min.js +1 -1
  8. package/dist/plotboilerplate.browser.min.js.map +1 -1
  9. package/dist/plotboilerplate.js +449 -91
  10. package/dist/plotboilerplate.min.js +1 -1
  11. package/package.json +1 -1
  12. package/src/cjs/BezierPath.d.ts +12 -1
  13. package/src/cjs/BezierPath.js +34 -5
  14. package/src/cjs/BezierPath.js.map +1 -1
  15. package/src/cjs/PBText.d.ts +116 -0
  16. package/src/cjs/PBText.js +66 -0
  17. package/src/cjs/PBText.js.map +1 -0
  18. package/src/cjs/PlotBoilerplate.d.ts +2 -1
  19. package/src/cjs/PlotBoilerplate.js +43 -15
  20. package/src/cjs/PlotBoilerplate.js.map +1 -1
  21. package/src/cjs/Polygon.d.ts +22 -1
  22. package/src/cjs/Polygon.js +102 -39
  23. package/src/cjs/Polygon.js.map +1 -1
  24. package/src/cjs/Vertex.d.ts +42 -4
  25. package/src/cjs/Vertex.js +62 -7
  26. package/src/cjs/Vertex.js.map +1 -1
  27. package/src/cjs/draw.d.ts +30 -2
  28. package/src/cjs/draw.js +51 -6
  29. package/src/cjs/draw.js.map +1 -1
  30. package/src/cjs/drawgl.d.ts +29 -2
  31. package/src/cjs/drawgl.js +21 -4
  32. package/src/cjs/drawgl.js.map +1 -1
  33. package/src/cjs/drawutilssvg.d.ts +25 -7
  34. package/src/cjs/drawutilssvg.js +62 -14
  35. package/src/cjs/drawutilssvg.js.map +1 -1
  36. package/src/cjs/entry.js +1 -0
  37. package/src/cjs/index.d.ts +1 -0
  38. package/src/cjs/index.js +1 -0
  39. package/src/cjs/index.js.map +1 -1
  40. package/src/cjs/interfaces/DrawLib.d.ts +27 -6
  41. package/src/cjs/interfaces/DrawLib.js +3 -0
  42. package/src/cjs/interfaces/DrawLib.js.map +1 -1
  43. package/src/cjs/interfaces/core.d.ts +9 -1
  44. package/src/cjs/interfaces/core.js +1 -0
  45. package/src/cjs/interfaces/core.js.map +1 -1
  46. package/src/cjs/utils/datastructures/Color.d.ts +28 -15
  47. package/src/cjs/utils/datastructures/Color.js +276 -88
  48. package/src/cjs/utils/datastructures/Color.js.map +1 -1
  49. package/src/cjs/utils/findInVertexArray.d.ts +19 -0
  50. package/src/cjs/utils/findInVertexArray.js +29 -0
  51. package/src/cjs/utils/findInVertexArray.js.map +1 -0
  52. package/src/esm/BezierPath.d.ts +12 -1
  53. package/src/esm/BezierPath.js +34 -5
  54. package/src/esm/BezierPath.js.map +1 -1
  55. package/src/esm/PBText.d.ts +116 -0
  56. package/src/esm/PBText.js +61 -0
  57. package/src/esm/PBText.js.map +1 -0
  58. package/src/esm/PlotBoilerplate.d.ts +2 -1
  59. package/src/esm/PlotBoilerplate.js +43 -15
  60. package/src/esm/PlotBoilerplate.js.map +1 -1
  61. package/src/esm/Polygon.d.ts +22 -1
  62. package/src/esm/Polygon.js +102 -39
  63. package/src/esm/Polygon.js.map +1 -1
  64. package/src/esm/Vertex.d.ts +42 -4
  65. package/src/esm/Vertex.js +62 -7
  66. package/src/esm/Vertex.js.map +1 -1
  67. package/src/esm/draw.d.ts +30 -2
  68. package/src/esm/draw.js +51 -6
  69. package/src/esm/draw.js.map +1 -1
  70. package/src/esm/drawgl.d.ts +29 -2
  71. package/src/esm/drawgl.js +21 -4
  72. package/src/esm/drawgl.js.map +1 -1
  73. package/src/esm/drawutilssvg.d.ts +25 -7
  74. package/src/esm/drawutilssvg.js +62 -14
  75. package/src/esm/drawutilssvg.js.map +1 -1
  76. package/src/esm/entry.js +1 -0
  77. package/src/esm/index.d.ts +1 -0
  78. package/src/esm/index.js +1 -0
  79. package/src/esm/index.js.map +1 -1
  80. package/src/esm/interfaces/DrawLib.d.ts +27 -6
  81. package/src/esm/interfaces/DrawLib.js +3 -0
  82. package/src/esm/interfaces/DrawLib.js.map +1 -1
  83. package/src/esm/interfaces/core.d.ts +9 -1
  84. package/src/esm/interfaces/core.js +1 -0
  85. package/src/esm/interfaces/core.js.map +1 -1
  86. package/src/esm/utils/datastructures/Color.d.ts +28 -15
  87. package/src/esm/utils/datastructures/Color.js +277 -89
  88. package/src/esm/utils/datastructures/Color.js.map +1 -1
  89. package/src/esm/utils/findInVertexArray.d.ts +19 -0
  90. package/src/esm/utils/findInVertexArray.js +25 -0
  91. package/src/esm/utils/findInVertexArray.js.map +1 -0
  92. package/src/ts/BezierPath.ts +37 -5
  93. package/src/ts/PBText.ts +147 -0
  94. package/src/ts/PlotBoilerplate.ts +47 -19
  95. package/src/ts/Polygon.ts +493 -451
  96. package/src/ts/Vertex.ts +66 -7
  97. package/src/ts/draw.ts +71 -8
  98. package/src/ts/drawgl.ts +48 -8
  99. package/src/ts/drawutilssvg.ts +94 -17
  100. package/src/ts/index.ts +1 -0
  101. package/src/ts/interfaces/DrawLib.ts +30 -4
  102. package/src/ts/interfaces/core.ts +9 -0
  103. package/src/ts/utils/datastructures/Color.ts +695 -508
  104. package/src/ts/utils/findInVertexArray.ts +28 -0
  105. package/dist/plotboilerplate.browser.min.js.LICENSE.txt +0 -8
  106. package/src/ts/utils/algorithms/clearPolygonDuplicateVertices.ts~ +0 -5
  107. package/src/ts/utils/algorithms/findPolygonSelfIntersections.ts~ +0 -45
  108. package/src/ts/utils/algorithms/sh-tmp.ts~ +0 -59
  109. package/src/ts/utils/algorithms/splitPolygonToNonIntersecting.ts~ +0 -113
  110. package/src/ts/utils/algorithms/sutherlandHodgman.ts~ +0 -88
  111. package/src/ts/utils/datastructures/Color.ts~ +0 -331
  112. package/src/ts/utils/datastructures/Girih.ts~ +0 -151
  113. package/src/ts/utils/datastructures/GirihTile.ts~ +0 -419
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @author Ikaros Kappler
3
+ * @date 2022-01-10
4
+ * @version 1.0.0
5
+ */
6
+
7
+ import { Vertex } from "../Vertex";
8
+ import { XYCoords } from "../interfaces";
9
+
10
+ /**
11
+ * In an array of vertices find the first occurence of a specific vertex, using
12
+ * and epsilon tolerance.
13
+ *
14
+ * @param {Array<Vertex>} vertexList - The vertex array to search in.
15
+ * @param {XYCoords} vertex - A vertex/position to search for. This can be any x-y-tuple and does not
16
+ * necessarily need to be an instance of Vertex.
17
+ * @param {number} epsilon - The epsilon tolerance to use (should be >= 0). This is a required param to avoid excessive
18
+ * is-undef checking if this function runs in a loop.
19
+ * @returns {boolean} - The first index of a vertex that matched or -1 if no such vertex could be found.
20
+ */
21
+ export const findInVertexArray = (vertexList: Array<Vertex>, vertex: XYCoords, epsilon: number): number => {
22
+ for (var i = 0; i < vertexList.length; i++) {
23
+ if (vertexList[i].distance(vertex) < epsilon) {
24
+ return i;
25
+ }
26
+ }
27
+ return -1;
28
+ };
@@ -1,8 +0,0 @@
1
- /**
2
- * index.es6 v0.1.17
3
- * super tiny size multi-touch gestures library for the web. Cloned from alloyfinger
4
- *
5
- * @author dntzhang
6
- * @license MIT
7
- * @preserve
8
- */
@@ -1,5 +0,0 @@
1
- /**
2
- *
3
- */
4
-
5
- const polygonClearDuplicateVertices
@@ -1,45 +0,0 @@
1
- /**
2
- * @requires Line
3
- * @requires Vertex
4
- *
5
- * @author Ikaros Kappler
6
- * @date 2020-12-04
7
- */
8
-
9
-
10
- /**
11
- * Collect all self-intersection points of the given polygon.
12
- *
13
- * @name findPolygonSelfIntersections
14
- * @param {Array<Vertex>} polygon
15
- * @return Array<Vertex>
16
- */
17
- var findPolygonSelfIntersections = function( polygon ) {
18
- var pointList = [];
19
- var lineA = new Line( new Vertex(), new Vertex() );
20
- var lineB = new Line( new Vertex(), new Vertex() );
21
- for( var a = 0; a < polygon.vertices.length; a++ ) {
22
- lineA.a.set( polygon.getVertexAt(a) );
23
- lineA.b.set( polygon.getVertexAt(a+1) );
24
- for( var b = 0; b < polygon.vertices.length; b++ ) {
25
- // Same edge or neighbour edges intersect by definition.
26
- // Skip them.
27
- if( a == b || a+1 == b || a == b+1
28
- || (a==0&&b+1==polygon.vertices.length) || (b==0&&a+1==polygon.vertices.length) )
29
- continue;
30
- lineB.a.set( polygon.getVertexAt(b) );
31
- lineB.b.set( polygon.getVertexAt(b+1) );
32
-
33
- // Commpute the intersection point of the (infinite) lines.
34
- // The point is undefined if and only if both line are parallel (co-linear).
35
- const intersectionPoint = lineA.intersection(lineB);
36
-
37
- // Check if the intersection point is on both (finite) edges of the polygon.
38
- if( intersectionPoint
39
- && lineA.hasPoint(intersectionPoint) && lineB.hasPoint(intersectionPoint) ) {
40
- pointList.push( intersectionPoint );
41
- }
42
- }
43
- }
44
- return pointList;
45
- };
@@ -1,59 +0,0 @@
1
-
2
- interface XYCoords {
3
- x : number;
4
- y : number;
5
- }
6
-
7
- const inside = ( cp1 : XYCoords, cp2 : XYCoords, p : XYCoords) : boolean => {
8
- return (cp2.x-cp1.x)*(p.y-cp1.y) > (cp2.y-cp1.y)*(p.x-cp1.x);
9
- };
10
-
11
- const intersection = ( cp1 : XYCoords ,cp2 : XYCoords ,s : XYCoords, e : XYCoords ) : XYCoords => {
12
- const dc = {
13
- x: cp1.x - cp2.x,
14
- y : cp1.y - cp2.y
15
- },
16
- dp = { x: s.x - e.x,
17
- y : s.y - e.y
18
- },
19
- n1 = cp1.x * cp2.y - cp1.y * cp2.x,
20
- n2 = s.x * e.y - s.y * e.x,
21
- n3 = 1.0 / (dc.x * dp.y - dc.y * dp.x);
22
- return { x : (n1*dp.x - n2*dc.x) * n3,
23
- y : (n1*dp.y - n2*dc.y) * n3
24
- };
25
- };
26
-
27
- export const sutherlandHodgman = ( subjectPolygon : Array<XYCoords>,
28
- clipPolygon : Array<XYCoords> ) : Array<XYCoords> => {
29
-
30
- let cp1 : XYCoords = clipPolygon[clipPolygon.length-1];
31
- let cp2 : XYCoords;
32
- let s : XYCoords;
33
- let e : XYCoords;
34
-
35
- let outputList : Array<XYCoords> = subjectPolygon;
36
-
37
- for( var j in clipPolygon ) {
38
- cp2 = clipPolygon[j];
39
- var inputList = outputList;
40
- outputList = [];
41
- s = inputList[inputList.length - 1]; // last on the input list
42
- for (var i in inputList) {
43
- e = inputList[i];
44
- if (inside(cp1,cp2,e)) {
45
- if (!inside(cp1,cp2,s)) {
46
- outputList.push(intersection(cp1,cp2,s,e));
47
- }
48
- outputList.push(e);
49
- }
50
- else if (inside(cp1,cp2,s)) {
51
- outputList.push(intersection(cp1,cp2,s,e));
52
- }
53
- s = e;
54
- }
55
- cp1 = cp2;
56
- }
57
- return outputList
58
- }
59
-
@@ -1,113 +0,0 @@
1
- /**
2
- * This function cuts a given self-intersecting polygon into non-self-intersecting
3
- * sub polygons.
4
- *
5
- * The algorithm only works for non-self-overlapping polygons.
6
- * Please note that the union set of the sub polygons themselves will _not_ be disjunct if
7
- * the input polyon overlaps with itself!
8
- *
9
- *
10
- * @requires Line
11
- * @requires Vertex
12
- * @requires greinerHormann
13
- *
14
- * @date 2020-12-04
15
- */
16
-
17
- (function(_context) {
18
-
19
- /**
20
- * @param {Array<Vertex>} vertices
21
- * @param {number=10} maxDepth
22
- */
23
- var splitToNonIntersectingPolygons = function( vertices, maxDepth ) {
24
- if( typeof maxDepth === "undefined" )
25
- maxDepth = 10;
26
- return _splitToNonIntersectingPolygons( vertices, maxDepth );
27
- };
28
-
29
-
30
- var _splitToNonIntersectingPolygons = function( vertices, maxDepth ) {
31
-
32
- if( maxDepth <= 0 ) {
33
- console.log('aborting at max depth');
34
- return [ vertices ];
35
- }
36
-
37
- if( vertices.length <= 3 ) {
38
- // No intersections possible
39
- return [ vertices ];
40
- }
41
-
42
- // var pointList = [];
43
- var n = vertices.length;
44
- var lineA = new Line( new Vertex(), new Vertex() );
45
- var lineB = new Line( new Vertex(), new Vertex() );
46
- for( var a = 0; a < vertices.length; a++ ) {
47
- lineA.a.set( vertices[a] );
48
- lineA.b.set( vertices[(a+1) % n] );
49
- for( var b = 0; b < vertices.length; b++ ) {
50
- // Equal or neighbour edges intersect by definition.
51
- // We ignore them.
52
- if( a == b || a+1 == b || a == b+1 || (a==0&&b+1==vertices.length) || (b==0&&a+1==vertices.length) )
53
- continue;
54
- lineB.a.set( vertices[b] );
55
- lineB.b.set( vertices[(b+1) % n] );
56
-
57
- const intersectionPoint = lineA.intersection(lineB);
58
- // console.log( 'intersectionPoint', intersectionPoint );
59
- if( intersectionPoint && lineA.hasPoint(intersectionPoint) && lineB.hasPoint(intersectionPoint) ) {
60
- // console.log( 'intersection found' );
61
- // pointList.push( intersectionPoint );
62
- // Cut polygon into two here
63
- var split = splitPolygonAt( vertices, a, b, intersectionPoint );
64
-
65
- // Split has 2 elements.
66
- var leftCleaned = _splitToNonIntersectingPolygons( split[0], maxDepth-1 );
67
- var rightCleaned = _splitToNonIntersectingPolygons( split[1], maxDepth-1 );
68
-
69
- return leftCleaned.concat( rightCleaned );
70
- }
71
- }
72
- }
73
- // console.log( 'intersectionPoints', pointList );
74
-
75
- // No intersection found:
76
- // just return a list with the original
77
- // polygon as its only element.
78
- return [ vertices ];
79
- };
80
-
81
-
82
- // Pre: edgeIndexA < edgeIndexB && vertices.length >= 4
83
- var splitPolygonAt = function( vertices, edgeIndexA, edgeIndexB, intersectionPoint ) {
84
-
85
- // console.log( 'split', edgeIndexA, edgeIndexB );
86
-
87
- var first = [];
88
- var second = [];
89
- for( var i = 0; i < vertices.length; i++ ) {
90
- if( i <= edgeIndexA )
91
- first.push( vertices[i] );
92
-
93
- if( i == edgeIndexA ) {
94
- first.push( intersectionPoint );
95
- second.push( intersectionPoint ); // clone???
96
- }
97
-
98
- if( i > edgeIndexA && i <= edgeIndexB )
99
- second.push( vertices[i] );
100
-
101
- if( i > edgeIndexB )
102
- first.push( vertices[i] );
103
-
104
- }
105
-
106
- // console.log( 'split', first, second );
107
-
108
- return [ first, second ];
109
- };
110
-
111
- _context.splitToNonIntersectingPolygons = splitToNonIntersectingPolygons;
112
-
113
- })(globalThis || window);
@@ -1,88 +0,0 @@
1
- "use strict";
2
-
3
- /**
4
- * The Sutherland-Hodgman convex polygon clipping algorithm.
5
- *
6
- * Converted to Vertex variant {x:number,y:number} by Ikaros Kappler.
7
- *
8
- * @date 2021-01-29
9
- * @version 1.0.0
10
- *
11
- * Original version:
12
- * https://rosettacode.org/wiki/Sutherland-Hodgman_polygon_clipping#JavaScript
13
- */
14
-
15
-
16
-
17
- (function() {
18
-
19
-
20
- /**
21
- * @param {Vertex}
22
- * @param {Vertex}
23
- **/
24
- var inside = function (_cp1,_cp2,p) {
25
- // console.log('x', _cp1);
26
- return (_cp2.x-_cp1.x)*(p.y-_cp1.y) > (_cp2.y-_cp1.y)*(p.x-_cp1.x);
27
- };
28
-
29
- /**
30
- * @param {Vertex}
31
- * @param {Vertex}
32
- * @param {Vertex}
33
- * @param {Vertex}
34
- */
35
- var intersection = function (_cp1,_cp2,_s,_e) {
36
- var
37
- dc = { x: _cp1.x - _cp2.x,
38
- y : _cp1.y - _cp2.y
39
- },
40
- dp = { x: _s.x - _e.x,
41
- y : _s.y - _e.y
42
- },
43
- n1 = _cp1.x * _cp2.y - _cp1.y * _cp2.x,
44
- n2 = _s.x * _e.y - _s.y * _e.x,
45
- n3 = 1.0 / (dc.x * dp.y - dc.y * dp.x);
46
- return { x : (n1*dp.x - n2*dc.x) * n3,
47
- y : (n1*dp.y - n2*dc.y) * n3
48
- };
49
- };
50
-
51
-
52
- /**
53
- * @param {Array<Vertex>} subjectPolygon
54
- * @param {Array<Vertex>} clipPolygon - Must be convex.
55
- */
56
- var sutherlandHodgman = function(subjectPolygon, clipPolygon) {
57
-
58
- var cp1, cp2, s, e;
59
-
60
- var outputList = subjectPolygon;
61
- cp1 = clipPolygon[clipPolygon.length-1];
62
-
63
- for (var j in clipPolygon) {
64
- var cp2 = clipPolygon[j];
65
- var inputList = outputList;
66
- outputList = [];
67
- s = inputList[inputList.length - 1]; // last on the input list
68
- for (var i in inputList) {
69
- var e = inputList[i];
70
- if (inside(cp1,cp2,e)) {
71
- if (!inside(cp1,cp2,s)) {
72
- outputList.push(intersection(cp1,cp2,s,e));
73
- }
74
- outputList.push(e);
75
- }
76
- else if (inside(cp1,cp2,s)) {
77
- outputList.push(intersection(cp1,cp2,s,e));
78
- }
79
- s = e;
80
- }
81
- cp1 = cp2;
82
- }
83
- return outputList
84
- }
85
-
86
- globalThis.sutherlandHodgman = sutherlandHodgman;
87
-
88
- })();
@@ -1,331 +0,0 @@
1
- // Found at
2
- // https://gist.github.com/neolitec/1344610
3
- // Thanks to neolitec
4
- //
5
- // @modified 2018-xx-xx Added a clone() function.
6
- // @modified 2018-xx-xx Allowing leading '#' in the makeHEX() function.
7
- // @modified 2018-11-28 Fixed the checkHEX() function to accept 000000.
8
- // @modified 2019-11-18 Added a generic parse(string) function that detects the format.
9
- // @modified 2020-01-09 Fixed a bug in the parse(string) function. Hex colors with only three elements were considered faulty.
10
- // @modified 2020-10-23 TS
11
-
12
-
13
- export class Color {
14
-
15
- r : number;
16
- g : number;
17
- b : number;
18
-
19
- h : number;
20
- s : number;
21
- l : number;
22
-
23
- a : number;
24
-
25
- constructor() {
26
- this.r = this.g = this.b = 0;
27
- this.h = this.s = this.l = 0;
28
- this.a = 1;
29
- };
30
- /** RGB */
31
- Color.prototype.cssRGB = function() {
32
- return "rgb("+Math.round(255*this.r)+","+Math.round(255*this.g)+","+Math.round(255*this.b)+")";
33
- };
34
- Color.prototype.cssRGBA = function() {
35
- return "rgba("+Math.round(255*this.r)+","+Math.round(255*this.g)+","+Math.round(255*this.b)+","+this.a+")";
36
- };
37
- Color.prototype.red = function() { return this.r; };
38
- Color.prototype.green = function() { return this.g; };
39
- Color.prototype.blue = function() { return this.b; };
40
- /** HSL */
41
- Color.prototype.cssHSL = function() {
42
- return "hsl("+Math.round(360*this.h)+","+Math.round(100*this.s)+"%,"+Math.round(100*this.l)+"%)";
43
- };
44
- Color.prototype.cssHSLA = function() {
45
- return "hsla("+Math.round(360*this.h)+","+Math.round(100*this.s)+"%,"+Math.round(100*this.l)+"%,"+Math.round(this.a)+")";
46
- };
47
- Color.prototype.hue = function() { return this.h; };
48
- Color.prototype.saturation = function() { return this.s; };
49
- Color.prototype.lightness = function() { return this.l; };
50
- /** HEX */
51
- Color.prototype.cssHEX = function() {
52
- return "#" +
53
- (255*this.r < 16 ? "0" : "") + Math.round(255*this.r).toString(16) +
54
- (255*this.g < 16 ? "0" : "") + Math.round(255*this.g).toString(16) +
55
- (255*this.b < 16 ? "0" : "") + Math.round(255*this.b).toString(16);
56
- }
57
- /** Transparency */
58
- Color.prototype.alpha = function() { return this.a; };
59
- /** Modifiers */
60
- Color.prototype.saturate = function(v) {
61
- if("string" == typeof v && v.indexOf("%") > -1 && (v = parseInt(v)) != 'NaN')
62
- this.s += v/100;
63
- else if("number" == typeof v) // range 255
64
- this.s += v/255;
65
- else throw new Error("error: bad modifier format (percent or number)");
66
- if(this.s > 1) this.s = 1; else if(this.s < 0) this.s = 0;
67
- Color.Convertor.HSLToRGB.apply(this);
68
- };
69
- Color.prototype.desaturate = function(v) {
70
- this.saturate("-" + v);
71
- };
72
- Color.prototype.lighten = function(v) {
73
- if("string" == typeof v && v.indexOf("%") > -1 && (v = parseInt(v)) != 'NaN')
74
- this.l += v/100;
75
- else if("number" == typeof v) // range 255
76
- this.l += v/255;
77
- else throw new Error("error: bad modifier format (percent or number)");
78
- if(this.l > 1) this.l = 1; else if(this.l < 0) this.l = 0;
79
- Color.Convertor.HSLToRGB.apply(this);
80
- };
81
- Color.prototype.darken = function(v) {
82
- this.ligthen("-" + v);
83
- };
84
- Color.prototype.fadein = function(v) {
85
- if("string" == typeof v && v.indexOf("%") > -1 && (v = parseInt(v)) != 'NaN')
86
- this.a += v/100;
87
- else if("number" == typeof v) // range 255
88
- this.a += v/255;
89
- else throw new Error("error: bad modifier format (percent or number)");
90
- if(this.a > 1) this.a = 1; else if(this.a < 0) this.a = 0;
91
- Color.Convertor.HSLToRGB.apply(this);
92
- };
93
- Color.prototype.fadeout = function(v) {
94
- this.fadein("-" + v);
95
- };
96
- Color.prototype.spin = function(v) {
97
- if("string" == typeof v && v.indexOf("%") > -1 && (v = parseInt(v)) != 'NaN')
98
- this.h += v/100;
99
- else if("number" == typeof v) // range 360
100
- this.h += v/360;
101
- else throw new Error("error: bad modifier format (percent or number)");
102
- if(this.h > 1) this.h = 1; else if(this.h < 0) this.h = 0;
103
- Color.Convertor.HSLToRGB.apply(this);
104
- };
105
- /** Debug */
106
- Color.prototype.toString = function() {
107
- return "<span style=\"color: "+this.cssRGB()+"\">"+this.cssRGB()+"</span> / <span style=\"color: "+this.cssHSL()+"\">"+this.cssHSL()+"</span> / <span style=\"color: "+this.cssHEX()+"\">"+this.cssHEX()+"</span> / alpha: "+this.a+"";
108
- };
109
-
110
- Color.makeRGB = function() {
111
- var c = new Color(),
112
- sanitized;
113
- if(arguments.length < 3 || arguments.length > 4)
114
- throw new Error("error: 3 or 4 arguments");
115
- sanitized = Color.Sanitizer.RGB(arguments[0], arguments[1], arguments[2]);
116
- c.r = sanitized[0];
117
- c.g = sanitized[1];
118
- c.b = sanitized[2];
119
- if(arguments.length == 4) c.a = arguments[3];
120
- Color.Convertor.RGBToHSL.apply(c);
121
- return c;
122
- };
123
-
124
- Color.makeHSL = function() {
125
- var c = new Color(),
126
- sanitized;
127
- if(arguments.length < 3 || arguments.length > 4)
128
- throw new Error("error: 3 or 4 arguments");
129
- sanitized = Color.Sanitizer.HSL(arguments[0], arguments[1], arguments[2]);
130
- c.h = sanitized[0];
131
- c.s = sanitized[1];
132
- c.l = sanitized[2];
133
- if(arguments.length == 4) c.a = arguments[3];
134
- Color.Convertor.HSLToRGB.apply(c);
135
- return c;
136
- };
137
-
138
- Color.makeHEX = function(value) {
139
- var c = new Color(),
140
- sanitized;
141
- // Edit Ika 2018-0308
142
- // Allow leading '#'
143
- if( value && value.startsWith('#') )
144
- value = value.substr(1);
145
- Color.Validator.checkHEX(value);
146
- if(value.length == 3) {
147
- sanitized = Color.Sanitizer.RGB(
148
- parseInt(value.substr(0, 1) + value.substr(0, 1), 16),
149
- parseInt(value.substr(1, 1) + value.substr(1, 1), 16),
150
- parseInt(value.substr(2, 1) + value.substr(2, 1), 16)
151
- );
152
- } else if(value.length == 6) {
153
- sanitized = Color.Sanitizer.RGB(
154
- parseInt(value.substr(0, 2), 16),
155
- parseInt(value.substr(2, 2), 16),
156
- parseInt(value.substr(4, 2), 16)
157
- );
158
- } else throw new Error("error: 3 or 6 arguments");
159
- c.r = sanitized[0];
160
- c.g = sanitized[1];
161
- c.b = sanitized[2];
162
- Color.Convertor.RGBToHSL.apply(c);
163
- return c;
164
- };
165
-
166
- Color.parse = function( str ) {
167
- if( typeof str == 'undefined' )
168
- return null;
169
- if( (str = str.trim().toLowerCase()).length == 0 )
170
- return null;
171
- if( str.startsWith('#') )
172
- return Color.makeHEX(str.substring(1,str.length));
173
- if( str.startsWith('rgb') ) {
174
- var open = str.indexOf('(');
175
- var close = str.indexOf(')');
176
-
177
- var parts = /^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(0\.\d+))?\)$/.exec(str);
178
- // [ str, r, g, b, a|undefined ]
179
- if( typeof parts[4] == 'undefined' )
180
- return Color.makeRGB(parts[1],parts[2],parts[3]);
181
- else
182
- return Color.makeRGB(parts[1],parts[2],parts[3],parts[4]);
183
- }
184
- else
185
- throw "Unrecognized color format: " + str;
186
- };
187
-
188
- // Test parser
189
- // Color.parse('rgba(28,192,255,0.5)');
190
- // Color.parse('rgb(28,192,255)');
191
- // Color.parse('Xrgb(28,192,255)'); // Should throw exception
192
-
193
- Color.Sanitizer = {
194
- RGB: function() {
195
- var o = [];
196
- if(arguments.length == 0) return;
197
- for(var i = 0 ; i < arguments.length ; i++) {
198
- var c = arguments[i];
199
- if("string" == typeof c && c.indexOf("%") > -1) {
200
- if((c = parseInt(c)) == 'NaN')
201
- throw new Error("Bad format");
202
- if(c < 0 || c > 100)
203
- throw new Error("Bad format");
204
- o[i] = c/100;
205
- } else {
206
- if("string" == typeof c && (c = parseInt(c)) == 'NaN') throw new Error("Bad format");
207
- if(c < 0) throw new Error("Bad format");
208
- else if(c >= 0 && c < 1) o[i] = c;
209
- else if(c >= 1 && c < 256) o[i] = c/255;
210
- else throw new Error("Bad format ("+c+")");
211
- }
212
- }
213
- return o;
214
- },
215
- HSL: function() {
216
- if(arguments.length < 3 || arguments.length > 4) throw new Error("3 or 4 arguments required");
217
- var h = arguments[0],
218
- s = arguments[1],
219
- l = arguments[2];
220
- if("string" == typeof h && (h = parseFloat(h)) == 'NaN') throw new Error("Bad format for hue");
221
- if(h < 0 || h > 360) throw new Error("Hue out of range (0..360)");
222
- else if(((""+h).indexOf(".") > -1 && h > 1) || (""+h).indexOf(".") == -1) h /= 360;
223
- if("string" == typeof s && s.indexOf("%") > -1) {
224
- if((s = parseInt(s)) == 'NaN')
225
- throw new Error("Bad format for saturation");
226
- if(s < 0 || s > 100)
227
- throw new Error("Bad format for saturation");
228
- s /= 100;
229
- } else if(s < 0 || s > 1) throw new Error("Bad format for saturation");
230
- if("string" == typeof l && l.indexOf("%") > -1) {
231
- if((l = parseInt(l)) == 'NaN')
232
- throw new Error("Bad format for lightness");
233
- if(l < 0 || l > 100)
234
- throw new Error("Bad format for lightness");
235
- l /= 100;
236
- } else if(l < 0 || l > 1) throw new Error("Bad format for lightness");
237
- return [h, s, l];
238
- },
239
- };
240
-
241
- Color.Validator = {
242
-
243
- /**
244
- * Check a hexa color (without #)
245
- */
246
- checkHEX: function(value) {
247
-
248
- if(value.length != 6 && value.length != 3)
249
- throw new Error("Hexa color: bad length ("+value.length+")," + value);
250
- value = value.toLowerCase();
251
- for(i in value) {
252
- var c = value.charCodeAt(i);
253
- if( !((c>=48 && c<=57) || (c>=97 && c<=102)) )
254
- throw new Error("Hexa color: out of range for " + value + " at position " + i);
255
- }
256
- }
257
- };
258
-
259
- Color.Convertor = {
260
-
261
- /**
262
- * Calculates HSL Color
263
- * RGB must be normalized
264
- * Must be executed in a Color object context
265
- * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
266
- */
267
- RGBToHSL: function() {
268
- //
269
- var r = this.r,
270
- g = this.g,
271
- b = this.b,
272
- max = Math.max(r, g, b), min = Math.min(r, g, b);
273
- this.l = (max + min) / 2;
274
- if(max == min){
275
- this.h = this.s = 0; // achromatic
276
- } else {
277
- var d = max - min;
278
- this.s = this.l > 0.5 ? d / (2 - max - min) : d / (max + min);
279
- switch(max){
280
- case r: this.h = (g - b) / d + (g < b ? 6 : 0); break;
281
- case g: this.h = (b - r) / d + 2; break;
282
- case b: this.h = (r - g) / d + 4; break;
283
- }
284
- this.h /= 6;
285
- }
286
- },
287
-
288
- /**
289
- * Calculates RGB color (nomalized)
290
- * HSL must be normalized
291
- * Must be executed in a Color object context
292
- * http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
293
- */
294
- HSLToRGB: function() {
295
- var h = this.h,
296
- s = this.s,
297
- l = this.l,
298
- hue2rgb = function(p, q, t){
299
- if(t < 0) t += 1;
300
- if(t > 1) t -= 1;
301
- if(t < 1/6) return p + (q - p) * 6 * t;
302
- if(t < 1/2) return q;
303
- if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
304
- return p;
305
- };
306
- if(s == 0) {
307
- this.r = this.g = this.b = l; // achromatic
308
- } else {
309
- var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
310
- var p = 2 * l - q;
311
- this.r = hue2rgb(p, q, h + 1/3);
312
- this.g = hue2rgb(p, q, h);
313
- this.b = hue2rgb(p, q, h - 1/3);
314
- }
315
- }
316
-
317
- };
318
-
319
-
320
- // Added by Ika 2017-0-19
321
- Color.prototype.clone = function() {
322
- return Color.makeRGB(this.r, this.g, this.b, this.a);
323
- };
324
- // Added by Ika 2018-12-30
325
- Color.prototype.interpolate = function( c, t ) {
326
- this.r += (c.r-c.r)*t;
327
- this.g += (c.g-c.g)*t;
328
- this.b += (c.b-c.b)*t;
329
- this.a += (c.a-c.a)*t;
330
- return this;
331
- };