Skip to content

Commit

Permalink
fix: replaceColor on SVG images, refactor previous fix, fixes #1519
Browse files Browse the repository at this point in the history
  • Loading branch information
GoldenMaximo committed May 6, 2021
1 parent 4a19da9 commit f04af8e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 46 deletions.
5 changes: 4 additions & 1 deletion core/main/src/Core/Particle.ts
Expand Up @@ -668,7 +668,10 @@ export class Particle implements IParticle {
const img = new Image();

imageRes = {
data: image,
data: {
...image,
svgData: svgColoredData,
},
loaded: false,
ratio: imageData.width / imageData.height,
replaceColor: imageData.replaceColor ?? imageData.replace_color,
Expand Down
7 changes: 1 addition & 6 deletions core/main/src/ShapeDrawers/ImageDrawer.ts
Expand Up @@ -77,13 +77,8 @@ export class ImageDrawer implements IShapeDrawer {
const image = imageShape.replaceColor
? await Utils.downloadSvgImage(imageShape.src)
: await Utils.loadImage(imageShape.src);

if (image) {
if (imageShape.replaceColor) {
const color = container.actualOptions.particles.color.value;
const coloredImage = await Utils.replaceSvgColor(image, color);
this.addImage(container, coloredImage);
return;
}
this.addImage(container, image);
}
} catch {
Expand Down
29 changes: 23 additions & 6 deletions core/main/src/Utils/ColorUtils.ts
Expand Up @@ -479,16 +479,33 @@ export class ColorUtils {
};
}

static replaceColorSvg(image: IImage, color: IHsl, opacity: number): string {
if (!image.svgData) {
return "";
static replaceColorSvg(imageShape: IImage, color: IHsl, opacity: number): string {
if (!imageShape) {
throw new Error("Error tsParticles - No image provided.");
}

const { source, svgData } = imageShape;
if (!source || !svgData) {
throw new Error("Error tsParticles - No image.src");
}

const imageType = source.substr(source.length - 3);
if (imageType !== "svg") {
throw new Error("Error tsParticles - replaceColor property provided to non-.svg image.src");
}

/* set color to svg element */
const svgXml = image.svgData;
const rgbHex = /#([0-9A-F]{3,6})/gi;
if (imageShape?.svgData?.includes("fill")) {
const currentColor = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\)|currentcolor)/i;
return svgData.replace(currentColor, () => ColorUtils.getStyleFromHsl(color, opacity));
}

const coloredSvgData = `${svgData?.substring(0, svgData.indexOf(">"))} fill="${ColorUtils.getStyleFromHsl(
color,
opacity
)}"${svgData?.substring(svgData.indexOf(">"))}`;

return svgXml.replace(rgbHex, () => ColorUtils.getStyleFromHsl(color, opacity));
return coloredSvgData;
}

static getLinkColor(p1: IParticle, p2?: IParticle, linkColor?: string | IRgb): IRgb | undefined {
Expand Down
33 changes: 0 additions & 33 deletions core/main/src/Utils/Utils.ts
Expand Up @@ -13,7 +13,6 @@ import { IParticle } from "../Core/Interfaces/IParticle";
import { ISideData } from "../Core/Interfaces/ISideData";
import { IRectSideResult } from "../Core/Interfaces/IRectSideResult";
import { ICircleBouncer } from "../Core/Interfaces/ICircleBouncer";
import type { IValueColor, IRgb, IHsl, IHsv } from "../Core/Interfaces/Colors";

type CSSOMString = string;
type FontFaceLoadStatus = "unloaded" | "loading" | "loaded" | "error";
Expand Down Expand Up @@ -268,38 +267,6 @@ export class Utils {
return image;
}

// TODO: add RGB / HSL support
static async replaceSvgColor(
imageShape: IImage,
color: SingleOrMultiple<string | IValueColor | IRgb | IHsl | IHsv>
): Promise<IImage> {
if (!imageShape) {
throw new Error("Error tsParticles - No image provided.");
}

const { source } = imageShape;
if (!source) {
throw new Error("Error tsParticles - No image.src");
}

const imageType = source.substr(source.length - 3);
if (imageType !== "svg") {
throw new Error("Error tsParticles - replaceColor property provided to non-.svg image.src");
}

const coloredSource = `${imageShape.svgData?.substring(
0,
imageShape.svgData.indexOf(">")
)} fill="${color}"${imageShape.svgData?.substring(imageShape.svgData.indexOf(">"))}`;

const image: IImage = {
...imageShape,
svgData: coloredSource,
};

return image;
}

static deepExtend(destination: unknown, ...sources: unknown[]): unknown {
for (const source of sources) {
if (source === undefined || source === null) {
Expand Down

0 comments on commit f04af8e

Please sign in to comment.