bezoerb-measure-text
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -163,13 +163,30 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.measureText = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
/** | ||
* Normalize options | ||
* | ||
* @param options | ||
* @returns {*} | ||
*/ | ||
function parseOptions(options) { | ||
if (options && isElement(options)) { | ||
options = { element: options }; | ||
} else { | ||
// set defaults | ||
options['font-size'] = options['font-size'] || DEFAULTS['font-size']; | ||
options['font-weight'] = options['font-weight'] || DEFAULTS['font-weight']; | ||
options['font-family'] = options['font-family'] || DEFAULTS['font-family']; | ||
// no option set | ||
if (isElement(options)) { | ||
return { element: options }; | ||
} | ||
return options; | ||
// normalize keys (fontSize => font-size) | ||
if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { | ||
Object.keys(options).forEach(function (key) { | ||
var dashedKey = key.replace(/([A-Z])/g, function ($1) { | ||
return '-' + $1.toLowerCase(); | ||
}); | ||
options[dashedKey] = options[key]; | ||
}); | ||
} | ||
// don't set defaults if we got an element | ||
if (options && isElement(options.element)) { | ||
return options; | ||
} | ||
return Object.assign({}, DEFAULTS, options || {}); | ||
} | ||
@@ -198,8 +215,84 @@ | ||
var metrics = ctx.measureText(styledText); | ||
if (options.multiline) { | ||
return computeLinebreaks(styledText, Object.assign({}, options, { style: style })).reduce(function (res, text) { | ||
return Math.max(res, ctx.measureText(text).width); | ||
}, 0); | ||
} | ||
return metrics.width; | ||
return ctx.measureText(styledText).width; | ||
} | ||
/** | ||
* compute lines of text with automatic word wraparound | ||
* element styles | ||
* | ||
* @param text | ||
* @param options | ||
* @returns {*} | ||
*/ | ||
function computeLinebreaks(text, options) { | ||
options = parseOptions(options); | ||
var style = getStyle(options); | ||
// get max width | ||
var max = parseInt(prop(options, 'width') || prop(options.element, 'offsetWidth', 0) || style.getPropertyValue('width'), 10); | ||
var delimiter = prop(options, 'delimiter', ' '); | ||
var styledText = getStyledText(text, style); | ||
var words = styledText.split(delimiter); | ||
if (words.length === 0) { | ||
return 0; | ||
} | ||
var ctx = void 0; | ||
try { | ||
ctx = document.createElement('canvas').getContext('2d'); | ||
ctx.font = prop(options, 'font', null) || getFont(style, options); | ||
} catch (err) { | ||
throw new Error('Canvas support required'); | ||
} | ||
var lines = []; | ||
var line = words.shift(); | ||
words.forEach(function (word, index) { | ||
var _ctx$measureText = ctx.measureText(line + delimiter + word), | ||
width = _ctx$measureText.width; | ||
if (width <= max) { | ||
line += delimiter + word; | ||
} else { | ||
lines.push(line); | ||
line = word; | ||
} | ||
if (index === words.length - 1) { | ||
lines.push(line); | ||
} | ||
}); | ||
if (words.length === 0) { | ||
lines.push(line); | ||
} | ||
return lines; | ||
} | ||
/** | ||
* Compute height from textbox | ||
* | ||
* @param text | ||
* @param options | ||
* @returns {number} | ||
*/ | ||
function height(text, options) { | ||
options = parseOptions(options); | ||
var style = getStyle(options); | ||
var lineHeight = parseInt(prop(options, 'line-height') || style.getPropertyValue('line-height'), 10); | ||
return computeLinebreaks(text, Object.assign({}, options, { style: style })).length * lineHeight; | ||
} | ||
/** | ||
* Compute Text Metrics based for given text | ||
@@ -223,3 +316,4 @@ | ||
// get max width | ||
var max = parseInt(prop(options, 'width') || prop(options.element, 'offsetWidth', 0), 10); | ||
// get max width | ||
var max = parseInt(prop(options, 'width') || prop(options.element, 'offsetWidth', 0) || options.style.getPropertyValue('width'), 10); | ||
@@ -260,2 +354,4 @@ // start with half the max size | ||
exports.width = width; | ||
exports.computeLinebreaks = computeLinebreaks; | ||
exports.height = height; | ||
exports.maxFontSize = maxFontSize; | ||
@@ -262,0 +358,0 @@ }); |
@@ -1,1 +0,1 @@ | ||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.measureText=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){(function(global,factory){if(typeof define==="function"&&define.amd){define(["exports"],factory)}else if(typeof exports!=="undefined"){factory(exports)}else{var mod={exports:{}};factory(mod.exports);global.index=mod.exports}})(this,function(exports){"use strict";var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};Object.defineProperty(exports,"__esModule",{value:true});var DEFAULTS={"font-size":"16px","font-weight":"400","font-family":"Helvetica, Arial, sans-serif"};function getFont(style,options){var font=[];var fontWeight=prop(options,"font-weight",style.getPropertyValue("font-weight"));if(["normal","bold","bolder","lighter","100","200","300","400","500","600","700","800","900"].indexOf(fontWeight.toString())!==-1){font.push(fontWeight)}var fontStyle=prop(options,"font-style",style.getPropertyValue("font-style"));if(["normal","italic","oblique"].indexOf(fontStyle)!==-1){font.push(fontStyle)}var fontVariant=prop(options,"font-variant",style.getPropertyValue("font-variant"));if(["normal","small-caps"].indexOf(fontVariant)!==-1){font.push(fontVariant)}var fontSize=prop(options,"font-size",style.getPropertyValue("font-size"));var fontSizeValue=parseFloat(fontSize);var fontSizeUnit=fontSize.replace(fontSizeValue,"");switch(fontSizeUnit){case"rem":case"em":fontSizeValue*=16;break;case"pt":fontSizeValue/=.75;break}font.push(fontSizeValue+"px");var fontFamily=prop(options,"font-family",style.getPropertyValue("font-family"));font.push(fontFamily);return font.join(" ")}function isCSSStyleDeclaration(val){return val&&typeof val.getPropertyValue==="function"}function canGetComputedStyle(el){return el&&el.style&&typeof window!=="undefined"&&typeof window.getComputedStyle==="function"}function isElement(el){return(typeof HTMLElement==="undefined"?"undefined":_typeof(HTMLElement))==="object"?el instanceof HTMLElement:el&&(typeof el==="undefined"?"undefined":_typeof(el))==="object"&&el!==null&&el.nodeType===1&&typeof el.nodeName==="string"}function getStyle(options){if(isCSSStyleDeclaration(options.style)){return options.style}var el=options&&isElement(options.element)&&options.element;if(canGetComputedStyle(el)){return window.getComputedStyle(el,prop(options,"pseudoElt",null))}return{getPropertyValue:function getPropertyValue(key){return prop(options,key)}}}function getStyledText(text,style){switch(style.getPropertyValue("text-transform")){case"uppercase":return text.toUpperCase();case"lowercase":return text.toLowerCase();default:return text}}function prop(src,attr,defaultValue){return src&&typeof src[attr]!=="undefined"&&src[attr]||defaultValue}function parseOptions(options){if(options&&isElement(options)){options={element:options}}else{options["font-size"]=options["font-size"]||DEFAULTS["font-size"];options["font-weight"]=options["font-weight"]||DEFAULTS["font-weight"];options["font-family"]=options["font-family"]||DEFAULTS["font-family"]}return options}function width(text,options){options=parseOptions(options);var style=getStyle(options);var styledText=getStyledText(text,style);var ctx=void 0;try{ctx=document.createElement("canvas").getContext("2d");ctx.font=prop(options,"font",null)||getFont(style,options)}catch(err){throw new Error("Canvas support required")}var metrics=ctx.measureText(styledText);return metrics.width}function maxFontSize(text,options){options=parseOptions(options);options.style=getStyle(options);var compute=function compute(size){options["font-size"]=size+"px";return width(text,options)};var max=parseInt(prop(options,"width")||prop(options.element,"offsetWidth",0),10);var size=Math.floor(max/2);var cur=compute(size);size=Math.floor(size/cur*max);cur=compute(size);if(Math.ceil(cur)===max){return size+"px"}if(cur>max&&size>0){while(cur>max&&size>0){cur=compute(size--)}return size+"px"}while(cur<max){cur=compute(size++)}size--;return size+"px"}exports.isCSSStyleDeclaration=isCSSStyleDeclaration;exports.canGetComputedStyle=canGetComputedStyle;exports.isElement=isElement;exports.getStyle=getStyle;exports.getStyledText=getStyledText;exports.width=width;exports.maxFontSize=maxFontSize})},{}]},{},[1])(1)}); | ||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.measureText=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){(function(global,factory){if(typeof define==="function"&&define.amd){define(["exports"],factory)}else if(typeof exports!=="undefined"){factory(exports)}else{var mod={exports:{}};factory(mod.exports);global.index=mod.exports}})(this,function(exports){"use strict";var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};Object.defineProperty(exports,"__esModule",{value:true});var DEFAULTS={"font-size":"16px","font-weight":"400","font-family":"Helvetica, Arial, sans-serif"};function getFont(style,options){var font=[];var fontWeight=prop(options,"font-weight",style.getPropertyValue("font-weight"));if(["normal","bold","bolder","lighter","100","200","300","400","500","600","700","800","900"].indexOf(fontWeight.toString())!==-1){font.push(fontWeight)}var fontStyle=prop(options,"font-style",style.getPropertyValue("font-style"));if(["normal","italic","oblique"].indexOf(fontStyle)!==-1){font.push(fontStyle)}var fontVariant=prop(options,"font-variant",style.getPropertyValue("font-variant"));if(["normal","small-caps"].indexOf(fontVariant)!==-1){font.push(fontVariant)}var fontSize=prop(options,"font-size",style.getPropertyValue("font-size"));var fontSizeValue=parseFloat(fontSize);var fontSizeUnit=fontSize.replace(fontSizeValue,"");switch(fontSizeUnit){case"rem":case"em":fontSizeValue*=16;break;case"pt":fontSizeValue/=.75;break}font.push(fontSizeValue+"px");var fontFamily=prop(options,"font-family",style.getPropertyValue("font-family"));font.push(fontFamily);return font.join(" ")}function isCSSStyleDeclaration(val){return val&&typeof val.getPropertyValue==="function"}function canGetComputedStyle(el){return el&&el.style&&typeof window!=="undefined"&&typeof window.getComputedStyle==="function"}function isElement(el){return(typeof HTMLElement==="undefined"?"undefined":_typeof(HTMLElement))==="object"?el instanceof HTMLElement:el&&(typeof el==="undefined"?"undefined":_typeof(el))==="object"&&el!==null&&el.nodeType===1&&typeof el.nodeName==="string"}function getStyle(options){if(isCSSStyleDeclaration(options.style)){return options.style}var el=options&&isElement(options.element)&&options.element;if(canGetComputedStyle(el)){return window.getComputedStyle(el,prop(options,"pseudoElt",null))}return{getPropertyValue:function getPropertyValue(key){return prop(options,key)}}}function getStyledText(text,style){switch(style.getPropertyValue("text-transform")){case"uppercase":return text.toUpperCase();case"lowercase":return text.toLowerCase();default:return text}}function prop(src,attr,defaultValue){return src&&typeof src[attr]!=="undefined"&&src[attr]||defaultValue}function parseOptions(options){if(isElement(options)){return{element:options}}if((typeof options==="undefined"?"undefined":_typeof(options))==="object"){Object.keys(options).forEach(function(key){var dashedKey=key.replace(/([A-Z])/g,function($1){return"-"+$1.toLowerCase()});options[dashedKey]=options[key]})}if(options&&isElement(options.element)){return options}return Object.assign({},DEFAULTS,options||{})}function width(text,options){options=parseOptions(options);var style=getStyle(options);var styledText=getStyledText(text,style);var ctx=void 0;try{ctx=document.createElement("canvas").getContext("2d");ctx.font=prop(options,"font",null)||getFont(style,options)}catch(err){throw new Error("Canvas support required")}if(options.multiline){return computeLinebreaks(styledText,Object.assign({},options,{style:style})).reduce(function(res,text){return Math.max(res,ctx.measureText(text).width)},0)}return ctx.measureText(styledText).width}function computeLinebreaks(text,options){options=parseOptions(options);var style=getStyle(options);var max=parseInt(prop(options,"width")||prop(options.element,"offsetWidth",0)||style.getPropertyValue("width"),10);var delimiter=prop(options,"delimiter"," ");var styledText=getStyledText(text,style);var words=styledText.split(delimiter);if(words.length===0){return 0}var ctx=void 0;try{ctx=document.createElement("canvas").getContext("2d");ctx.font=prop(options,"font",null)||getFont(style,options)}catch(err){throw new Error("Canvas support required")}var lines=[];var line=words.shift();words.forEach(function(word,index){var _ctx$measureText=ctx.measureText(line+delimiter+word),width=_ctx$measureText.width;if(width<=max){line+=delimiter+word}else{lines.push(line);line=word}if(index===words.length-1){lines.push(line)}});if(words.length===0){lines.push(line)}return lines}function height(text,options){options=parseOptions(options);var style=getStyle(options);var lineHeight=parseInt(prop(options,"line-height")||style.getPropertyValue("line-height"),10);return computeLinebreaks(text,Object.assign({},options,{style:style})).length*lineHeight}function maxFontSize(text,options){options=parseOptions(options);options.style=getStyle(options);var compute=function compute(size){options["font-size"]=size+"px";return width(text,options)};var max=parseInt(prop(options,"width")||prop(options.element,"offsetWidth",0)||options.style.getPropertyValue("width"),10);var size=Math.floor(max/2);var cur=compute(size);size=Math.floor(size/cur*max);cur=compute(size);if(Math.ceil(cur)===max){return size+"px"}if(cur>max&&size>0){while(cur>max&&size>0){cur=compute(size--)}return size+"px"}while(cur<max){cur=compute(size++)}size--;return size+"px"}exports.isCSSStyleDeclaration=isCSSStyleDeclaration;exports.canGetComputedStyle=canGetComputedStyle;exports.isElement=isElement;exports.getStyle=getStyle;exports.getStyledText=getStyledText;exports.width=width;exports.computeLinebreaks=computeLinebreaks;exports.height=height;exports.maxFontSize=maxFontSize})},{}]},{},[1])(1)}); |
{ | ||
"name": "bezoerb-measure-text", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "My swell module", | ||
@@ -42,4 +42,6 @@ "license": "MIT", | ||
"babel-core": "^6.7.4", | ||
"babel-plugin-object-assign": "^1.2.1", | ||
"babel-plugin-transform-es2015-modules-umd": "^6.6.5", | ||
"babel-preset-es2015": "^6.6.0", | ||
"babel-polyfill": "^6.7.4", | ||
"babel-preset-es2015": "^6.2.4", | ||
"canvas": "^1.3.12", | ||
@@ -46,0 +48,0 @@ "coveralls": "^2.11.9", |
@@ -59,5 +59,11 @@ # measure-text | ||
#### measureText.height(text, [element | options]) | ||
Compute text height. | ||
#### measureText.maxFontSize(text, [element | options]) | ||
Compute max fontsize to fit element. | ||
#### measureText.computeLinebreaks(text, [element | options]) | ||
Compute lines of text with automatic word wraparound | ||
### text | ||
@@ -122,3 +128,3 @@ | ||
Used for `getMaxFontSize` | ||
Used for `getMaxFontSize`, `height`, `computeLinebreaks` and `width` with multiline option. | ||
Takes precedence over element offsetWidth. | ||
@@ -139,4 +145,4 @@ | ||
[dlcounter-url]: https://www.npmjs.com/package/measure-text | ||
[dlcounter-image]: https://img.shields.io/npm/dm/measure-text.svg | ||
[dlcounter-url]: https://www.npmjs.com/package/bezoerb-measure-text | ||
[dlcounter-image]: https://img.shields.io/npm/dm/bezoerb-measure-text.svg | ||
@@ -143,0 +149,0 @@ [coveralls-url]: https://coveralls.io/github/bezoerb/measure-text?branch=master |
121
src/index.js
@@ -140,13 +140,28 @@ /* eslint-env es6, browser */ | ||
/** | ||
* Normalize options | ||
* | ||
* @param options | ||
* @returns {*} | ||
*/ | ||
function parseOptions(options) { | ||
if (options && isElement(options)) { | ||
options = {element: options}; | ||
} else { | ||
// set defaults | ||
options['font-size'] = options['font-size'] || DEFAULTS['font-size']; | ||
options['font-weight'] = options['font-weight'] || DEFAULTS['font-weight']; | ||
options['font-family'] = options['font-family'] || DEFAULTS['font-family']; | ||
// no option set | ||
if (isElement(options)) { | ||
return {element: options}; | ||
} | ||
return options; | ||
// normalize keys (fontSize => font-size) | ||
if (typeof options === 'object') { | ||
Object.keys(options).forEach(key => { | ||
const dashedKey = key.replace(/([A-Z])/g, $1 => `-${$1.toLowerCase()}`); | ||
options[dashedKey] = options[key]; | ||
}); | ||
} | ||
// don't set defaults if we got an element | ||
if (options && isElement(options.element)) { | ||
return options; | ||
} | ||
return Object.assign({}, DEFAULTS, options || {}); | ||
} | ||
@@ -175,8 +190,87 @@ | ||
let metrics = ctx.measureText(styledText); | ||
if (options.multiline) { | ||
return computeLinebreaks(styledText, Object.assign({}, options, {style})).reduce((res, text) => { | ||
return Math.max(res, ctx.measureText(text).width); | ||
}, 0); | ||
} | ||
return metrics.width; | ||
return ctx.measureText(styledText).width; | ||
} | ||
/** | ||
* compute lines of text with automatic word wraparound | ||
* element styles | ||
* | ||
* @param text | ||
* @param options | ||
* @returns {*} | ||
*/ | ||
export function computeLinebreaks(text, options) { | ||
options = parseOptions(options); | ||
const style = getStyle(options); | ||
// get max width | ||
const max = parseInt( | ||
prop(options, 'width') || | ||
prop(options.element, 'offsetWidth', 0) || | ||
style.getPropertyValue('width') | ||
, 10); | ||
const delimiter = prop(options, 'delimiter', ' '); | ||
const styledText = getStyledText(text, style); | ||
const words = styledText.split(delimiter); | ||
if (words.length === 0) { | ||
return 0; | ||
} | ||
let ctx; | ||
try { | ||
ctx = document.createElement('canvas').getContext('2d'); | ||
ctx.font = prop(options, 'font', null) || getFont(style, options); | ||
} catch (err) { | ||
throw new Error('Canvas support required'); | ||
} | ||
let lines = []; | ||
let line = words.shift(); | ||
words.forEach((word, index) => { | ||
const {width} = ctx.measureText(line + delimiter + word); | ||
if (width <= max) { | ||
line += (delimiter + word); | ||
} else { | ||
lines.push(line); | ||
line = word; | ||
} | ||
if (index === words.length - 1) { | ||
lines.push(line); | ||
} | ||
}); | ||
if (words.length === 0) { | ||
lines.push(line); | ||
} | ||
return lines; | ||
} | ||
/** | ||
* Compute height from textbox | ||
* | ||
* @param text | ||
* @param options | ||
* @returns {number} | ||
*/ | ||
export function height(text, options) { | ||
options = parseOptions(options); | ||
const style = getStyle(options); | ||
const lineHeight = parseInt(prop(options, 'line-height') || style.getPropertyValue('line-height'), 10); | ||
return computeLinebreaks(text, Object.assign({}, options, {style})).length * lineHeight; | ||
} | ||
/** | ||
* Compute Text Metrics based for given text | ||
@@ -200,3 +294,8 @@ | ||
// get max width | ||
let max = parseInt(prop(options, 'width') || prop(options.element, 'offsetWidth', 0), 10); | ||
// get max width | ||
const max = parseInt( | ||
prop(options, 'width') || | ||
prop(options.element, 'offsetWidth', 0) || | ||
options.style.getPropertyValue('width') | ||
, 10); | ||
@@ -203,0 +302,0 @@ // start with half the max size |
33512
583
170
14