Javascript Font scaling code from body to div / element - javascript

I found some code which will scale some text when the browser window is resized and it seems to work well.
Here is the code:
document.body.setScaledFont = function (f) {
var s = this.offsetWidth,
fs = s * f;
this.style.fontSize = fs + '%';
return this
};
document.body.setScaledFont(0.35);
window.onresize = function () {
document.body.setScaledFont(0.35);
}
My question is:
How can I modify this code so the text scales when a specified div is scaled instead?
Updated code from suggested answer by #Deano. This code scales only when the browser is resized.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#window {
border:1px dashed #ccc;
overflow: hidden;
resize: both;
text-align: center;
}
</style>
</head>
<body>
<div id="window">Scale the window</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('#window').mouseup( function() {
document.getElementById('window').setScaledFont = function (f) {
var s = this.offsetWidth,
fs = s * f;
this.style.fontSize = fs + '%';
return this
};
document.getElementById('window').setScaledFont(0.35);
window.onresize = function () {
document.getElementById('window').setScaledFont(0.35);
}
});
});
</script>
</body>
</html>

document.body targets the entire body, if you want to target a specific element, use Id or class.
document.getElementById('window').setScaledFont = function (f) {
var s = this.offsetWidth,
fs = s * f;
this.style.fontSize = fs + '%';
return this
};
document.getElementById('window').setScaledFont(0.35);
window.onresize = function () {
document.getElementById('window').setScaledFont(0.35);
}
div {
font-size:2em;
}
<div id="window">Scale the window</div>
JSfiddle
Update Since the question requirement has changed :-/
You will need to use a libary like mimetic.js DEMO

Related

Ascii Art Animation in Browser

I want to animate Ascii Art in the Browser.
The Ascii Art should be loaded via a text file. There are many libraries which convert but I have found none, which actually animates it.
By animation I mean a typewriter animation that speeds up over time and changes the 'zoom factor' so that the whole image is visible in the viewport at the end.
Hopefully anyone knows a libary for my problem.
I have a feeling SO doesn't like library recommendations, and actually I haven't found one, so here's some basic code to get you started.
It sets the typing speed to the old Teletype 10 chars per second and of course that can be changed, and an acceleration function can be added when you know what you want for that. Note: the txt file needs to be on the same domain to prevent CORS problems.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Typewriter print</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Courier, monospace;
font-size: 12px;
}
</style>
</head>
<body>
<div id="container">
<input id="file" type="text" value="" placeholder="Filename" />
<button onclick="loadFile()">Click to draw the file</button>
<div id="picture"></div>
</div>
<script>
let file = '';
let reader = new XMLHttpRequest();
function loadFile() {
file = document.getElementById('file').value;
reader.open('get', file, true);
reader.onreadystatechange = draw;
reader.send(null);
}
function draw() {
if (reader.readyState == 4) {
const picture = document.getElementById('picture');
picture.innerHTML = '';
let str = reader.responseText;
let chs = str.split('');
//set as the typing speed in characters
//per second 10 is the old teletype speed
let chsPerSec = 10;
let i = 0;
function reveal() {
if (i < chs.length) {
let nextch = chs[i];
if (nextch.charCodeAt(0) == 10) {
nextch = '<br>';
} else if (nextch.charCodeAt(0) == 32) {
nextch = '<span style="color:transparent;">.</span>';
}
picture.innerHTML = picture.innerHTML + nextch;
setTimeout(reveal, Math.floor(1000 / chsPerSec));
i++;
}
}
reveal();
}
}
</script>
</body>
</html>

How to increase size of emoji using 'ArrowUp' in Javascript

