AllType card line splitting and scaling

This commit is contained in:
Cássio Zen
2016-07-12 17:03:22 -03:00
parent 1741c12bea
commit e9d72b07af
3 changed files with 143 additions and 9 deletions

View File

@ -1,14 +1,82 @@
import React, { PropTypes } from 'react';
import { Card } from '../UI';
import ScaledLine from './ScaledLine';
export default function AlltypeCard({ onClick, text }) {
return (
<Card onClick={onClick}>
<p>{text}</p>
</Card>
);
export default class AlltypeCard extends React.Component {
// Based on the Slabtype Algorithm by Erik Loyer
// http://erikloyer.com/index.php/blog/the_slabtype_algorithm_part_1_background/
renderInscription(inscription) {
var idealCharPerLine = 20;
// segment the text into lines
var words = inscription.split(' ');
var preText, postText, finalText;
var preDiff, postDiff;
var wordIndex = 0;
var lineText = [];
// while we still have words left, build the next line
while (wordIndex < words.length) {
postText = '';
// build two strings (preText and postText) word by word, with one
// string always one word behind the other, until
// the length of one string is less than the ideal number of characters
// per line, while the length of the other is greater than that ideal
while (postText.length < idealCharPerLine) {
preText = postText;
postText += words[wordIndex] + ' ';
wordIndex++;
if (wordIndex >= words.length) {
break;
}
}
// calculate the character difference between the two strings and the
// ideal number of characters per line
preDiff = idealCharPerLine - preText.length;
postDiff = postText.length - idealCharPerLine;
// if the smaller string is closer to the length of the ideal than
// the longer string, and doesnt contain just a single space, then
// use that one for the line
if ((preDiff < postDiff) && (preText.length > 2)) {
finalText = preText;
wordIndex--;
// otherwise, use the longer string for the line
} else {
finalText = postText;
}
lineText.push(finalText.substr(0, finalText.length - 1));
}
return lineText.map(text => (
<ScaledLine toWidth={216}>
{text}
</ScaledLine>
));
}
render() {
const { onClick, text } = this.props;
return (
<Card onClick={onClick}>
<div>{this.renderInscription(text)}</div>
</Card>
);
}
}
AlltypeCard.propTypes = {
onClick: PropTypes.func,
text: PropTypes.string.isRequired
};
AlltypeCard.defaultProps = {
onClick: function() {},
};

View File

@ -0,0 +1,45 @@
import React, { PropTypes } from 'react';
export default class ScaledLine extends React.Component {
constructor(props) {
super(props);
this._content = null;
this.state = {
contentWidth: 0,
ratio: 1,
};
}
componentDidMount() {
const actualContent = this._content.children[0];
this.setState({
contentWidth: actualContent.offsetWidth,
ratio: this.props.toWidth / actualContent.offsetWidth,
});
}
render() {
const { ratio } = this.state;
const { children } = this.props;
var baseFontSize = 15;
var styles = {
whiteSpace: 'nowrap',
textAlign: 'center'
};
styles.fontSize = Math.round((baseFontSize * ratio)*1000)/1000
return (
<div ref={(c) => this._content = c} style={styles}>
<span>{children}</span>
</div>
)
}
};
ScaledLine.propTypes = {
toWidth: PropTypes.number.isRequired,
children: PropTypes.node.isRequired
};