Conditional media query loading - javascript

I'm trying use to a Conditional CSS loading technique found here but I cannot get this to work. The code can be found below (I've stripped out some parts for clarity) here is live link.
The media queries do not apply when the screen is stretched above 650px. The idea is use conditional loading to prevent downloading unnecessary CSS files.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" class="mediaquerydependent"
data-media="screen and (min-width: 300px)"
data-href="styles/stylemin300.css">
<link rel="stylesheet" class="mediaquerydependent"
data-media="screen and (min-width: 650px)"
data-href="styles/stylemin650.css">
<script type="text/javascript" src="js/mediamatch.js">
</head>
<body>
<h2>HELLO</h2>
</body>
</html>
Here is the JavaScript:
(function(){
var queries = document.
querySelectorAll('.mediaquerydependent'),
all = queries.length,
cur = null,
attr = null;
while (all--) {
cur = queries[all];
if (cur.dataset.media &&
window.matchMedia(cur.dataset.media).matches) {
for (attr in cur.dataset) {
if (attr !== 'media') {
cur.setAttribute(attr, cur.dataset[attr]);
}
}
}
}
}());

Related

How to use p5.js sound in instance mode

I'm trying to make a website with multiple p5 canvases on the same page, so after a lot of research, I came to the conclusion that the most adequate way to do that is by using instance mode on p5.
I spent the whole day trying to understand the instance mode, i even found a converter online that converts it for me, but I'm trying to do it all by my self using it just to check errors. The problem is that i can't find a way to use sound in my sketch using instance mode. the code i have is a lot more complex, but even trying just the basic it still does not work.
var s = function(p) {
let song;
p.preload = function() {
p.song = load('thunder.mp3')
}
p.setup = function() {
p.createCanvas(720, 200);
p.background(255, 0, 0);
p.song.loop();
};
};
var myp5 = new p5(s, 'c1');
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
<style> body {padding: 0;
margin: 0;
}
<meta charset="UTF-8">
</style>
</head>
<body>
<div id="c1"></div> <br>
<div id="c2"></div>
</body>
</html>
you can test it here: https://editor.p5js.org/jgsantos.dsn/sketches/rUWb6Nurt
This code works great in the global mode:
let song;
function preload() {
song = loadSound('thunder.mp3');
}
function setup() {
createCanvas(720, 200);
background(255,0,0);
song.loop();
}
html, body {
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
You can test it here https://editor.p5js.org/jgsantos.dsn/sketches/_lQcDqOsp
It shows this error: "Uncaught ReferenceError: load is not defined (: line 9)"
What am I'm doing wrong?
Thanks in advance!
Please try to post the exact code you're running. Your question contains different code than the link you posted in the comments.
But taking a step back, here's how I would think about instance mode and libraries:
Instance mode means that the variables and functions that belong to a sketch are now referenced via a variable, in your case the p variable.
But variables and functions that belong to a library are still referenced directly, i.e. in "global mode".
In other words, you don't want to reference the load() (or is it loadSound()?) function using instance mode. You should still reference that function directly, since it's coming from a library instead of from a specific sketch.

Can't use a class from a script in another script

This is a basic problem I guess, but I can't find what the problem is. I have two scripts, one "main" and one containing a basic class, I try to instantiate the class in the main script like this:
Script.js
window.onload = function() {
var car = new Card('Ressources/Sprites/Axel.png', [50, 50]);
}
Card.js
class Card {
constructor(path, position) {
this.position = position;
this.texture = PIXI.Texture.from(sprite);
this.card = PIXI.Sprite(texture);
this.setPosition(position);
}
function setPosition(position){
card.x = position.x;
card.y = position.y;
}
}
Index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World</title>
</head>
<style>* {padding: 0; margin: 0}</style>
<script src="Ressources/Libraries/pixi.min.js"></script>
<script src="Scripts/Card.js"></script>
<script src="script.js"></script>
<body>
</body>
</html>
In the console I have this error :
Uncaught ReferenceError: Card is not defined
at window.onload

How to switch between different stylesheets using JQuery?

I'm trying to change the size of the browser according to the size of the display using JQuery however it does not seem to work currently.
HTML Code:
<head>
<link rel="stylesheet" type="text/css" href="SmallDesktopScreen.css">
<link id="newSize" rel="stylesheet" type="text/css" href="LargeScreen.css">
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
function adjustStyleSheet(width){
width= parseInt(width);
if ((width>=1352)&&(width<=1880)){
$("#newSize").attr("href", "css/SmallDesktopScreen.css");
}
else if(width>1881){
$("#newSize").attr("href", "css/LargeScreen.css");
}
}
<!-- 1352 1881 -->
$("document").ready(function(){
$(function() {
adjustStyleSheet($(this).width());
$(window).resize(function() {
adjustStyleSheet($(this).width());
});
});
});
it is possible to switch stylesheets using jquery.
for example
var stylesheets = ['style1.css','style2.css'];
var primary_sheet = 0;
if(primary_sheet === 0) {
$('link').attr('href',stylesheets[0]);
else {
$('link').attr('href',stylesheets[1]);
}
Changing some of your scripts will do the trick.
First of all you cannot, get the link element and set href(which will eventually not work in all the browsers). But you can create one easily.
Check the script code below. This will work.
function adjustStyleSheet(width){
width= parseInt(width);
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.id = "";
link.rel = 'stylesheet';
link.type = 'text/css';
link.media = 'all';
var linkHref = "css/SmallDesktopScreen.css";
if ((width>=1352)&&(width<=1880)){
linkHref = 'css/SmallDesktopScreen.css';
}
else if(width>=1881){
linkHref = 'css/LargeScreen.css';
}
link.href = linkHref;
head.appendChild(link);
}
<!-- 1352 1881 -->
$("document").ready(function(){
$(function() {
adjustStyleSheet($(window).outerWidth());//OuterWidth gets the width of your original screen size not the window size alone.
$(window).resize(function() {
adjustStyleSheet($(window).outerWidth());
});
});
});
It is good doing stuffs in Javascript or jQuery. But I will support #media queries in CSS for responsive kind of works, which is very easy actually.

Can't view Google Maps in HTML, Cordova

I'm trying to displayGoogle Maps on a html page in cordova.
The example code I'm trying to replicate is this one: https://developers.google.com/maps/documentation/javascript/examples/map-simple?hl=it
Here is my code:
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<title>Hello World</title>
</head>
<body>
<div class="app">
<div id="map-canvas"></div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src=js/jquery-1.11.1.min.js></script>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script type="text/javascript" src="js/google_map.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
index.js (I used some alert() and every method was called)
var app = {
initialize: function() {
this.bindEvents();
},
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
onDeviceReady: function() {
toIndex();
}
};
$(document).ready( function(){
app.initialize();
});
function toIndex(){
google_map.init();
}
google_map.js
the class which take care of the map
var google_map = (function(){
var _map;
var _$map_canvas;
function init(){
_$map_canvas = $('.app').find('#map-canvas');
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644)
};
_map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
function getMap(){
return _map;
}
return {
init:init,
getMap:getMap
}
})();
and the index.css file
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
Instead of displaying the map, I see a white page.
Second question:
code here: http://jsfiddle.net/qbddfdk7/1/
This one doesn't work too, the problem is at line 14:
if I change it from
map = new google.maps.Map(map_canvas, mapOptions);
to
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
It will work, but I can't undesrstand why.
The problem with your second question is a timing issue.
You see, your inline javascript is in the <head>, so at the time var map_canvas = document.getElementById('map-canvas'); runs, the element with the id map-canvas is not loaded yet, so var map_canvas is set to null.
Moving the <script> tag to the bottom of the <body> element solves this issue. I've updated your jsFiddle accordingly.
As for your first issue, try Chrome Remote Debugging if available, or weinre. These will help you find the source of your problem.
I've had no luck using their recommendation to use percentages for the map-canvas. To ensure everything is working fine, hard-code the div tag to a fixed width and height.
Once you have the map displayed, then you'll need to write javascript to adjust the style width and height during the pagecreate or pageinit. You can then change the same properties during the orientationchange event.
There are several articles on the best way to find the screen size. I'm using:
function effectiveDeviceWidth(factor) {
var deviceWidth = window.orientation == 0 ? window.screen.width : window.screen.height;
// iOS returns available pixels, Android returns pixels / pixel ratio
// http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html
if (navigator.userAgent.indexOf('Android') >= 0 && window.devicePixelRatio) {
deviceWidth = deviceWidth / window.devicePixelRatio;
}
return parseInt(deviceWidth) * factor + 'px';
}
function effectiveDeviceHeight(factor) {
var deviceHeight = window.orientation == 0 ? window.screen.height : window.screen.width;
// iOS returns available pixels, Android returns pixels / pixel ratio
// http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html
if (navigator.userAgent.indexOf('Android') >= 0 && window.devicePixelRatio) {
deviceHeight = deviceHeight / window.devicePixelRatio;
}
return parseInt(deviceHeight) * factor + 'px';
}
$('#map-canvas').width(effectiveDeviceWidth(.8));
$('#map-canvas').height(effectiveDeviceHeight(.6));
Hope this helps.
The problem was in the css, in eclipse I corrcted the css to this:
html, body, #map-canvas {
height: 100%;
width: 100%;
position: relative;
z-index: -1;
margin: 0px;
padding: 0px
}
I'm new to web languages and I didn't know that I had to write css even for the hmtl and the body tag, as you can see those tag are missing from the code in the question.

Internet Explorer 8 Messing Up My Bulletgraphs

I've created HTML and JavaScript files to display bulletgraphs, using the 'canvas' HTML5 tag. I've tried it in Chrome and it works nicely and changes width along with the size of the browser. I have to have this working in IE8, too, so I've used Excanvas, which is working in all except one way: when I resize the browser I get remnants of the valueIndicator. This only happens on IE8.
I've tried looking round for information on redrawing the canvas but I don't think this is the issue. Can anyone see where I'm going wrong, please?
EDIT
I'm keeping the complete code at the bottom, however, following advice I've cut my code down somewhat.
In IE8 it looks like this:
In Chrome it looks like this:
When I refresh the IE8 page it looks OK again.
Cut-down Bulletgraph.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bulletgraph</title>
<!--[if IE]><script src="excanvas.js"></script><![endif]-->
</head>
<body>
<canvas id="graph1"></canvas>
<script src="Scripts.js"></script>
<script>
drawGraphs();
window.onresize=function() { drawGraphs() };
function drawGraphs() {
drawBulletGraph(getScreenWidth(),300,1000,350,"graph1");
}
</script>
</body>
</html>
Complete code:
Cut-down Scripts.js:
function drawBulletGraph (cwidth, left, right, loValue, id) {
var canvas=document.getElementById(id);
var cheight=30;
var multiplier=cwidth/(right-left);
canvas.width=cwidth;
canvas.height=cheight;
var valueIndicator=canvas.getContext("2d");
valueIndicator.lineWidth="1";
valueIndicator.moveTo((loValue-left)*multiplier,0);
valueIndicator.lineTo((loValue-left)*multiplier,cheight);
valueIndicator.fill();
valueIndicator.stroke();
}
function getScreenWidth () {
return (window.innerWidth || document.documentElement.clientWidth)/7;
}
Bulletgraph.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bulletgraph</title>
<!--[if IE]><script src="excanvas.js"></script><![endif]-->
</head>
<body>
<canvas id="graph1"></canvas><br>
<canvas id="graph2"></canvas>
<script src="Scripts.js"></script>
<script>
drawGraphs();
window.onresize=function() { drawGraphs() };
function drawGraphs() {
drawBulletGraph(bgWidth(getScreenWidth()),300,400,450,600,700,1000,800,350,850,"graph1");
drawBulletGraph(bgWidth(getScreenWidth()),250,450,500,650,700,1200,600,350,850,"graph2");
}
</script>
</body>
</html>
Scripts.js:
function drawBulletGraph (cwidth, left, loRed, loAmber, hiAmber, hiRed, right, value, loValue, hiValue, id) {
var canvas=document.getElementById(id);
var cheight=16;
var colour="#008000";
if (value <= loRed || value >= hiRed)
{
colour="#FF0000";
}
else if (value <= loAmber || value >= hiAmber)
{
colour="#FFA500";
}
var multiplier=cwidth/(right-left);
canvas.width=cwidth;
canvas.height=cheight;
var red=canvas.getContext("2d");
red.fillStyle="#F4C3C6";
red.fillRect(0,0,cwidth,cheight);
var amber=canvas.getContext("2d");
amber.fillStyle="#F4F6C6";
amber.fillRect((loRed-left)*multiplier,0,(hiRed-loRed)*multiplier,cheight);
var green=canvas.getContext("2d");
green.fillStyle="#CCE5CC";
green.fillRect((loAmber-left)*multiplier,0,(hiAmber-loAmber)*multiplier,cheight);
var valueIndicator=canvas.getContext("2d");
valueIndicator.fillStyle=colour;
valueIndicator.strokeStyle=colour;
valueIndicator.lineWidth="2";
valueIndicator.moveTo((loValue-left)*multiplier,0);
valueIndicator.lineTo((loValue-left)*multiplier,cheight);
valueIndicator.moveTo((loValue-left)*multiplier,cheight/2);
valueIndicator.lineTo((hiValue-left)*multiplier,cheight/2);
valueIndicator.moveTo((hiValue-left)*multiplier,0);
valueIndicator.lineTo((hiValue-left)*multiplier,cheight);
valueIndicator.moveTo(((value-left)*multiplier)-(cheight/2),cheight/2);
valueIndicator.stroke();
valueIndicator.lineWidth="1";
valueIndicator.lineTo((value-left)*multiplier,cheight);
valueIndicator.lineTo(((value-left)*multiplier)+(cheight/2),cheight/2);
valueIndicator.lineTo((value-left)*multiplier,0);
valueIndicator.lineTo(((value-left)*multiplier)-(cheight/2),cheight/2);
valueIndicator.fill();
valueIndicator.stroke();
}
function getScreenWidth () {
return window.innerWidth || document.documentElement.clientWidth;
}
function bgWidth (screenWidth) {
var graphWidth=screenWidth/7;
if (graphWidth<70) {graphWidth=70;}
if (graphWidth>260) {graphWidth=260;}
return graphWidth;
}
I've managed to get a solution. It feels like a bit of a hack but it does the trick. Basically it involves drawing a white line round the canvas and filling it each time it's drawn again. The following code goes between the var valueIndicator=canvas.getContext("2d"); and the valueIndicator.lineWidth="1"; lines:
valueIndicator.fillStyle="#FFFFFF";
valueIndicator.strokeStyle="#FFFFFF";
valueIndicator.moveTo(0,0);
valueIndicator.beginPath();
valueIndicator.lineTo(0,cheight);
valueIndicator.lineTo(cwidth,cheight);
valueIndicator.lineTo(cwidth,0);
valueIndicator.closePath();
valueIndicator.fill();
valueIndicator.stroke();
valueIndicator.strokeStyle="#000000";
I've tried it in the full code and it works. If anyone has a more elegant solution, and I'm sure there must be many, I would still love to see them.

Categories

Resources