I'm trying to continually increase the size of the balloon emoji 10px when a user pushes the up arrow as well as decrease size by 10px with down arrow on keypad.
I've been trying to set:
let size = para.style.fontSize;
in order to get a variable for the size and then adjust that value by adding +/- 10px in my function. However, I've tried this method and it seems as if you can not set:
para.style.fontSize = size +10;
Does anybody have any suggestions to get this to work?
Note: I have not included the size variable in the code below as I found it does not work.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
p {
font-size: 50px;
}
</style>
</head>
<body>
<p>🎈</p>
<script>
let para = document.querySelector('p');
window.addEventListener("keydown", e => {
if (e.key == "ArrowUp") {
para.style.fontSize = '60px';
} else {
para.style.fontSize = '40px';
}
});
</script>
</body>
</html>
To achieve growing/shrinking behavior over multiple keydown events, you'll need to increment/decrement para.style.fontSize per event. Once way this could be done is as follows:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
p {
font-size: 50px;
}
</style>
</head>
<body>
<p>🎈</p>
<script>
let para = document.querySelector('p');
window.addEventListener("keydown", e => {
let currentSize = parseInt(para.style.fontSize);
// If unable to determine current fontSize, default to 50
if (isNaN(currentSize)) {
currentSize = 50;
}
// Define the rate of change
let changeAmount = 5;
if (e.key == "ArrowUp") {
para.style.fontSize = (currentSize + changeAmount) + 'px';
} else {
// Protect againt zero or negative font sizes via Math.max()
para.style.fontSize = Math.max(changeAmount, currentSize - changeAmount) + 'px';
}
});
</script>
</body>
</html>
The issue is that the current fontSize property was null so you can't add to a null value. The second issue is that the fontSize property is actually a string with "px". So if you want to increase or decrease the value, you need to parse out the integer value. Then, when you assign it back to para.style.fontSize, you need to append "px" back.
Here is your code with the changes described above.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
p {
font-size: 50px;
}
</style>
</head>
<body>
<p>🎈</p>
<script>
let para = document.querySelector('p');
// Set to default size
para.style.fontSize = '24px';
window.addEventListener("keydown", e => {
var sizeAsInteger = parseInt(para.style.fontSize, 10);
if (e.key == "ArrowUp") {
sizeAsInteger += 10;
} else {
sizeAsInteger -= 10;
}
para.style.fontSize = sizeAsInteger + 'px';
});
</script>
</body>
</html>
Note that if you grab the size and then do console.log(size), you will get a blank result for the first round (because it's initially not set) and all subsequent rounds you get the size with px appended to the end. Thus, size + 10 with an initial size of 40px will give you 40px10. This results in undesired behavior.
To fix this, you need to remove the px, convert to a number, then append the px again:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
p {
font-size: 50px;
}
</style>
</head>
<body>
<p>🎈</p>
<script>
let para = document.querySelector('p');
window.addEventListener("keydown", e => {
let size = para.style.fontSize.replace('px', '');
size = size == '' ? '50' : size; // size may not be initialized, so default to our intended starting value!
size = parseInt(size);
if (e.key == "ArrowUp") {
para.style.fontSize = (size + 10) + 'px';
} else {
para.style.fontSize = (size - 10) + 'px';
}
});
</script>
</body>
</html>

Expanding the textarea height

I created this codes to make automatic expanding of textarea height when the text inside exceeded to height of the textarea but this only works in jsfiddle but when i run this in my project this doesnt work. does anyone can help me? Thanks.
$("#ta").keyup(function (e) {
autoheight(this);
});
function autoheight(a) {
if (!$(a).prop('scrollTop')) {
do {
var b = $(a).prop('scrollHeight');
var h = $(a).height();
$(a).height(h - 5);
}
while (b && (b != $(a).prop('scrollHeight')));
};
$(a).height($(a).prop('scrollHeight') + 20);
}
autoheight($("#ta"));
#ta {
width:250px;
min-height:116px;
max-height:300px;
resize:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="ta"></textarea>
If you are using jquery then you have to load Jquery library and add your code in the document ready or window load. Below is the updated code:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<style>
#ta {
width:250px;
min-height:116px;
max-height:300px;
resize:none;
}
</style>
<script>
$(document).ready(function(){
$("#ta").keyup(function (e) {
autoheight(this);
console.log("log");
});
});
function autoheight(a) {
if (!$(a).prop('scrollTop')) {
do {
var b = $(a).prop('scrollHeight');
var h = $(a).height();
$(a).height(h - 5);
}
while (b && (b != $(a).prop('scrollHeight')));
};
$(a).height($(a).prop('scrollHeight') + 20);
}
autoheight($("#ta"));
</script>
</head>
<body>
<textarea id="ta"></textarea>
</body>
</html>
It is working for me in IE 11 as well, try the below js fiddle link in IE -
https://jsfiddle.net/wp3wvuj2/3/
$(document).ready(function(){
$("#ta").keyup(function (e) {
autoheight(this);
console.log("log");
});
});
function autoheight(a) {
if (!$(a).prop('scrollTop')) {
do {
var b = $(a).prop('scrollHeight');
var h = $(a).height();
$(a).height(h - 5);
}
while (b && (b != $(a).prop('scrollHeight')));
};
$(a).height($(a).prop('scrollHeight') + 20);
}
autoheight($("#ta"));

Why IIFE can fix "cannot set property 'onclick' of null"

I have a block of code as the following
<body id="main">
<h1>Matching Game</h1>
<p>Click on the extra smile face on the left</p>
<div id="left_side"></div>
<div id="right_side"></div>
<script>
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
quan+=5;
dele();
generateFace();
}
</script>
</body>
This line theLeftSide.lastChild.onclickwill throw an error, saying that "cannot set property 'onclick' of null", because at the time javascript engine scans through it, it hasn't has any child yet. This problem can be solved by putting this code inside $(document).ready, I know.
However, I also tried IIFE, which means that wrapping all those code inside
(function(){
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
quan+=5;
dele();
generateFace();
}
})()
and also see that the problem is fixed, but cannot figure out why. Any one can explain me ?
Here's the full original code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>part4</title>
<style>
div{
position:absolute;
}
#left_side{
width:500px; height: 500px; border-right:#000 thin inset;
float: left;
}
#right_side{
width:500px; height: 500px;
float:left; left:500px;
}
img{
position: absolute;
}
body{
margin:0px;
}
</style>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.3.min.js"></script>
</head>
<body onload="generateFace()" id="main">
<h1>Matching Game</h1>
<p>Click on the extra smile face on the left</p>
<div id="left_side"></div>
<div id="right_side"></div>
<script>
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
var e = event;
var theBody= document.getElementById("main");
var post_left =0;
var post_top=0;
var quan = 4;
function generateFace(){
var i =0;
for(i=0; i<= quan; i++){
var img = document.createElement("img");
img.src="smile.png"; post_top=getRandom(); post_left=getRandom();
img.style.top = post_top + "px";
img.style.left = post_left +"px";
theRightSide.appendChild(img);
var clone = img.cloneNode(true);
theLeftSide.appendChild(clone);
}
//var clone = theRightSide.cloneNode(true);
//theLeftSide.appendChild(clone);
var extra = document.createElement("img");
extra.src="smile.png"; post_top=getRandom(); post_left=getRandom();
extra.style.top = post_top + "px";
extra.style.left = post_left +"px";
theLeftSide.appendChild(extra);
};
function getRandom(){
var i = Math.random() * 400 +1;
return Math.floor(i);
};
function dele(){
while(theLeftSide.firstChild != null){
theLeftSide.removeChild(theLeftSide.firstChild);
}
while(theRightSide.firstChild != null){
theRightSide.removeChild(theRightSide.firstChild);
}
};
theBody.onclick = function gameOver() {
alert("Game Over!");
dele();
theBody.onclick = null;
theLeftSide.lastChild.onclick = null;
};
function nextLevel(event){
event.stopPropagation();
quan+=5;
delse();
generateFace();
}
</script>
</body>
</html>
and with IIFE:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>part4</title>
<style>
div{
position:absolute;
}
#left_side{
width:500px; height: 500px; border-right:#000 thin inset;
float: left;
}
#right_side{
width:500px; height: 500px;
float:left; left:500px;
}
img{
position: absolute;
}
body{
margin:0px;
}
</style>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.3.min.js"></script>
</head>
<body id="main">
<h1>Matching Game</h1>
<p>Click on the extra smile face on the left</p>
<div id="left_side"></div>
<div id="right_side"></div>
<script>
(function(){
var theLeftSide = document.getElementById("left_side");
var theRightSide = document.getElementById("right_side");
var e = event;
var theBody= document.getElementById("main");
var post_left =0;
var post_top=0;
var quan = 4;
generateFace();
function generateFace(){
var i =0;
for(i=0; i<= quan; i++){
var img = document.createElement("img");
img.src="smile.png"; post_top=getRandom(); post_left=getRandom();
img.style.top = post_top + "px";
img.style.left = post_left +"px";
theRightSide.appendChild(img);
var clone = img.cloneNode(true);
theLeftSide.appendChild(clone);
}
//var clone = theRightSide.cloneNode(true);
//theLeftSide.appendChild(clone);
var extra = document.createElement("img");
extra.src="smile.png"; post_top=getRandom(); post_left=getRandom();
extra.style.top = post_top + "px";
extra.style.left = post_left +"px";
theLeftSide.appendChild(extra);
};
function getRandom(){
var i = Math.random() * 400 +1;
return Math.floor(i);
};
function dele(){
while(theLeftSide.firstChild != null){
theLeftSide.removeChild(theLeftSide.firstChild);
}
while(theRightSide.firstChild != null){
theRightSide.removeChild(theRightSide.firstChild);
}
};
theBody.onclick = function gameOver() {
alert("Game Over!");
dele();
//theBody.onclick = undefined;
//theLeftSide.lastChild.onclick = undefined;
};
theLeftSide.lastChild.onclick = function nextLevel(event){
event.stopPropagation();
quan+=5;
dele();
generateFace();
}
})();
</script>
</body>
</html>
In the original piece of code, generateFace() is called on page load. In the second piece of code, generateFace() is called directly. There is no relation with the IIFE. Please forget it! :-P Here is a simplified version of what you are doing in each case (open your browser console before running the snippets):
Original code (throws a TypeError)
console.log('attempting to initialize onclick');
document.getElementById('clickable').onclick = function () {
alert(this.id);
};
console.log('onclick initialized successfully');
function gendiv () {
console.log('gendiv was called');
document.body.innerHTML = '<div id="clickable">click me</div>';
}
<body onload="gendiv()"></body>
Modified code
gendiv();
console.log('trying to initialize onclick');
document.getElementById('clickable').onclick = function () {
alert(this.id);
};
console.log('onclick initialized successfully');
function gendiv () {
console.log('gendiv was called');
document.body.innerHTML = '<div id="clickable">click me</div>';
}
<body></body>

Progress bar not working in html file

I am creating a progrees bar is it working fine in jsfiddle demo but when i use in html file it is not working here is my code
i am writing same code as given in jsfiddle but it is not working
<html>
<head>
<style>
.ui-progressbar.beginning .ui-progressbar-value { background: red; }
.ui-progressbar.middle .ui-progressbar-value { background: yellow; }
.ui-progressbar.end .ui-progressbar-value { background: green; }
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<script>
var $progressbar = $("div").progressbar();
function updateProgressbar(current, target) {
var value = parseInt(current / target * 100);
$progressbar
.progressbar("value", value)
.removeClass("beginning middle end")
.addClass(value < 40 ? "beginning" : value < 80 ? "middle" : "end");
}
var total = 255;
var working = 0;
function update() {
working++;
updateProgressbar(working, total);
if (working < total) setTimeout(update, 10);
}
var $progressbar = $("div").progressbar();
function updateProgressbar(current, target) {
var value = parseInt(current / target * 100);
$progressbar
.progressbar("value", value)
.removeClass("beginning middle end")
.addClass(value < 40 ? "beginning" : value < 80 ? "middle" : "end");
}
var total = 255;
var working = 0;
function update() {
working++;
updateProgressbar(working, total);
if (working < total) setTimeout(update, 10);
}
</script>
</head>
<body onload="update()">
<div>
</div></body></html>
and here is js fiddle link working
http://jsfiddle.net/ZQrnC/305/
Look in the left sidebar of jsfiddle below "External Resources". You are embedding the jQuery UI css and js for your progressbar() there, but your html file jQuery UI is missing.
Add the following after your jquery-1.9.1.js-script-tag:
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css"/>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
There are three reasons why it does not work:
As robbi5 stated you don't import the jquery ui JS and CSS files
Your var $progressbar is initialized in the header when the page is not already loaded and so no div can be found. In other words $progressbar points on nothing
Your progress bar has an height of zero making it invisble, you should wrap him a container div with a fixed height
Also your code contains duplicate part but it may due to a wrong copy/paste.
Here is an updated working version of your page with the corrected points. I checked rapidly only on chrome and firefox and it works.
<html>
<head>
<style>
.ui-progressbar.beginning .ui-progressbar-value { background: red; }
.ui-progressbar.middle .ui-progressbar-value { background: yellow; }
.ui-progressbar.end .ui-progressbar-value { background: green; }
</style>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script src=" http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js" type="text/javascript"></script>
</head>
<script>
var $progressbar;
function updateProgressbar(current, target) {
var value = parseInt(current / target * 100);
$progressbar.progressbar("value", value).removeClass("beginning middle end")
.addClass(value < 40 ? "beginning" : value < 80 ? "middle" : "end");
}
var total = 255;
var working = 0;
function update() {
$progressbar = $("#pbholder").progressbar();
working++;
updateProgressbar(working, total);
if (working < total) setTimeout(update, 10);
}
</script>
</head>
<body onload="update()">
<div id="container" style="height:50px">
<div id="pbholder">
</div>
</div>
</body></html>

Categories

Resources