Use emoji as favicon in websites - javascript

Emojis are awesome, so I was thinking how could add one as a favicon using link tag.
One possible solution:
I found one possible way in this blog post here. Based on that it's been achieved what I wanted so far with the following solution.
JavaScript code snippet:
const setFavicon = (emoji) => {
const canvas = document.createElement('canvas');
canvas.height = 32;
canvas.width = 32;
const ctx = canvas.getContext('2d');
ctx.font = '28px serif';
ctx.fillText(emoji, -2, 24);
const favicon = document.querySelector('link[rel=icon]');
if (favicon) { favicon.href = canvas.toDataURL(); }
}
setFavicon('🐢');
The link tag in HTML:
<link rel="icon" type="image/png" href="favicon.ico"/>
So my question:
Maybe creating favicon.ico file for this purpose would do the thing also. Is there any better way to achieve this without converting or having extra JavaScript snippets in your code? Thank you!

Now that all major browsers support SVG favicons, it's possible to refer to an SVG that contains the emoji inside:
<!-- favicon.svg -->
<svg xmlns="http://www.w3.org/2000/svg">
<text y="32" font-size="32">🚀</text>
</svg>
Link it up like you'd normally do:
<link rel="icon" href="/favicon.svg" />

Another way to do it is:
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎯</text></svg>">
From: https://css-tricks.com/emojis-as-favicons/

Favicon are images, so just make a static image and use that.
You're not going to change it constantly, so there's no need to make people's computers spend the time running JS to generate an asset that is always the same, better to generate it once, save that as your favicon image file, and point to that. As a bonus, browsers will cache it, so instead of recomputing it every time, or even downloading it every time, as a favicon it'll only be downloaded once and then never again.
Also note that you don't need the .ico extension (it's the extension for an ancient image format), instead just use the extension the image is supposed to have, and set the type to the correct image mime type.

Making a screenshot is probably the better and easier solution (as Mike mentioned).
And there is one more advantage of this solution:
Emojis can look very different on different platforms.
An example:
You won't need to handle that problem, too..

Related

How to fix a grayscale border when downloading html elements with html2 canvas

I am building a sudoku puzzle generator + sudoku downloader. There is no problem with the sudoku itself, but with the downloaded image of it.
So, I'm using html2 canvas, which allows me to download html elements. I did this with the sudoku. The big problem is that when I download that html element, I see some grayscale around the borders, as you can see in this example:
And in the website you can't see that grayscale border:
This probably does not have to do anything with css, because there is no problem in the styling itself, but in the way the html was downloaded.
I tried using different image formats, like png, jpg and heic, the results were all the same.
If someone knows anything that could solve my problem, please let me know.
This is a minimal example of my code. The screenshotTarget is just a html 2 element in this situation
document.getElementById("dl-png").onclick = function () {
const screenshotTarget = document.getElementById("example-table");
html2canvas(screenshotTarget, {
scale: 4.5,
}).then((canvas) => {
const base64image = canvas.toDataURL("image/jpg");
var anchor = document.createElement("a");
anchor.setAttribute("href", base64image);
anchor.setAttribute("download", "sudoku.jpg");
anchor.click();
anchor.remove();
});
};
You have to play with the scale value to increase the size of a target first before capturing it. See html2canvas configuration. Try scale 2 to 5.
If html2canvas cannot give you what you need, you might have to opt to a different tool. Try domtoimage. Or the accepted answer for the same question
(Refer to this stackoverflow answer here)
Or maybe you have a similar case with this guy where he was on a retina display. See his solution.

I want to write Javascript for an HTML5 canvas, but I don't know how to set the canvas up

Up until now, I have only used Javascript in an environment that doesn't require any HTML, like the one on Khan Academy here. However, now I'm using sublime text, and I realize that I can't just write ellipse() and have it show up on the screen. Now I need the element. However, according to w3schools, now, for a circle to show up, I need to do this:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(95,50,40,0,2*Math.PI);
ctx.stroke();
Ugh. I really don't want to have to write "ctx" before every single line of code I make, or learn a bunch of new commands like "beginPath" and "lineTo". Is there a way I can create the canvas, and still make a program without all this messy stuff? Or, if that's not possible, could someone point me to a library that can? Thanks so much!
While this approach still doesn't free you from the responsibility of knowing your way around the canvas element, you can make use of the with keyword to avoid continually typing ctx - the approach is not one I use and as per the MDN page Statements and declarations>with you can run into problems with ambiguity.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
with (ctx)
{
beginPath();
arc(95,50,40,0,2*Math.PI);
stroke();
}
<canvas id='myCanvas'></canvas>
Not really sure what the question is. But from what I understood you need to learn how to add a canvas to a HTML file and link your JS to the same. If so, here's how to do it.
HTML as below
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<title>Your Canvas Application</title>
<!-- link your js file as below -->
<script src = "path/to/yourjsfile.js">
</head>
<body>
<canvas id="myCanvas" width="500" height="500"></canvas>
</body>
JS file (yourjsfile.js) as below
window.onload = function () {
var canvas = document.getElementById("myCanvas");
var c = canvas.getContext("2d");
c.beginPath();
c.arc(95,50,40,0,2*Math.PI);
c.stroke();
};
You really can not entirely get rid of 'ctx', but instead you can shorten it for something like 'c'. Rather than looking for libraries, I recommend you learn the basics correct first. Then you can go ahead and explore the other options.

DOM Security Exception 18: Tainted Canvas

I'm nearly finished with a Javascript/HTML5-based game, and i've been testing it by using Chrome to open the HTML page on my local file system (i haven't uploaded anything anywhere). I'm using Chrome's file:// protocol to do this. But i'm running into a problem... At the beginning of the game, i display an image for a couple seconds before moving onto the menu screen. I pause the game by grabbing the canvas' pixel data, displaying that, then drawing a semi-transparent rectangle across the whole thing, with a crosshair as a custom pointer. However, Chrome is giving me trouble about a DOM Security Exception 18: "Unable to get image data from canvas because the canvas has been tainted by cross-origin data."
So i did some research on the Internet, and it turns out this is because Chrome sees that the image is grabbed from the local file system, and sees this as a security error. Using this question as a reference, i tried doing some research on Cross-Origin Resource Sharing, but quickly got lost. I figured it would be much easier to simply open the test HTML file using http:// and localhost like the question answerer suggested. But i have no idea how to do this, either.
I'd really like to use Chrome to continue testing my game (the developer tools accessed through Ctrl-Shift-I have proved to be invaluable), so i figured there were three solutions: Either figure out what CORS is and how to use it, learn how to open a local file using http://, or somehow hard-code my image data as a variable in my JavaScript script file (like a XPM file in C). I don't know how to do the first two, and i'm trying to avoid the third.
Yes, it’s probably time to download a local web server or sign up for a hosted server.
But if you want to continue testing without a server, you can sign up for a free dropbox.com account and host your images there.
Dropbox allows access to images using CORS friendly crossOrigin=”anonymous”.
Then CORS is no problem on Chrome & Mozilla. But, IE still fails to be CORS friendly—come on IE :(
Here’s how to load an image without CORS problems from dropbox (Chrome & Mozilla, not IE).
The “secret” is setting image.crossOrigin=”anonymous” before setting the image.src:
var externalImage2=document.createElement("img");
externalImage2.onload=function(){
canvas.width=externalImage2.width;
canvas.height=externalImage2.height;
ctx.drawImage(externalImage2,0,0);
// use getImageData to replace blue with yellow
var imageData=recolorImage(externalImage2,0,0,255,255,255,0);
// put the altered data back on the canvas
// this will FAIL on a CORS violation
ctxAnonymous.putImageData(imageData,0,0);
}
externalImage2.crossOrigin = "Anonymous";
externalImage2.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/YdzHT/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvasCORS=document.getElementById("canvasCORS");
var ctxCORS=canvasCORS.getContext("2d");
var canvasAnonymous=document.getElementById("canvasAnonymous");
var ctxAnonymous=canvasAnonymous.getContext("2d");
// Using image WITHOUT crossOrigin=anonymous
// Fails in all browsers
var externalImage1=new Image();
externalImage1.onload=function(){
canvas.width=externalImage1.width;
canvas.height=externalImage1.height;
ctx.drawImage(externalImage1,0,0);
// use getImageData to replace blue with yellow
var imageData=recolorImage(externalImage1,0,0,255,255,255,0);
// put the altered data back on the canvas
// this will FAIL on a CORS violation
ctxCORS.putImageData(imageData,0,0);
}
externalImage1.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";
// Using image WITH crossOrigin=anonymous
// Succeeds in Chrome+Mozilla, Still fails in IE
var externalImage2=new Image();
externalImage2.onload=function(){
canvas.width=externalImage2.width;
canvas.height=externalImage2.height;
ctx.drawImage(externalImage2,0,0);
// use getImageData to replace blue with yellow
var imageData=recolorImage(externalImage2,0,0,255,255,255,0);
// put the altered data back on the canvas
// this will FAIL on a CORS violation
ctxAnonymous.putImageData(imageData,0,0);
}
externalImage2.crossOrigin = "Anonymous";
externalImage2.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/colorhouse.png";
function recolorImage(img,oldRed,oldGreen,oldBlue,newRed,newGreen,newBlue){
var c = document.createElement('canvas');
var ctx=c.getContext("2d");
var w = img.width;
var h = img.height;
c.width = w;
c.height = h;
// draw the image on the temporary canvas
ctx.drawImage(img, 0, 0, w, h);
// pull the entire image into an array of pixel data
var imageData = ctx.getImageData(0, 0, w, h);
// examine every pixel,
// change any old rgb to the new-rgb
for (var i=0;i<imageData.data.length;i+=4)
{
// is this pixel the old rgb?
if(imageData.data[i]==oldRed &&
imageData.data[i+1]==oldGreen &&
imageData.data[i+2]==oldBlue
){
// change to your new rgb
imageData.data[i]=newRed;
imageData.data[i+1]=newGreen;
imageData.data[i+2]=newBlue;
}
}
return(imageData);
}
}); // end $(function(){});
</script>
</head>
<body>
<p>Original external image</p>
<canvas id="canvas" width=140 height=140></canvas>
<p>.getImageData with .crossOrigin='anonymous'
<p>[Succeeds in Chrome+Mozilla, still fails in IE]</p>
<canvas id="canvasAnonymous" width=140 height=140></canvas>
<p>.getImageData without .crossOrigin='anonymous'
<p>[Fails on all browsers]</p>
<canvas id="canvasCORS" width=140 height=140></canvas>
</body>
</html>
Developing using the local file system is generally not a good idea for precisely the reason you have discovered. To use the localhost option you'll need a web server installed on your PC. Google for a WAMP package (Windows, Apache. MysQL, PHP) which should give you everything you need.
Unfortunately, CORS will only work for you if you have a web server!
[edit] You can get a WAMP server from wampserver.com, obviously!

How to resize an image with JavaScript / jQuery without pixelation like the browser does?

I'm making a javascript / jquery program for a webpage to let a user open an image file locally from their computer, and then the program resizes it to a 16 x 16 icon size and saves it as a data url.
Everything works fine, except the resized image is very pixelated. I currently am taking the local image file, and making a data url from it. Then creating a 16 x 16 canvas element, and then drawing the image onto the canvas, and making a new data url from that.
I would like some different way to do it, as the newly resized image is very pixelated and not smooth, and does not seem anti-aliased. When the browser displays the original image with the width and height attributes set to 16, it looks very nice and smooth. This is what I would like. I don't understand how to get the same result as what is displayed when the browser does it. I am using Google Chrome.
I made a small example of it here: http://jsfiddle.net/5Pj8m/
In the example I used the jsFiddle logo, although you could test it with any local file, and see the results. Maybe this code can help someone else learn how to do it, but still, I think the resulting resize image could or should look much better!
I hope I have explained what I am trying to do, and that it is somehow possible. Can anyone help me or figure this out?
Here is the code.
HTML:
<input type='file' id='inputFile'>
<table border=1><tr><td>
<span id='spanDisplayOrigFull'>OrigFull:
<img src=http://doc.jsfiddle.net/_images/jsfiddle-logo-thumb.png>
</span>
</td><td>
<span id='spanDisplayOrigIcon'>OrigIcon:
<img src=http://doc.jsfiddle.net/_images/jsfiddle-logo-thumb.png width='16' height='16'>
</span>
</td></tr><tr><td>
<span id='spanDisplayNewFull'>NewFull: </span>
</td><td>
<span id='spanDisplayNewIcon'>NewIcon: </span>
</td></tr></table>
JAVASCRIPT:
$('#inputFile').bind('change', function()
{
var file = inputFile.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function()
{
var imageUrlFull = reader.result;
var imageLocalFull = new Image();
imageLocalFull.src = imageUrlFull;
imageLocalFull.id = 'imageLocalFull';
imageLocalFull.onload = function()
{
var canvas = document.createElement('canvas');
canvas.width = 16; canvas.height = 16;
var context = canvas.getContext('2d');
context.drawImage(imageLocalFull, 0, 0, 16, 16);
var imageUrlIcon = canvas.toDataURL(file.type);
var imageLocalIcon = new Image();
imageLocalIcon.src = imageUrlIcon;
imageLocalIcon.id = 'imageLocalIcon';
imageLocalIcon.onload = function()
{
spanDisplayNewFull.appendChild(imageLocalFull);
spanDisplayNewIcon.appendChild(imageLocalIcon);
};
};
};
});
You could use a php base like timthumb script to scale.
So the basic idea is using js detect when the browser or div or whatever change or resize. Then trigger the php script to resize the image.
script.setAttribute( 'src', 'remote.php?value=my message' );
remote.php
you have your php code.
Well, from your code it looks like the image scaling job is actually left to your browser's implementation, so I think you're going to have varying results with different browsers. Some might smooth it, some might not.
I see two ways to go about trying to tackle this problem. One way is to use active content, such as a Java applet/Flash or to use an actual back-end to do the scaling. I.e. you receive the file, send it to a server and the server returns the scaled-down image, as most image scaling sites do.
The second way is to try HTML5 and implement a down-scaling algorithm yourself. The best I can do there for guidance is point you to this and this as a starting point.
Sorry if that doesn't help.

best practice for creating a canvas element

I've been experimenting with creating a canvas element in a few different ways and was wondering if anyone knows which of these (or some other) ways is the most efficient.
the most basic seems to be placing a canvas element in the html like this:
<canvas id="myCanvas" width="500", height="500"></canvas>
and then in the javascript:
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
there are times I need to keep all my canvas biznass in a .js file (ex when I want to dynamically change the width/height of the element) and I'll do it like this:
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.height = '500';
canvas.width = '500';
var ctx = canvas.getContext('2d');
or when I get lazy, something like this:
document.write("<canvas id='myCanvas' width='500', height='500'></canvas>");
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
Pros? Cons? Edits? Other options?
The first one is the best by far.
The first one wins on efficiency (slightly) because the second and third ones cause the page to re-layout unnecessarily. Also, if there's an error in the JavaScript that halts subsequent execution the page will look awfully weird.
Furthermore, you should always choose the first one for accessibility purposes. If someone has JavaScript disabled you will still want them to see the fallback content. Even if it is just to say "turn on JavaScript!" or "Get a modern browser!"
If you use the second or third method, the user might never know, and they will continue on merely thinking that you suck at page layouts because there's a strange space where fallback content (or a canvas for that matter) ought to be.
Even aside from all that, methods 2 and 3 break the order of things a little bit. When are you adding the canvas? after onload fires? Well by firing onload the page just said that the DOM was done doing it's dance and its all ready! And then you go and change the DOM!
...How rude!
Of course you probably won't be using any libraries that rely on the the implicit promise made in onload that you are sorta breaking by using 2 or 3, but it's an unnecessary break of convention if you can avoid it.
By the way for the start of simple apps or examples I have this fiddle bookmarked:
http://jsfiddle.net/eAVMs/
Which uses the first method. If you use canvas a lot, you should bookmark this fiddle too!
document.write("<canvas id='myCanvas' width='500', height='500'></canvas>");
Is the only method Id caution against. Using document.write is generally considered bad practice for arbitrarily creating elements.
I could just repeat why here, but this answer explains it well enough.
The other two methods are perfectly valid and fine. Its really just a matter of preference. Generally I create a canvas tag, unless I need a temp canvas to do something, in which Ill use the createElement method.
Other than that its really just a matter of preference and overall doesn't affect performance in any way.

Categories