Reputation: 2843
So basically. I'm trying to loop through each letter in a text (in this case the text is "marius"). Now, the problem is that the first letter is never drawn. If the text is "marius", it draws "arius". I've tried what I can think of, but I can't find the error. Does anyone know what I am doing wrong? Don't worry about anything else. The code is not done, but this problem if eating my brains out. Thanks in advance. :)
WebFont.load({
google: {
families: ['Audiowide']
},
active: function() {
// Just the requestAnimationFrame
// for different types of browsers
const requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
// Canvas
const c = document.getElementById('canvas');
const ctx = c.getContext('2d');
const cWidth = c.width = window.innerWidth;
const cHeight = c.height = window.innerHeight;
// Framerate settings
// Better not touch theese if you
// do not know what you are doing
let now, delta;
let fps = (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) ? 29 : 60;
let then = Date.now();
const interval = 1000 / fps;
/*-------------------------------------------------------
PREPARATION BELOW
-------------------------------------------------------*/
var text = 'marius';
var letters = [];
var lettersCount;
const config = {
'background': '#222',
'letterSize': '72px',
'letterFont': 'Audiowide',
'letterSpacing': 50,
'amp': 60,
'yOffset': cHeight / 2
};
for (let i = 0, lettersCount = text.length; i < lettersCount; i++) {
letters.push(new Letter(text[i]));
}
for (let i = 0, len = letters.length; i < len; i++) {
var addThisToo = (i == 0) ? 0 : letters[i - 1].letterOffset;
var letterWidth = getTextWidth(letters[i].letter, config.letterSize + ' ' + config.letterFont);
letters[i].letterOffset = letterWidth + addThisToo;
}
/*-------------------------------------------------------
END PREPARATION
-------------------------------------------------------*/
/**
* draw()
* The draw function, where everything is happening
* @return null
*/
function draw() {
looper();
if (delta > interval) {
// Calculate then
then = now - (delta % interval);
// All your own stuff here
drawBackground();
drawLetters();
}
}
/**
* drawLetters()
* Draw the letters from letters Array
* Sinusoidal wave!
*/
function drawLetters() {
for (let i = 0, len = letters.length; i < len; i++) {
// Prepare X and Y of the letter
let letterOffset = (i > 0) ? letters[i - 1].letterOffset : letters[i].letterOffset;
let x = letters[i].xPos + letterOffset;
let y = config.yOffset + (sin(letters[i].xPos / 45 + i) * config.amp);
// Create gradient color
var gradient = ctx.createLinearGradient(0, 0, cWidth, 0);
gradient.addColorStop('0', '#ff6666');
gradient.addColorStop('0.5', '#66ff66');
gradient.addColorStop('1', '#6666ff');
// Draw and fill the letter
ctx.font = config.letterSize + ' ' + config.letterFont;
ctx.fillText(letters[i].letter, x, y);
ctx.fillStyle = gradient;
// Update letter X and Y position
letters[i].yPos += 0.05 * i;
letters[i].xPos -= letters[i].xVel;
}
}
/**
* letter(letter)
* Letter object
* @return nul
*/
function Letter(letter) {
this.letter = letter;
this.xPos = cWidth;
this.yPos = 0;
this.xVel = 2;
this.yVel = 0;
this.letterOffset = 0;
}
/**
* Looper()
* Looper function, do not touch!
* @return null
*/
function looper() {
requestAnimationFrame(draw);
now = Date.now();
delta = now - then;
}
/**
* drawBackground()
* Draws the background
* @return null
*/
function drawBackground() {
ctx.fillStyle = config.background;
ctx.fillRect(0, 0, c.width, c.height);
}
/**
* randInt(min, max)
* Returns random integer between min - max
* @param integer min
* @param integer max
* @return integer
*/
function randInt(min, max) {
max = max === undefined ? min - (min = 0) : max;
return Math.floor(Math.random() * (max - min) + min);
}
/**
* sin(x)
* Sinus of X
* @return float
*/
function sin(x) {
return Math.sin(x);
}
/**
* getTextWidth(text, font)
* Return the width of the text
* @return integer
*/
function getTextWidth(text, font) {
ctx.font = font;
var metrics = ctx.measureText(text);
return Math.round(metrics.width);
}
/**
* EventListener - Click
*/
document.addEventListener('click', function(e) {
let x, y;
if (e.offsetX) {
x = e.offsetX;
y = e.offsetY;
} else if (e.layerX) {
x = e.layerX;
y = e.layerY;
}
});
requestAnimationFrame(draw);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js"></script>
<canvas id="canvas"></canvas>
Upvotes: 2
Views: 76
Reputation: 11377
The problem in your implementation is that you set the ctx.fillStyle
after you do the fillText
call. This means that you only set the fillStyle
of the second letter and as the default fillStyle
is black the first will not be visible. If you switch the two lines it will work.
Then you have a second mistake which is that the first and the second letter are at the same x
position. I changed the preparation method and the draw method to make the letter spacing work properly.
WebFont.load({
google: {
families: ['Audiowide']
},
active: function() {
// Just the requestAnimationFrame
// for different types of browsers
const requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
// Canvas
const c = document.getElementById('canvas');
const ctx = c.getContext('2d');
const cWidth = c.width = window.innerWidth;
const cHeight = c.height = window.innerHeight;
// Framerate settings
// Better not touch theese if you
// do not know what you are doing
let now, delta;
let fps = (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) ? 29 : 60;
let then = Date.now();
const interval = 1000 / fps;
/*-------------------------------------------------------
PREPARATION BELOW
-------------------------------------------------------*/
var text = 'marius';
var letters = [];
var lettersCount;
const config = {
'background': '#222',
'letterSize': '72px',
'letterFont': 'Audiowide',
'letterSpacing': 50,
'amp': 60,
'yOffset': cHeight / 2
};
for (let i = 0, lettersCount = text.length; i < lettersCount; i++) {
letters.push(new Letter(text[i]));
}
for (let i = 1, len = letters.length; i < len; i++) {
var addThisToo = letters[i - 1].letterOffset;
var letterWidth = getTextWidth(letters[i - 1].letter, config.letterSize + ' ' + config.letterFont);
letters[i].letterOffset = letterWidth + addThisToo + config['letterSpacing'];
}
/*-------------------------------------------------------
END PREPARATION
-------------------------------------------------------*/
/**
* draw()
* The draw function, where everything is happening
* @return null
*/
function draw() {
looper();
if (delta > interval) {
// Calculate then
then = now - (delta % interval);
// All your own stuff here
drawBackground();
drawLetters();
}
}
/**
* drawLetters()
* Draw the letters from letters Array
* Sinusoidal wave!
*/
function drawLetters() {
for (let i = 0, len = letters.length; i < len; i++) {
// Prepare X and Y of the letter
let letterOffset = letters[i].letterOffset;
let x = letters[i].xPos + letterOffset;
let y = config.yOffset + (sin(letters[i].xPos / 45 + i) * config.amp);
// Create gradient color
var gradient = ctx.createLinearGradient(0, 0, cWidth, 0);
gradient.addColorStop('0', '#ff6666');
gradient.addColorStop('0.5', '#66ff66');
gradient.addColorStop('1', '#6666ff');
// Draw and fill the letter
ctx.font = config.letterSize + ' ' + config.letterFont;
ctx.fillStyle = gradient;
ctx.fillText(letters[i].letter, x, y);
// Update letter X and Y position
letters[i].yPos += 0.05 * i;
letters[i].xPos -= letters[i].xVel;
}
}
/**
* letter(letter)
* Letter object
* @return nul
*/
function Letter(letter) {
this.letter = letter;
this.xPos = cWidth;
this.yPos = 0;
this.xVel = 2;
this.yVel = 0;
this.letterOffset = 0;
}
/**
* Looper()
* Looper function, do not touch!
* @return null
*/
function looper() {
requestAnimationFrame(draw);
now = Date.now();
delta = now - then;
}
/**
* drawBackground()
* Draws the background
* @return null
*/
function drawBackground() {
ctx.fillStyle = config.background;
ctx.fillRect(0, 0, c.width, c.height);
}
/**
* randInt(min, max)
* Returns random integer between min - max
* @param integer min
* @param integer max
* @return integer
*/
function randInt(min, max) {
max = max === undefined ? min - (min = 0) : max;
return Math.floor(Math.random() * (max - min) + min);
}
/**
* sin(x)
* Sinus of X
* @return float
*/
function sin(x) {
return Math.sin(x);
}
/**
* getTextWidth(text, font)
* Return the width of the text
* @return integer
*/
function getTextWidth(text, font) {
ctx.font = font;
var metrics = ctx.measureText(text);
return Math.round(metrics.width);
}
/**
* EventListener - Click
*/
document.addEventListener('click', function(e) {
let x, y;
if (e.offsetX) {
x = e.offsetX;
y = e.offsetY;
} else if (e.layerX) {
x = e.layerX;
y = e.layerY;
}
});
requestAnimationFrame(draw);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js"></script>
<canvas id="canvas"></canvas>
Upvotes: 3