2015-04-17 16 views
2

在famo.us中,我想在頂部附近放置一個可變長度的包裝標題,然後有圖像等。所有項目必須是自己的表面,因爲一些點擊事件和動畫,但所有的定位必須超快計算和放置的文字高度,當然必須避免60fps的DOM訪問。這必須發生在一系列微型帖子上,實時流媒體和無限滾動。如何計算famo.us表面的包裝文字高度?

到目前爲止,我想出了一種方法,如果不在localStorage中,則使用ascii字符映射到像素寬度加載關閉屏幕上的init。它使用jquery爲每個字符進行大小調整,然後通過檢查中斷字和該框的高度來確定行高。之後,我使用這張地圖進行實時計算,所以我不再觸摸DOM。它似乎工作正常,但完全依賴於知道字體的樣式將以非常特定的方式使用。對於每種新風格,我都必須有一個不同的映射。

是否還有另外一種更適合famo.us的方法?

回答

0

我在回答我自己的問題,因爲坦白地說,這個新框架將在本月的6月22日發佈(撰寫本文時)。我只是想說明我如何做到這一點,這是我上面描述的方式。

這是Famou.us的0.3.5方法。

這是在一個文件「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 
     }; 
});