How to correctly/cleanly draw SVG graphics using ProcessingJS? - javascript

I'm getting started with ProcessingJS and I'm currently playing with SVG a bit.
Unfortunately I've ran into a strange behaviour displaying SVG.
Here is the output:
and here is the code that produces that:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="http://cloud.github.com/downloads/processing-js/processing-js/processing-1.4.1.min.js"></script>
<script>
$(document).ready(function() {
$('body').append($('<canvas id="preview"><p>Your browser does not support the canvas tag.</p></canvas>'));
function onPJS(p) {
var glasses;
p.setup = function(){
glasses = p.loadShape("brighteyes.svg");
p.size(Math.floor(glasses.width), Math.floor(glasses.height)+Math.floor(glasses.height * .25));
//p.shape(glasses,0,0);
p.frameRate(1);
}
//*
p.draw = function() {
p.background(32);
p.shape(glasses, 0, 0);
console.log(p.mousePressed);//prints undefined
};
//*/
}
new Processing(document.getElementById("preview"), onPJS);
});
</script>
I'm experiencing this odd rendering (renderer seems to place a vertex at 0,0 for the shape)
on OSX 10.8 on Chrome Version 26.0.1410.65 (but not on Safari (6.0 (8536.25))). You can run the code here.
How do I get read of these weird rendering bug ?
There is another unexpected thing happening: mousePressed prints undefined, but might address that in a different question.

Processing's support for SVG is patchy. You should probably just report the bug at https://github.com/processing-js/processing-js/issues/new, and then use a PNG copy instead.
NB: renders OK on Firefox 35.
Edit: reported for you. https://github.com/processing-js/processing-js/issues/137
GoToLoop at the above link says that your problem with mousepressed is caused by the fact that to avoid name collisions in JS, the boolean mousepressed is called __mousePressed in JS. They recommend that you use Java syntax to code your app and have it automatically translated into JS, to avoid these gotchas.
Result: just update Chrome, which you've probably done anyway now.

Related

Animating three.js font from fontLoader()

I caught a bug when trying to deploy my site and the three.js canvas would not load (for some reason worked on dev but that's neither here nor there)
The problem is that I am trying to animate text that was loaded using fontLoader.load(). For example, I add text to the scene using the following:
fontLoader.load(
'node_modules/three/examples/fonts/droid/droid_serif_regular.typeface.json',
(droidFont) => {
const textGeometry = new TextGeometry('Scroll to Start', {
size: 5,
height: 1,
font: droidFont,
bevelSize: 5,
bevelThickness: 2,
});
const introTexture = new THREE.TextureLoader().load('suntexture.png');
const textMaterial = new THREE.MeshBasicMaterial({map: introTexture, transparent:true, opacity: .5});
cosnt introText = new THREE.Mesh(textGeometry, textMaterial);
introText.position.set(-5, 37, -140);
scene.add(introText);
}
);
Then, I want it to gently oscillate on the screen so as to not appear static, to do this I would include something like this in my animation function (called at the end of main.js):
function introAnimate() {
introText.position.y += (Math.sin(clock.getElapsedTime())/62.8);
introText.rotation.y += (Math.cos(clock.getElapsedTime())/700);
}
The problem with this is that the console (on dev/preview) says that introText is not defined, I'm assuming because it was declared in a function. I tried to fix this by first declaring them as var or const (didn't work), then adding globalThis. or window. (ie window.introText). But the problem persists.
To be honest, I am surprised the npm run dev version ran correctly in the first place given this reference error.
I have seen some versions of text animation using three.js flow, but I am interested in triggering certain animations on scroll, and rotating/changing other properties that I don't think flow can do. Any suggestions on how to address this would be much appreciated.
I think your problem is that you're running introAnimate() before your font finishes loading.
fontLoader.load() runs asynchronously, meaning it starts loading, and the rest of your code (introAnimate() for instance) keeps running until your font finally loads at which point it calls the callback.
Locally on in your dev environment the font might load instantly, but in production the font takes relatively longer time to download.
And until then, if introAnimate() tries to run, it'll fail because the callback to declare the window.introText was not called yet.
The solution would be to declare window.introText = null before calling fontLoader.load(), overwrite it once it's initialized, and in your introAnimate() check if introText is not null before doing anything:
function introAnimate() {
if (introText === null) return;
introText.position.y += (Math.sin(clock.getElapsedTime())/62.8);
introText.rotation.y += (Math.cos(clock.getElapsedTime())/700);
}

