#flash #flip #jsfl
#flash #перевернуть #jsfl
Вопрос:
Я пишу экспортер в JSFL для экспорта Flash-анимации в формат, который можно воспроизвести в пользовательском проигрывателе. Экспортер в основном перебирает временную шкалу и все элементы в каждом ключевом кадре и записывает имя элемента, положение, поворот, масштаб и локальное смещение. Они считываются в пользовательский проигрыватель, который передает данные в спрайтовый движок для воссоздания каждого кадра анимации.
Что я хочу иметь возможность сделать, так это определить, был ли данный элемент перевернут (т. Е. Во Flash вы выбираете элемент (символ), затем Modify-> Transform-> Flip Horizontal), чтобы экспортер мог также включить эту информацию, позволяя движку спрайтов в проигрывателе переворачивать элемент (символ).)UVS текстуры для воспроизведения того, что происходит во Flash. Это было бы полезно для (скажем) использования одного символа для правой руки персонажа и просто переворачивания его в левую руку, вместо того, чтобы создавать совершенно новый символ.
К сожалению, я не вижу никакого способа узнать эту информацию. Ни одна из имеющейся у меня информации для элементов, похоже, не подразумевает, что произошел какой-либо перелистывание. Как я могу обнаружить переключение? Если это невозможно сделать алгоритмически, я бы согласился с тем, что аниматору нужно вручную указать, что символ был перевернут (создав какой-то плагин, который дает им флажок, который записывает значение в элемент с помощью setPersistentData() , например), но я не знаю, как это сделатьдля создания такого плагина тоже. Помогите!
Комментарии:
1. Если он недоступен в API JSFL, другой подход заключается в извлечении настроек элемента непосредственно из FLA. Сначала убедитесь, что ваш FLA сохранен в формате Flash CS5 (11.0), переименуйте расширение файла с .fla на .zip, извлеките XML и найдите элемент в XML, чтобы узнать, есть ли там нужная вам информация.
Ответ №1:
scaleX не работает, кажется, что он всегда дает положительное значение. В конце концов, мне пришлось сделать это с матрицей, чтобы получить ответ. Это основано на идее, что мы знаем, что матрица всегда содержит поворот 2D, и мы знаем угол, поэтому мы можем избавиться от поворота элементов матрицы, чтобы просто оставить нам масштаб. Это ужасно, но, похоже, работает.
Кроме того, вращение иногда отображается как NaN, особенно когда элемент был перевернут. использование значения skewX, похоже, работает для вещей, которые, как вы знаете, не искажены, но я хочу, чтобы мой экспортер мог обрабатывать искаженные элементы, поэтому я думаю, что это может быть основой для другого вопроса здесь.
var rotationRadians;
if(isNaN(someElement.rotation)) {
rotationRadians = someElement.skewX * Math.PI / 180;
}
else {
rotationRadians = someElement.rotation * Math.PI / 180;
}
var sinRot = Math.sin(rotationRadians);
var cosRot = Math.cos(rotationRadians);
var SOME_EPSILON = 0.01;
var flipScaleX, flipScaleY;
if(Math.abs(cosRot) < SOME_EPSILON) {
// Avoid divide by zero. We can use sine and the other two elements of the matrix instead.
flipScaleX = (someElement.matrix.b / sinRot);
flipScaleY = (someElement.matrix.c / -sinRot);
}
else {
flipScaleX = someElement.matrix.a / cosRot;
flipScaleY = someElement.matrix.d / cosRot;
}
flipScaleX выдает значение ~ -1, если он перевернут по горизонтали, ~ 1, если нет. Значение flipScaleY равно ~ -1, если он перевернут вертикально, ~ 1, если нет.
Комментарии:
1. Это полезно. Я бы не подумал проверять перекос, когда вращение было NaN! Не могу не думать, что должен быть лучший способ.
Ответ №2:
Разве scaleX или matrix не работают? http://help.adobe.com/en_US/flash/cs/extend/WS5b3ccc516d4fbf351e63e3d118a9024f3f-7f6c.html
Комментарии:
1. scaleX не работает, но матрица работает после довольно болезненного извлечения. Смотрите ниже, если вам интересно.
Ответ №3:
Вот решение electrodruid, упакованное в несколько удобных функций:
function isFlippedHorizontally (element) {
return Math.round(getFlip(element)[0]) == -1;
}
function isFlippedVertically (element) {
return Math.round(getFlip(element)[0]) == -1;
}
function getFlip (element) {
var rotationRadians;
if(isNaN(element.rotation)) {
rotationRadians = element.skewX * Math.PI / 180;
}
else {
rotationRadians = element.rotation * Math.PI / 180;
}
var sinRot = Math.sin(rotationRadians);
var cosRot = Math.cos(rotationRadians);
var SOME_EPSILON = 0.01;
var flipScaleX, flipScaleY;
if(Math.abs(cosRot) < SOME_EPSILON) {
// Avoid divide by zero. We can use sine and the other two elements of the matrix instead.
flipScaleX = (element.matrix.b / sinRot);
flipScaleY = (element.matrix.c / -sinRot);
}
else {
flipScaleX = element.matrix.a / cosRot;
flipScaleY = element.matrix.d / cosRot;
}
return [flipScaleX, flipScaleY];
}
Пример использования:
var element = currentDoc.getTimeline().layers[0].frames[0].elements[0];
trace("Element is flipped:" isFlippedHorizontally(element));
Спасибо за код electrodruid.