Internet Explorer 8 Messing Up My Bulletgraphs - javascript

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.

Related

Having trouble finding sprite on canvas of html5 game

I am new at learning coding and game development. I have attempted to make a HTML5 simple game based off my online instructor's. Looking though my html coding, I believe it is exactly how my instructor did it. Problem is that I cannot seem to find my sprite.
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Tico's Flight</title>
<script type="text/javascript" src="simpleGame.js"></script>
<script type="text/javascript">
var scene;
var bird;
function init() {
scene = new Scene();
bird = new Sprite(scene, "birdgame.png", 50, 50);
bird.setAngle(270);
bird.setSpeed(0);
scene.start();
}
function update() {
scene.clear();
if (keyDown[K_UP]) {
bird.setSpeedBy(1);
}
if (keyDown[K_DOWN]) {
bird.changeSpeedBy(-1);
}
if (keyDown[K_LEFT]) {
bird.changeAngleBy(-5);
}
if (keyDown[K_RIGHT]) {
bird.changeAngleBy(5);
}
bird.update();
}
</script>
</head>
<body onload="init()">
<center>
<h1>Fly Tico!</h1>
</body>
</html>
I figured it out! Something simple, as I am learning it usually is: I typed "keyDown" instead of "keysDown". Got my bird visible and flying around.

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.

Uncaught TypeError: canvas1.position is not a function in p5.js

I am trying to make program using p5.js and javascript. But I got a problem in p5.dom.js and got error like:
"Uncaught TypeError: canvas1.position is not a function"
And i almost consume a day :(
I was about to make another js file using p5.js.
Here is my code!
main.html
<html>
<head>
<meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<canvas id="canvas" width=1200 height=1334></canvas>
<script src="coords.js"></script>
<script src="p5/p5/p5.min.js"></script>
<script src="p5/p5/p5.dom.js"></script>
</body>
</html>
coords.js
if(flag==1 && count==2){
$('body').append('<script src="sketch.js"></script>');
$.getScript("p5/p5/p5.min.js")
.done(function(){
$.getScript("p5/p5/p5.dom.js")
.done(function(){
$.getScript("sketch.js",function(){
setup();
});
});
});
}
sketch.js
var canvas1;
function setup(){
canvas1=createCanvas(width1,height1);
canvas1.position(minX1,maxY1);//got error here!!
}
Please help me!!
Okay given that coords has other code you should probably do something like this:
Include sketch.js as normal, and put it after the p5 files.
Then include coords as normal
<html>
<head>
<meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<canvas id="canvas" width=1200 height=1334></canvas>
<script src="p5/p5/p5.min.js"></script>
<script src="p5/p5/p5.dom.js"></script>
<script src="sketch.js"></script>
<script src="coords.js"></script>
</body>
</html>
Then your coords.js can look like this:
if(flag==1 && count==2){
setup();
}
This way you dont have strange and unnecessary ajax calls loading code youre already loading.
EDIT
Given that setup() runs by default you should be able to put setup within your if condition and remove sketch.js altogether.
if(flag==1 && count==2){
var canvas1;
function setup(){
canvas1=createCanvas(width1,height1);
canvas1.position(minX1,maxY1);//got error here!!
}
}
or as answered by g aand
if (flag == 1 && count == 2) {
$('body').append('<script src="sketch.js"></script>');
}
or you could use a namespace:
var s = function( p ) {
var x = 100;
var y = 100;
p.setup = function() {
p.createCanvas(x, y);
p.position(x,y);
};
p.draw = function() {
p.background(0);
p.fill(255);
p.rect(x,y,50,50);
};
};
if (flag == 1 && count == 2) {
var myp5 = new p5(s);
}

Why can't I get the naturalHeight/naturalWidth of an image in javascript/JQuery?

So I'm trying to do some very basic div re-sizing based on the properties of the image contained within it. I know I can do something really basic like set the background an padding around the image and achieve the same effect, but this is sort of a personal challenge.
The problem I am having is that when I try to fetch the naturalHeight or naturalWidth values of the image, I get a value of 0. However, when I try to fetch these values using the console, they return the correct values. Also, my resizeDiv() function is coming up as undefined in console.
Here's the code:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>kitten_resize - WesGilleland.com</title>
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var kittens = new Array("100x100_kitten.jpeg","150x150_kitten.jpeg","200x150_kitten.jpeg");
$('#kittens').attr('src', kittens[0]); //set the image
function resizeDiv() {
var img = document.getElementById('kittens');
var imgH = img.naturalHeight;
var imgW = img.naturalWidth;
$('div').width(imgW);
$('div').height(imgH);
console.log('Current imgH: '+imgH);
console.log('Current imgW: '+imgW);
};
resizeDiv();
});
</script>
<style>
div {
background-color: black;
padding: 10px;
margin: auto;
}
</style>
</head>
<body>
<div>
<img id="kittens" src='' />
</div>
</body>
</html>
You can also find a working copy here: http://www.wesgilleland.com/projects/kitten_resize/
I feel like it's something very basic that I'm missing; I haven't fiddled with this stuff since my associate's degree a year ago. Thanks to anyone who can help!
That's because your image isn't yet loaded when you read the original dimensions.
You should read the dimensions when the image is loaded :
var img = $('#kittens')[0];
img.onload = resizeDiv;
img.src = kittens[0];

