I have this table in my html having a lot of blank space from both upper and lower sides of the text.
I have tried css and html but I couldn't fix it myself. Any idea how to remove white space?
Screenshot (red arrows mean where I want the space to be reduced):
My Source code
<!DOCTYPE HTML>
<html>
<head>
<style>
#font-face {
font-family: 'gill-sans-light';
src:url('gill-sans-std-light-59139f0a2c460.eot'); /* IE9 Compat Modes */
src:url('gill-sans-std-light-59139f0a2c460.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('gill-sans-std-light-59139f0a2c460.woff2') format('woff2'), /* Super Modern Browsers */
url('gill-sans-std-light-59139f0a2c460.woff') format('woff'), /* Pretty Modern Browsers */
url('gill-sans-std-light-59139f0a2c460.ttf') format('truetype'), /* Safari, Android, iOS */
url('gill-sans-std-light-59139f0a2c460.svg#gill-sans-light') format('svg'); /* Legacy iOS */
}
p {
text-align: center;
font-size: 120px;
font-family: 'gill-sans-light';
}
</style>
</head>
<body>
<table border="1px" align ="center" id="table" cellpadding="0">
<tr>
<td><p id="years"></p></td>
<td><p id="months"></p></td>
<td><p id="days"></p></td>
<td><p id="hours"></p></td>
<td><p id="minutes"></p></td>
<td><p id="seconds"></p></td>
<td><p id="milliseconds"></p></td>
</tr>
<tr>
<td><p>y</p></td>
<td><p>m</p></td>
<td><p>d</p></td>
<td><p>h</p></td>
<td><p>m</p></td>
<td><p>s</p></td>
<td><p>ms</p></td>
</tr>
</table>
<p id="done_message"></p>
<script>
// Set the date we're counting down to
var countDownDate = new Date("May 12, 2019 00:00:00").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
var milliseconds = distance%1000;
var months = Math.floor(days/30);
days = days - months*30;
var years = Math.floor (months/12);
months = months - years*12;
if(years<10){
document.getElementById("years").innerHTML = "0" + years + " . " ;
} else {
document.getElementById("years").innerHTML = years + " . " ;
}
if(months<10){
document.getElementById("months").innerHTML = "0" + months + " . " ;
} else {
document.getElementById("months").innerHTML = months+ " . " ;
}
if(days<10){
document.getElementById("days").innerHTML = "0" + days + " . " ;
} else {
document.getElementById("days").innerHTML = days + " . " ;
}
if(hours<10){
document.getElementById("hours").innerHTML = "0" + hours + " . " ;
} else {
document.getElementById("hours").innerHTML = hours + " . " ;
}
if(minutes<10){
document.getElementById("minutes").innerHTML = "0" + minutes + " . " ;
} else {
document.getElementById("minutes").innerHTML = minutes + " . " ;
}
if(seconds<10){
document.getElementById("seconds").innerHTML = "0" + seconds + " . " ;
} else {
document.getElementById("seconds").innerHTML = seconds + " . " ;
}
if(milliseconds>=100){
document.getElementById("milliseconds").innerHTML = milliseconds ;
} else if(milliseconds<10){
document.getElementById("milliseconds").innerHTML = "00" + milliseconds ;
} else {
document.getElementById("milliseconds").innerHTML = "0" + milliseconds ;
}
;
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("done_message").innerHTML = "EXPIRED";
document.getElementById("years").innerHTML = "00.";
document.getElementById("months").innerHTML = "00.";
document.getElementById("days").innerHTML = "00.";
document.getElementById("hours").innerHTML = "00.";
document.getElementById("minutes").innerHTML = "00.";
document.getElementById("seconds").innerHTML = "00.";
document.getElementById("milliseconds").innerHTML = "000 ";
}
},1);
</script>
</body>
It's relative to your code. For example, if your using headlines (h1, h2...) than you'll need to add margin an padding set to zero in those elements.
If your font-size is high, maybe the line-height property is what your looking for. Set it to the same as your font-size.
Also, have you removed the padding in the table cells and the table's border spacing? If not, you must a declartion like follow:
table {
border-spacing: 0;
border-collapse: separate;
}
table tr td {
padding: 0;
}
I believe that all of those will help you, but it's necessary to give a look at yuor full code and CSS.
EDIT:
After watching your code, the mentioned gap in your table cells is cause by your paragraphes.
Every element has a default margin and padding. To avoid this in your case, just add the following code to remove all of the spaces in the paragraphes of your HTML code:
p {
margin: 0;
padding: 0;
}
For next time, I'd recommend using the Developer Console of the Chrome browser (Click F12). It shows you the style properties of each element you choose, and than you test your code much better. Good luck.
You can set a row height in your CSS:
tr{height: 20px;}
Related
I am trying to add a countdown to my website as a custom html content but when I add the code it changed the style of the entire page instead of just the counter. PLEASE help me understand what I am doing wrong
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
p {
text-align: center;
font-size: 60px;
margin-top: 0px;
color:#0011;
}
</style>
</head>
<body>
<p id="demo"></p>
<script>
// Set the date we're counting down to
var countDownDate = new Date("Jan 10, 2022 15:37:25").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get today's date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Output the result in an element with id="demo"
document.getElementById("demo").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
// If the count down is over, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("demo").innerHTML = "EXPIRED";
}
}, 1000);
</script>
</body>
</html>
Your issue is that you are styling a tag in your header. When you do this:
<style>
p {
text-align: center;
font-size: 60px;
margin-top: 0px;
color:#0011;
}
</style>
What you're telling the HTML is to style any paragraph tag with this styling. What you'll want to do is delete the code above and modify your innerHTML to use a span or something with a class attribute. Then use a class or an id to style your body.
<style>
.test {
text-align: center;
font-size: 60px;
margin-top: 0px;
color:#0011;
}
</style>
// Output the result in an element with id="demo"
document.getElementById("demo").innerHTML = "<span class='test'>"+days + "d " + hours + "h "
+ minutes + "m " + seconds + "s </span>";
I've been working on some sort of a drawing grid recently and used border-spacing.
HTML:
<table id="table"></table>
<script>
var res = 16;
var cell_size = 8;
var table = document.getElementById("table");
var border_size = parseInt(window.getComputedStyle(table).getPropertyValue("border-spacing"),10);
table.style.width = (cell_size + border_size) * res + border_size + "px";
table.style.height = (cell_size + border_size) * res + border_size + "px";
for(y=0;y<res;y++){
var row = table.insertRow();
for(x=0;x<res;x++){
row.insertCell();
}
}
</script>
CSS:
table{
background: #000000;
border-spacing: 1px;
}
td{
padding: 0;
background: #c9c9c9;
}
Idea is to form a table with fixed amount of cells with pre-set size and border spacing.
var res = 16;
var cell_size = 8;
var border_size = parseInt(window.getComputedStyle(table).getPropertyValue("border-spacing"),10);
Size of the whole table is then computed based on these parameters.
table.style.width = (cell_size + border_size) * res + border_size + "px";
table.style.height = (cell_size + border_size) * res + border_size + "px";
Finally the table is created via nested loop.
for(y=0;y<res;y++){
var row = table.insertRow();
for(x=0;x<res;x++){
row.insertCell();
}
}
If I use small (<4px) border size it doesn't seem to work right in Chrome - cell sizes start to be offset around 0.4 px. In Chrome there are 2 computed webkit options affecting this offset:
-webkit-border-horizontal-spacing
-webkit-border-vertical-spacing
However I can't change them like so:
-webkit-border-horizontal-spacing: 1px;
-webkit-border-vertical-spacing: 1px;
Computed values will still stay at 0.8 px. It isn't much at the end, but it really bothers me. Is there any reason for such behaviour and is it possible to have exact cell sizes with such low values?
Here is an example fiddle: https://jsfiddle.net/kdqoc4vy/1/
Note that cell_size should be exactly 20px, but in fact it is 19.2.
P.S. With Edge evertyhing works as it should. This 0.8px is almost nothing when the table is small, but when it has 64 rows and columns such inconsistency becomes a problem. Thanks in advance for your reply!
So, I am making a cookie clicker, I want my upgrades to go next to my cookies, which is centered. How would I make my upgrades go left and have the cookie still centered? It would look much better if I could. If you have any idea how, please, please respond quickly.
Help would be appreciated! :^)
<script>
function update() {
document.getElementById('text').value = cookiecount;
document.title = cookiecount + " Cookies";
document.getElementById('ammountMultiplier').innerHTML = "Multiplier Upgrade x" + (multiplier+1);
document.getElementById('ammountMultiplier2').innerHTML = "x" + (multiplier+1);
document.getElementById('costMultiplier').innerHTML = ((multiplier+1) * 100) + " Cookies";
document.getElementById('currentMultiplier').innerHTML = "Your current Multiplier is x" + (multiplier);
document.getElementById('ammountAutoClick').innerHTML = "You Own " + autoClick + " Auto Clickers";
document.getElementById('costAutoClick').innerHTML = ((autoClick+1) * 12) + " Cookies";
document.getElementById('ammountFarms').innerHTML = "You Own " + farms + " Farms";
document.getElementById('costFarms').innerHTML = ((farms+1) * 15) + " Cookies";
document.getElementById('ammountGrandma').innerHTML = "You Own " + grandma +" Grandmas";
document.getElementById('costGrandma').innerHTML = ((grandma+1) * 15) + "Cookies";
document.getElementById('cookiespersecond').innerHTML = "You are gaining " + (((autoClick)+(farms*2)+(grandma*2))*multiplier) + " Cookies per/s";
}
var multiplier = 1;
var cookiecount = 0;
var autoClick = 0;
var farms = 0;
var grandma = 0;
function timer() {
cookiecount = cookiecount + autoClick*multiplier;
cookiecount = cookiecount + farms*2*multiplier;
cookiecount = cookiecount + grandma*2*multiplier;
update()
}
setInterval(timer, 1000)
</script>
<html>
<style>
body{
background-image: url('http://pa1.narvii.com/6718/86e6473ccdc4cfefcb427d96def5cf6917d481f4_00.gif');
background-size: cover;
}
</style>
<center>
<head><title>0 Cookies</title></head>
<body>
<p id="cookiespersecond">You are gaining 0 Cookies per/s</p>
<img src="cookie.jpg">
<br><br>
You got:
<input type="text" id="text" disabled style= text-align:center value=0>
<script>
function add() {
cookiecount = cookiecount + 1
update()
}
</script>
Cookies
<br><br></center>
<button>Save</button>
<button>Load</button>
<br><br>
<p id="ammountMultiplier">Multiplier Upgrade x2</p>
<button><span id="ammountMultiplier2">x2</span></button>
<p id="costMultiplier">200 Cookies</p>
<p id="currentMultiplier">Your current Multiplier is x1</p>
<br>
<p>Buy 1 Auto Clicker</p>
<button><img src=mouse.jpg width="30px" height="40px"></button>
<p id="costAutoClick">12 Cookies</p>
<p id="ammountAutoClick">You Own 0 Auto Clickers</p>
<br>
<p>Buy 1 Farm</p>
<button><img src="farm.jpg" width="50px" height="50px"></button>
<p id="costFarms">15 Cookies</p>
<p id="ammountFarms">You Own 0 Farms</p>
<br>
<p>Buy 1 Grandma</p>
<button><img src="grandma.jpg" width="50px" height="50px"></button>
<p id="costGrandma">15 Cookies</p>
<p id="ammountGrandma">You own 0 Grandmas</p>
<script>
function save() {
localStorage.setItem("cookiecount", cookiecount);
localStorage.setItem("autoClick", autoClick);
localStorage.setItem("farms", farms);
localStorage.setItem("multiplier", multiplier);
}
function load() {
cookiecount = localStorage.getItem("cookiecount");
cookiecount = parseInt(cookiecount);
autoClick = localStorage.getItem("autoClick");
autoClick = parseInt(autoClick);
farms = localStorage.getItem("farms");
farms = parseInt(farms);
multiplier = localStorage.getItem("multiplier");
multiplier = parseInt(multiplier);
update()
}
function buyAutoClick() {
if (cookiecount >= ((autoClick+1) * 12)) {
cookiecount = cookiecount - ((autoClick+1) * 12);
autoClick = autoClick + 1;
update()
}
}
function buyFarm() {
if (cookiecount >= ((farms+1) * 15)) {
cookiecount = cookiecount - ((farms+1) * 15);
farms = farms + 1;
update()
}
}
function buyMultiplier() {
if (cookiecount >= ((multiplier+1) * 100)) {
cookiecount = cookiecount - ((multiplier+1) * 50);
multiplier = multiplier + 1;
update()
}
}
function buyGrandma() {
if (cookiecount >= ((grandma+1) * 15)) {
cookiecount = cookiecount - ((grandma+1) * 15);
grandma = grandma + 1;
update()
}
}
</script>
</html>
Please help!
You could try separating the HTML elements that you created with JS into two categories of cookie-side and upgrades/buildings and put both of those into their own div tags which would be held in another div with the class of game-wrapper tag which you would add the following code to in CSS:
.game-wrapper {
display: flex;
align-items: center;
}
Here is my angular code to define a countdown timer for my website:
function AlbumCtrl($scope, $timeout) {
$scope.counter = new Date("Nov 30, 2017 09:00:00").getTime() - new Date().getTime();
$scope.onTimeout = function() {
$scope.counter--;
var distance = $scope.counter;
$scope.countdown = Math.floor(distance / (1000 * 60 * 60 * 24)) + "d " +
Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) + "h " +
Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)) + "m " +
Math.floor(((distance % (1000 * 60)) / 1000)) + "s ";
if ($scope.counter > 0) {
mytimeout = $timeout($scope.onTimeout, 1000);
} else {
alert("Time is up!");
}
}
var mytimeout = $timeout($scope.onTimeout, 1000);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <!-- added for a working snippet -->
<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/angular-1.0.0rc11.min.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
</head>
<body>
<div ng-controller="AlbumCtrl">
{{counter}} {{countdown}}
</div>
</body>
</html>
The 'counter' appears to decrement correctly on my page but the 'countdown' stays fixed and shows the correct value only on page load or refresh. For example, I get the following output as time passes:
1115148833 12d 21h 45m 48s
1115148745 12d 21h 45m 48s
1115148693 12d 21h 45m 48s
What exactly is going wrong? Thanks for your help.
https://github.com/johnpapa/angular-styleguide/tree/master/a1
// Declare a "main" module for the single page application
// second argument to module is an array of dependencies your module
// uses (examples: ui-router ui-bootstrap etc., 'ng' module is assumed as a dependency)
angular.module('myApp', [])
//Defining a service on the module allows you to encapsulate some functionality
//Injecting the angular $timeout service from the 'ng' module and defining
//a new service. This object gets initialized the first time it's
//referenced and stays alive until the application/page is refreshed.
.service("CountdownService", function($timeout){
//Define an object to attach properties and functions to and return for
//use elsewhere in the app
var countdownService = {};
//Basically the functional code you had already adjusted the
//seconds to just use %60 since some sort of issue with the existing math
// %60 should give remainder after dividing by 60 and appears the "distance"
// was moving at 1 second per second not 1000, so removed the 1000 factors
countdownService.counter = new Date("Nov 30, 2017 09:00:00").getTime() - new Date().getTime();
countdownService.onTimeout = function() {
countdownService.counter--;
var distance = countdownService.counter;
var newValue = Math.floor(distance / (1000 * 60 * 60 * 24)) + "d " +
Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) + "h " +
Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)) + "m " +
Math.floor((distance % (60)) ) + "s ";
countdownService.countdown = newValue;
console.log(Math.floor((distance % (60))) + "s ");
if (countdownService.counter > 0) {
mytimeout = $timeout(countdownService.onTimeout, 1000);
} else {
alert("Time is up!");
}
}
var mytimeout = $timeout(countdownService.onTimeout, 1000);
return countdownService;
})
//Now the controller just has the new service injected it uses "this"
//instead of scope in the ng-controller we use "controllerAs" syntax
//so we don't need to use the scope (angular 2 hides the scope so good
//to just get used to not using it)
.controller("TestCtrl", function(CountdownService){
this.CountdownService = CountdownService;
});
<!doctype html>
<html ng-app="myApp">
<head>
</head>
<body>
<div ng-controller="TestCtrl as testCtrl">
{{testCtrl.CountdownService.counter}} {{testCtrl.CountdownService.countdown}}
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.js"></script> <!-- added for a working snippet -->
</body>
</html>
This is interesting . Your Math.floor function is giving round figure of the fraction and your fraction number changes so minutely with counter , only seconds string decreases from one number when counter comes to 1095904999. So you are not able to notice the change , see yourself :
function AlbumCtrl($scope, $timeout) {
$scope.counter = new Date("Nov 30, 2017 09:00:00").getTime() - new Date().getTime();
$scope.onTimeout = function() {
--$scope.counter;
var distance = $scope.counter;
$scope.countdown = $scope.counter/ (1000 * 60 * 60 * 24) + "d " +
( $scope.counter% (1000 * 60 * 60 * 24)) / (1000 * 60 * 60) + "h " +
( $scope.counter% (1000 * 60 * 60)) / (1000 * 60)+ "m " +
(( $scope.counter% (1000 * 60)) / 1000) + "s ";
if ($scope.counter > 0) {
mytimeout = $timeout($scope.onTimeout, 1000);
} else {
alert("Time is up!");
}
}
var mytimeout = $timeout($scope.onTimeout, 1000);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <!-- added for a working snippet -->
<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/angular-1.0.0rc11.min.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
</head>
<body>
<div ng-controller="AlbumCtrl">
{{counter}} {{countdown}}
</div>
</body>
</html>
For demonstration purposes(to simplify correctness of answer checking) I set destination date to 1 day and 2 hours later from now:
function AlbumCtrl($scope, $timeout) {
var date = new Date();
date.setHours(date.getHours() + 2);
date.setDate(date.getDate() + 1);
$scope.counter = date.getTime() - new Date().getTime();
$scope.onTimeout = function() {
$scope.counter = $scope.counter - 1000;
var ost = $scope.counter;
function GetPart(koef) {
koef *= 1000;
var res = Math.floor(ost / koef);
ost = ost - res * koef;
return res;
}
var days = GetPart(60 * 60 * 24);
var hours = GetPart(60 * 60);
var min = GetPart(60);
var sec = GetPart(1);
$scope.countdown = days + "d " + hours + "h " + min + "m " + sec + "s ";
if ($scope.counter > 0)
mytimeout = $timeout($scope.onTimeout, 1000);
else
alert("Time is up!");
}
var mytimeout = $timeout($scope.onTimeout, 1000);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!-- added for a working snippet -->
<!doctype html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/angular-1.0.0rc11.min.js"></script>
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
</head>
<body>
<div ng-controller="AlbumCtrl">
{{countdown}}
</div>
</body>
</html>
has anyone noticed or found a solution to the problem I've been experiencing? It takes a long time to render large fonts (>100px) in Chrome on the canvas using fillText(). I need to have a much faster frame rate, but once the fonts get big it take like a second to load each frame. In firefox it runs well though...
UPDATE:
Here is the pertinent code that is running in my draw() function which runs every 10 milliseconds on interval. If anything pops out to you, that would be great. I'll try to profiler thing though, thanks.
g.font = Math.floor(zoom) + "px sans-serif";
g.fillStyle = "rgba(233,233,245," + (ZOOM_MAX-zoom*(zoom*0.01))/(ZOOM_MAX) + ")";
for (h=0; h<76; h++)
{
h_offset = 2.75*h*Math.floor(zoom);
// only render if will be visible, because it tends to lag; especially in Chrome
hpos = Math.floor(half_width + std_offset + h_offset);
if (hpos > (-half_width)-h_offset && hpos < WIDTH+h_offset)
{
g.fillText(1950+h, hpos, anchor_y - 0);
}
}
g.font = "600 " + Math.floor(zoom/40) + "px sans-serif";
g.fillStyle = "rgba(233,233,245," + (ZOOM_MAX-zoom*(zoom*0.0001))/(ZOOM_MAX) + ")";
for (h=0; h<76; h++)
{
h_offset = 2.75*h*Math.floor(zoom);
hpos = Math.floor(half_width + std_offset + h_offset);
if (hpos > (-half_width)-h_offset && hpos < WIDTH+h_offset)
{
// see if we should bother showing months (or will it be too small anyways)
if (zoom/40 > 2)
{
// show months
for (i=0; i<12; i++)
{
i_offset = 0.175*i*zoom;
ipos = Math.floor(WIDTH/2 + std_offset + i_offset + h_offset) + 10;
if (ipos > -half_width && ipos < WIDTH)
{
g.fillText(months[i], ipos, anchor_y - 20);
}
}
}
}
}
g.font = "600 " + Math.floor(zoom/350) + "px sans-serif";
g.fillStyle = "rgba(233,233,245," + (ZOOM_MAX-zoom/5)/(ZOOM_MAX*2.25) + ")";
for (h=0; h<76; h++)
{
h_offset = 2.75*h*Math.floor(zoom);
// only render if will be visible, because it tends to lag; especially in Chrome
hpos = Math.floor(half_width + std_offset + h_offset);
if (hpos > (-half_width)-h_offset && hpos < WIDTH+h_offset)
{
// see if we should bother showing months (or will it be too small anyways)
if (zoom/40 > 2)
{
// show months
for (i=0; i<12; i++)
{
i_offset = 0.175*i*zoom;
ipos = Math.floor(WIDTH/2 + std_offset + i_offset + h_offset) + 10;
// see if we should bother showing days (or will it be too small anyways)
if (zoom/350 > 2)
{
// show days
for (j=0; j<31; j++)
{
j_offset = 0.005*j*zoom + zoom*0.005;
jpos = Math.floor(half_width + std_offset + j_offset + i_offset + h_offset);
if (jpos > -half_width && jpos < WIDTH)
{
g.fillText(days[i][j], jpos, anchor_y - 20);
selected_days += 'm: '+i+', d: '+j+' | ';
}
}
}
}
}
}
}
We'd need a lot more information, I'm not convinced that drawing a large font is actually whats causing the performance issues. Drawing such a large font works extremely quickly on my machines for any browser that I've tried.
The first thing you should do is open up the Chrome profiler and then run the code, and see if it is actually the ctx.fillText call that is taking up the time. I imagine its actually something else.
It's possible you are calling something too much, like setting ctx.font over and over unnecessarily. Setting ctx.font on some browsers actually takes significantly longer to do than calls to fillRect! If your font changes in the app you can always cache.
Here's a test back from October: http://jsperf.com/set-font-perf
As you can see, in many versions of Chrome setting the font unnecessarily doubles the time it takes! So make sure you set it as little as possible (with caching, etc).