How does the ProcessingJS link work without an internet connection? - javascript

This isn't a problem, just asking out of curiosity:
How do HTML/JS projects which include the ProcessingJS library work even when offline, given that the library link is the standard https kind and not a link to a file on the disk?
I tested this by turning WiFi off, then opening the project file in Safari (which worked), and trying to load a different webpage (which didn't, as expected). I know that the library is also available as downloadable file, but this project isn't using that, only the link:
<!DOCTYPE html>
<html>
<head>
<title>Example Program</title>
<style>
body {
background-color: purple;
}
#canvasDiv {
margin-left: 20%;
margin-right: 20%;
text-align: center;
}
</style>
</head>
<body>
<div id="canvasDiv">
<canvas id="_canvas"></canvas>
</div>
</body>
<script src="https://cdn.jsdelivr.net/processing.js/1.4.8/processing.min.js"></script>
<script>
var canvasWidth = 200;
var canvasHeight = 200;
var drawSmiley = function(p, x, y, d) {
p.background(255);
p.strokeWeight(3);
p.stroke(0);
p.fill(250, 200, 0);
p.ellipse(x, y, d, d);
p.strokeWeight(8);
p.point(x - 0.2*d, y - 0.1*d);
p.point(x + 0.2*d, y - 0.1*d);
p.strokeWeight(5);
p.arc(x, y + 0.05*d, 0.6*d, 0.4*d, 0.5, 2.64);
p.textSize(24);
p.fill(0, 200, 0);
p.noStroke();
p.textAlign(p.CENTER, p.CENTER);
p.text("Hello", 100, 20);
p.text("World", 100, 180);
};
var applyProcessing = function(p) {
p.setup = function() {
p.size(canvasWidth, canvasHeight);
drawSmiley(p, 100, 100, 100);
};
};
var canvas = document.getElementById("_canvas");
var pInstance = new Processing(canvas, applyProcessing);
</script>
</html>
Does running the script for the first time automatically download and store a copy of the library somewhere, or is ProcessingJS functionality built into the browser too, like regular JavaScript?

Look at the requests that your browser makes, and you can see that the script response gets cached. The red line below is when I disconnected the internet and loaded the page again.
jsdelivr sets the following header on scripts it serves:
cache-control: public, max-age=31536000, s-maxage=31536000, immutable
And:
The max-age=N response directive indicates that the response remains fresh until N seconds after the response is generated.)
Indicates that caches can store this response and reuse it for subsequent requests while it's fresh.
So the script is permitted to stay in storage and not be re-fetched for 31536000 seconds. See here for a description of "freshness".
jsdelivr does this for all of its scripts, not just Processing.js. jsdelivr could well have set different headers and told browsers that it should re-download the script every time - but that would both require more of their server resources and would have broken your example page while no internet connection is available.

Related

Wrong value for window.innerWidth during onload event in Firefox for Android?

Okay, so, the problem I am facing is this: my mobile Firefox browser is not retrieving the correct values for window.innerWidth, document.documentElement.clientWidth, or even the width of a div styled to take up the whole client window after page load.
I am not crazy, my code works just fine in every other browser! For some reason Firefox initializes these values with defaults and then gets the correct values later on. If at any point I interrupt my JavaScript with an alert(), these properties magically become accurate afterwards.
I have scoured the internet for an answer and all I can find is a hack workaround: use window.setTimeout to delay the use of these properties until they have time to populate correctly. That is crazy! Users want speed, not an extra delay just to view my site on a Firefox browser.
What I don't understand is that I can set a div up to fill the client window perfectly before the values become accurate. I do this in css by setting width and height of my div's id to 100%. document.documentElement is basically the same as document.getElementById("my_div"); after all the document elements have loaded, so, how does the browser know how big the div should be when it doesn't have the correct dimensions of the client window in the first place?
I have tried running my code inside a window.addEventListener("load",function(event_){ //My Code }); but still these values will not generate. Is there a page load event that comes after window.onload?
If anyone can tell me why only Firefox mobile seems to display this odd behavior I will give you a mental high five.
Here's a bit of sample code for recreating the problem:
<!DOCTYPE HTML>
<html>
<head>
<!-- Added " after javascript during edit. -->
<script type="text/javascript">
window.addEventListener("load",function(event_){
var output=document.getElementById("output");
/* Returns some default value like 980. */
output.innerHTML=window.innerWidth;
alert("After this alert, the value will change.");
/* Returns an accurate value like 511. */
output.innerHTML=window.innerWidth;
});
</script>
<!-- Added title during edit. -->
<title>Title</title>
</head>
<body>
<p id="output">Default Output</p>
</body>
</html>
My Firefox for android version is 35.0.1. My Android version is 4.4.4. On my device, Firefox displays "980" in the output p element, shows the alert, and then displays "980" again. After page refresh, the first two steps remain the same, but the output after the alert changes to 360. This happens with document.documentElement.clientWidth as well. No properties I try seem to get the correct values. It seems that Firefox has some sort of delay after page load before it has access to the client window's dimensions...
I tried the verge.airve.com plugin without JQuery and its initial feedback remained at 980. It also initialized as 980 on Chrome, which was weird, because Chrome worked as expected without it...
After much debate a solution was found! Firefox apparently resizes the window after it is loaded (I guess for good measure, who really knows)! So, by adding a resize event handler in addition to window.onload, this problem can be averted! See accepted answer below for more details.
Make sure your measurement is done when whole document is loaded and resized.
window.onload = showViewport;
window.onresize = showViewport;
function showViewport() {
var output=document.getElementById("output");
var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var height= Math.max(document.documentElement.clientHeight, window.innerHeight || 0)
output.innerHTML = "Viewport size is " + width + "x" + height;
}
<body>
<p id="output">Default Output</p>
</body>
The problem (innerWidth === 980) persists for Firefox 40.0 under Android 4.4.4. A 1 msec wait is a circumvention. Replace window.onload = myProgram; by
window.onload = function() {setTimeout(myProgram, 1)};
In the meantime I encountered this problem while adapting a fairly elaborate site to small screens. Firefox obeys the CSS following "#media only screen and (max-width: 768px)". However, when one tries to set event handlers depending on device widths, Firefox fails miserably. I needed the above trick with 0.5 second wait at all spots where I picked up the device width. This wait time was necessary for Nexus 7 (2012), but who knows what is needed for other devices?
I can confirm the issue, for example in Firefox 38.0.1 on Android 4.1.2. Created a js bin for testing purposes.
I'd like to check window.innerWidth for custom DOM manipulations on different resolutions (mobile, tablet and desktop size), so it'd be important to get the correct window.innerWidth value already in the document.ready() state and not just only in the window.load().
$('#inline').html($(window).width());
$(document).ready(function() {
$('#ready').html(window.innerWidth);
});
$(window).load(function() {
$('#load').html(window.innerWidth);
});
setTimeout(function() {
$('#setTimeout').html(window.innerWidth);
}, 1000);
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JS Bin</title>
</head>
<body>
<p><span id="inline"></span></p>
<p>$(document).ready(): <span id="ready"></span></p>
<p>$(window).load(): <span id="load"></span></p>
<p>setTimeout(1000): <span id="setTimeout"></span></p>
</body>
</html>
(I wanted to add only a comment, and not answer, but no reputations yet to do so :-)
I was facing the same issue while using BrowserComponent in CodeNameOne and Android
My solution was to put the js inside a function like so
function runScripts()
{
//get width here
}
And listen to the onLoad event of the BrowserComponent to execute this script once the browser has been fully loaded
like so:
BrowserComponent browser = new BrowserComponent();
browser.addWebEventListener("onLoad", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
browser.execute("runScripts()");
}
});
browser.setURL("http://www.URL.com");
Handling window.onload in the html wasn't enough to wait for the appropriate width to be served
Besides this solution I also found that window.setTimeout(runScripts, 500); works to get the right document width, at the expense of wasting half a second
window.setTimeout(yourFunction, 1);
This did the job for me, 1ms is enough.
A very hack solution I found is to invoke a fake link in the header. My guess is the time delay allows updating of window.innerWidth and window.innerHeight prior to script execution.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/fake.css"/>
I had the same problem, getting varying width when fetching window.innerWidth on an android device with Firefox. I tried some of the suggestions above, but without success - possibly implementing the examples in a wrong way?
However, by using the code below, I got a system that seems to be working 100% as far as I have tested. It also makes little delay as it break the loop as soon as it get a stable result.
var canvasWidth = 0;
var canvasHeight = 0;
var previousWidth = -1;
var previousHeight = -1;
while ((canvasWidth != previousWidth) || (canvasHeight != previousHeight))
{
previousWidth = canvasWidth;
previousHeight = canvasHeight;
canvasWidth = window.innerWidth;
canvasHeight = window.innerHeight;
}

Javascript animation does not work in WordPress

I am trying to add some JavaScript code to my WordPress page that makes a blue circle move across the screen whenever the page is loaded (via the Raphael JS documentation). I copied and pasted the JS code into the "Text" section of my WordPress page but when I saved and previewed the page, not only did the ball not appear but all of the tags were deleted. Here is the source code I inserted:
<script src="raphael-min.js"></script>
<script>
window.onload = function() {
var p = Raphael(10, 10, 400,400);
var c = p.circle(100, 100, 45);
c.attr({
fill: 'blue',
cursor: 'pointer'
}).animate({
cx : 300
}, 5000);
}
</script>
Is there some standard way to use JavaScript in WordPress? All help is greatly appreciated. Thanks!
You must check your .js file path correctly,
- use phoenix editor extension in firefox to check your .js loaded or not
- make sure your .js file position in top position before </head

Chrome doesn't cache images inside SVG

I just discovered that Chrome doesn't cache images which are placed inside SVGs if their cache-control header is set to no-cache. Firefox & IE10 seem to ignore this setting.
I've created a little test page with a static SVG:
HTML:
<div style="width: 500px; text-align: center;">
<input id="move-left-btn" type="button" value="<<">
<input id="move-right-btn" type="button" value=">>">
</div>
<div class="svgwrapper" style="width: 500px; height: 250px; background-color: lightgrey;">
<svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" width="500" height="250">
<g id="svggroup" class="transition-on" transform="matrix(0.2,0,0,0.2,80,35)">
<image width="1672" height="887" opacity="1" xlink:href="https://dl.dropboxusercontent.com/sh/q7htlj5h8qqfhjf/SVDuynM7R3/car.png"></image>
</g>
</svg>
</div>
Javascript:
$(document).ready(function() {
var curXPos = 80;
// Local test function which represent some server calls in my "real life" scenario
// Just updates the x-position in the transform matrix in this test case
function updateSvgText(svgText, posXDelta) {
curXPos += posXDelta;
if (curXPos < 0) {
curXPos = 160;
} else if (curXPos > 160) {
curXPos = 0;
}
return svgText.replace(/matrix\(.*\)/, 'matrix(0.2,0,0,0.2,' + curXPos + ',35)');
}
// Fetch the new SVG (in real life from server) and rerender it
function moveSvg(posXDelta) {
var svg = $('#svg'),
svgText = updateSvgText($('.svgwrapper').html(), posXDelta);
svg.empty();
svg.append($(svgText).children());
}
$('#move-left-btn').click($.proxy(moveSvg, this, -20));
$('#move-right-btn').click($.proxy(moveSvg, this, 20));
});
Working example with cache-control header of source image set to no-cache (flickers in chrome after every press on the "move" buttons):
http://jsfiddle.net/zF6NF/4/
Same example with different source image with cache-control header set to max-age=315360000,public (no flickering):
http://jsfiddle.net/zF6NF/5/
In Chrome you can see the reloading of the images on each button click in the first example ("flickering" of the image & visible in the network tab of the dev tools) whereas Firefox rerenders the SVG in both examples smoothly without any reloading.
Some additional information:
This is just an example. In my "real-life-scenario" I receive a new SVG from the server (instead of the updateSvgText method call) which means that I can't just perform partial updates of the SVG by changing the value of the transform matrix attribute but have to rerender the whole SVG every time (at least by now...).
I can't control where the images come from which means 2 things:
I can't change the cache-control header
I can't create Base64 encoded data-uris, save them locally and just replace the images inside the SVG with those data-uris before rendering (can't create Base64 encoded data-uri because of "Same resource origin" policies...)
Is there any way to either...
Overwrite/overrule the cache-control header locally even if the image is from an uncontrolled remote location?
Create the Base64 encoded data-uri from an Image that is loaded from a different domain I don't have any control over client sided?
Somehow tell Chrome to always cache images inside my SVGs?
Needless to say that other solutions are also very welcome!
Thanks
Unfortunately, when it comes to caching, it's 99% the server's job.
In-dept guide : here
Browsers will always look for more recent versions of the file based on certain conditions:
The cached entry has no expiration date and the content is being accessed for the first time in a browser session
The cached entry has an expiration date but it has expired
Cache-Control/Pragma tells the browser not to cache
Etag in header is a pain.
In terms of solutions you have:
Be very insistent to your server guys that you need caching
(remove etag, Cache-Control: public,max-age=31536000, Pragma: public)
Create a proxy on your domain that requires the image from the site, (optionally convert to base64) then send to your client (with the proper headers). Here's an example for PHP : here

Using TypeKit's WebFontLoader for Canvas text

I'm having a hard time using fonts loaded via the TypeKit webfontloader as font faces for text that is drawn on a canvas element.
I boiled it down to the following test case:
WebFont.load({
google: {
families: ['Droid Sans', 'Droid Serif']
},
monotype: {
projectId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' //this is valid & working
},
fontactive : function(font, fvd){
testFont(font, fvd, 'active');
},
fontinactive : function(font, fvd){
testFont(font, fvd, 'inactive');
}
});
function testFont(font, fvd, state){
console.log('loaded ' + state, font, fvd);
var $canvas = $('<canvas>').attr({width: 400, height: 100}).appendTo($('body'));
var canvas = $canvas[0];
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'black';
ctx.font = '30px ' + font;
ctx.fillText('CANVAS PARTY YALL!', 50, 50);
}
The callbacks for each font will fire, yet the font isn't used in the canvas text. One strange aspect is that the fonts loaded from fonts.com (the monotype) part do declare themselves as fontinactive, yet I can apply them to all HTML without problems. The Google fonts will always fire a fontactive.
The other strange aspect is that the Google Fonts will display in one of about 20 cases, yet when I wrap my testFont function inside a setTimeout with a delay of 1000ms this behavior reverses and makes the fonts.com font display from time to time.
All this leads me to the conclusion that the handlers probably fire too early, but I have no clue what to do about this (instead of hacky stuff like timeouts and praying). Any idea what I am doing wrong or what I could do to fix this?
EDIT: To add to the confusion I just noticed that the fonts.com font is actually working perfectly fine in IE9. All other browsers seem to do the things I described above.
Ok, so I did find out that everything is working fine when I do not hide elements of .wf-loading via my Stylesheet so I do not use:
.wf-loading{
display: none;
}
anymore but use screen offset to hide unrendered elements.

Can't display any graph with Sigma.js

I want to visualize a large network graph on a web interface. After a few days of search, I decided to use Sigma.js because it looks simple and it's HTML5 compatible.
The problem is that I can't display any graph example from Sigma.js web page, even when I use the minimal code that the author has on Sigma.js's homepage. I even copy-pasted entire web pages, with right click-view code, but in vain (like this). I have pasted all the necessary files in the same folder that the simple .html file is located (css files, js files and even the .gexf file that the example needs) but I only get a page with a black rectangle and nothing more. The graph isn't displayed. What am I doing wrong?
Do I need to first build the sigma.js file, as the author mentions in the code repository of the library in GitHub? I need this tool to visualize the graph (I'm going to feed the graph with data on the fly) but I can't even experiment with some simple code! I even followed that "guide" and did every step but I can't anything working.
Webstudio: Microsoft Expression Web 4 and OS: Windows 8 Pro (I tried opening the web pages in IE10, FF17 and Chrome 23).
The div you want to have your graph has to be absolute positioned. I think it's a canvas issue.
so the html
<!DOCTYPE html>
<html>
<head>
<script src="http://sigmajs.org/js/sigma.min.js"></script>
<script src="/js/sigmatest.js"></script>
<link rel="stylesheet" href="/css/sigma.css">
</head>
<body>
<div id="sigma-parent">
<div id="sigma-example">
</div>
</div>
</body>
</html>
the css
#sigma-parent {
width: 500px;
height: 500px;
position: relative;
}
#sigma-example {
position: absolute;
width: 100%;
height: 100%;
}
the js in sigmatest.js
function init() {
var sigRoot = document.getElementById('sigma-example');
var sigInst = sigma.init(sigRoot);
sigInst.addNode('hello',{
label: 'Hello',
x: 10,
y: 10,
size: 5,
color: '#ff0000'
}).addNode('world',{
label: 'World !',
x: 20,
y: 20,
size: 3,
color: '#00ff00'
}).addEdge('hello_world','hello','world').draw();
}
if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', init, false);
} else {
window.onload = init;
}
This probably won't help as many people, but in my case it was simply that I didn't specify x or y properties for each node. I was trying to use the forceAtlas2 algorithm to automatically "place" my nodes, not realizing they had to be drawn in some position first in order for the layout to then apply.
Make sure you have downloaded this file http://sigmajs.org/data/arctic.gexf
and refered the path properly in the code
Sigma js has browser compatibilty issue. Try updating the bowser or use some other browser.
I work with firefox and it works fine.

Categories