Dygraph graph gets distorted/partially shifted

I am regularly updating several Dygraphs graphs. After some period of time, normally a few minutes, some or all of them get corrupted as shown in the figure below. I haven't been able to tie this a particular event or browser. This happens even with a simple graph where I am just reloading the data stored in a CSV file. I call updateOptions({ file: URL }) on the graph object, where URL points to the CSV file, followed by calling resetZoom() on the graph object to update the axes. Googling hasn't revealed anyone suffering similar behaviour, so I'm lost as to what is causing this.
Update 1: It is linked to minimizing and maximizing the browser.
Update 2: The problem doesn't occur in Firefox. It does happen in Google Chrome and Internet Explorer, although IE has the additional problem of freezing after a while (a problem for another day).
Update 3: Minimum working examples added at http://jsfiddle.net/williamshipman/tvxekq56/ and http://jsfiddle.net/williamshipman/af66qstt/. Repeatedly minimize and maximize the browser window, after a while the distortion occurs. The first example uses AngularJS (like my own work), while the second demonstrates the same bug in pure JavaScript. You may have to minimize and maximize more than a dozen times to see the bug, it seems pretty random.
For me similar problem appears when I show and hide Y2 axis.
This one line helped me: ctx.clearRect(0, 0, this.width, this.height);
File: dygraph-canvas.js
var DygraphCanvasRenderer = function(dygraph, element, elementContext, layout) {
...
ctx = this.dygraph_.hidden_ctx_;
ctx.clearRect(0, 0, this.width, this.height); // <== clear whole canvas before cliping
ctx.beginPath();
ctx.rect(this.area.x, this.area.y, this.area.w, this.area.h);
ctx.clip();
};
The root of the problem
Canvas context is not fully restored after all draw is done.
Solution 1. (workaround)
Injecting canvas_ctx_.restore() after draw is done and context.save() before. save() is needed because library is restoring the context before every draw(except the initial one).
let g = new Dygraph('graph', {
underlayCallback: (context) => {
context.save();
},
drawCallback: (dygraph) => {
dygraph.canvas_ctx_.restore();
},
});
Solution 2. (library fix)
Here is my commit you can apply to the lib's src/dygraph.js
https://github.com/pawelzwronek/dygraphs/commit/c66ca37b82f14e096652a338cae8abf568b9c764

Create js animation of a horizontal spritesheet

I have gone through the docs and sample only to be lost in outdated docs. Apparently there is no samples for the latest version of createjs.
I need to smooth scroll a horizontal spritesheet. So that the middle of images are shown before the new image is entirely in the "window". So the place in the page doesnt move only what is displayed from the single column horizontal spritesheet is different. And we do not switch between images we scroll up and down.
I am at my wits end with this.
this.sprite = new createjs.BitmapAnimation(spriteSheet);
that line gives an error
not a constructor
this.sprite = createjs.BitmapAnimation(spriteSheet);
gives an error
not a function
here is the sprite sheet
https://github.com/nydehi/asp.net-mvc-example-invoicing-app/blob/master/screenshots/1.png
i am doing this now and no error but nothing is displayed.
<script type="text/javascript" src="createjs-2014.12.12.min.js"></script>
<script>
function init() {
var data = {
images: ["1.png"],
frames: {width:15, height:20},
animations: {
stand:0,
run:[1,5],
jump:[6,8,"run"]
}
};
var spriteSheet = new createjs.SpriteSheet(data);
var animation = new createjs.Sprite(spriteSheet, "run");
var stage = new createjs.Stage("demoCanvas");
stage.addChild(animation);
animation.gotoAndPlay("run"); //walking from left to right
stage.update();
}
</script>
You're probably using a more recent version of CreateJS (around version 0.8.2) which no longer has a BitmapAnimation class on it.
Older versions (0.6.0) had it, but it was most likely replaced by the SpriteSheet class.
Check here for the most recent documentation.
The earlier comments about BitmapAnimation being deprecated long ago are right. Your updated code sample looks fine otherwise.
I think you are just missing something to update the stage when contents change. Your sample just has the one update, but because your image is loaded using a string path, it is not ready yet when you call stage.update().
Any time contents change, you need to tell the stage to refresh. Typically, this is manually controlled when contents change, or constantly using the Ticker.
createjs.Ticker.on("tick", function(event) {
// Other updates
// Update the stage
stage.update(event);
});
// Or a handy shortcut if you don't need to do anything else on tick:
createjs.Ticker.on("tick", stage);

