デザイナーからプログラマーへのファイル転送。 スクリプト

画像

モバイルデバイス用アプリケーションの開発者チームがあるとします。 そのようなチームには間違いなくデザイナーがいて、プログラマーは間違いなくいます。 最初に、彼らはそれぞれの仕事をします-プログラマーはプロトタイプ、メカニックを開発し、デザイナーはキー、背景のドラフトを作成します。 しかし、設計者がアプリケーションですでにそれを見るために彼の作品を転送しなければならない時が来ます。 そして、ここで困難が生じるかもしれません。



単一のメニュー画面の例でこれを考慮してください。 30〜40個のグラフィック要素を含めることができます。 これらは、キー(静的、押された)、10個のオブジェクトのアニメーション化されたロゴ、ポップアップメニュー、背景のアニメーションです。 ほとんどの場合、デザイナーは各ファイルを個別に発行し、プログラマーはそれを新しい方法で追加します。 したがって、デザイナーは数回折りたたまれたり展開したりします。 その後、設計が変更される可能性があり、すべてを新しい方法で行う必要があります。



このプロセスを可能な限り自動化する方法


ここでは、品質を損なうことなく最も便利な一連のファイルが設計者からプログラマーに届くようにするために使用するいくつかの手順を示します。



デザインのドラフトバージョンを含むAIの最大解像度(私の場合は2048 * 1536px) のソースファイル

-すべてのオブジェクトをレイヤーに分解およびグループ化します

-正しく名前を付けてください(ボタン-Btn、アイコン-アイコン、素材-アンダーレイ...)

-すべての要素の幅と高さを2pxの倍数にする

-すべての要素をXYで2pxの倍数で配置します

-各レイヤーのXY座標、その名前とシート上の位置をエクスポートします。 Illustratorはテキストファイルのエクスポート方法を知らないため、データはオブジェクトの最上位のレイヤー*テキスト*に配置されます。

XYレイヤー座標スクリプト
if (app.documents.length > 0) { var doc = app.activeDocument; var x, y, t; app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM; var count = doc.layers.length; var out_txt=""; for ( var i = 0; i < count; ++i) { doc.activeLayer = doc.layers[i]; doc.layers[i].hasSelectedArtwork = true; } for ( var i = 0; i < count; ++i) { x = doc.selection[i].position[0]; y = doc.selection[i].position[1]*(-1); // Layer name, X, Y, layer number out_txt += doc.layers[i].name + ";;;;x=" + x.toFixed(0) + ";;;;y=" + y.toFixed(0) + ";;;;" + i +"\n"; } //Create text frame in first layer on position 0,0 t = doc.layers[0].textFrames.add(); t.contents = out_txt; }
      
      







-各レイヤーを個別のPNG24ファイルにダブルサイズでエクスポートします。 アークティックミル

レイヤーをPNGファイルとしてエクスポート
 // *** Export Layers as PNG files (in multiple resolutions) *** // This script will export all layers that have a name starting with "#", or "%" into a subfolder of the current .ai document. // These options can be configured below: // *** Config options *** var subFolderName = "Export"; var saveInMultipleResolutions = true; // ... // Note: only use one character! var exportLayersStartingWith = "#"; var exportLayersWithArtboardClippingStartingWith = "%"; // ... var lowResolutionFileAppend = "@Low"; var normalResolutionFileAppend = "-ipad"; var highResolutionFileAppend = "-ipadhd"; // ... var lowResolutionScale = 50; var normalResolutionScale = 100; var highResolutionScale = 200; // *** Start of script *** var doc = app.activeDocument; // Make sure we have saved the document if (doc.path != "") { // Check if we need to create the export directory or we will get errors up ahead var exportDirectoryPath = doc.path + "/" + subFolderName; var exportDirectory = new Folder(exportDirectoryPath); if (!exportDirectory.exists) { // We must create the export directory it seems var newFolder = new Folder(exportDirectoryPath); newFolder.create(); } var layerData = new Array(); // Finds all layers that should be saved and saves these to the export layers array collectLayerData(doc, null); var layersToExportCount = 0; for (var i = 0; i < layerData.length; i++) { if ((layerData[i].tag == "include") || (layerData[i].tag == "include_and_clip")) { // Hide all layers first hideAllLayers(); var clipToArtboard = false; if (layerData[i].tag == "include_and_clip") { clipToArtboard = true; } // Now show all layers needed to actually display the current layer on screen layerData[i].showIncludingParentAndChildLayers(); //showIncludingParents(); // Now we can export the layer as one or multiple PNG files! var savePath = doc.path; // Save to same folder as document but in a sub directory if (saveInMultipleResolutions) { // iPhone 3GS (50%) savePath.changePath(subFolderName + "/" + layerData[i].layer.name.substring(1, layerData[i].layer.name.length) + fixFileAppend(lowResolutionFileAppend)); savePNG(savePath, lowResolutionScale, clipToArtboard); savePath = doc.path; // iPhone 4 (100%) savePath.changePath(subFolderName + "/" + layerData[i].layer.name.substring(1, layerData[i].layer.name.length) + fixFileAppend(normalResolutionFileAppend)); savePNG(savePath, normalResolutionScale, clipToArtboard); savePath = doc.path; // iPad Retina (200%) savePath.changePath(subFolderName + "/" + layerData[i].layer.name.substring(1, layerData[i].layer.name.length) + fixFileAppend(highResolutionFileAppend)); savePNG(savePath, highResolutionScale, clipToArtboard); } else { // Save normally (100%) savePath.changePath(subFolderName + "/" + layerData[i].layer.name.substring(1, layerData[i].layer.name.length)); savePNG(savePath, normalResolutionScale, clipToArtboard); } layersToExportCount++; } } // Restore everything like it was before! restoreAllLayers(); // Was there anything exported? If not make a warning! if (layersToExportCount == 0) { alert("Ooops, Found no layers to export!\n\nRemember that you must add a \"" + exportLayersStartingWith + "\" (when exporting the layer cropped to it's bound) or \"" + exportLayersWithArtboardClippingStartingWith + "\" (when layer should be clipped to artboard) to the beginning of the layer name. Also make sure that they layers you want to export are not locked or hidden."); } else { // Show a completed message alert(layersToExportCount + " layer(s) was successfully exported to: \n" + exportDirectoryPath); } } else { // Document not saved yet! alert("Sorry, but you must save your document before you can use the export layers script! This is because exported images are saved in a subfolder to your original file."); } function fixFileAppend(fileAppend) { if (fileAppend == "") { return ""; } else { return fileAppend + ".png"; } } function hideAllLayers() { for (var i = 0; i < layerData.length; i++) { layerData[i].hide(); } } function restoreAllLayers() { for (var i = 0; i < layerData.length; i++) { layerData[i].restoreVisibility(); } } // Collects information about the various layers function collectLayerData(rootLayer, extendedRootLayer) { for (var i = 0; i < rootLayer.layers.length; i++) { // We never even process locked or hidden layers if ((!rootLayer.layers[i].locked) && (rootLayer.layers[i].visible)) { var extendedLayer = new ExtendedLayer(rootLayer.layers[i]); // Set up parent extendedLayer.parentLayer = extendedRootLayer; // Also add this layer to the parents child collection if (extendedRootLayer != null) { extendedRootLayer.childLayers.push(extendedLayer); } layerData.push(extendedLayer); // Tag these layers so that we later can find out if we should export these layers or not if (rootLayer.layers[i].name.substring(0, 1) == exportLayersStartingWith) { extendedLayer.tag = "include"; } else if (rootLayer.layers[i].name.substring(0, 1) == exportLayersWithArtboardClippingStartingWith) { extendedLayer.tag = "include_and_clip"; } else { extendedLayer.tag = "skip"; } // We should not export this layer but we continue looking for sub layers that might need to be exported collectLayerData(rootLayer.layers[i], extendedLayer); } } } // Holds info and additional methods for layers function ExtendedLayer(layer) { this.originalVisibility = layer.visible; this.layer = layer; this.tag = ""; this.hide = hide; this.show = show; this.showIncludingParentAndChildLayers = showIncludingParentAndChildLayers; this.restoreVisibility = restoreVisibility; this.restoreVisibilityIncludingChildLayers = restoreVisibilityIncludingChildLayers; this.layerName = layer.name; // Set after creating this.childLayers = new Array(); this.parentLayer = null; function hide() { layer.visible = false; } function show() { layer.visible = true; } // Shows this layer including it's parent layers (up to the root) and it's child layers function showIncludingParentAndChildLayers() { var parentlayerName = ""; if (this.parentLayer != null) { parentlayerName = this.parentLayer.layerName; } // Show all parents first var aParentLayer = this.parentLayer; while (aParentLayer != null) { aParentLayer.restoreVisibility(); // Keep looking aParentLayer = aParentLayer.parentLayer; } // Show our own layer finally this.restoreVisibilityIncludingChildLayers(); } function restoreVisibility() { layer.visible = this.originalVisibility; } function restoreVisibilityIncludingChildLayers() { this.restoreVisibility(); // Call recursively for each child layer for (var i = 0; i < this.childLayers.length; i++) { this.childLayers[i].restoreVisibilityIncludingChildLayers(); } } } // Save PNG file function savePNG(file, scale, artBoardClipping) { var exp = new ExportOptionsPNG24(); exp.transparency = true; exp.horizontalScale = scale exp.verticalScale = scale; exp.artBoardClipping = artBoardClipping; doc.exportFile(file, ExportType.PNG24, exp); }
      
      







-ZwoptexまたはTexture Packerを使用して、これらのファイルから4096 * 4096サイズ(または小さいが、必ずしも正方形)のアトラスを作成します。 8px画像をインデントしてください

-ベクターファイルで2pxの多重度を無視した場合に発生する透明性の問題を回避します。 幸いなことにPhotoshop AlphaUnityのアクションがあります

画像

-アトラスを2倍減らす

-PNG8のファイルを追い越す



したがって、プログラマーは、写真の名前、座標、シート上の位置、座標と回転を含むPLISTまたはXML、最適な品質の写真のアトラス、およびプレビューを含むテキストファイルを私から受け取ります。 設計者もプログラマもこのルーチンに参加したくはないが、非常に必要な手順を実行したいということが起こりました。



このようなアクションのアルゴリズムは、初めて難しく、長くなりますが、プロジェクトのすべての参加者の生活を大幅に簡素化します。



スクリプトとアクションへのリンク。 Github



All Articles