mirror of
https://github.com/BlackMATov/unity-flash-tools.git
synced 2025-12-13 11:39:54 +07:00
959 lines
31 KiB
JavaScript
959 lines
31 KiB
JavaScript
ft_main = function (external_ft, opts) {
|
|
ft = external_ft;
|
|
opts = opts || {};
|
|
|
|
//
|
|
// config
|
|
//
|
|
|
|
var cfg = {
|
|
profile_mode : opts.profile_mode === undefined ? false : opts.profile_mode,
|
|
verbose_mode : opts.verbose_mode === undefined ? false : opts.verbose_mode,
|
|
|
|
graphics_scale : opts.graphics_scale === undefined ? 1.0 : opts.graphics_scale,
|
|
scale_precision : opts.scale_precision === undefined ? 0.01 : opts.scale_precision,
|
|
|
|
optimize_big_items : opts.optimize_big_items === undefined ? true : opts.optimize_big_items,
|
|
optimize_small_items : opts.optimize_small_items === undefined ? true : opts.optimize_small_items,
|
|
optimize_static_items : opts.optimize_static_items === undefined ? true : opts.optimize_static_items,
|
|
optimize_single_graphics : opts.optimize_single_graphics === undefined ? true : opts.optimize_single_graphics,
|
|
|
|
open_documents : opts.open_documents === undefined ? [] : opts.open_documents,
|
|
export_path_postfix : opts.export_path_postfix === undefined ? "_export" : opts.export_path_postfix,
|
|
close_after_conversion : opts.close_after_conversion === undefined ? false : opts.close_after_conversion,
|
|
revert_after_conversion : opts.revert_after_conversion === undefined ? true : opts.revert_after_conversion,
|
|
max_convertible_selection : opts.max_convertible_selection === undefined ? 3900 : opts.max_convertible_selection
|
|
};
|
|
|
|
//
|
|
// document
|
|
//
|
|
|
|
var ftdoc = {};
|
|
|
|
ftdoc.prepare = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.prepare_folders(doc); }, "Prepare folders");
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.full_exit_edit_mode(doc); }, "Full exit edit mode");
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.remove_unused_items(doc); }, "Remove unused items");
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.prepare_all_bitmaps(doc); }, "Prepare all bitmaps");
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.unlock_all_timelines(doc); }, "Unlock all timelines");
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.prepare_all_tweens(doc); }, "Prepare all tweens");
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.prepare_all_groups(doc); }, "Prepare all groups");
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.calculate_item_scales(doc); }, "Calculate item scales");
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.optimize_all_timelines(doc); }, "Optimize all timelines");
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.rasterize_all_shapes(doc); }, "Rasterize all shapes");
|
|
ft.profile_function(cfg.profile_mode, function() { ftdoc.export_swf(doc); }, "Export swf");
|
|
};
|
|
|
|
ftdoc.get_temp = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
if (!ftdoc.get_temp_ft_temp) {
|
|
ftdoc.get_temp_ft_temp = {};
|
|
}
|
|
if (!ftdoc.get_temp_ft_temp[doc.pathURI]) {
|
|
ftdoc.get_temp_ft_temp[doc.pathURI] = {
|
|
max_scales : {}
|
|
};
|
|
}
|
|
return ftdoc.get_temp_ft_temp[doc.pathURI];
|
|
};
|
|
|
|
ftdoc.calculate_item_prefer_scale = function (doc, optional_item) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert_if_defined(optional_item, LibraryItem);
|
|
var final_scale = cfg.graphics_scale;
|
|
if (optional_item && (cfg.optimize_big_items || cfg.optimize_small_items)) {
|
|
var item_name = optional_item.name;
|
|
var max_scales = ftdoc.get_temp(doc).max_scales;
|
|
if (max_scales && max_scales.hasOwnProperty(item_name)) {
|
|
var max_scale = max_scales[item_name];
|
|
var big_item = cfg.optimize_big_items && (max_scale - cfg.scale_precision > 1.0);
|
|
var small_item = cfg.optimize_small_items && (max_scale + cfg.scale_precision < 1.0);
|
|
if (big_item || small_item) {
|
|
final_scale *= max_scale;
|
|
}
|
|
}
|
|
}
|
|
return final_scale;
|
|
};
|
|
|
|
ftdoc.convert_selection_to_bitmap = function (doc, location_name, optional_item) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(location_name, 'string');
|
|
ft.type_assert_if_defined(optional_item, LibraryItem);
|
|
|
|
var selection_r = doc.getSelectionRect();
|
|
if ( selection_r ) { // getSelectionRect returns 0 for empty clips
|
|
var selection_w = selection_r.right - selection_r.left;
|
|
var selection_h = selection_r.bottom - selection_r.top;
|
|
|
|
var max_scale = cfg.max_convertible_selection / Math.max(selection_w, selection_h);
|
|
var prefer_scale = ftdoc.calculate_item_prefer_scale(doc, optional_item);
|
|
var final_scale = Math.min(prefer_scale, max_scale);
|
|
|
|
if (final_scale < prefer_scale) {
|
|
var down_scale = Math.floor(final_scale / prefer_scale * 1000) * 0.001;
|
|
ft.trace_fmt(
|
|
"[Warning] {0}\n" +
|
|
"- Converted element was downscaled ({1}x) to maximum allowed size ({2}px)",
|
|
location_name, down_scale, cfg.max_convertible_selection);
|
|
}
|
|
|
|
if (ft.approximately(final_scale, 1.0, cfg.scale_precision)) {
|
|
(function() {
|
|
var elem_r = doc.getSelectionRect();
|
|
|
|
var elem_x = elem_r.left;
|
|
var elem_y = elem_r.top;
|
|
var elem_w = elem_r.right - elem_r.left;
|
|
var elem_h = elem_r.bottom - elem_r.top;
|
|
|
|
var elem_dx = Math.round(elem_x) - elem_x;
|
|
var elem_dy = Math.round(elem_y) - elem_y;
|
|
var elem_dw = Math.round(elem_w) - elem_w;
|
|
var elem_dh = Math.round(elem_h) - elem_h;
|
|
|
|
doc.convertSelectionToBitmap();
|
|
var elem = doc.selection[0];
|
|
|
|
elem.x -= elem_dx;
|
|
elem.y -= elem_dy;
|
|
elem.width -= elem_dw;
|
|
elem.height -= elem_dh;
|
|
})();
|
|
} else {
|
|
(function() {
|
|
var wrapper_item_name = ft.gen_unique_name();
|
|
var wrapper_item = doc.convertToSymbol("graphic", wrapper_item_name , "top left");
|
|
fttim.recursive_scale_filters(doc, wrapper_item, final_scale);
|
|
|
|
var elem = doc.selection[0];
|
|
elem.setTransformationPoint({x: 0, y: 0});
|
|
doc.scaleSelection(final_scale, final_scale);
|
|
|
|
var elem_x = elem.x;
|
|
var elem_y = elem.y;
|
|
var elem_w = elem.width;
|
|
var elem_h = elem.height;
|
|
|
|
var elem_dx = Math.round(elem_x) - elem_x;
|
|
var elem_dy = Math.round(elem_y) - elem_y;
|
|
var elem_dw = Math.round(elem_w) - elem_w;
|
|
var elem_dh = Math.round(elem_h) - elem_h;
|
|
|
|
doc.convertSelectionToBitmap();
|
|
elem = doc.selection[0];
|
|
|
|
elem.x -= elem_dx;
|
|
elem.y -= elem_dy;
|
|
elem.width -= elem_dw;
|
|
elem.height -= elem_dh;
|
|
|
|
elem.setTransformationPoint({x: (elem_x - elem.x), y: (elem_y - elem.y)});
|
|
doc.scaleSelection(1.0 / final_scale, 1.0 / final_scale);
|
|
|
|
fttim.recursive_scale_filters(doc, wrapper_item, 1.0 / final_scale);
|
|
})();
|
|
}
|
|
}
|
|
};
|
|
|
|
ftdoc.prepare_folders = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
var export_folder = ftdoc.get_export_folder(doc);
|
|
if (!FLfile.exists(export_folder) && !FLfile.createFolder(export_folder)) {
|
|
throw "Can't create document export folder ({0})!"
|
|
.format(export_folder);
|
|
}
|
|
};
|
|
|
|
ftdoc.get_export_folder = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
return ft.combine_path(
|
|
ft.escape_path(doc.pathURI),
|
|
cfg.export_path_postfix + "/");
|
|
};
|
|
|
|
ftdoc.full_exit_edit_mode = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
for (var i = 0; i < 100; ++i) {
|
|
doc.exitEditMode();
|
|
}
|
|
};
|
|
|
|
ftdoc.remove_unused_items = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
var unused_items = doc.library.unusedItems;
|
|
if (unused_items && unused_items !== undefined) {
|
|
ft.array_reverse_foreach(unused_items, function(item) {
|
|
if (cfg.verbose_mode) {
|
|
ft.trace_fmt("Remove unused item: {0}", item.name);
|
|
}
|
|
doc.library.deleteItem(item.name);
|
|
});
|
|
}
|
|
};
|
|
|
|
ftdoc.prepare_all_bitmaps = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
ftlib.prepare_all_bitmaps(doc.library);
|
|
};
|
|
|
|
ftdoc.unlock_all_timelines = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
ftlib.unlock_all_timelines(doc, doc.library);
|
|
fttim.unlock_all_layers(doc, doc.getTimeline());
|
|
};
|
|
|
|
ftdoc.prepare_all_tweens = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
ftlib.prepare_all_tweens(doc, doc.library);
|
|
fttim.prepare_all_tweens(doc, doc.getTimeline());
|
|
};
|
|
|
|
ftdoc.prepare_all_groups = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
var arr1 = ftlib.prepare_all_groups(doc, doc.library);
|
|
var arr2 = fttim.prepare_all_groups(doc, doc.getTimeline());
|
|
var new_symbols = arr1.concat(arr2);
|
|
var process_item = function (item) {
|
|
if (doc.library.editItem(item.name)) {
|
|
var arr3 = fttim.prepare_all_groups(doc, item.timeline);
|
|
new_symbols = new_symbols.concat(arr3);
|
|
doc.exitEditMode();
|
|
}
|
|
};
|
|
while (new_symbols.length > 0) {
|
|
var new_symbols_copy = ft.array_clone(new_symbols);
|
|
new_symbols = [];
|
|
ft.array_foreach(new_symbols_copy, process_item);
|
|
}
|
|
};
|
|
|
|
ftdoc.calculate_item_scales = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
|
|
var max_scales = {};
|
|
|
|
var walk_by_timeline = function(timeline, func, acc) {
|
|
ft.type_assert(timeline, Timeline);
|
|
ft.type_assert(func, Function);
|
|
ft.array_foreach(timeline.layers, function (layer) {
|
|
ft.array_foreach(layer.frames, function (frame) {
|
|
ft.array_foreach(frame.elements, function (elem) {
|
|
walk_by_timeline(
|
|
elem.libraryItem.timeline,
|
|
func,
|
|
func(elem, acc));
|
|
}, fttim.is_symbol_instance);
|
|
}, fttim.is_keyframe);
|
|
});
|
|
};
|
|
|
|
var walk_by_library = function(lib, func, acc) {
|
|
ft.type_assert(lib, Library);
|
|
ft.type_assert(func, Function);
|
|
ft.array_foreach(lib.items, function (item) {
|
|
walk_by_timeline(item.timeline, func, acc);
|
|
}, ftlib.is_symbol_item);
|
|
};
|
|
|
|
var x_func = function(elem, acc) {
|
|
var elem_sx = elem.scaleX * acc;
|
|
var item_name = elem.libraryItem.name;
|
|
max_scales[item_name] = Math.max(
|
|
max_scales.hasOwnProperty(item_name) ? max_scales[item_name] : elem_sx,
|
|
elem_sx);
|
|
return elem_sx;
|
|
};
|
|
|
|
var y_func = function(elem, acc) {
|
|
var elem_sy = elem.scaleY * acc;
|
|
var item_name = elem.libraryItem.name;
|
|
max_scales[item_name] = Math.max(
|
|
max_scales.hasOwnProperty(item_name) ? max_scales[item_name] : elem_sy,
|
|
elem_sy);
|
|
return elem_sy;
|
|
};
|
|
|
|
walk_by_library(doc.library, x_func, 1.0);
|
|
walk_by_timeline(doc.getTimeline(), x_func, 1.0);
|
|
|
|
walk_by_library(doc.library, y_func, 1.0);
|
|
walk_by_timeline(doc.getTimeline(), y_func, 1.0);
|
|
|
|
ftdoc.get_temp(doc).max_scales = max_scales;
|
|
|
|
if (cfg.verbose_mode) {
|
|
for (var item_name in max_scales) {
|
|
var max_scale = max_scales.hasOwnProperty(item_name) ? max_scales[item_name] : 1.0;
|
|
if (max_scale - cfg.scale_precision > 1.0) {
|
|
ft.trace_fmt("Big item for optimize: {0} - {1}", item_name, max_scale);
|
|
} else if (max_scale + cfg.scale_precision < 1.0) {
|
|
ft.trace_fmt("Small item for optimize: {0} - {1}", item_name, max_scale);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
ftdoc.optimize_all_timelines = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
if (cfg.optimize_static_items) {
|
|
ft.profile_function(cfg.profile_mode, function () {
|
|
ftlib.optimize_static_items(doc, doc.library);
|
|
}, "Optimize static items");
|
|
}
|
|
if (cfg.optimize_single_graphics) {
|
|
ft.profile_function(cfg.profile_mode, function () {
|
|
ftlib.optimize_single_graphics(doc, doc.library);
|
|
}, "Optimize single graphics");
|
|
}
|
|
};
|
|
|
|
ftdoc.rasterize_all_shapes = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
ftlib.rasterize_all_shapes(doc, doc.library);
|
|
fttim.rasterize_all_shapes(doc, doc.getTimeline());
|
|
};
|
|
|
|
ftdoc.export_swf = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
doc.exportSWF(ftdoc.get_export_swf_path(doc));
|
|
};
|
|
|
|
ftdoc.get_export_swf_path = function (doc) {
|
|
ft.type_assert(doc, Document);
|
|
return ft.combine_path(
|
|
ftdoc.get_export_folder(doc),
|
|
doc.name + ".swf");
|
|
};
|
|
|
|
//
|
|
// library
|
|
//
|
|
|
|
var ftlib = {};
|
|
|
|
ftlib.is_folder_item = function (item) {
|
|
ft.type_assert(item, LibraryItem);
|
|
return item.itemType == "folder";
|
|
};
|
|
|
|
ftlib.is_bitmap_item = function (item) {
|
|
ft.type_assert(item, LibraryItem);
|
|
return item.itemType == "bitmap";
|
|
};
|
|
|
|
ftlib.is_symbol_item = function (item) {
|
|
ft.type_assert(item, LibraryItem);
|
|
return item.itemType == "button" || item.itemType == "graphic" || item.itemType == "movie clip";
|
|
};
|
|
|
|
ftlib.find_item_by_name = function (library, item_name) {
|
|
ft.type_assert(library, Library);
|
|
ft.type_assert(item_name, 'string');
|
|
for (var i = 0; i < library.items.length; ++i) {
|
|
var item = library.items[i];
|
|
if (item.name == item_name) {
|
|
return item;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
|
|
ftlib.edit_all_items = function (doc, library, func, filter) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(library, Library);
|
|
ft.type_assert(func, Function);
|
|
ft.type_assert_if_defined(filter, Function);
|
|
ft.array_foreach(library.items, function (item) {
|
|
if (library.editItem(item.name)) {
|
|
func(item);
|
|
doc.exitEditMode();
|
|
}
|
|
}, filter);
|
|
};
|
|
|
|
ftlib.edit_all_symbol_items = function (doc, library, func) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(library, Library);
|
|
ft.type_assert(func, Function);
|
|
ftlib.edit_all_items(doc, library, func, ftlib.is_symbol_item);
|
|
};
|
|
|
|
ftlib.prepare_all_bitmaps = function (library) {
|
|
ft.type_assert(library, Library);
|
|
ft.array_foreach(library.items, function (item) {
|
|
item.compressionType = "lossless";
|
|
}, ftlib.is_bitmap_item);
|
|
};
|
|
|
|
ftlib.unlock_all_timelines = function (doc, library) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(library, Library);
|
|
ftlib.edit_all_symbol_items(doc, library, function (item) {
|
|
fttim.unlock_all_layers(doc, item.timeline);
|
|
});
|
|
};
|
|
|
|
ftlib.optimize_static_items = function (doc, library) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(library, Library);
|
|
|
|
var replaces = {};
|
|
ft.array_reverse_foreach(library.items, function (item) {
|
|
var new_item_name = ft.gen_unique_name();
|
|
if (ftlib.bake_symbol_item(doc, library, item.name, new_item_name, 0)) {
|
|
replaces[item.name] = new_item_name;
|
|
if (cfg.verbose_mode) {
|
|
ft.trace_fmt("Optimize static item: '{0}'", item.name);
|
|
}
|
|
} else {
|
|
if (cfg.verbose_mode) {
|
|
ft.trace_fmt("NOT Optimize static item: '{0}'", item.name);
|
|
}
|
|
}
|
|
}, function (item) {
|
|
return ftlib.is_symbol_item(item) && fttim.is_static(item.timeline);
|
|
});
|
|
|
|
ftlib.edit_all_symbol_items(doc, library, function (item) {
|
|
fttim.replace_baked_symbols(doc, item.timeline, replaces);
|
|
});
|
|
fttim.replace_baked_symbols(doc, doc.getTimeline(), replaces);
|
|
};
|
|
|
|
ftlib.bake_symbol_item = function (doc, library, item_name, new_item_name, first_frame) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(library, Library);
|
|
ft.type_assert(item_name, 'string');
|
|
ft.type_assert(new_item_name, 'string');
|
|
ft.type_assert(first_frame, 'number');
|
|
|
|
if (library.itemExists(new_item_name)) {
|
|
return true;
|
|
}
|
|
|
|
var item = ftlib.find_item_by_name(library, item_name);
|
|
if (!item) {
|
|
return false;
|
|
}
|
|
|
|
var item_frame_area = fttim.calculate_frame_area(item.timeline, first_frame);
|
|
var item_elems_area = fttim.calculate_elems_area(item.timeline, first_frame);
|
|
|
|
if (cfg.verbose_mode) {
|
|
ft.trace_fmt(
|
|
"Library item: '{0}'\n- frame area: {1}\n- elems area: {2}",
|
|
item_name, item_frame_area, item_elems_area);
|
|
}
|
|
|
|
if (item_frame_area >= item_elems_area) {
|
|
return false;
|
|
}
|
|
|
|
if (!library.addNewItem("graphic", new_item_name)) {
|
|
return false;
|
|
}
|
|
|
|
if (!library.editItem(new_item_name)) {
|
|
library.deleteItem(new_item_name);
|
|
return false;
|
|
}
|
|
|
|
if (library.addItemToDocument({x: 0, y: 0}, item_name)) {
|
|
var new_item_elem = doc.selection[0];
|
|
new_item_elem.symbolType = "graphic";
|
|
new_item_elem.firstFrame = first_frame;
|
|
new_item_elem.setTransformationPoint({x: 0, y: 0});
|
|
new_item_elem.transformX = 0;
|
|
new_item_elem.transformY = 0;
|
|
var location_name = "Symbol: {0}".format(item_name);
|
|
ftdoc.convert_selection_to_bitmap(doc, location_name, item);
|
|
doc.exitEditMode();
|
|
return true;
|
|
} else {
|
|
doc.exitEditMode();
|
|
library.deleteItem(new_item_name);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
ftlib.optimize_single_graphics = function (doc, library) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(library, Library);
|
|
ft.array_reverse_foreach(library.items, function (item) {
|
|
fttim.optimize_single_graphics(doc, item.timeline, item);
|
|
}, ftlib.is_symbol_item);
|
|
fttim.optimize_single_graphics(doc, doc.getTimeline(), null);
|
|
};
|
|
|
|
ftlib.rasterize_all_shapes = function (doc, library) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(library, Library);
|
|
ftlib.edit_all_symbol_items(doc, library, function (item) {
|
|
fttim.rasterize_all_shapes(doc, item.timeline);
|
|
});
|
|
};
|
|
|
|
ftlib.prepare_all_tweens = function (doc, library) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(library, Library);
|
|
ftlib.edit_all_symbol_items(doc, library, function (item) {
|
|
fttim.prepare_all_tweens(doc, item.timeline);
|
|
});
|
|
};
|
|
|
|
ftlib.prepare_all_groups = function (doc, library) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(library, Library);
|
|
var new_symbols = [];
|
|
ftlib.edit_all_symbol_items(doc, library, function (item) {
|
|
var arr = fttim.prepare_all_groups(doc, item.timeline);
|
|
new_symbols = new_symbols.concat(arr);
|
|
});
|
|
return new_symbols;
|
|
};
|
|
|
|
//
|
|
// timeline
|
|
//
|
|
|
|
var fttim = {};
|
|
|
|
fttim.is_element_locked = function (elem) {
|
|
return elem.locked;
|
|
};
|
|
|
|
fttim.is_shape_element = function (elem) {
|
|
return elem.elementType == "shape";
|
|
};
|
|
|
|
fttim.is_group_shape_element = function (elem) {
|
|
return fttim.is_shape_element(elem) && elem.isGroup;
|
|
};
|
|
|
|
fttim.is_object_shape_element = function (elem) {
|
|
return fttim.is_shape_element(elem) && elem.isDrawingObject;
|
|
};
|
|
|
|
fttim.is_simple_shape_element = function (elem) {
|
|
return fttim.is_shape_element(elem) && !elem.isGroup && !elem.isDrawingObject;
|
|
};
|
|
|
|
fttim.is_complex_shape_element = function (elem) {
|
|
return fttim.is_shape_element(elem) && (elem.isGroup || elem.isDrawingObject);
|
|
};
|
|
|
|
fttim.is_instance_element = function (elem) {
|
|
return elem.elementType == "instance";
|
|
};
|
|
|
|
fttim.is_bitmap_instance = function (elem) {
|
|
return fttim.is_instance_element(elem) && elem.instanceType == "bitmap";
|
|
};
|
|
|
|
fttim.is_symbol_instance = function (elem) {
|
|
return fttim.is_instance_element(elem) && elem.instanceType == "symbol";
|
|
};
|
|
|
|
fttim.is_symbol_graphic_instance = function (elem) {
|
|
return fttim.is_symbol_instance(elem) && elem.symbolType == "graphic";
|
|
};
|
|
|
|
fttim.is_symbol_graphic_single_frame_instance = function (elem) {
|
|
return fttim.is_symbol_instance(elem) && elem.symbolType == "graphic" && elem.loop == "single frame";
|
|
};
|
|
|
|
fttim.is_symbol_movie_clip_instance = function (elem) {
|
|
return fttim.is_symbol_instance(elem) && elem.symbolType == "movie clip";
|
|
};
|
|
|
|
fttim.is_tween_frame = function (frame) {
|
|
ft.type_assert(frame, Frame);
|
|
return frame.tweenType != "none";
|
|
};
|
|
|
|
fttim.is_shape_tween_frame = function (frame) {
|
|
ft.type_assert(frame, Frame);
|
|
return frame.tweenType == "shape";
|
|
};
|
|
|
|
fttim.is_motion_tween_frame = function (frame) {
|
|
ft.type_assert(frame, Frame);
|
|
return frame.tweenType == "motion";
|
|
};
|
|
|
|
fttim.is_keyframe = function (frame, frame_index) {
|
|
ft.type_assert(frame, Frame);
|
|
ft.type_assert(frame_index, 'number');
|
|
return frame.startFrame == frame_index;
|
|
};
|
|
|
|
fttim.is_not_guide_layer = function(layer) {
|
|
ft.type_assert(layer, Layer);
|
|
return layer.layerType != "guide";
|
|
};
|
|
|
|
fttim.unlock_all_layers = function (doc, timeline) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(timeline, Timeline);
|
|
ft.array_foreach(timeline.layers, function (layer, layer_index) {
|
|
layer.locked = false;
|
|
layer.visible = true;
|
|
ft.array_foreach(layer.frames, function (frame, frame_index) {
|
|
var has_locked = ft.array_any(frame.elements, fttim.is_element_locked);
|
|
if (has_locked) {
|
|
timeline.currentFrame = frame_index;
|
|
try {
|
|
doc.unlockAllElements();
|
|
} catch (e) {}
|
|
}
|
|
}, fttim.is_keyframe);
|
|
});
|
|
};
|
|
|
|
fttim.calculate_elems_area = function (timeline, frame_index) {
|
|
ft.type_assert(timeline, Timeline);
|
|
ft.type_assert(frame_index, 'number');
|
|
return ft.array_foldl(timeline.layers, function (layer, acc) {
|
|
if (frame_index >= 0 && frame_index < layer.frames.length) {
|
|
return ft.array_foldl(layer.frames[frame_index].elements, function (elem, acc2) {
|
|
return acc2 + Math.round(elem.width) * Math.round(elem.height);
|
|
}, acc);
|
|
} else {
|
|
return acc;
|
|
}
|
|
}, 0);
|
|
};
|
|
|
|
fttim.calculate_frame_area = function (timeline, frame_index) {
|
|
ft.type_assert(timeline, Timeline);
|
|
ft.type_assert(frame_index, 'number');
|
|
var bounds = ft.array_foldl(timeline.layers, function (layer, acc) {
|
|
if (frame_index >= 0 && frame_index < layer.frames.length) {
|
|
return ft.array_foldl(layer.frames[frame_index].elements, function (elem, acc2) {
|
|
acc2.left = Math.min(acc2.left, elem.left);
|
|
acc2.right = Math.max(acc2.right, elem.left + elem.width);
|
|
acc2.top = Math.min(acc2.top, elem.top);
|
|
acc2.bottom = Math.max(acc2.bottom, elem.top + elem.height);
|
|
return acc2;
|
|
}, acc);
|
|
} else {
|
|
return acc;
|
|
}
|
|
}, {
|
|
left: Number.POSITIVE_INFINITY,
|
|
right: Number.NEGATIVE_INFINITY,
|
|
top: Number.POSITIVE_INFINITY,
|
|
bottom: Number.NEGATIVE_INFINITY
|
|
});
|
|
var frame_width = Math.max(0, bounds.right - bounds.left);
|
|
var frame_height = Math.max(0, bounds.bottom - bounds.top);
|
|
return Math.round(frame_width) * Math.round(frame_height);
|
|
};
|
|
|
|
fttim.scale_elem_filters = function (elem, scale) {
|
|
if (fttim.is_symbol_instance(elem)) {
|
|
var elem_filters = elem.filters;
|
|
if (elem_filters && elem_filters !== undefined) {
|
|
ft.array_foreach(elem_filters, function (elem_filter, filter_index) {
|
|
elem_filter.blurX *= scale;
|
|
elem_filter.blurY *= scale;
|
|
});
|
|
elem.filters = elem_filters;
|
|
}
|
|
}
|
|
if (fttim.is_group_shape_element(elem)) {
|
|
ft.array_foreach(elem.members, function(member) {
|
|
fttim.scale_elem_filters(member, scale);
|
|
});
|
|
}
|
|
};
|
|
|
|
fttim.recursive_scale_filters = function (doc, item, scale, optional_scaled_items) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(item, LibraryItem);
|
|
ft.type_assert(scale, 'number');
|
|
ft.type_assert_if_defined(optional_scaled_items, Array);
|
|
|
|
var scaled_items = optional_scaled_items || [];
|
|
if (ft.array_contains(scaled_items, item)) {
|
|
return;
|
|
} else {
|
|
scaled_items.push(item);
|
|
}
|
|
|
|
ft.array_foreach(item.timeline.layers, function (layer) {
|
|
ft.array_foreach(layer.frames, function (frame, frame_index) {
|
|
ft.array_foreach(frame.elements, function (elem) {
|
|
fttim.scale_elem_filters(elem, scale);
|
|
if (fttim.is_group_shape_element(elem)) {
|
|
ft.array_foreach(elem.members, function(member) {
|
|
fttim.recursive_scale_filters(doc, member.libraryItem, scale, scaled_items);
|
|
}, fttim.is_symbol_instance);
|
|
}
|
|
if (fttim.is_symbol_instance(elem)) {
|
|
fttim.recursive_scale_filters(doc, elem.libraryItem, scale, scaled_items);
|
|
}
|
|
});
|
|
}, fttim.is_keyframe);
|
|
}, fttim.is_not_guide_layer);
|
|
};
|
|
|
|
fttim.replace_baked_symbols = function (doc, timeline, replaces) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(timeline, Timeline);
|
|
ft.array_foreach(timeline.layers, function (layer) {
|
|
ft.array_foreach(layer.frames, function (frame, frame_index) {
|
|
timeline.currentFrame = frame_index;
|
|
doc.selectNone();
|
|
ft.array_foreach(frame.elements, function (elem) {
|
|
if (replaces.hasOwnProperty(elem.libraryItem.name)) {
|
|
doc.selectNone();
|
|
doc.selection = [elem];
|
|
doc.swapElement(replaces[elem.libraryItem.name]);
|
|
}
|
|
}, fttim.is_symbol_instance);
|
|
}, fttim.is_keyframe);
|
|
}, fttim.is_not_guide_layer);
|
|
};
|
|
|
|
fttim.optimize_single_graphics = function (doc, timeline, opt_item) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(timeline, Timeline);
|
|
ft.array_foreach(timeline.layers, function (layer) {
|
|
ft.array_foreach(layer.frames, function (frame, frame_index) {
|
|
ft.array_foreach(frame.elements, function (elem) {
|
|
var lib_item_name = elem.libraryItem.name;
|
|
var lib_item_cache_name = "ft_cache_name_" + lib_item_name + "_" + elem.firstFrame;
|
|
if (ftlib.bake_symbol_item(doc, doc.library, lib_item_name, lib_item_cache_name, elem.firstFrame)) {
|
|
if (cfg.verbose_mode) {
|
|
ft.trace_fmt("Optimize single graphic '{0}' for frame '{1}' in '{2}'",
|
|
lib_item_name, elem.firstFrame, timeline.name);
|
|
}
|
|
if (opt_item === null || doc.library.editItem(opt_item.name)) {
|
|
if (timeline.currentFrame != frame_index) {
|
|
timeline.currentFrame = frame_index;
|
|
}
|
|
doc.selectNone();
|
|
doc.selection = [elem];
|
|
doc.swapElement(lib_item_cache_name);
|
|
doc.selection[0].firstFrame = 0;
|
|
doc.exitEditMode();
|
|
}
|
|
} else {
|
|
if (cfg.verbose_mode) {
|
|
ft.trace_fmt("NOT Optimize single graphic '{0}' for frame '{1}' in '{2}'",
|
|
lib_item_name, elem.firstFrame, timeline.name);
|
|
}
|
|
}
|
|
}, function (elem) {
|
|
return fttim.is_symbol_graphic_single_frame_instance(elem) && !fttim.is_static(elem.libraryItem.timeline);
|
|
});
|
|
}, fttim.is_keyframe);
|
|
}, fttim.is_not_guide_layer);
|
|
};
|
|
|
|
fttim.is_static = function (timeline) {
|
|
ft.type_assert(timeline, Timeline);
|
|
if (timeline.frameCount > 1) {
|
|
return false;
|
|
}
|
|
return ft.array_foldl(timeline.layers, function (layer, acc) {
|
|
return ft.array_foldl(layer.frames, function (frame, acc2) {
|
|
return ft.array_foldl(frame.elements, function (elem, acc3) {
|
|
return acc3 && fttim.is_symbol_instance(elem) ? elem.blendMode != "erase" && (fttim.is_symbol_graphic_single_frame_instance(elem) || fttim.is_static(elem.libraryItem.timeline)) : acc3;
|
|
}, acc2);
|
|
}, acc);
|
|
}, true);
|
|
};
|
|
|
|
fttim.prepare_all_tweens = function (doc, timeline) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(timeline, Timeline);
|
|
|
|
var is_end_of_tween = function(frame_index, frames) {
|
|
while (--frame_index >= 0) {
|
|
var frame = frames[frame_index];
|
|
if (fttim.is_keyframe(frame, frame_index)) {
|
|
return fttim.is_motion_tween_frame(frame) && frame.duration > 1;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
ft.array_reverse_foreach(timeline.layers, function (layer, layer_index) {
|
|
ft.array_foreach(layer.frames, function (frame, frame_index) {
|
|
if (fttim.is_shape_tween_frame(frame)) {
|
|
if (ft.is_function(frame.convertToFrameByFrameAnimation)) {
|
|
ft.trace_fmt(
|
|
"[Warning] Timeline: '{0}' Layer: '{1}' Frame: {2}\n" +
|
|
"- Shape tween strongly not recommended because it rasterized to frame-by-frame bitmap sequence.",
|
|
timeline.name, layer.name, frame_index + 1);
|
|
frame.convertToFrameByFrameAnimation();
|
|
} else {
|
|
throw "Animation uses shape tweens. To export this animation you should use Adobe Animate CC or higher!";
|
|
}
|
|
} else if (fttim.is_motion_tween_frame(frame) || is_end_of_tween(frame_index, layer.frames)) {
|
|
var has_shapes = ft.array_any(frame.elements, fttim.is_shape_element);
|
|
if (has_shapes || frame.elements.length > 1) {
|
|
ft.trace_fmt(
|
|
"[Warning] Timeline: '{0}' Layer: '{1}' Frame: {2}\n" +
|
|
"- Frame contains incorrect objects for motion tween.",
|
|
timeline.name, layer.name, frame_index + 1);
|
|
timeline.currentFrame = frame_index;
|
|
doc.selectNone();
|
|
doc.selection = frame.elements;
|
|
doc.convertToSymbol("graphic", ft.gen_unique_name(), "top left");
|
|
}
|
|
}
|
|
}, fttim.is_keyframe);
|
|
}, fttim.is_not_guide_layer);
|
|
};
|
|
|
|
fttim.prepare_all_groups = function (doc, timeline) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(timeline, Timeline);
|
|
|
|
var check_need_for_ungroup = function (frame, elem) {
|
|
if (fttim.is_tween_frame(frame)) {
|
|
return true;
|
|
}
|
|
if (fttim.is_group_shape_element(elem)) {
|
|
return ft.array_any(elem.members, function (member) {
|
|
if (fttim.is_instance_element(member)) {
|
|
return true;
|
|
}
|
|
return check_need_for_ungroup(frame, member);
|
|
});
|
|
}
|
|
return false;
|
|
};
|
|
|
|
var new_symbols = [];
|
|
ft.array_reverse_foreach(timeline.layers, function (layer, layer_index) {
|
|
ft.array_foreach(layer.frames, function (frame, frame_index) {
|
|
var has_complex_shapes = ft.array_any(frame.elements, fttim.is_complex_shape_element);
|
|
if (has_complex_shapes) {
|
|
timeline.currentFrame = frame_index;
|
|
doc.selectNone();
|
|
|
|
var elements = ft.array_clone(frame.elements);
|
|
ft.array_foreach(elements, function (elem, elem_index) {
|
|
if (fttim.is_simple_shape_element(elem)) {
|
|
// nothing
|
|
} else if (fttim.is_complex_shape_element(elem) && check_need_for_ungroup(frame, elem)) {
|
|
doc.selectNone();
|
|
doc.selection = [elem];
|
|
if (fttim.is_object_shape_element(elem)) {
|
|
doc.breakApart();
|
|
doc.group();
|
|
}
|
|
doc.unGroup();
|
|
try {
|
|
doc.unlockAllElements();
|
|
} catch (e) {}
|
|
var wrapper_item = doc.convertToSymbol("graphic", ft.gen_unique_name(), "top left");
|
|
new_symbols.push(wrapper_item);
|
|
} else {
|
|
doc.selectNone();
|
|
doc.selection = [elem];
|
|
doc.arrange("front");
|
|
}
|
|
});
|
|
}
|
|
}, fttim.is_keyframe);
|
|
}, fttim.is_not_guide_layer);
|
|
return new_symbols;
|
|
};
|
|
|
|
fttim.rasterize_all_shapes = function (doc, timeline) {
|
|
ft.type_assert(doc, Document);
|
|
ft.type_assert(timeline, Timeline);
|
|
|
|
var rasterize_count = 0;
|
|
ft.array_reverse_foreach(timeline.layers, function (layer, layer_index) {
|
|
ft.array_foreach(layer.frames, function (frame, frame_index) {
|
|
var has_shapes = ft.array_any(frame.elements, fttim.is_shape_element);
|
|
if (has_shapes) {
|
|
timeline.currentFrame = frame_index;
|
|
doc.selectNone();
|
|
var groups_arr = ft.array_group_by(frame.elements, fttim.is_shape_element);
|
|
for (var i = 0; i < groups_arr.length; ++i) {
|
|
var groups = groups_arr[i];
|
|
if (fttim.is_shape_element(groups.peek())) {
|
|
doc.selectNone();
|
|
doc.selection = groups;
|
|
var location_name = "Timeline: {0}".format(timeline.name);
|
|
ftdoc.convert_selection_to_bitmap(doc, location_name, timeline.libraryItem);
|
|
++rasterize_count;
|
|
} else {
|
|
doc.selectNone();
|
|
doc.selection = groups;
|
|
doc.arrange("front");
|
|
}
|
|
}
|
|
}
|
|
}, fttim.is_keyframe);
|
|
}, fttim.is_not_guide_layer);
|
|
|
|
if (rasterize_count > 0 && cfg.verbose_mode) {
|
|
ft.trace_fmt("Rasterize vector shapes({0}) in '{1}'", rasterize_count, timeline.name);
|
|
}
|
|
};
|
|
|
|
//
|
|
// run
|
|
//
|
|
|
|
(function () {
|
|
ft.clear_output();
|
|
fl.showIdleMessage(false);
|
|
ft.trace("[Start]");
|
|
|
|
if (cfg.open_documents.length > 0) {
|
|
ft.profile_function(cfg.profile_mode, function () {
|
|
ft.array_foreach(cfg.open_documents, function (uri) {
|
|
fl.openDocument(uri);
|
|
});
|
|
}, "Open documents");
|
|
}
|
|
|
|
ft.profile_function(cfg.profile_mode, function() {
|
|
ft.array_foreach(fl.documents, function (doc) {
|
|
ft.profile_function(cfg.profile_mode, function() {
|
|
try {
|
|
ft.trace_fmt("[Document] '{0}' conversion started...", doc.name);
|
|
ftdoc.prepare(doc);
|
|
ft.trace_fmt("[Document] '{0}' conversion complete!", doc.name);
|
|
} catch (e) {
|
|
ft.trace_fmt("[Document] '{0}' conversion error: '{1}'", doc.name, e);
|
|
}
|
|
}, "Prepare document: '{0}'".format(doc.name));
|
|
});
|
|
}, "Prepare documents");
|
|
|
|
if (cfg.revert_after_conversion) {
|
|
ft.profile_function(cfg.profile_mode, function () {
|
|
ft.array_foreach(fl.documents, function (doc) {
|
|
if (doc.canRevert()) {
|
|
fl.revertDocument(doc);
|
|
}
|
|
});
|
|
}, "Revert documents");
|
|
}
|
|
|
|
if (cfg.close_after_conversion) {
|
|
ft.profile_function(cfg.profile_mode, function () {
|
|
ft.array_foreach(fl.documents, function (doc) {
|
|
fl.closeDocument(doc, false);
|
|
});
|
|
}, "Close documents");
|
|
}
|
|
|
|
ft.trace("[Finish]");
|
|
})();
|
|
};
|