1 | import { AlterType } from "../Enums/Types/AlterType.js";
|
2 | import { getStyleFromRgb } from "./ColorUtils.js";
|
3 | const origin = { x: 0, y: 0 }, defaultTransform = {
|
4 | a: 1,
|
5 | b: 0,
|
6 | c: 0,
|
7 | d: 1,
|
8 | };
|
9 | export function drawLine(context, begin, end) {
|
10 | context.beginPath();
|
11 | context.moveTo(begin.x, begin.y);
|
12 | context.lineTo(end.x, end.y);
|
13 | context.closePath();
|
14 | }
|
15 | export function paintBase(context, dimension, baseColor) {
|
16 | context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
|
17 | context.fillRect(origin.x, origin.y, dimension.width, dimension.height);
|
18 | }
|
19 | export function paintImage(context, dimension, image, opacity) {
|
20 | if (!image) {
|
21 | return;
|
22 | }
|
23 | context.globalAlpha = opacity;
|
24 | context.drawImage(image, origin.x, origin.y, dimension.width, dimension.height);
|
25 | context.globalAlpha = 1;
|
26 | }
|
27 | export function clear(context, dimension) {
|
28 | context.clearRect(origin.x, origin.y, dimension.width, dimension.height);
|
29 | }
|
30 | export function drawParticle(data) {
|
31 | const { container, context, particle, delta, colorStyles, backgroundMask, composite, radius, opacity, shadow, transform, } = data, pos = particle.getPosition(), defaultAngle = 0, angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : defaultAngle), rotateData = {
|
32 | sin: Math.sin(angle),
|
33 | cos: Math.cos(angle),
|
34 | }, rotating = !!angle, identity = 1, transformData = {
|
35 | a: rotateData.cos * (transform.a ?? defaultTransform.a),
|
36 | b: rotating ? rotateData.sin * (transform.b ?? identity) : transform.b ?? defaultTransform.b,
|
37 | c: rotating ? -rotateData.sin * (transform.c ?? identity) : transform.c ?? defaultTransform.c,
|
38 | d: rotateData.cos * (transform.d ?? defaultTransform.d),
|
39 | };
|
40 | context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
|
41 | if (backgroundMask) {
|
42 | context.globalCompositeOperation = composite;
|
43 | }
|
44 | const shadowColor = particle.shadowColor;
|
45 | if (shadow.enable && shadowColor) {
|
46 | context.shadowBlur = shadow.blur;
|
47 | context.shadowColor = getStyleFromRgb(shadowColor);
|
48 | context.shadowOffsetX = shadow.offset.x;
|
49 | context.shadowOffsetY = shadow.offset.y;
|
50 | }
|
51 | if (colorStyles.fill) {
|
52 | context.fillStyle = colorStyles.fill;
|
53 | }
|
54 | const minStrokeWidth = 0, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
|
55 | context.lineWidth = strokeWidth;
|
56 | if (colorStyles.stroke) {
|
57 | context.strokeStyle = colorStyles.stroke;
|
58 | }
|
59 | const drawData = {
|
60 | container,
|
61 | context,
|
62 | particle,
|
63 | radius,
|
64 | opacity,
|
65 | delta,
|
66 | transformData,
|
67 | strokeWidth,
|
68 | };
|
69 | drawShape(drawData);
|
70 | drawShapeAfterDraw(drawData);
|
71 | drawEffect(drawData);
|
72 | context.globalCompositeOperation = "source-over";
|
73 | context.resetTransform();
|
74 | }
|
75 | export function drawEffect(data) {
|
76 | const { container, context, particle, radius, opacity, delta, transformData } = data;
|
77 | if (!particle.effect) {
|
78 | return;
|
79 | }
|
80 | const drawer = container.effectDrawers.get(particle.effect);
|
81 | if (!drawer) {
|
82 | return;
|
83 | }
|
84 | drawer.draw({
|
85 | context,
|
86 | particle,
|
87 | radius,
|
88 | opacity,
|
89 | delta,
|
90 | pixelRatio: container.retina.pixelRatio,
|
91 | transformData: { ...transformData },
|
92 | });
|
93 | }
|
94 | export function drawShape(data) {
|
95 | const { container, context, particle, radius, opacity, delta, strokeWidth, transformData } = data, minStrokeWidth = 0;
|
96 | if (!particle.shape) {
|
97 | return;
|
98 | }
|
99 | const drawer = container.shapeDrawers.get(particle.shape);
|
100 | if (!drawer) {
|
101 | return;
|
102 | }
|
103 | context.beginPath();
|
104 | drawer.draw({
|
105 | context,
|
106 | particle,
|
107 | radius,
|
108 | opacity,
|
109 | delta,
|
110 | pixelRatio: container.retina.pixelRatio,
|
111 | transformData: { ...transformData },
|
112 | });
|
113 | if (particle.shapeClose) {
|
114 | context.closePath();
|
115 | }
|
116 | if (strokeWidth > minStrokeWidth) {
|
117 | context.stroke();
|
118 | }
|
119 | if (particle.shapeFill) {
|
120 | context.fill();
|
121 | }
|
122 | }
|
123 | export function drawShapeAfterDraw(data) {
|
124 | const { container, context, particle, radius, opacity, delta, transformData } = data;
|
125 | if (!particle.shape) {
|
126 | return;
|
127 | }
|
128 | const drawer = container.shapeDrawers.get(particle.shape);
|
129 | if (!drawer?.afterDraw) {
|
130 | return;
|
131 | }
|
132 | drawer.afterDraw({
|
133 | context,
|
134 | particle,
|
135 | radius,
|
136 | opacity,
|
137 | delta,
|
138 | pixelRatio: container.retina.pixelRatio,
|
139 | transformData: { ...transformData },
|
140 | });
|
141 | }
|
142 | export function drawPlugin(context, plugin, delta) {
|
143 | if (!plugin.draw) {
|
144 | return;
|
145 | }
|
146 | plugin.draw(context, delta);
|
147 | }
|
148 | export function drawParticlePlugin(context, plugin, particle, delta) {
|
149 | if (!plugin.drawParticle) {
|
150 | return;
|
151 | }
|
152 | plugin.drawParticle(context, particle, delta);
|
153 | }
|
154 | export function alterHsl(color, type, value) {
|
155 | const lFactor = 1;
|
156 | return {
|
157 | h: color.h,
|
158 | s: color.s,
|
159 | l: color.l + (type === AlterType.darken ? -lFactor : lFactor) * value,
|
160 | };
|
161 | }
|