Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I made a SVG fixer for TurboWarp #1053

Open
Heaveeeen opened this issue Aug 21, 2024 · 0 comments
Open

I made a SVG fixer for TurboWarp #1053

Heaveeeen opened this issue Aug 21, 2024 · 0 comments

Comments

@Heaveeeen
Copy link

Heaveeeen commented Aug 21, 2024

When you stretch or rotate a path in costume editor, scratch calculates each float for the path. This sometimes spilt a single point to two coincide points.

It seems like this, I call them "hangnail":

a costume with "hangnail"

I made a tool for these "hangnail". Scratch SVG Fixer can fix all these coincide points for a SVG, by "snapping" two very close but incompletely coincide points.

The above costume can be fixed like this:

the costume fixed by my tool

Here is a simple manual for the Scratch SVG Fixer.

manual

My Repository: Scratch SVG Fixer

I hope that TurboWarp could automatically fix costumes, by using my sc_svg_snap.js. sc_svg_snap.js defined a global object scsvgsnap. It has some useful methods:

parsePath(code)
code is a SVG path string, e.g. M100,150l50,-50l-10,35v20z, returns an array.

const path = scsvgsnap.parsePath("M100,150l50,-50l-10,35v20z");
// [ ["M", 100, 100], ["l", 50, -50], ["l", -10, 35], ["v", 20], ["z"] ]

isSnapped(path, threshold = 0.02)
path is the array parsed by parsePath. This method can judges if there is "hangnail" for a path.

let issnap = scsvgsnap.isSnapped(path);
// true, which means there's no "hangnail" in this path.

snap(path, threshold = 0.02)
This method fix "hangnail" for a path and return the path.

dumpPath(path)
Convert a path array into a string.

const path = [ ["M", 100, 100], ["l", 50, -50], ["l", -10, 35], ["v", 20], ["z"] ];
scsvgsnap.dumpPath(path);
// "M 100 150 l 50 -50 l -10 35 v 20 z"

There is an interesting regexp: (?<=<path d="[Mz\d\-\.clvh ,]*)M([\d\-\.clvh ,]+)z*, it matchs all path code from a SVG file.
convertSVG(svg, cfg) use this regexp to fix all paths for a SVG file. You can fix all "hangnail" for a SVG like this:

const reg = new RegExp('(?<=<path d="[Mz\d\-\.clvh ,]*)M([\d\-\.clvh ,]+)z*', "g");

const svg = LoadYourSVGFileAsAString();

const newsvg = svg.replace(reg, (match) => {
    const path = scsvgsnap.parsePath(match);
    scsvgsnap.snap(path);
    const newpath = scsvgsnap.dumpPath(path);
    return newpath
});

OverwriteYourSVGFileBy(newsvg);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant