I am using EaselJS and want to allow for backwards compatibility with ExplorerCanvas.
This should be possible using the following code (see here):
createjs.createCanvas = function () { ... return canvas implementation here ... }
However, If I put an alert in this function and run the code, the function is never run.
How do I go about getting this to work?
Edit:
Here is a simplified example of the code I am using:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<script src='/Scripts/jquery-1.7.1.js'></script>
<script src="/Scripts/excanvas/excanvas.compiled.js"></script>
<script src="/Scripts/easeljs/lib/easeljs-0.5.0.min.js"></script>
<script src='/Scripts/core/jquery.mousewheel.js'></script>
<style>
canvas
{
border: 1px solid #ccc;
}
</style>
<script type='text/javascript'>
$(document).ready(function () {
// Variables
var img;
var stage;
var bmp;
// Bindings
$('#load').click(function () { initialize() }); // DELETE
// Functions
function initialize() {
img = new Image();
img.onload = imageLoadedEvent;
img.src = '/Scripts/viewer/June.jpg';
}
function imageLoadedEvent() {
var canvasElement = generateContext('testCanvas', 400, 400);
stage = new createjs.Stage('testCanvas');
bmp = new createjs.Bitmap(img);
stage.autoClear = true;
stage.addChild(bmp);
stage.update();
}
function generateContext(canvasID, width, height) {
var canvasElement = document.createElement('canvas');
if (typeof (G_vmlCanvasManager) != 'undefined')
canvasElement = G_vmlCanvasManager.initElement(canvasElement);
canvasElement.setAttribute("width", width);
canvasElement.setAttribute("height", height);
canvasElement.setAttribute("id", canvasID);
document.getElementById('viewer').appendChild(canvasElement);
}
});
</script>
</head>
<body>
<div id='viewer'>
<button id='load'>load</button>
</div>
</body>
</html>
This example will run in Chrome and IE9 as a native canvas element is created and used. However in IE8 it fails.
I ran across this issue as well, trying to get ExCanvas to play nice with EaselJS. Here is how I got it working. Hope this helps with your image issue.
Get the source code for EaselJS : https://github.com/gskinner/EaselJS.git. This will get all the javascript files separated out into their own parts.
Copy all those files over to a "easel" folder in your project directory.
The order in which the files are loaded is important, so see below on how to do it.
EaselJS has an option to override the createCanvas method, which is required to use ExCanvas with it. This happens after loading the SpriteSheet.js file, and BEFORE loading Graphics.js, DisplayObject.js, Container.js, etc. In the code below, I used jQuery to load the rest of the js files that easelJs needed. This all happens in the $(document).ready() function.
If done correctly, you should see a 700 x 700 canvas with a red line from top left to bottom right in IE (tested in 8).
head>
<!--
Load ExCanvas first, and jquery
-->
<script type='text/javascript' src='./javascript/excanvas.js'></script>
<script type='text/javascript' src='./javascript/jquery-1.8.2.min.js'></script>
<!--
Have to load Easel js files in a certain order, and override the createCanvas
function in order for it to work in < IE9.
-->
<script type='text/javascript' src='./javascript/easel/UID.js'></script>
<script type='text/javascript' src='./javascript/easel/Ticker.js'></script>
<script type='text/javascript' src='./javascript/easel/EventDispatcher.js'></script>
<script type='text/javascript' src='./javascript/easel/MouseEvent.js'></script>
<script type='text/javascript' src='./javascript/easel/Matrix2D.js'></script>
<script type='text/javascript' src='./javascript/easel/Point.js'></script>
<script type='text/javascript' src='./javascript/easel/Rectangle.js'></script>
<script type='text/javascript' src='./javascript/easel/Shadow.js'></script>
<script type='text/javascript' src='./javascript/easel/SpriteSheet.js'></script>
<script type='text/javascript'>
var canvas, stage;
createjs.createCanvas = function () { return getCanvas(); };
function getCanvas() {
// This is needed, otherwise it will keep adding canvases, but it only use the last one it creates.
canvas = document.getElementById("myCanvas");
if (canvas != null) {
document.getElementById("container").removeChild(canvas);
}
canvas = document.createElement("canvas");
document.getElementById("container").appendChild(canvas);
if (typeof (G_vmlCanvasManager) != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
canvas.setAttribute("height", "700");
canvas.setAttribute("width", "700");
canvas.setAttribute("style", "height:700px; width:700px;");
canvas.setAttribute("id", "myCanvas");
}
return canvas;
}
</script>
<script type="text/javascript">
$(document).ready(function () {
loadOtherScripts();
stage = new createjs.Stage(canvas);
// Draw a red line from top left to bottom right
var line = new createjs.Shape();
line.graphics.clear();
line.graphics.setStrokeStyle(2);
line.graphics.beginStroke("#FF0000");
line.graphics.moveTo(0, 0);
line.graphics.lineTo(700, 700);
stage.addChild(line);
stage.update();
});
function loadOtherScripts() {
var jsAr = new Array(13);
jsAr[0] = './javascript/easel/Graphics.js';
jsAr[1] = './javascript/easel/DisplayObject.js';
jsAr[2] = './javascript/easel/Container.js';
jsAr[3] = './javascript/easel/Stage.js';
jsAr[4] = './javascript/easel/Bitmap.js';
jsAr[5] = './javascript/easel/BitmapAnimation.js';
jsAr[6] = './javascript/easel/Shape.js';
jsAr[7] = './javascript/easel/Text.js';
jsAr[8] = './javascript/easel/SpriteSheetUtils.js';
jsAr[9] = './javascript/easel/SpriteSheetBuilder.js';
jsAr[10] = './javascript/easel/DOMElement.js';
jsAr[11] = './javascript/easel/Filter.js';
jsAr[12] = './javascript/easel/Touch.js';
for (var i = 0; i < jsAr.length; i++) {
var js = jsAr[i];
$.ajax({
async: false,
type: "GET",
url: js,
data: null,
dataType: 'script'
});
}
}
</head>
<body>
<div id="container"></div>
</body>
</html>
You should instantiate the quasi canvas element by making reference to the original canvas source as provided on the project page example:
<head>
<!--[if lt IE 9]><script src="excanvas.js"></script><![endif]-->
</head>
var el = document.createElement('canvas');
G_vmlCanvasManager.initElement(el);
var ctx = el.getContext('2d');
EDIT:
After further investigation i came to the following conclusions!
There are multiple reasons for not being able to include the image into the canvas:
1st probably there is a bug in the excanvas code for not being able to mimic the native canvas features. I used with more success the modified sancha code, which you can obtain here: http://dev.sencha.com/playpen/tm/excanvas-patch/excanvas-modified.js. See live example here: http://jsfiddle.net/aDHKm/ (try it on IE).
2nd before Easeljs initialize the core objects and classes first is searching for the canvas element existence. Because IE < 9 doesn't have implemented the canvas it's obvious that easeljs core graphics API's can not be instantiated. I think these are the two main reasons that your code is not working.
My suggestion is to try to remake the code without the easeljs. I made a fiddle with the necessary modification to show you how can be done without easeljs: http://jsfiddle.net/xdXrw/. I don't know if it's absolute imperative for you to use easeljs, but certainly it has some limitations in terms of IE8 hacked canvas.
Related
I have been using Physijs with the older version of three.js and it works perfectly
But when I downloaded the latest version of threejs it doesn't work even to just put a plane mesh on the scene
It brings out this error
Uncaught TypeError: Class constructor Scene cannot be invoked without 'new' line:391 of:file:///storage /emulated/0/threejs /learning-threejs/libs/physi .js
I don't understand why exactly
Here's my code
<html>
<head>
<title>Example 01.01 - Basic skeleton</title>
<script type="text/javascript" src="../libs/three.min.js"></script>
<script type="text/javascript" src="../libs/dat.gui.js"></script>
<script type="text/javascript" src="../libs/TrackballControls.js"></script>
<script type="text/javascript" src="../libs/physi.js"></script>
<style>
body {
/* set margin to 0 and overflow to hidden, to
use the complete page */
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<!-- Div which will hold the Output -->
<div id="WebGL-output">
</div>
<!-- Javascript code that runs our Three.js examples -->
<script type="text/javascript">
// once everything is loaded, we run our Three.js stuff.
function init() {
Physijs.scripts.worker = '../libs/physijs_worker.js';
Physijs.scripts.ammo = '../libs/ammo.js';
//renderer
var renderer=new THREE.WebGLRenderer({antialias:true})
renderer.setSize(innerWidth,innerHeight)
renderer.setPixelRatio=devicePixelRatio
renderer.shadowMap.enabled=true
renderer.setClearColor(new THREE.Color(0xff00ff))
//physijs scene
var scene=new Physijs.Scene
scene.setGravity(new THREE.Vector3(0,-300,-50))
//ground
var groundgeo=new THREE.PlaneGeometry(50,50)
var groundmat=new Physijs.createMaterial(new THREE.MeshBasicMaterial({color:0xd2b48c ,side:THREE.DoubleSide}))
var ground=new Physijs.PlaneMesh(groundgeo,groundmat,0)
ground.rotation.x=-0.5*Math.PI
ground.position.set(-20.0,0,0.0)
ground.receiveShadow=true
scene.add(ground)
var camera=new THREE.PerspectiveCamera(40,innerWidth/innerHeight,0.1,10000)
camera.position.set(70,65,0)
camera.lookAt(ground.position)
scene.add(camera)
var trackballControls = new THREE.TrackballControls(camera);
trackballControls.rotateSpeed = 1.0;
trackballControls.zoomSpeed = 1.0;
trackballControls.panSpeed = 1.0;
trackballControls.staticMoving = true;
document.getElementById("WebGL-output").appendChild(renderer.domElement)
render()
var step=0
function render(){
scene.simulate(undefined,2)
trackballControls.update()
requestAnimationFrame(render)
renderer.render(scene,camera)
}}
window.onload = init()
</script>
</body>
Thanks in advance
The new version of three js doesn't support physi.js but it support Cannon.js
So cannon.js(or other recent physics library) should be used instead of physi.js
When I'm referencing my JavaScript file to my index.html file (two separate files in the same folder), and I load the html file in a browser, the drawing i made in the javascript file doesnt show in the canvas.
Here is this HTML code:
<!DOCTYPE html>
<html>
<head>
<title>snake</title>
<script language="javascript" type="text/javascript" src="snake.js"></script>
</head>
<body>
<canvas id="dots" height="500" width="500"></canvas>
</body>
</html>
and here is the JavaScript:
function snake() {
var canvas = document.getElementById("dots");
var snakehead = canvas.getContext('2d');
snakehead.beginPath();
snakehead.arc(100, 75, 50, 0, 2 * Math.PI);
snakehead.stroke();
snakehead.fillStyle = "#2776ff";
snakehead.fill();
}
snake();
in JS-fiddle the code works, it looks like this: https://jsfiddle.net/j2ny6gaf/72/
I'm also getting some errors from JSLint.
"Missing use of 'strict' statement, on the var canvas = document.getElementById
"Combine this with the previous var statement var snake = canvasgetcontext
and a ERROR;
"Document is not defined.[no-undef]
Try adding your script inside the head section (script src=“file-name.js” /script) and try adding a canvas size.
Try
window.onload = function snake() {...}
Try using the script tag
<script type="text/javascript" src="snake.js"></script>
Inside the head section.
I can't get this to work on my public webpage. I've made sure all permissions on files are correct, but when I go to the site, it just shows a blank page. It's supposed to have a matrix-like effect. I edited it through Codepen.io, but when I transfer it over to actual files and upload them, nothing works.
HTML:
<html><head>
<script src="(link the js file attached that is in the directory of my webpage)" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<meta charset="utf-8">
<title>Matrix</title>
</head>
<body>
<div align="center">
<canvas id="canvas" width="500" height="500">
</canvas><br/><br/>
</div>
</body>
</html>
JavaScript:
//this is my matrix.js file
$(document).ready(function(){
var s=window.screen;
var width = canvas.width=s.width;
var height = canvas.height;
var inLink = false;
var yPositions = Array(300).join(0).split('');
var context=canvas.getContext('2d');
var draw = function () {
context.fillStyle='rgba(0,0,0,.05)';
context.fillRect(0,0,width,height);
context.fillStyle='#0F0';
canvas.addEventListener("click", on_click, false);
canvas.addEventListener("mousemove", on_mousemove, false);
context.fillText(linkText,10,50);
context.font = '12pt Georgia';
yPositions.map(function(y, index){
text = String.fromCharCode(1e3+Math.random()*33);//determines characters randomly from this specific font
x = (index * 10)+10;
canvas.getContext('2d').fillText(text, x, y);
if(y > 100 + Math.random()*1e4)
{
yPositions[index]=0;
}
else
{
yPositions[index] = y + 10;
}
});
};
RunMatrix();
function RunMatrix()
{
if(typeof Game_Interval != "undefined") clearInterval(Game_Interval);
Game_Interval = setInterval(draw, 33);
}
})
You have to include your javascript files after the libraries they depend upon
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
type="text/javascript"></script>
<script src="(link the js file attached that is in the directory of my webpage)" type="text/javascript"></script>
Also, consider using a newer version of jQuery
try adding...
var canvas = document.getElementById('canvas');
at the start of your $(document).ready function...
$(document).ready(function(){
var canvas = document.getElementById('canvas');
....
basically you are referencing 'canvas', which doesn't appear to exist yet..
also make sure you're including jquery before any libraries or scripts that attempt to use it!
I have a problem about jQuery and javascript code; when I write this jQuery below between </head> and <body>
<script type="text/javascript">
var $j = jQuery.noConflict();
$j(document).ready(function(){
$j('#page_effect').fadeIn(3000);
});
</script>
and then write javascript code in body tag
<script src="bubbles.js"></script>
<script type="text/javascript">
bubblesMain(new Object({
type : 'linear',
minSpeed : 100,
maxSpeed : 400,
minSize : 30,
maxSize : 55,
num : 100,
colors : new Array('#FF0000','#FFFFFF','#FFCC99', '#FF33CC')
}));
</script>
then jQuery code can work , but javascript code doesn't work. Finally I found that when I resize the browser after the first loading, it's OK to run.
the bubble.js is to automatically create a canvas element and then raises some bubbles with animation inside canvas.
the partly code is on below :
function bubblesMain(obj){
bubbleResize();
bubbles = new bubbleObject(obj);
bubbles.createBubbles();
setInterval(start,1000/60);
};
//WHEN WINDOW HEIGHT IS CHANGED, REMAKE THE CANVAS ELEMENT
window.onresize = function(event) {
bubbleResize();
}
function bubbleResize(){
var height = parseInt(document.getElementById("canvasBubbles").clientHeight);
var width = parseInt(document.getElementById("canvasBubbles").clientWidth);
document.getElementById("canvasBubbles").innerHTML = '<canvas id="canvas" width="'+width+'px" height="'+height+'px"></canvas>';
}
function start(){
var canvas = document.getElementById("canvas");
canvas.width = canvas.width;
bubbles.move();
bubbles.draw();
};
and I have a <div id="canvasBubbles"></div> indise html.
Then after I added the following code into bubbles.js, It's work to run.
window.onload = function(event) {
bubbleResize();
}
I wonder if someone can suggest a smarter solution to this? thank you.
As stated in the other answers, the <script> tags should be the last thing before the </body> tag. See this question.
The problem with where you've put the tags is that the body of the HTML page hasn't loaded and is therefore not available for manipulation. The reason the window.onload and window.onresize work is because they are called later, when the body of the document is available for manipulation with JS.
Given the details provided in your question, you don't need the jQuery.noConflict() statement.
Here is an alternate version of your code that should do the same thing but with a bit more efficiency. Put it at the end of the body element, just before the </body> tag. I haven't tested it since I don't have all the scripts needed (bubbles, etc).
<!-- this goes at the end of your body element, just before the closing tag -->
<script type="text/javascript" src="bubbles.js"></script>
<script type="text/javascript">
$.ready(function(){
var canvasWrap,
canvasElm,
bubbles;
init();
setInterval(update, 1000/60);
window.onresize = resize;
$('#page_effect').fadeIn(3000);
function init(){
canvasWrap = document.getElementById("canvasBubbles");
canvasElm = document.createElement('canvas');
canvasElm.setAttribute('id', 'canvas');
canvasElm.setAttribute('width', canvasWrap.clientWidth);
canvasElm.setAttribute('height', canvasWrap.clientHeight);
canvasWrap.appendChild(canvasElm);
bubbles = new bubbleObject({
type: 'linear',
minSpeed: 100,
maxSpeed: 400,
minSize: 30,
maxSize: 55,
num: 100,
colors: ['#FF0000','#FFFFFF','#FFCC99', '#FF33CC']
});
bubbles.createBubbles();
update(); // you might not need this
}
function resize() {
canvasElm.setAttribute('width', canvasWrap.clientWidth);
canvasElm.setAttribute('height', canvasWrap.clientHeight);
}
function update(){
// canvasElm.width = canvasElm.width; // is this a hack for something?
bubbles.move();
bubbles.draw();
};
});
</script>
You can write all this inside <body>...</body> or inside <head> ... </head>
NOT works between </body> and <head> tag (maybe works for some less formal browser like old IE).
Script tags should always go at the bottom of the page directly before the tag unless the codes needs to be executed before then for some reason.
And as far as I know, the jQuery noConflict() method is only required when you are using two different libraries that both use the dollar sign, aka jQuery and MooTools, on the same page. You can use jQuery and vanilla javascript without having to use noConflict without any problems.
I've got some code which takes a drawing made on in SVG with Raphael (a 400x400 image loaded into the SVG with Raphael), converts it to a canvas with canvg, and should then take canvas.toDataURL and make it an image. All of this should happen when a button is pushed. The first two steps work, but the third is glitchy. The first time I press the button, a 300x150 blank image is placed in the final div instead of the 400x400 image. If I press the button again, the image shows up fine (correct size and everything). I've tried to use both img.onload and the jquery version $(img).load but neither seems to keep the problem from happening. Therefore, I feel like it's an issue with the canvas having not been drawn completely yet but I can't prove that and I can't seem to make the code wait until it has been drawn. Below is all the code. I tried to make it a fiddle but I kept getting security errors with the image.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
<script type="text/javascript" src="scripts/jquery.js"></script>
<script type="text/javascript" src="scripts/raphael.js"></script>
<script type="text/javascript" src="scripts/excanvas.compiled.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var nowX, nowY, R = Raphael("svg_drawing", 400, 400);
$($("svg").get(0)).attr("xmlns:xlink", "http://www.w3.org/1999/xlink");
var templ = R.image("images/band_clutch.jpg", 0, 0, 400, 400);
});
function toImg(){
var svg = $("#svg_drawing").html().replace(/>\s+/g, ">").replace(/\s+</g, "<");
var canvas = $("#canvas")[0];
canvg(canvas, svg);
var imgData = canvas.toDataURL('image/jpg');
var img = new Image();
$(img).load(function(){
$("#drawing_area").html("");
$(img).appendTo("#drawing_area");
});
img.src = imgData;
}
</script>
<title>Sandbox</title>
</head>
<body style="margin: 0; width:3000px">
<div id="svg_drawing" style="background-color:white;display:inline-block;height:400px;width:400px;border:1px solid black;"></div>
<canvas id="canvas" style="display:inline-block;height:400px;width:400px;border:1px solid red;"></canvas>
<div id="drawing_area" style="background-color:white;display:inline-block;height:400px;width:400px;border:1px solid black;"></div>
<button onclick="toImg()" style="display:inline-block;vertical-align:top;">Do it</button>
</body>
</html>
It sounds like the canvas area is staying at the default 350 x 150. Try setting
canvas.width = canvas.height = 400;
before drawing (keep the inline CSS as-is).
To fix the actual rendering issue, you need to tell the canvg method to do the toDataURI stuff asyncronously, once the rendering has been complete:
function toImg(){
var svg = $("#svg_drawing").html().replace(/>\s+/g, ">").replace(/\s+</g, "<");
var canvas = $("#canvas")[0];
canvg(canvas, svg, {
renderCallback : function(){
var imgData = canvas.toDataURL('image/jpg');
var img = new Image();
$(img).load(function(){
$("#drawing_area").html("");
$(img).appendTo("#drawing_area");
});
img.src = imgData;
}
});
}