Issue
I want my users to be able to select a font from their computer and update the webpage so that it uses that font.
<style>
html * { font-family: Arial !important; }
</style>
I use html *
in css
and I want to change the font family to user's file.
<script>
function change_css() {
// ???
}
</script>
<div>
<div</div>
<input type="file" name="upload" id="upload"/>
<input type="submit" value="submit" onclick="change_css();">
</div>
How to implement this?
Solution
Changing the Webpage Font
In JavaScript, if you have a DOM element and want to change its font, you can do that by manipulating its CSSStyleDeclaration
object. Specifically, by setting element.style.fontFamily
.
For example,
document.body.style.fontFamily = 'Noto Sans, Arial, sans-serif';
This demo creates an HTML select element with a couple of font options. By default, the body's font is 'Arial', but the select element has an event handler attached so that when it is changed, the body's font is changed to match the newly selected option.
If you want to add more fonts to the list, simply add additional options to the select element, and set the value
attribute to the font's name.
var fontSelector = document.getElementById('font-selector');
fontSelector.addEventListener('change', (event) => {
document.body.style.fontFamily = event.target.value;
});
body { font-family: 'Arial'; }
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<label for="font-selector">Select Font</label>
<select id="font-selector">
<option value="Arial">Arial</option>
<option value="Times">Times</option>
<option value="Courier">Courier</option>
</select>
Getting Fonts from the User
tl;dr: You can use any fonts that the user has installed, without them needing to upload them. But you can't know which fonts the user has installed, for privacy reasons.
When you specify the name of a font in CSS, the browser will use that font if it is present on the user's computer (or if it is provided as a webfont), otherwise the browser will revert to its default. There's no need to actually upload the font from the user's computer onto your server.
To rephrase: when the browser is doing font rendering, it gets the fonts from the user's computer, not from your server. There is no point in uploading a font from the user's computer to your server. When you use webfonts, you are sending a font from your server to the user's computer (it gets stored in a temporary location) and then the browser uses it. Note also that webfonts are typically not the same file format as fonts that the user has installed on their computer.
The caveat is, of course, that you don't know what fonts the user has on their computer (so you don't know which fonts to list in the select element for the example above). Most websites don't try to know, they simply use a "web-safe" font (i.e. font that is installed on most operating systems by default) or explicitly provide a webfont (often via services like Google Fonts).
JavaScript does not provide an API for knowing which fonts are installed on a user's computer. This is on purpose, because such information could be used to trivially 'fingerprint' visitors to a website. In general, allowing websites to know too much about the specifics of how a user's computer is set up would be considered a privacy concern.
There do exist libraries and scripts (this one, for example) that allow you to query whether a particular font is installed on the user's computer (not a list of all fonts installed, just a query "is font [x] installed?"). These work by making a few guesses and will not always be correct. There is also a way to get the full list of installed fonts using Adobe Flash (notice that domain is browserspy.dk, because this technique is used for fingerprinting as I discussed earlier), but most users do not have Flash installed these days.
The standard approach would be to offer any fonts you desire as webfonts, served to the user over the network.
A Hacky Solution
With all that said, here's something you can do, with a bit of elbow grease:
You can let a user choose a font file (no need to upload it to the server) and then use this javascript library to extract the font name from that file, then set the webpage's font to that name.
Now, if they just have a random font file sitting on their desktop or downloads folder or something, this won't work. The file the user provides must be a font that they actually have installed on their system.
var fontSelector = document.getElementById('font-selector');
fontSelector.addEventListener('change', (event) => {
const fontFile = event.target.files[0];
const fontReader = new FileReader();
fontReader.onload = (e) => {
try {
const fontMeta = FontName.parse(e.target.result)[0];
document.body.style.fontFamily = fontMeta.fontFamily;
}
catch(err) {
// failed
}
};
fontReader.readAsArrayBuffer(fontFile);
});
body { font-family: 'Arial'; }
<script src="https://danbovey.uk/fontname/index.js"></script>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<label for="font-selector">Select Font</label>
<input type="file" id="font-selector" accept=".ttf,application/x-font-ttf">
A More Robust Solution
Web-based photo editing software accomplishes this sort of technique by taking over the font rendering entirely. Rather than letting the browser render text using the system fonts, they use javascript libraries that can parse font files and then create SVG definitions for each glyph. Then they manage the placement of each SVG on the webpage, including kerning, line-spacing, ligatures, etc. These javascript libraries are very large and complex, and will require you to do a lot more integration work to get it going.
To explore this option, you should start by taking a look at libraries such as Typr.js or opentype.js.
Answered By - Woodrow Barlow
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.