After installing flash, swfobject still wont embed video until i reload the original page

I have a simple html page with some javascript where if i click a link, it will show a flash video in a div using the swfobject.embedSWF function.
I did a test:
Uninstalled flash from my machine, then reloaded the page and clicked the link...I correctly saw no video.
I then installed flash and came back to the same page (no reload) and the embed still won't work.
I know in swfobject 1.5 (I'm now using 2.2), I would be able to embed the swf after the user installs flash, but now the user needs to reload the page in order to get the flash to appear. This is not good for my current situation, anyone know what is going on here?
Here is sample code using a youtube video:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>SWFOBJECT TEST</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js' type='text/javascript'></script>
<script src='http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js' type='text/javascript'></script>
<style>
#link{
display:block;
margin-bottom:10px;
}
#videoContainer{
width:610px;
height:360px;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
$("#link").click(function(){
var flashVars = {};
var params = {};
flashVars["lang"] = "en";
params["menu"] = "false";
params["wmode"] = "opaque";
params["allowScriptAccess"] = "always";
params["allowFullScreen"] = "true";
params["bgcolor"] = "#fff";
//add video
swfobject.embedSWF("http://www.youtube.com/v/uZ0LL1SJ-6U?enablejsapi=1&playerapiid=ytplayer", "videoContainer",640, 480, "9.0.0", null, flashVars, params,{});
});
});
</script>
</head>
<body>
Click me
<div id="videoContainer"></div>
</body>
</html>
If you take your swfEmbed call out of the jquery, it works. I didn't really delve in to far, but I did this:
Click me
I made a new function called replaceDiv, which basically just does everything you are already doing in your jquery click function.
function replaceDiv () {
var flashVars = {};
var params = {};
flashVars["lang"] = "en";
params["menu"] = "false";
params["wmode"] = "opaque";
params["allowScriptAccess"] = "always";
params["allowFullScreen"] = "true";
params["bgcolor"] = "#fff";
//add video
swfobject.embedSWF("http://www.youtube.com/v/uZ0LL1SJ-6U?enablejsapi=1&playerapiid=ytplayer", "videoContainer",640, 480, "9.0.0", null, flashVars, params,{})
}
I then removed all of your existing JS and VOILA- works every time.
Let me know if you want me to actually try to debug your JQuery; I might add that it looks perfectly fine. You may be needing something else, I don't know.
-A
ps. Squarepusher is a BEAST. :P

Categories

Resources