Skip to content

Instantly share code, notes, and snippets.

@Roms1383
Last active March 30, 2023 06:19
Show Gist options
  • Select an option

  • Save Roms1383/a80bb47b4a024f6663f254fee042397a to your computer and use it in GitHub Desktop.

Select an option

Save Roms1383/a80bb47b4a024f6663f254fee042397a to your computer and use it in GitHub Desktop.
Illustrator scripting - Trace image and export to SVG - reuse in Vue.js and Storybook
// on MacOS, Adobe CC 2019 scripts are located at : /Applications/Adobe Illustrator CC 2019/Presets.localized/en_US/Scripts
/*
will process all jpg and png files from folder like :
e.g. take some file like my-exported-graphic.jpg, trace it and export it as my-exported-graphic.svg
*/
// SPECIFY YOUR OWN PATHS OR USE selectFolder() instead
var origin = Folder('~/from/folder/image');
var destination = Folder('~/to/folder/svg');
// select folder for import
function selectFolder() {
// allow user to select from dialog
return Folder.selectDialog('Please select the folder to be imported:', Folder('~/Development/sandbox/cyberpunk/refacto/my-tests'));
}
function getFiles(folder) {
return folder ? folder.getFiles() : undefined;
}
function convertFiles(files) {
if (files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (!file || !(file instanceof File)) continue;
var filename = file.name.toLowerCase();
var valid = (filename.indexOf('.jpg') != -1) || (filename.indexOf('.png') != -1)
if (!valid) {
continue;
} else {
convertFile(files[i]);
}
}
} else {
alert('no file to convert');
}
}
function write (document, filename) {
var options = new ExportOptionsSVG();
options.documentEncoding = SVGDocumentEncoding.UTF8;
var file = new File(destination + '/' + filename);
document.exportFile(file, ExportType.SVG, options);
}
function convertFile (file) {
var filename = file.name.toLowerCase();
// create new document
var document = app.documents.add();
try {
var layer = document.layers[0];
layer.name = filename.substring(0, filename.indexOf('.'));
// place image file in the layer
var placed = layer.placedItems.add();
placed.file = file;
// position placed image in the document
placed.top = document.height;
placed.left = 0;
// trace image with custom options derived from [Default] preset
var plugin = placed.trace();
var tracing = plugin.tracing;
var options = tracing.tracingOptions;
options.loadFromPreset('[Default]');
options.ignoreWhite = true;
// apply tracing change and expand
app.redraw();
tracing.expandTracing();
// resize artboard to traced image
var artboard = document.artboards[0];
artboard.artboardRect = [0, placed.height, placed.width, 0];
// easier to position group to origins first
var element = document.pageItems[0];
element.position = [0, document.artboards[0].artboardRect[1]];
// then actually ungroup
var group = document.groupItems[0];
var nested = group.pageItems;
var count = nested.length;
for (var i = count - 1; i >= 0; i--) {
nested[i].move(layer, ElementPlacement.PLACEATBEGINNING);
}
// export as SVG
var outname = layer.name + '.svg';
write(document, outname);
document.close();
} catch (error) {
document.close(SaveOptions.DONOTSAVECHANGES);
}
}
if (BridgeTalk.appName == "illustrator") {
var files = getFiles(origin);
convertFiles(files);
}
// Utility Node.js script to convert previously exported SVG to light JSON
// these can then be stored (e.g. database) and quickly reuse in project (e.g. Vue.js)
/*
will process all svg files from folder like :
e.g. with given my-exported-graphic.svg :
// my-exported-graphic.json
{
"name": "my-exported-graphic.svg",
"viewBox": "0 0 12 24",
"paths": [
"...",
"...",
"..."
]
}
*/
const fs = require('fs')
const path = require('path')
const { parse } = require('svg-parser')
const origin = path.join(__dirname, '..', 'svg')
const destination = path.join(__dirname, '..', 'json')
const files = fs.readdirSync(origin, { encoding: 'utf8' })
.filter(name => name.indexOf('.svg') !== -1)
let content, svg, viewBox, paths, output, outname
for (const file of files) {
paths = []
content = fs.readFileSync(path.join(origin, file), { encoding: 'utf8' })
svg = parse(content)
viewBox = svg.children[0].properties.viewBox
paths = svg.children[0].children
.filter(({ tagName }) => tagName === 'path')
.map(({ properties }) => properties.d.replace(/(\n|\r|\t|\s)/gm, ''))
outname = file.substring(0, file.lastIndexOf('.')) + '.json'
output = { name: file, viewBox, paths }
fs.writeFileSync(path.join(destination, outname), JSON.stringify(output, null, 2), { encoding: 'utf8' })
}
// example of usage with Storybook
import MyComponent from './MyComponent'
import data from '../json/my-exported-graphic.json'
// symbol id must match in MyComponent.vue
const convert = raw => `<svg xmlns="http://www.w3.org/2000/svg" display="none">
<symbol id="graphic">
${raw.paths.map(path => '<path fill="green" d="' + path + '"/>\n')}
</symbol>
</svg>`
export default {
title: 'MyComponent',
}
export const normal = () => ({
components: { MyComponent },
template: `<MyComponent viewBox="${data.viewBox}">${convert(data)}</MyComponent>`,
})
<!-- symbol id must match in MyComponent.stories.js -->
<template>
<div class="container">
<slot></slot>
<svg :viewBox="viewBox" preserveAspectRatio="xMidYMin meet">
<use xlink:href="#graphic" />
</svg>
</div>
</template>
<script>
export default {
name: 'Component',
props: { viewBox: String }, // will allow for correct scaling of the SVG to fit div.container size
}
</script>
<style scoped>
div.container {
position: relative;
width: 300px;
height: 300px;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment