SVG-2-PIXELART
SVG-2-PIXELART copied to clipboard
Flash 2 Pixelart - Experiments with Adobe Animate
Flash 2 Pixelart
Flash 2 Pixelart is a tool for converting animation in Adobe Flash to pixel art. It allows you to adjust the pixel size, alpha threshold, outline size,
Prerequisites
To use Flash 2 Pixelart, you will need the following:
- Adobe Animate
- A web browser that supports HTML5 Canvas and the ability to download multiple files (such as Google Chrome or Mozilla Firefox)
Instructions
- Create a new HTML5 Canvas document in Adobe Animate:
- Press
F9
to open the Actions Menu, and SelectGlobal / Script
:
- Paste the code bellow into the script window:
// Made by Mauro Junior [ CC-BY ] - https://www.behance.net/gallery/65727549/Portifolio-2018-Mauro-Junior
// You can edit the canvas2pixel to control what changes from start
// and hide/show the in-browser controller
//
// Thanks :]
var anim;
var canvas2pixel = {
defaultVal: {
alphaThreshold: 10,
pixelSize: 5,
outlineSize: 0,
outlineColor: '#000',
expandEdges: true,
},
showController: true
}
var flaName;
var renderedFrames = {};
var currFrame;
function ID(obj) {
return document.getElementById(obj)
}
function createControllers() {
window.ctrlStyle = document.createElement('style');
ctrlStyle.innerHTML = `
#ctrlDiv{ display: ${canvas2pixel.showController ? "table-caption" : "none"}; width: 150px; position: absolute; right: 0; top: 0; padding: 15px; background-color: #fff5;}
#ctrlDiv * {display: inline-block; min-width: 30px; text-align: center; }
#ctrlDiv [type=color] {width: 100%; margin: 5px 0;}
canvas { filter: url(#strokeFilter); }
`;
document.getElementsByTagName('head')[0].appendChild(ctrlStyle);
window.ctrlSvg = document.createElement('div');
ctrlSvg.style.cssText= "width:0; height:0; overflow:hidden;"
window.ctrlDiv = document.createElement('div');
ctrlDiv.id = 'ctrlDiv';
ctrlDiv.style.display = canvas2pixel.showController ? "block" : "none";
ctrlDiv.style.position = "fixed";
ctrlDiv.innerHTML += `
Pixel Size: <label id="pixelSizeDisplay"></label><input type="range" step=".1" min="1" max="30" value="${canvas2pixel.defaultVal.pixelSize}" id="pixelSize" oninput="changePixelSize(this.value)">
Alpha Threshold: <label id="alphaThresholdDisplay"></label> <input type="range" step="1" min="1" max="100" value="${canvas2pixel.defaultVal.alphaThreshold}" id="alphaThreshold" oninput="changeAlphaThreshold(this.value)">
Outline Size: <label id="outlineSizeDisplay"></label> <input type="range" step=".1" min="0" max="30" value="${canvas2pixel.defaultVal.outlineSize}" id="outlineSize" oninput="changeAlphaThreshold(ID('alphaThreshold').value)">
Outline color: <input type="color" value="${canvas2pixel.defaultVal.outlineColor}" id="outlineColor" oninput="changeAlphaThreshold(ID('alphaThreshold').value)">
Expand Edges: <input type="checkbox" ${canvas2pixel.defaultVal.expandEdges == true ? 'checked': ''} id="expandEdges" oninput="changeAlphaThreshold(ID('alphaThreshold').value)">
<br><br>Frame: <a id="currFrame"></a>/<a id="durFrame"></a>
<br>Resolution:<a id="dispW"></a>x<a id="dispH"></a>
<br><br><input id="downloadBT" type="button" value="Rendering" onclick="initDownload()" disabled></input>
`
}
function changePixelSize(pixelNewSize = canvas2pixel.defaultVal.pixelSize) {
renderedFrames = {};
ID("pixelSizeDisplay").innerHTML = pixelNewSize;
stage.canvas.style.imageRendering = "pixelated";
stage.canvas.width = initialSize[0] / pixelNewSize;
stage.canvas.height = initialSize[1] / pixelNewSize;
stage.children[0].scaleX = 1 / pixelNewSize;
stage.children[0].scaleY = 1 / pixelNewSize;
changeAlphaThreshold(Number(ID("alphaThresholdDisplay").innerHTML));
}
function changeAlphaThreshold(feedArrayXtimes = canvas2pixel.defaultVal.alphaThreshold) {
renderedFrames = {};
var alphaTableVals = [0];
ID("alphaThresholdDisplay").innerHTML = feedArrayXtimes;
var pixelSize = Number(ID("pixelSizeDisplay").innerHTML)
for (var i = 0; i < feedArrayXtimes; i++) alphaTableVals.push(1 * ID('expandEdges').checked);
alphaTableVals.push(1);
createSVG(alphaTableVals, pixelSize);
ctx = stage.canvas.getContext("2d");
ctx.filter = "url(#pixelateFilter)"; //+"url(#strokeFilter)";
}
function createSVG(alphaTable = "0 1", strokeSize = 0) {
var outlineSize = ID('outlineSize').value;
var outlineColor = ID('outlineColor').value;
ID("outlineSizeDisplay").innerHTML = outlineSize;
ctrlSvg.innerHTML = `
<svg>
<filter id="pixelateFilter" color-interpolation-filters="sRGB">
<feComponentTransfer>
<feFuncA tableValues="${alphaTable}" type="discrete"/>
</feComponentTransfer>
</filter>
<filter id="strokeFilter" color-interpolation-filters="sRGB">
<feMorphology operator="dilate" radius="${strokeSize*outlineSize}" in="SourceAlpha" result="morphology"/>
<feFlood flood-color="${outlineColor}" flood-opacity="1" result="flood"/>
<feComposite in="flood" in2="morphology" operator="in" result="composite"/>
<feMerge result="merge">
<feMergeNode in="composite" result="mergeNode"/>
<feMergeNode in="SourceGraphic" result="mergeNode1"/>
</feMerge>
</filter>
</svg>
`
};
window.addEventListener('load', function() {
createControllers();
document.body.appendChild(ctrlDiv);
ctrlSvg = document.body.appendChild(ctrlSvg);
var interval = setInterval(function() {
if (typeof stage == 'undefined') return;
console.log('Element is ready');
var lib = AdobeAn.getComposition(AdobeAn.bootcompsLoaded[0]).getLibrary();
flaName = Object.getOwnPropertyNames(lib)[Object.getOwnPropertyNames(lib).length-3];
lib = '';
anim = stage.getChildAt(0);
clearInterval(interval);
ID("durFrame").innerHTML = stage.getChildAt(0).totalFrames;
createjs.Ticker.on("tick", tick);
function tick() {
currFrame = stage.getChildAt(0).currentFrame
//stage.getChildAt(0).jonas.text = currFrame;
ID("currFrame").innerHTML = currFrame;
ID("dispW").innerHTML = stage.canvas.width;
ID("dispH").innerHTML = stage.canvas.height;
if( stage.getChildAt(0).totalFrames == Object.keys(renderedFrames).length ) return ID("downloadBT").disabled = false, ID("downloadBT").value = "Download Frames";
ID("downloadBT").disabled = true, ID("downloadBT").value = "Rendering Frames"
renderedFrames[currFrame] = makeCanvas();
}
document.body.style.backgroundColor = "#5EC941";
initialSize = [stage.canvas.width, stage.canvas.height];
changePixelSize();
changeAlphaThreshold();
}, 10);
});
function padLeadingZeros(num, size) {
var s = num+"";
while (s.length < size) s = "0" + s;
return s;
}
this.makeCanvas = function() {
var dt = canvas.toDataURL('image/png');
this.href = dt.replace(/^data:image\/[^;]/, 'data:application/octet-stream');
return {"data": dt, "filename": flaName + "_" + padLeadingZeros(currFrame,4)};
};
function initDownload(){
Object.keys(renderedFrames).forEach(key => {
setTimeout(() => {
obj = renderedFrames[key];
console.log(obj.filename)
downloadImage(obj.data,obj.filename);
}, key*300);
});
}
function downloadImage(url, name){
fetch(url)
.then(resp => resp.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
// the filename you want
a.download = name;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
})
.catch(() => alert('An error sorry'));
};
- Hit
CTRL + Enter
to preview it!
Known Issues and Quirks
- Semi transparent pixels may not work. You can try adjusting the blending modes between graphics/Movieclip as a workaround.
- The outline generated by the code cannot be exported as an image.
- You may need to break the assets into different layers to see the transparency crop working properly.
- You will need to allow your browser to download multiple files in order to download all the exported images.
- Better results may be achieved by changing the background color to transparent.
Tips and Tricks
- Experiment with different canvas2pixel settings to achieve the desired appearance of your pixel art.
- You may want to double your animation size, since it gets downscaled being pixelated.
- For best results, try breaking your assets into different layers.
- Use Graphics/Movieclip
Blend Mode
instead of changes in opacity - If you are having trouble with transparent pixels, try changing the background color to transparent.
Need Help?
If you have any questions or need help using Flash 2 Pixelart, feel free to reach out for assistance. You can also consider posting your code to a code sharing platform like GitHub, where other developers may be able to review and contribute to it.