2015-04-17 2 views
2

Внутри famo.us, я хочу поместить заголовок обертывания переменной длины рядом с верхним, а затем изображения и т. Д. Все элементы должны быть их собственными поверхностями, поскольку у некоторых есть события кликов и анимации, но все позиционирование должно быть очень быстрым, чтобы вычислять и размещать на основе высоты текста и, конечно же, должны избегать доступа DOM для 60 кадров в секунду. Это должно произойти для серии мини-сообщений, потокового реального времени и для бесконечного прокрутки.Как вычислить высоту текста обтекания на поверхности famo.us?

До сих пор я придумал подход, который работает с использованием карты символов ascii для загрузки ширины пикселя с экрана на init, если он еще не находится в localStorage. Он использует jquery для выполнения калибровки для каждого символа, затем определяет высоту строки, проверяя сломанное слово и высоту этого поля. После этого я использую эту карту для расчетов «на лету», поэтому я больше не прикасаюсь к DOM. Кажется, он работает нормально, но полностью зависит от того, как стиль шрифта будет использоваться очень определенным образом. Для каждого нового стиля я должен иметь другое сопоставление, которое отстой.

Есть ли другой подход, который больше встроен в famo.us?

ответ

0

Я отвечаю на свой вопрос, потому что, честно говоря, новая структура будет выпущена 22 июня этого месяца (на момент написания этой статьи). Просто хочу сказать, как я это делаю сейчас, так, как я описал выше.

Для этого используйте способ 0.3.5 Famou.us.

Это файл «utils/lines.js», который я взбивал. Хак, да. Работает, да.

define(function(require) { 
     'use strict'; 

     var $ = require('jquery'); 
     var cache = require('utils/cache'); 

     function getLineInfo(id) { 
     var cacheKey = 'lineInfo_' + id; 
     var savedLineInfo = cache.get(cacheKey); 
     if (savedLineInfo) 
      return savedLineInfo; 

     var charStart = 32; // space 
     var charEnd = 126; // ~ 
     var $charDump = $('<div>', { id: id }); 
     $('body').append($charDump); 

     for (var i = charStart; i <= charEnd; i++) 
      $charDump.append($('<div>', { class: 'char', css: { top: (i-32) * 20 } }).html('&#' + i)); 

     var charMap = {}; 
     $charDump.find('.char').each(function() { 
      var $this = $(this); 
      var char = $this.text().charCodeAt(0); 
      var w = $this.width(); 
      charMap[char] = w; 
     }); 
     $charDump.html('<div class="line">abc<br>123<br>456</div>'); 
     var lineHeight = $charDump.height()/3; 
     $charDump.remove(); 
     savedLineInfo = { 
      lineHeight: lineHeight, 
      charMap: charMap 
     }; 
     cache.set(cacheKey, savedLineInfo); 
     return savedLineInfo; 
     } 

     function getLines(text, width, id, maxLines) { 
     var lineInfo = getLineInfo(id); 
     var cleaned = $.trim(text.replace(/\s+/gm, ' ')); 
     var words = cleaned.split(' '); 
     var lines = 1; 
     var lineWidth = 0; 
     var spaceLength = lineInfo.charMap[32]; 
     var allLines = ''; 
     words.forEach(function(word) { 
      var wordLength = 0; 
      word.split('').forEach(function(char) { 
      var charLength = lineInfo.charMap[char.charCodeAt(0)]; 
      if (!charLength) 
       charLength = spaceLength; 
      wordLength += charLength; 
      }); 
      if (lineWidth + wordLength + spaceLength <= width) { 
      lineWidth += wordLength + spaceLength; 
      if (maxLines) 
       allLines += word + ' '; 
      } 
      else { 
      lineWidth = wordLength; 
      if (maxLines && lines <= maxLines) 
       allLines += word + ' '; 
      else if (maxLines) 
       return {text: allLines.substr(0, allLines.length - 3) + '...', lines: lines}; 
      lines++; 
      } 
     }); 
     if (maxLines) 
      return {text: allLines, lines: lines}; 
     return lines; 
     } 

     function getTextHeight(text, width, id, maxLines) { 
     var lineInfo = getLineInfo(id); 
     var info; 
     if (maxLines) { 
      info = getLines(text, width, id, maxLines); 
      info.height = lineInfo.lineHeight * info.lines; 
      return info; 
     } 
     return lineInfo.lineHeight * getLines(text, width, id); 
     } 

     return { 
     getLines: getLines, 
     getLineInfo: getLineInfo, 
     getTextHeight: getTextHeight 
     }; 
}); 
Смежные вопросы