Chrome 31.0 HTML5 Canvas Draw Image

Since downloading the current version of chrome (Version 31.0.1650.57) I've been completely unable to draw images in a HTML5 Canvas with my code; there are no errors and it's finding the resources, they just aren't drawing. I'd really appreciate some help on this!
var grass_img = new Image();
grass_img.src = 'grass.gif';
grass_img.onload = draw_here(grass_img, (center_x + base_x + xpos), (center_y + base_y + ypos),1);
Which appears here and there on several different images and calls:
function draw_here(image, x, y, scale){
draw_canv.drawImage(image, x, y, image.width * scale, image.height * scale);
}
X and Y are correct, as is the scale; there are no coding errors picked up by the debugger and the program worked perfectly until the latest version of chrome came out. Downgrading chrome is also not an option.
The problem is in this line:
grass_img.onload = draw_here( /* ... */ );
You seem to think that you assign the function draw_here as an onload-handler. But that's not what really happens in this line. What you really do is execute draw_here immediately and assign the return-value of that function (which is undefined) to grass_img.onload.
Try this instead:
grass_img.onload = function() {
draw_here(grass_img, (center_x + base_x + xpos), (center_y + base_y + ypos),1);
}
This creates an anonymous function which is assigned to the onload-handler. When that anonymous function is called (which will happen when the load-event is triggered) it calls your draw-handler with your arguments.
I solved the problem. It seems that the latest version of Chrome does not like it if you declare your image in every frame iteration. (Something it seems to have allowed previously, but I really shouldn't have been doing.) If you declare your images and their sources at the top of your js, outside of any functions, and only draw them in functions then the problem is solved, eg:
var image = new Image();
image.src='image.jpg';
someFunction() {
canvas.drawImage(image,0,0);
}
Note: .src should always be called AFTER .onload. Otherwise lots of hard-to-track-down buggies (like this one) appear. Especially if your image loads before onload can be parsed. Your currently accepted solution is possibly functional due to a race condition with function overhead timing.

javascript stack overflow while drawing images

I am simply loading a ton of images (about 5000) into "new Image()" objects and draw them each in a canvas by calling canvas.drawImage(image, 0, 0);
This works totally fine with IE10, but as soon as I am using Firefox I will get an stack overflow error, because somehow the memory usage of the Firefox rises and rises till it overflows. Does anyone have an idea why? I think the GC dont really collect my images after drawing them into the canvas. Even when I am using 100 Image objects and just cycle the src of the Image objects before drawing them, the memory usage rises and rises. I will test Chrome and Safari soon, but still need a solution for that, cause everyone is using "the best browser" Firefox.
EDIT:
function play() {
//calculated iLag here
//calculated wondow.FrameCtr here
var iFrameRate = Math.round(1000 / 25);
var oImage = new Image();
oImage.onload = function () {
renderImage(this);
}
//window.Video is an array of window.URL.createObjectURL(data) (about 500 items)
oImage.src = window.Video[window.FrameCtr];
oImage = null;
setTimeout(
function () {
play()
}, iFrameRate - iLag
);
function renderImage(oImage) {
$("#video")[0].getContext("2d").drawImage(oImage, 0, 0);
}
I do loop this video (500 items, 25fps) 10 times, and ff isn't even able to play it once, cause of stack overflow.
As I mentioned before it is working fine with IE10 and works even better with Chrome, so I don't think the problem here is the recursion. Is there any other way to get binary data into in canvas, than using an Image object and setting the src?
It is already noted as a bug in Firefox. You can see the bug report here. It is showing a last modified date of 2010-09-17 but I am not sure has it been resolved in newer version or what.
But I guess newer version of Firefox should not have that problem.

Categories