Skip to content

Commit

Permalink
Add support for multiline texts and text alignment
Browse files Browse the repository at this point in the history
  • Loading branch information
georapbox committed Dec 14, 2023
1 parent 4bb6b08 commit 762a4c1
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 11 deletions.
7 changes: 7 additions & 0 deletions src/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ input[type="file"]:disabled::-webkit-file-upload-button {
cursor: pointer;
}

.inputs-container .meme-text {
min-width: 0;
min-height: calc(1.5em + 0.75rem + 2px);
height: calc(1.5em + 0.75rem + 2px);
margin: 0.5rem;
}

/* Buttons */
.btn:disabled {
cursor: not-allowed;
Expand Down
23 changes: 16 additions & 7 deletions src/js/create-text-box.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const createTextBox = (index, data = {}) => {
<div class="d-flex align-items-center">
<button class="btn" data-button="delete-text-box" aria-label="Remove"></button>
<input class="form-control m-2" type="text" value="${data.text}" data-input="text" autocomplete="off" placeholder="${`Text #${index + 1}`}" style="min-width: 0;">
<textarea class="form-control meme-text" type="text" data-input="text" autocomplete="off" rows="1" placeholder="${`Text #${index + 1}`}">${data.text}</textarea>
<div class="d-flex align-items-center pr-2">
<input class="form-control" type="color" value="${data.fillColor}" data-input="fillColor" title="Fill color">
Expand All @@ -16,7 +16,7 @@ export const createTextBox = (index, data = {}) => {
<div class="p-2" data-section="settings" ${data._isSettingsOpen ? '' : 'hidden'}>
<div class="form-row">
<div class="col-6 mb-3">
<div class="col-4 mb-3">
<label for="fontInput_${index}" class="mb-1 d-block text-truncate">Font: </label>
<select class="custom-select" data-input="font" id="fontInput_${index}">
Expand All @@ -42,12 +42,12 @@ export const createTextBox = (index, data = {}) => {
</select>
</div>
<div class="col-3 mb-3">
<div class="col-4 mb-3">
<label for="fontSizeInput_${index}" class="mb-1 d-block text-truncate">Size:</label>
<input class="form-control" type="number" min="1" value="${data.fontSize}" data-input="fontSize" id="fontSizeInput_${index}">
</div>
<div class="col-3 mb-3">
<div class="col-4 mb-3">
<label for="fontWeightInput_${index}" class="mb-1 d-block text-truncate">Weight:</label>
<select class="custom-select" data-input="fontWeight" id="fontWeightInput_${index}">
<option value="normal" selected>Normal</option>
Expand All @@ -57,12 +57,21 @@ export const createTextBox = (index, data = {}) => {
</div>
<div class="form-row">
<div class="col-6 mb-3">
<div class="col-4 mb-3">
<label for="shadowWidthInput_${index}" class="mb-1 d-block text-truncate">Shadow width:</label>
<input class="form-control" type="number" min="0" max="10" value="${data.shadowBlur}" data-input="shadowBlur" id="shadowWidthInput_${index}">
</div>
<div class="col-6 mb-3">
<div class="col-4 mb-3">
<label for="textAlign_${index}" class="mb-1 d-block text-truncate">Text align:</label>
<select class="custom-select" data-input="textAlign" id="textAlignInput_${index}">
<option value="left">Left</option>
<option value="center" selected>Center</option>
<option value="right">Right</option>
</select>
</div>
<div class="col-4 mb-3">
<label class="mb-1 d-block text-truncate" for="textRotateInput_${index}">Rotate:</label>
<input class="form-control" type="number" value="${data.rotate}" data-input="rotate" id="textRotateInput_${index}" min="-360" max="360">
</div>
Expand Down Expand Up @@ -108,7 +117,7 @@ export const createTextBox = (index, data = {}) => {
div.setAttribute('data-index', index);
div.innerHTML = inputTemplate;
div.querySelector('[data-input="font"]').value = data.font;
// div.querySelector('[data-input="textAlign"]').value = data.textAlign;
div.querySelector('[data-input="textAlign"]').value = data.textAlign;
div.querySelector('[data-input="allCaps"]').checked = data.allCaps;

return fragment.appendChild(div);
Expand Down
14 changes: 10 additions & 4 deletions src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const defaultTextOptions = {
font: 'Anton',
fontSize: 40,
fontWeight: 'normal',
textAlign: 'center',
shadowBlur: 3,
offsetY: 0,
offsetX: 0,
Expand Down Expand Up @@ -107,13 +108,14 @@ const draw = image => {
ctx.font = `${item.fontWeight} ${item.fontSize}px ${item.font}`;

const multiplier = index + 1;
const lineHeight = ctx.measureText('M').width + 20;
const lineHeight = ctx.measureText('M').width + item.fontSize / 2;
const xPos = canvas.width / 2;
const shadowBlur = item.shadowBlur;
const text = item.allCaps === true ? item.text.toUpperCase() : item.text;
const textLines = text.split('\n');

ctx.fillStyle = item.fillColor;
ctx.textAlign = 'center';
ctx.textAlign = item.textAlign;
ctx.save();

if (shadowBlur !== 0) {
Expand All @@ -126,11 +128,13 @@ const draw = image => {
if (item.rotate) {
ctx.translate(xPos + item.offsetX, lineHeight * multiplier + item.offsetY);
ctx.rotate(item.rotate * Math.PI / 180);
ctx.fillText(text, 0, 0);
textLines.forEach((text, index) => ctx.fillText(text, 0, index * lineHeight));
ctx.rotate(-(item.rotate * Math.PI / 180));
ctx.translate(-(xPos + item.offsetX), -(lineHeight * multiplier + item.offsetY));
} else {
ctx.fillText(text, xPos + item.offsetX, lineHeight * multiplier + item.offsetY);
textLines.forEach((text, index) => {
ctx.fillText(text, xPos + item.offsetX, index * lineHeight + lineHeight * multiplier + item.offsetY);
});
}

ctx.restore();
Expand Down Expand Up @@ -349,6 +353,8 @@ const handleInputsContainerInput = evt => {
prop = 'fontSize';
} else if (element.matches('[data-input="fontWeight"]')) {
prop = 'fontWeight';
} else if (element.matches('[data-input="textAlign"]')) {
prop = 'textAlign';
} else if (element.matches('[data-input="shadowBlur"]')) {
prop = 'shadowBlur';
} else if (element.matches('[data-input="offsetY"]')) {
Expand Down

0 comments on commit 762a4c1

Please sign in to comment.