Font Awesome has a very good collection of icons to be used in web projects. I want to use one of those icons as cursor (custom cursor).
In my understanding, Custom Cursors need an image url, but I am unable to find the image urls for Font Awesome icons.
Got it!
Create a canvas
Draw the fa icon on it
Change it into a base-64 image url
Apply the image on the cursor css style
And I made a demo: http://jsfiddle.net/rqq8B/2/
// http://stackoverflow.com/questions/13761472/how-to-render-glyphs-from-fontawesome-on-a-canvas-element
// http://stackoverflow.com/questions/13932291/css-cursor-using-data-uri
$(function() {
var canvas = document.createElement("canvas");
canvas.width = 24;
canvas.height = 24;
//document.body.appendChild(canvas);
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#000000";
ctx.font = "24px FontAwesome";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("\uf002", 12, 12);
var dataURL = canvas.toDataURL('image/png')
$('body').css('cursor', 'url('+dataURL+'), auto');
});
body {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
In the end, I couldn't get #fish_ball's code working reliably, so I just downloaded the images, used gimp to crop and edit them to 32×32px, and used them like this:
.myClass { cursor: url('/static/img/pencil30_32x32.png') 1 30, crosshair }
The 1 30 part sets the mouse pointer 'hotspot' 1px from the left and 30px from the top of the image.
There is jQuery Awesome Cursor, where you can add font-awesome icons to your cursor by calling only one simple code:
$('body').awesomeCursor('pencil');
Or passing it some options:
$('body').awesomeCursor('pencil', {
/* your options here */
size: 22,
color: 'orange',
flip: 'horizontal'
});
Disclaimer: I am NOT the author of this library I have just found it.
The canvas method mentioned results in blurry cursors.
Using SVG offers better results:
Download the SVG for the icon you want to use from Encharm's Font-Awesome-SVG-PNG.
Edit the SVG using a text editor and specify the width and height you'd like to use
e.g.: 24 x 24.
Keep in mind there's usually a maximum size in the browser (128 x 128 in Firefox.)
Declare the cursor in CSS, e.g.: cursor: url( '/assets/img/volume-up.svg' ), pointer;
For anyone using Vue.js, there is an easier approach:
Importing font awesome icon as a component:
import { library } from '#fortawesome/fontawesome-svg-core';
import { fas } from '#fortawesome/free-solid-svg-icons';
import { fab } from '#fortawesome/free-brands-svg-icons';
import { far } from '#fortawesome/free-regular-svg-icons';
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome';
library.add(fas);
library.add(fab);
library.add(far);
Vue.component('fa-icon', FontAwesomeIcon);
and using it directly in the HTML of a page:
<fa-icon icon="copy" #click="yourFunction"/>
and surrounding your tag with <span>:
<span class="hover"><fa-icon icon="copy" #click="yourFunction"/></span>
and adding to your css:
span.hover {
cursor: pointer;
}
This will add a pointer on all <span> tags with class hover in your code (and thus your font awesome icons !)
Related
I need to render an image on which I have put some HTML text on it and then the user to be able to download the image with the text as an image or even better as a pdf.
The certText element is taken from a TinyMCE variable, where the user each time uses different HTML tags within the text.
So it could be
"Hello user, how are you"
or
"Hi there, great that you succeed on the certification".
Starting from the image option I have created below code but Canvas do no translate the HTML tags.
I have read that with Canvas it's not possible to render the HTML tags, but is there any other alternative to succeed this.
The code is used on a Laravel project that I have made.
var p = document.getElementById("certificate");
var ptx = p.getContext("2d");
var imgp = document.getElementById("certificateEmpty");
var txtp = document.getElementById("certText").innerHTML;
imgp.onload = function(){
ptx.drawImage(imgp, 0, 0);
ptx.font = "48px Nunito";
ptx.fillText(txtp, 150, 1000);
};
imgp.src = "{{$attendees[0]->certBLocation}}";
What are you trying to achive when you say "render html tags"?
Do you mean you want to style the text that is drawn on the canvas?
If so, you have to use canvas functions to set what the text will look like.
In the below example using your code, I use "fillStyle" to set the drawing fill colour in which the text will be drawn.
var p = document.getElementById("certificate");
var ptx = p.getContext("2d");
var imgp = document.getElementById("certificateEmpty");
var txt = document.getElementById("certText");
var txtp = txt.innerHTML;
imgp.onload = function(){
ptx.drawImage(imgp, 0, 0, p.width, p.height);
var styles = window.getComputedStyle(txt);
ptx.fillStyle = styles.color;
//ptx.font = styles.font; // Doesn't seem to work in firefox.
ptx.font = styles['font-weight']+" "+styles['font-size']+" "+styles.fontFamily; // Access properties array style because of hyphens.
ptx.fillText(txtp, 0, 100);
};
imgp.src = "https://www.gravatar.com/avatar/7b67c827ee1671ba3b43f4aebf6794fb?s=200";
img, canvas {
width: 200px;
height: 200px;
}
#certText {
color: #ff0000;
font-weight: bold;
font-size: 40px;
}
<img id="certificateEmpty"/>
<canvas id="certificate"></canvas>
<div id="certText">
some text
</div>
Text drawn on the canvas looks squashed on my screen (Ubuntu/Chrome), not sure why.
Canvas.filltext won't render custom font (though body text will, and canvas.filltext will render local fonts)
I want to paint some text on a canvas, using a custom font called jelleebold. Here's an abbreviated version of the function that I hoped would do that:
function paintLinkNameOnCanvas(linkName, canvas){
let context = canvas.getContext('2d');
context.font = "25px jelleebold";
context.fillText(linkName, 50, 50);
return canvas;
}
However, the font that gets used is whatever the browser (Chrome) uses as its fallback (Times New Roman, I think). Here's the html link
<link href="./CSS/stylesheet.css" rel="stylesheet" type="text/css">
and the css, downloaded from fontsquirrel, and modified to suit my local directory structure:
#font-face {
font-family: jelleebold;
src: url('/fonts/jellee-roman-webfont.woff2') format('woff2'),
url('/fonts/jellee-roman-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
I believe that this has worked, and Jelleebold has loaded successfully, because index.php contains:
<body style ="font-size: 50px; font-family: 'jelleebold'">
<div id= "output" >
test
</div>
etc.
and the word 'test' gets printed in jelleebold.
In contrast, if the paintLinkNameOnCanvas function specifies a font that is installed on the local machine (such as context.font = "25px 'Balford Base'"), the linkname does get painted in that font.
So why isn't the custom font being used to paint the linkname on the canvas?
And after a very helpful suggestion from Renato Bibiano, I've now produced an updated version of the function (shown below). The commented lines are a hint about the next problem; how do I get it to work with both woff- and woff2-formatted fonts? It works with either one, but not the other.
function paintLinkNameOnCanvas(linkName, canvas){
let earl = "";
// earl += "url('/fonts/jellee-roman-webfont.woff' ) format('woff' ";
// earl += ", ";
earl += "url('/fonts/jellee-roman-webfont.woff2')format('woff2')";
let f = new FontFace("jelleebold", earl);
f.load().then(function() {
let context = canvas.getContext('2d');
context.font = '23px jelleebold';
context.fillText('Hey, world', 0, 100);
});
return canvas;
}
I feel that taking the comment slashes out should produce something sensible, but if both specifications (woff and woff2) are included, the ouput reverts to the default font, TNR.
I have an image gallery on the home page which is using this plugin:
http://codecanyon.net/item/jquery-slider-zoom-inout-effect-fully-responsive/2457203
My client wants to have a lighter logo for darker images and a darker logo for lighter images. I'm pretty comfortable with jQuery, but have never had to do something like this.
This is the effect they're looking for:
http://www.aplusi.com/
I know on this site, they're adding a class (dark-slide) to the body and then using a more specific class:
.dark-slide #logo {
color: #fff;
}
to get the logo to change from black to white. My only problem is I don't know how they're doing it since it also works with their swipe functionality as well. I've dug into their JS but can't seem to find the code.
I have a few ideas like having a click handler on the arrows to check what image is presented and then add the necessary class. The only problem with this is that the gallery has a swipe functionality and jQuery doesn't have an event handler for touch events.
My other thought was to have an interval timer and then add the class onto the necessary image at the right time - this is something I haven't done and wouldn't know where to start.
I'm thinking this should be fairly easy, but I can't seem to come up with a decent solution so I thought I would ask.
Any help would be greatly appreciated.
Their JavaScript is obfuscated unfortunately, but the code you are looking for is this (which funnily enough seems to be missing a semicolon):
var u = e.Color.getBrightness(o.getAttribute("data-top-right-color"));
e.one(document.body).toggleClass("dark-slide", u < 35)
"data-top-right-color" is an attribute set individually on each slide. Every time the slide changes, the function containing the above code fires and checks that data- attribute to see if it should add the "dark-slide" class to make the logo font white.
There must be a container for the image which is active. To change the logo as per the image prsent in the slider, you have 2 options:
Maintain some attribute in the img tag so that you can diffrentiate as per the value of the attribute. Eg. <img src='image.png' data-value='dark'>
If you are unable to maintain the attribute then a complex solution will be to write an algo to determine the type of active image Using canvas
To change the logo:
var logoImg=$('#logo');
if(activeImgType=='dark')
{
logoImg.attr('light.png');
}else{
logoImg.attr('dark.png');
}
You can use the following code to get it done. It uses a canvas for processing the image. The concept is based on detecting whether the image is dark or light using a grayscale version of the original image.
Here's is a working version based on background color of a div.
If you want to use images as background, please refer my code here. I have uploaded a sample with the background images. I couldn't produce a fiddle or online demo because of cross origin problems.
The code for simple rgb backgrounds is below:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Dynamic text color demo using canvas</title>
</head>
<body>
<label><b>Image with text</b></label>
<div id="content" style="box-shadow:0px 0px 1px #000;width:200px;height:100px;background-color:#333;">
<b style="z-index:2;position:absolute;color:black !important;">BLACK Text</b>
<br><b style="z-index:2;position:absolute;color:white !important;">WHITE Text</b>
<br><b style="z-index:2;position:absolute;color:rgb(127,127,127) !important;">GRAY Text</b>
<br><b style="z-index:2;position:absolute">CORRECTED COLOR</b>
</div><br><br>
<label><b>Variables</b></label>
<div id="height">
</div>
<div id="width">
</div>
<div id="dataLength">
</div>
<div id="blackCount">
</div>
<br>
<label><b>Canvas for grayscale</b></label><br>
<canvas id="myCanvas" width="200px" height="100px" style="box-shadow:0px 0px 1px #000"></canvas>
<script>
/* ~~~~~ This function loops over various images ~~~~~ */
var c=0;
var color;
function loop(){
c++;
document.getElementById('content').style.backgroundColor='rgb('+(c*29)%255+','+(c*29)%255+','+(c*29)%255+')';
var imageObj = new Image();
imageObj.onload = function() {
drawImage(color);
}
color=document.getElementById('content').style.backgroundColor;
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
var x = 0;
var y = 0;
context.rect(0,0,canvas.width, canvas.height);
context.fillStyle='rgb('+(c*29)%255+','+(c*29)%255+','+(c*29)%255+')';
context.fill();
/* ~~~~~ Print height and widht of image ~~~~~ */
document.getElementById('height').innerHTML="height: "+imageObj.height;
document.getElementById('width').innerHTML="width: "+imageObj.width;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
var imageData = context.getImageData(x, y, canvas.width, canvas.height);
var data = imageData.data;
/* ~~~~~ This part converts the image to grayscale ~~~~~ */
for(var i = 0; i < data.length; i += 4) {
var brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
// red
data[i] = brightness;
// green
data[i + 1] = brightness;
// blue
data[i + 2] = brightness;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* ~~~~~ This part counts the number of dark pixels ~~~~~ */
var count=0;
for(var j=0;j<data.length;j+=4){
if(data[j]<200 && data[j+1]<200 && data[j+2]<200){
count+=4;
}
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* ~~~~~ If the number of dark pixels are 80% of total pixels, then assume image to be dark ~~~~~ */
if(count>=(data.length*0.8)){
document.getElementById('content').style.color="white";
}else{
document.getElementById('content').style.color="black";
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* ~~~~~ Print total pixel and counted dark pixels ~~~~~ */
document.getElementById('dataLength').innerHTML ="Data length"+data.length+" Data length/2 "+(data.length/2);
document.getElementById('blackCount').innerHTML ="Black Count"+count;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
// Draw grayscale image on cavas
context.putImageData(imageData, x, y);
}
setInterval(loop,2000);
</script>
</body>
</html>
I'm working on my first HTML5 Canvas game. I am trying to put in a background image, and I don't know how to do it. The game will change backgrounds throughout levels, but I think I understand how to make that happen. However, if I just try to draw an image, then it appears above my title text. Any ideas how to fix this? I don't think the CSS method will work, because the background will change. Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>How Well Do You Know Your Swedish?</title>
</head>
<body>
<canvas width="640" height="480" id="game" style="display: block; margin-left: auto; margin-right: auto; border: 1px solid black;" Your Browser is not compatible with this game. We recommend Google Chrome, Mozilla Firefox, or Opera.></canvas>
<script>
var game_canvas = document.getElementById("game");
var game_context = game_canvas.getContext("2d");
var swedishflagbg = new Image();
swedishflagbg.src = "resources/images/swedishflagbg.png";
swedishflagbg.onload = function() {
game_context.drawImage(swedishflagbg, 0, 0);
}
game_context.fillStyle = "#000000";
game_context.font = "35px Ubuntu";
game_context.textAlign = "center";
game_context.textBaseline = "top";
game_context.fillText("How Well Do You Know Your Swedish?", 320, 0);
</script>
</body>
</html>
I am new to JavaScript, and even newer to the HTML5 Canvas.
Extending from comment:
The "why":
Because the background image is drawn in an onload event, which will happen "later", while text is drawn immediately.
So the text is drawn first, and then sometimes later the image is drawn, thus causing the text to be covered.
The "how":
Depending on how "dynamic" the background image is, you can consider:
use CSS background-image on cancas/canvas container, and use className/classList to switch between different backgrounds;
put an <img> tag underneath the canvas, and change its src property;
use an additional "background" canvas underneath the current one, so you can draw the game content in current one, and draw the (probably not frequently-updated) background in the new one.
Credit of idea 1 and 2 goes to #markE :)
First things:
Check the size of your image. It should be equivalent to the size of the canvas.
context.drawImage can also take width and height parameter for the image.
Syntax: context.drawImage(img, x, y, width, height);
After editing, it should look like this
let game_canvas = document.getElementById("game");
let game_context = game_canvas.getContext("2d");
let swedishflagbg = new Image();
swedishflagbg.src = "resources/images/swedishflagbg.png";
swedishflagbg.onload = function() {
game_context.drawImage(swedishflagbg, 0, 0, game_canvas.width, game_canvas.height);
}
game_context.fillStyle="#000000";
game_context.font="35px Ubuntu";
game_context.textAlign="center";
game_context.textBaseline="top";
game_context.fillText("How Well Do You Know Your Swedish?", 320, 0);
To anyone who is still facing the problem of background image overlaying text (Image above text), I thought "why not drawing text inside onload function after loading bg image!?"
And it worked!! The browser (Or whatever) loads image first and load my text above image.
<canvas width="534" height="104" id="game" style="display: block; margin-left: auto; margin-right: auto; border: 1px solid black;" Your Browser is not compatible with this game. We recommend Google Chrome, Mozilla Firefox, or Opera.></canvas>
<script>
let game_canvas = document.getElementById("game");
let game_context = game_canvas.getContext("2d");
let swedishflagbg = new Image();
swedishflagbg.src = "./img/logo1.png";
swedishflagbg.onload = function() {
game_context.drawImage(swedishflagbg, 0, 0, game_canvas.width, game_canvas.height);
game_context.fillStyle = "#000000";
game_context.font = "35px Ubuntu";
game_context.textAlign = "center";
game_context.textBaseline = "top";
game_context.fillText("How Well Do You Know Your Swedish?", 320, 0);
}
</script>
I'm using Font-Awesome, but while the font files are not loaded, the icons appear with .
So, I want these icons to have display:none while files are not loaded.
#font-face {
font-family: "FontAwesome";
src: url('../font/fontawesome-webfont.eot');
src: url('../font/fontawesome-webfont.eot?#iefix') format('eot'), url('../font/fontawesome-webfont.woff') format('woff'), url('../font/fontawesome-webfont.ttf') format('truetype'), url('../font/fontawesome-webfont.svg#FontAwesome') format('svg');
font-weight: normal;
font-style: normal;
}
How do I know that these files have been loaded and I'm finally able to show the icons?
Edit:
I'm not talking when the page is loaded (onload), because the font could be loaded before the whole page.
Now on GitHub: https://github.com/patrickmarabeas/jQuery-FontSpy.js
Essentially the method works by comparing the width of a string in two different fonts. We are using Comic Sans as the font to test against, because it is the most different of the web safe fonts and hopefully different enough to any custom font you will be using. Additionally we are using a very large font-size so even small differences will be apparent. When the width of the Comic Sans string has been calculated, the font-family is changed to your custom font, with a fallback to Comic Sans. When checked, if the string element width is the same, the fallback font of Comic Sans is still in use. If not, your font should be operational.
I rewrote the method of font load detection into a jQuery plugin designed to give the developer the ability to style elements based upon whether the font has been loaded or not. A fail safe timer has been added so the user isn’t left without content if the custom font fails to load. That’s just bad usability.
I have also added greater control over what happens during font loading and on fail with the inclusion of classes addition and removal. You can now do whatever you like to the font. I would only recommend modifying the fonts size, line spacing, etc to get your fall back font as close to the custom as possible so your layout stays intact, and users get an expected experience.
Here's a demo: http://patrickmarabeas.github.io/jQuery-FontSpy.js
Throw the following into a .js file and reference it.
(function($) {
$.fontSpy = function( element, conf ) {
var $element = $(element);
var defaults = {
font: $element.css("font-family"),
onLoad: '',
onFail: '',
testFont: 'Comic Sans MS',
testString: 'QW#HhsXJ',
delay: 50,
timeOut: 2500
};
var config = $.extend( defaults, conf );
var tester = document.createElement('span');
tester.style.position = 'absolute';
tester.style.top = '-9999px';
tester.style.left = '-9999px';
tester.style.visibility = 'hidden';
tester.style.fontFamily = config.testFont;
tester.style.fontSize = '250px';
tester.innerHTML = config.testString;
document.body.appendChild(tester);
var fallbackFontWidth = tester.offsetWidth;
tester.style.fontFamily = config.font + ',' + config.testFont;
function checkFont() {
var loadedFontWidth = tester.offsetWidth;
if (fallbackFontWidth === loadedFontWidth){
if(config.timeOut < 0) {
$element.removeClass(config.onLoad);
$element.addClass(config.onFail);
console.log('failure');
}
else {
$element.addClass(config.onLoad);
setTimeout(checkFont, config.delay);
config.timeOut = config.timeOut - config.delay;
}
}
else {
$element.removeClass(config.onLoad);
}
}
checkFont();
};
$.fn.fontSpy = function(config) {
return this.each(function() {
if (undefined == $(this).data('fontSpy')) {
var plugin = new $.fontSpy(this, config);
$(this).data('fontSpy', plugin);
}
});
};
})(jQuery);
Apply it to your project
.bannerTextChecked {
font-family: "Lobster";
/* don't specify fallback font here, do this in onFail class */
}
$(document).ready(function() {
$('.bannerTextChecked').fontSpy({
onLoad: 'hideMe',
onFail: 'fontFail anotherClass'
});
});
Remove that FOUC!
.hideMe {
visibility: hidden !important;
}
.fontFail {
visibility: visible !important;
/* fall back font */
/* necessary styling so fallback font doesn't break your layout */
}
EDIT: FontAwesome compatibility removed as it didn't work properly and ran into issues with different versions. A hacky fix can be found here: https://github.com/patrickmarabeas/jQuery-FontFaceSpy.js/issues/1
Try WebFont Loader (github repo), developed by Google and Typekit.
This example first displays the text in the default serif font; then after the fonts have loaded it displays the text in the specified font. (This code reproduces Firefox's default behavior in all other modern browsers.)
Actually, there is a good way to understand all fonts begin to download or loaded completely or not and fall into some errors, but it is not just for a specific font, pay attention to the following code:
document.fonts.onloading = () => {
// do someting when fonts begin to download
};
document.fonts.onloadingdone = () => {
// do someting when fonts are loaded completely
};
document.fonts.onloading = () => {
// do someting when fonts fall into some error
};
And also there is an option that returns Promise and it could handle with .then function:
document.fonts.ready
.then(() => console.log('do someting at the final with each status'))
Here is a different approach to the solutions from others.
I'm using FontAwesome 4.1.0 to build WebGL textures. That gave me the idea to use a tiny canvas to render a fa-square to, then check a pixel in that canvas to test whether it has loaded:
function waitForFontAwesome( callback ) {
var retries = 5;
var checkReady = function() {
var canvas, context;
retries -= 1;
canvas = document.createElement('canvas');
canvas.width = 20;
canvas.height = 20;
context = canvas.getContext('2d');
context.fillStyle = 'rgba(0,0,0,1.0)';
context.fillRect( 0, 0, 20, 20 );
context.font = '16pt FontAwesome';
context.textAlign = 'center';
context.fillStyle = 'rgba(255,255,255,1.0)';
context.fillText( '\uf0c8', 10, 18 );
var data = context.getImageData( 2, 10, 1, 1 ).data;
if ( data[0] !== 255 && data[1] !== 255 && data[2] !== 255 ) {
console.log( "FontAwesome is not yet available, retrying ..." );
if ( retries > 0 ) {
setTimeout( checkReady, 200 );
}
} else {
console.log( "FontAwesome is loaded" );
if ( typeof callback === 'function' ) {
callback();
}
}
}
checkReady();
};
As it uses a canvas it requires a fairly modern browser, but it might work on IE8 as well with the polyfill.
Here's another way of knowing if a #font-face has already been loaded without having to use timers at all: utilize a "scroll" event to receive an instantaneous event when the size of a carefully crafted element is changed.
I wrote a blog post about how it's done and have published the library on Github.
Try something like
$(window).bind("load", function() {
$('#text').addClass('shown');
});
and then do
#text {visibility: hidden;}
#text.shown {visibility: visible;}
The load event should fire after the fonts are loaded.
alternatively, you could add font-display: block to your #font-face declaration.
this instructs browsers to render the fallback font as invisible until your font is loaded, no need for display: none or any javascript load font detection
Solution for Typescript, Angular.
If you are working with Angular, you can use this module in order to do a font check.
// document.fonts.check extension
import type {} from 'css-font-loading-module';
ngOnInit() {
this.onFontLoad();
}
public onFontLoad() {
let myTimer = setInterval(() => {
if (document.fonts.check('14px MyFont')) {
console.log('Font is loaded!');
clearInterval(myTimer);
} else {
console.log('Font is loading');
}
}, 1);
}
Also, some fonts are extremely heavy. Therefore, you can add a loading screen while the font is loading and remove the loading screen when the font is loaded. I believe this is a better approach rather than changing your CSS class to display: none, merely because it might take 3-4+ seconds to download some fonts if the user has slow internet.
This is an alternate approach that will at least ensure that font-awesome is loaded, NOT a complete solution to the OP. Original code found in the wordpress forums here https://wordpress.stackexchange.com/a/165358/40636.
It's agnostic and will work with any font style resource like font-awesome where a font-family can be checked. With a little more thought I bet this could be applied to much more...
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script>
(function($){
var faSpan = $('<span class="fa" style="display:none"></span>').appendTo('body');
if (faSpan .css('fontFamily') !== 'FontAwesome' ) {
// Fallback Link
$('head').append('<link href="/css/font-awesome.min.css" rel="stylesheet">');
}
faSpan.remove();
})(jQuery);
</script>
Use the below code:
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<canvas id="canvasFont" width="40px" height="40px" style="position: absolute; display: none;"></canvas>
<script>
function IsLoadedFonts()
{
var Args = arguments;
var obj = document.getElementById('canvasFont');
var ctx = obj.getContext("2d");
var baseFont = (/chrome/i.test(navigator.userAgent))?'tims new roman':'arial';
//................
function getImg(fon)
{
ctx.clearRect(0, 0, (obj).width, (obj).height);
ctx.fillStyle = 'rgba(0,0,0,1.0)';
ctx.fillRect( 0, 0, 40, 40 );
ctx.font = '20px '+ fon;
ctx.textBaseline = "top";
ctx.fillStyle = 'rgba(255,255,255,1.0)';
ctx.fillText( '\u0630', 18, 5 );
return ctx.getImageData( 0, 0, 40, 40 );
};
//..............
for(var i1=0; i1<Args.length; i1++)
{
data1 = getImg(Args[i1]);
data2 = getImg(baseFont);
var isLoaded = false;
//...........
for (var i=0; i<data1.data.length; i++)
{
if(data1.data[i] != data2.data[i])
{isLoaded = true; break;}
}
//..........
if(!isLoaded)
return false;
}
return true;
};
setTimeout(function(){alert(IsLoadedFonts('myfont'));},100);
</script>
</body>
Can check many fonts:
setTimeout(function(){alert(IsLoadedFonts('font1','font2','font3'));},100);
The below code works in opera only but is easy:
if(!document.defaultView.getComputedStyle(document.getElementById('mydiv'))['fontFamily'].match(/myfont/i))
alert("font do not loaded ");