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

Flash 2 Pixelart - Experiments with Adobe Animate #1

Open
jetrotal opened this issue Jul 18, 2022 · 0 comments
Open

Flash 2 Pixelart - Experiments with Adobe Animate #1

jetrotal opened this issue Jul 18, 2022 · 0 comments

Comments

@jetrotal
Copy link
Owner

jetrotal commented Jul 18, 2022

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,

c

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

  1. Create a new HTML5 Canvas document in Adobe Animate:

image

  1. Press F9 to open the Actions Menu, and Select Global / Script:

image

  1. 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'));
};
  1. 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.

image image

@jetrotal jetrotal changed the title Experiments with Adobe Animate Flash 2 Pixelart - Experiments with Adobe Animate Dec 21, 2022
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