Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 10.04.2018, 20:18
RedHead90 вне форума Посмотреть профиль Отправить личное сообщение для RedHead90 Найти все сообщения от RedHead90
  № 1  
Ответить с цитированием
RedHead90

Регистрация: Apr 2018
Сообщений: 42
По умолчанию TextField - неожиданное поведение при масштабировании

Уважаемые знатоки! Имеется, казалось бы, простейшая задача - нужно разместить на сцене текст в динамически меняющем свои размеры прямоугольнике, при этом чтобы текст заполнял весь прямоугольник. Текст однострочный, но с включенным переносом по словам. Немного поковырявшись, понял, что для того, чтобы сохранить пропорции заданной области и чтобы при этом текст полностью умещался, нужно масштабировать текстовое поле. Пишется все это дело на Haxe/OpenFL. Так вот, при компиляции в HTML5 и Neko, все работает очень хорошо, текст масштабируется плавно. Но во flash-плеере происходит какая-то дичь. Во-первых, текст масштабируется дерганно, во-вторых пропорции не соблюдаются и текст постоянно норовит выбраться за пределы отведенной ему области (что пришлось решить небольшим костылем). Но все это не так страшно, как то, что иногда последняя строка текста просто уходит за пределы поля. Ее можно увидеть, если мышкой прокрутить поле, но программно такая ситуация никак не отслеживается. Прилагаю код. Чтобы баг проявился, нужно просто менять размер окна и тогда станет заметно мерцание нижнего слова.
Никак не пойму, что я делаю не так?

Код AS3:
package {
 
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
 
public class Main extends Sprite {
 
    public static const SHORT_TEXT:String = 'Hello world';
    public static const LONG_TEXT:String = 'Когда воин принимает решение, он должен быть готов к смерти. Если он готов умереть, то не будет никаких ловушек, никаких неприятных сюрпризов и никаких ненужных поступков. Все должно мягко укладываться на свое место, потому что он не ожидает ничего.';
 
    var textfield:TextField;
 
    var accuracy:Number = 0.01;
    var fixAccuracy:Number = 1;
 
    public function Main() {
        stage.align = StageAlign.TOP_LEFT;
        stage.scaleMode = StageScaleMode.NO_SCALE;
 
        var format = new TextFormat(null, 12);
        format.align = TextFormatAlign.CENTER;
 
        textfield = new TextField();
        textfield.defaultTextFormat = format;
        textfield.text = SHORT_TEXT;
        textfield.wordWrap = true;
        //textfield.border = true;
 
        addChild(textfield);
 
        drawRect(10, 10, stage.stageWidth - 20, stage.stageHeight - 20);
        calculateSize(textfield, 10, 10, stage.stageWidth - 20, stage.stageHeight - 20);
 
        stage.addEventListener(Event.RESIZE, onResize);
    }
 
    function onResize(e:Event) {
        drawRect(10, 10, stage.stageWidth - 20, stage.stageHeight - 20);
        calculateSize(textfield, 10, 10, stage.stageWidth - 20, stage.stageHeight - 20);
    }
 
    function drawRect(x:Number, y:Number, width:Number, height:Number) {
        graphics.clear();
        graphics.lineStyle(1, 0xff0000);
        graphics.drawRect(x, y, width, height);
    }
 
    public function calculateSize(textfield:TextField, x:Number, y:Number, width:Number, height:Number):void {
        if (width <= 0 || height <= 0) {
            textfield.scaleX = textfield.scaleY = 0;
            return;
        }
 
        textfield.scaleX = textfield.scaleY = 1;
        textfield.autoSize = TextFieldAutoSize.LEFT;
 
        var scale:Number;
 
        if (textfield.wordWrap) {
 
            var oneLineWidth:Number = textfield.textWidth;
            var oneLineHeight:Number = textfield.textHeight;
            var ratio:Number = width / height;
            var lines:Number = Math.sqrt(oneLineWidth / oneLineHeight / ratio);
 
            var dif:Number;
 
            do {
                textfield.width = Math.floor(oneLineHeight * lines * ratio);
                lines += accuracy;
                dif = ratio - textfield.width / textfield.height;
            } while (dif > 0);
 
            scale = Math.min(width / textfield.width, height / textfield.height);
            textfield.scaleX = textfield.scaleY = scale;
 
            //flash костыль
            while (textfield.height > height) {
                scale = Math.max(scale - (scale / textfield.width * fixAccuracy), 0);
                textfield.scaleX = textfield.scaleY = scale;
            }
 
        }
        else {
 
            scale = Math.min(width / textfield.width, height / textfield.height);
            textfield.scaleX = textfield.scaleY = scale;
 
            //flash костыль
            while (textfield.width > width) {
                scale = Math.max(scale - (scale / textfield.width * fixAccuracy), 0);
                textfield.scaleX = textfield.scaleY = scale;
            }
        }
 
        textfield.x = x + width / 2 - textfield.width / 2;
        textfield.y = y + height / 2 - textfield.height / 2;
    }
}
}

Создать новую тему Ответ Часовой пояс GMT +4, время: 19:43.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 19:43.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.