@fbltd/math 1.0.40 → 1.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/src/colors/blend.js +23 -0
- package/dist/bin/src/colors/color.js +1 -1
- package/dist/bin/src/colors/constants.js +6 -0
- package/dist/bin/src/colors/{conic.gradient.js → gradient/base.gradient.js} +23 -41
- package/dist/bin/src/colors/gradient/conic.gradient.js +26 -0
- package/dist/bin/src/colors/gradient/index.js +2 -0
- package/dist/bin/src/colors/gradient/linear.gradient.js +19 -0
- package/dist/bin/src/colors/index.js +4 -1
- package/dist/types/src/colors/blend.d.ts +5 -0
- package/dist/types/src/colors/constants.d.ts +6 -0
- package/dist/types/src/colors/gradient/base.gradient.d.ts +17 -0
- package/dist/types/src/colors/gradient/conic.gradient.d.ts +12 -0
- package/dist/types/src/colors/gradient/index.d.ts +2 -0
- package/dist/types/src/colors/gradient/linear.gradient.d.ts +6 -0
- package/dist/types/src/colors/index.d.ts +4 -1
- package/package.json +1 -1
- package/dist/types/src/colors/conic.gradient.d.ts +0 -27
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Color } from "./color.js";
|
|
2
|
+
/**
|
|
3
|
+
* Смешение цветов
|
|
4
|
+
*/
|
|
5
|
+
export function blend(background, ...foregrounds) {
|
|
6
|
+
let temp;
|
|
7
|
+
let red, green, blue;
|
|
8
|
+
for (let foreground of foregrounds) {
|
|
9
|
+
const fgAlpha = foreground.alpha;
|
|
10
|
+
const bgAlpha = background.alpha;
|
|
11
|
+
let alpha = 1 - (1 - fgAlpha) * (1 - bgAlpha);
|
|
12
|
+
if (alpha <= 0) {
|
|
13
|
+
background = new Color(0, 0, 0, 0);
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
temp = bgAlpha * (1 - fgAlpha) / alpha;
|
|
17
|
+
red = Math.floor(foreground.red * fgAlpha / alpha + background.red * temp);
|
|
18
|
+
green = Math.floor(foreground.green * fgAlpha / alpha + background.green * temp);
|
|
19
|
+
blue = Math.floor(foreground.blue * fgAlpha / alpha + background.blue * temp);
|
|
20
|
+
background = new Color(red, green, blue, alpha);
|
|
21
|
+
}
|
|
22
|
+
return background;
|
|
23
|
+
}
|
|
@@ -1,87 +1,69 @@
|
|
|
1
|
-
import { Color } from "
|
|
2
|
-
|
|
1
|
+
import { Color } from "../color.js";
|
|
2
|
+
import { denormalizeShade } from "../utils.js";
|
|
3
|
+
export class BaseGradient {
|
|
3
4
|
colors;
|
|
4
5
|
constructor(...colors) {
|
|
5
|
-
this.colors = [...colors].sort((a, b) => a.
|
|
6
|
+
this.colors = [...colors].sort((a, b) => a.percentage - b.percentage);
|
|
6
7
|
this.colors.push({
|
|
7
|
-
|
|
8
|
+
percentage: 1,
|
|
8
9
|
color: this.colors[0].color
|
|
9
10
|
});
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
13
|
* Получить цвет по углу от оси X по часовой стрелке
|
|
13
|
-
* @param
|
|
14
|
+
* @param percentage единица измерения угла должна быть той же самой, что и углы всех передаваемых в констурктор цветов
|
|
14
15
|
*/
|
|
15
|
-
|
|
16
|
+
getColorAtPercentage(percentage) {
|
|
16
17
|
let prev = undefined;
|
|
17
18
|
let next = undefined;
|
|
18
19
|
for (let entry of this.colors) {
|
|
19
|
-
if (entry.
|
|
20
|
+
if (entry.percentage === percentage)
|
|
20
21
|
return entry.color;
|
|
21
|
-
if (entry.
|
|
22
|
+
if (entry.percentage < percentage)
|
|
22
23
|
prev = entry;
|
|
23
|
-
if (entry.
|
|
24
|
+
if (entry.percentage > percentage) {
|
|
24
25
|
next = entry;
|
|
25
26
|
break;
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
if (!prev || !next)
|
|
29
30
|
return undefined;
|
|
30
|
-
const coef = (
|
|
31
|
-
return new Color(Math.floor((next.color.red - prev.color.red) * coef + prev.color.red), Math.floor((next.color.green - prev.color.green) * coef + prev.color.green), Math.floor((next.color.blue - prev.color.blue) * coef + prev.color.blue));
|
|
31
|
+
const coef = (percentage - prev.percentage) / (next.percentage - prev.percentage);
|
|
32
|
+
return new Color(Math.floor((next.color.red - prev.color.red) * coef + prev.color.red), Math.floor((next.color.green - prev.color.green) * coef + prev.color.green), Math.floor((next.color.blue - prev.color.blue) * coef + prev.color.blue), (next.color.alpha - prev.color.alpha) * coef + prev.color.alpha);
|
|
32
33
|
}
|
|
33
|
-
|
|
34
|
+
getPercentageByColor(color) {
|
|
34
35
|
let prev;
|
|
35
36
|
let next = this.colors[0];
|
|
36
37
|
if (color.isEqual(next.color))
|
|
37
|
-
return next.
|
|
38
|
+
return next.percentage;
|
|
38
39
|
for (let i = 1; i < this.colors.length; i++) {
|
|
39
40
|
next = this.colors[i];
|
|
40
41
|
prev = this.colors[i - 1];
|
|
41
42
|
if (color.isEqual(next.color))
|
|
42
|
-
return next.
|
|
43
|
+
return next.percentage;
|
|
43
44
|
let redDif = next.color.red - prev.color.red;
|
|
44
45
|
let greenDif = next.color.green - prev.color.green;
|
|
45
46
|
let blueDif = next.color.blue - prev.color.blue;
|
|
47
|
+
let alphaDif = denormalizeShade(next.color.alpha) - denormalizeShade(prev.color.alpha);
|
|
46
48
|
let redDifColor = color.red - prev.color.red;
|
|
47
49
|
let greenDifColor = color.green - prev.color.green;
|
|
48
50
|
let blueDifColor = color.blue - prev.color.blue;
|
|
51
|
+
let alphaDifColor = denormalizeShade(color.alpha) - denormalizeShade(prev.color.alpha);
|
|
49
52
|
if (((redDifColor >= 0 && redDifColor <= redDif) || (redDifColor <= 0 && redDifColor >= redDif)) &&
|
|
50
53
|
((greenDifColor >= 0 && greenDifColor <= greenDif) || (greenDifColor <= 0 && greenDifColor >= greenDif)) &&
|
|
51
|
-
((blueDifColor >= 0 && blueDifColor <= blueDif) || (blueDifColor <= 0 && blueDifColor >= blueDif))
|
|
54
|
+
((blueDifColor >= 0 && blueDifColor <= blueDif) || (blueDifColor <= 0 && blueDifColor >= blueDif)) &&
|
|
55
|
+
((alphaDifColor >= 0 && alphaDifColor <= alphaDif) || (alphaDifColor <= 0 && alphaDifColor >= alphaDif))) {
|
|
52
56
|
const redCoef = ((color.red - prev.color.red) / (next.color.red - prev.color.red));
|
|
53
57
|
const greenCoef = ((color.green - prev.color.green) / (next.color.green - prev.color.green));
|
|
54
58
|
const blueCoef = ((color.blue - prev.color.blue) / (next.color.blue - prev.color.blue));
|
|
55
|
-
const
|
|
56
|
-
|
|
59
|
+
const alphaCoef = ((color.alpha - prev.color.alpha) / (next.color.alpha - prev.color.alpha));
|
|
60
|
+
const coefs = [redCoef, greenCoef, blueCoef, alphaCoef].filter(Boolean);
|
|
61
|
+
return (next.percentage - prev.percentage) * Math.min(...coefs) + prev.percentage;
|
|
57
62
|
}
|
|
58
63
|
}
|
|
59
64
|
return undefined;
|
|
60
65
|
}
|
|
61
66
|
isColorInRange(color) {
|
|
62
|
-
return Boolean(this.
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Для использования метода, углы должны быть в Turn единицах измерения
|
|
66
|
-
*/
|
|
67
|
-
toCanvas(ctx, center) {
|
|
68
|
-
const gradient = ctx.createConicGradient(0, ...center);
|
|
69
|
-
for (let color of this.colors) {
|
|
70
|
-
gradient.addColorStop(color.angle, color.color.toString());
|
|
71
|
-
}
|
|
72
|
-
return gradient;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Для использования метода, углы должны быть в Turn единицах измерения
|
|
76
|
-
*/
|
|
77
|
-
toCSS() {
|
|
78
|
-
let s = '';
|
|
79
|
-
for (let color of this.colors) {
|
|
80
|
-
if (s)
|
|
81
|
-
s += ',';
|
|
82
|
-
s += `rgb(${color.color.red},${color.color.green},${color.color.blue})`;
|
|
83
|
-
}
|
|
84
|
-
s = `conic-gradient(in srgb from 0.25turn at 50% 50%, ${s})`;
|
|
85
|
-
return s;
|
|
67
|
+
return Boolean(this.getPercentageByColor(color));
|
|
86
68
|
}
|
|
87
69
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseGradient } from "./base.gradient.js";
|
|
2
|
+
export class ConicGradient extends BaseGradient {
|
|
3
|
+
/**
|
|
4
|
+
* Для использования метода, углы должны быть в Turn единицах измерения
|
|
5
|
+
*/
|
|
6
|
+
toCanvas(ctx, center) {
|
|
7
|
+
const gradient = ctx.createConicGradient(0, ...center);
|
|
8
|
+
for (let color of this.colors) {
|
|
9
|
+
gradient.addColorStop(color.percentage, color.color.toString());
|
|
10
|
+
}
|
|
11
|
+
return gradient;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Для использования метода, углы должны быть в Turn единицах измерения
|
|
15
|
+
*/
|
|
16
|
+
toCSS() {
|
|
17
|
+
let s = '';
|
|
18
|
+
for (let color of this.colors) {
|
|
19
|
+
if (s)
|
|
20
|
+
s += ',';
|
|
21
|
+
s += `rgb(${color.color.red},${color.color.green},${color.color.blue})`;
|
|
22
|
+
}
|
|
23
|
+
s = `conic-gradient(in srgb from 0.25turn at 50% 50%, ${s})`;
|
|
24
|
+
return s;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BaseGradient } from "./base.gradient.js";
|
|
2
|
+
export class LinearGradient extends BaseGradient {
|
|
3
|
+
toCanvas(ctx, p1, p2) {
|
|
4
|
+
const gradient = ctx.createLinearGradient(...p1, ...p2);
|
|
5
|
+
for (let color of this.colors) {
|
|
6
|
+
gradient.addColorStop(color.percentage, color.color.toString());
|
|
7
|
+
}
|
|
8
|
+
return gradient;
|
|
9
|
+
}
|
|
10
|
+
toCSS(direction = 'to bottom') {
|
|
11
|
+
let s = '';
|
|
12
|
+
for (let color of this.colors) {
|
|
13
|
+
if (s)
|
|
14
|
+
s += ',';
|
|
15
|
+
s += `rgb(${color.color.red},${color.color.green},${color.color.blue})`;
|
|
16
|
+
}
|
|
17
|
+
return `conic-gradient(${direction}, ${s})`;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Color } from "../color.ts";
|
|
2
|
+
export declare abstract class BaseGradient {
|
|
3
|
+
protected colors: {
|
|
4
|
+
percentage: number;
|
|
5
|
+
color: Color;
|
|
6
|
+
}[];
|
|
7
|
+
constructor(...colors: typeof this.colors);
|
|
8
|
+
/**
|
|
9
|
+
* Получить цвет по углу от оси X по часовой стрелке
|
|
10
|
+
* @param percentage единица измерения угла должна быть той же самой, что и углы всех передаваемых в констурктор цветов
|
|
11
|
+
*/
|
|
12
|
+
getColorAtPercentage(percentage: number): Color | undefined;
|
|
13
|
+
getPercentageByColor(color: Color): number | undefined;
|
|
14
|
+
isColorInRange(color: Color): boolean;
|
|
15
|
+
abstract toCanvas(ctx: CanvasRenderingContext2D, ...args: any): CanvasGradient;
|
|
16
|
+
abstract toCSS(...args: any): string;
|
|
17
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { IPoint2 } from "../../figures/index.ts";
|
|
2
|
+
import { BaseGradient } from "./base.gradient.ts";
|
|
3
|
+
export declare class ConicGradient extends BaseGradient {
|
|
4
|
+
/**
|
|
5
|
+
* Для использования метода, углы должны быть в Turn единицах измерения
|
|
6
|
+
*/
|
|
7
|
+
toCanvas(ctx: CanvasRenderingContext2D, center: IPoint2): CanvasGradient;
|
|
8
|
+
/**
|
|
9
|
+
* Для использования метода, углы должны быть в Turn единицах измерения
|
|
10
|
+
*/
|
|
11
|
+
toCSS(): string;
|
|
12
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BaseGradient } from "./base.gradient.ts";
|
|
2
|
+
import type { IPoint2 } from "../../figures/index.ts";
|
|
3
|
+
export declare class LinearGradient extends BaseGradient {
|
|
4
|
+
toCanvas(ctx: CanvasRenderingContext2D, p1: IPoint2, p2: IPoint2): CanvasGradient;
|
|
5
|
+
toCSS(direction?: string): string;
|
|
6
|
+
}
|
package/package.json
CHANGED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Color } from "./color.ts";
|
|
2
|
-
import type { IPoint2 } from "../figures/index.ts";
|
|
3
|
-
export declare class ConicGradient {
|
|
4
|
-
colors: {
|
|
5
|
-
angle: number;
|
|
6
|
-
color: Color;
|
|
7
|
-
}[];
|
|
8
|
-
constructor(...colors: {
|
|
9
|
-
angle: number;
|
|
10
|
-
color: Color;
|
|
11
|
-
}[]);
|
|
12
|
-
/**
|
|
13
|
-
* Получить цвет по углу от оси X по часовой стрелке
|
|
14
|
-
* @param angle единица измерения угла должна быть той же самой, что и углы всех передаваемых в констурктор цветов
|
|
15
|
-
*/
|
|
16
|
-
getColorAtAngle(angle: number): Color | undefined;
|
|
17
|
-
getAngleByColor(color: Color): number | undefined;
|
|
18
|
-
isColorInRange(color: Color): boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Для использования метода, углы должны быть в Turn единицах измерения
|
|
21
|
-
*/
|
|
22
|
-
toCanvas(ctx: CanvasRenderingContext2D, center: IPoint2): CanvasGradient;
|
|
23
|
-
/**
|
|
24
|
-
* Для использования метода, углы должны быть в Turn единицах измерения
|
|
25
|
-
*/
|
|
26
|
-
toCSS(): string;
|
|
27
|
-
}
|