So I'm trying to read data and then pass that to another function so I can draw a path.
The data is fine, it's all working and I can view it in the console.
The normal drawing (Using the onMouseEvent) functions work fine.
The only way I can get it to draw using a different function, is if I declare the path at the top of the JS file:
var reloadPath = new Path();
The problem with this, is that when I call reloadPath, it automatically connects the lines (even if the user has clicked elsewhere) which is what I don't want.
I've tried var reloadPath; at the start of the file, and then this
function reloadDrawing(data) {
reloadPath = new Path();
reloadPath.strokeColor = 'black';
reloadPath.add(data);
view.draw();
}
But this just doesn't draw anything.
Thanks.
edit:
Tried the amendments but they didn't work. I'm using Jade instead of HTML (using node.js) so theres really nothing in my html: using socket.io as well
JS:
This does all the dynamic drawing stuff
io.on( 'reloadDrawing', function( data ) {
console.log("fired");
endDrawing(data);
startDrawing(data);
});
function endDrawing(data){
reloadPath.add(data);
view.draw();
reloadPath = new Path();
}
function startDrawing(data) {
reloadPath = new Path();
reloadPath.strokeColor = 'black';
reloadPath.add(data);
view.draw();
}
In your function, you overwrite the reloadPath and thus destroy the data that's already there. Delete the one line and add another function endDrawing (or any name you like). Call this new function in the onMouseUpEvent, in order "finish" the line. In the onMouseDown-event start a new line using the startDrawing function.
function reloadDrawing(data) {
reloadPath.add(data);
view.draw();
}
function endDrawing(data){
reloadPath.add(data);
view.draw();
reloadPath = new Path();
}
function startDrawing(data) {
reloadPath = new Path();
reloadPath.strokeColor = 'black';
reloadPath.add(data);
view.draw();
}
Related
I am using createjs as my framework. I've placed a Bitmap on the canvas and I created a function to try and remove it but I keep getting an error message in the console that image is not defined. This is what my code looks like:
// onload=init() called in html doc
function init(){
var canvas = new createjs.Stage("canvas");
// Add image to canvas
image = new createjs.Bitmap("image.png");
image.x = 200;
image.y = 180;
image.scaleX = 0.35;
image.scaleY = 0.35;
canvas.addChild(image);
image.addEventListener('click', pop);
canvas.update();
}
//remove image from canvas
function pop() {
console.log('pop');
canvas.removeChild(image);
}
When I click on it, I get the console message "pop" followed by the error I mentioned above. I've tried moving the function inside init but I appear to get the same problem.
Make image as global variable, so that it can be accessed by all the functions in your case function pop.
var image;// defining 'image' variable as global
function init(){
var canvas = new createjs.Stage("canvas");
// Add image to canvas
image = new createjs.Bitmap("image.png");
image.x = 200;
image.y = 180;
image.scaleX = 0.35;
image.scaleY = 0.35;
canvas.addChild(image);
image.addEventListener('click', pop);
canvas.update();
}
//remove image from canvas
function pop() {
console.log('pop');
canvas.removeChild(image);
}
This is a scope issue. You defined image inside your init function, so it is not accessible on the pop method.
There are two easy fixes. Either move the var image outside of the init function, or use the click target instead.
var image;
function init() {
init = new createjs.Bitmap();
// etc
}
// OR
function pop(event) {
stage.removeChild(event.target);
}
Scope is really important to understand when building JavaScript applications, so I suggest getting to know it a little better :)
Cheers,
am loading multiple models on the same time to a scene, but it fails to load all the models, it only loading one model on the scene
For example am having a building scene with the multiple objects like chairs, toys and so on inside that building, while loading those objects the only one object is loading, but somehow if i do a alert on end of the function all the models are loading
Image1 what am getting now, Image2 what actually i want
my code is follows
function load_file(floor_number,x,y,z,width,height,rotation,angle,file)
{
obj_x=x;
obj_y=y;
obj_z=z;
obj_width=width;
obj_height=height;
obj_rotation=rotation;
var object_material = new THREE.MeshBasicMaterial({
color: 0xd6d6d6,
traansparent : true,
opacity : -2.5,
side: THREE.DoubleSide
});
var loader = new THREE.JSONLoader();
loader.load("uploads/accessories/3d/code/3dfile_"+file+".js",
function(geometry, object_material)
{
var object = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(object_material));
console.log(object);
model = new THREE.Object3D();
model.add(object);
model.position.set(obj_x,obj_y,obj_z);
model.scale.set(obj_width,obj_height,obj_rotation);
model.opacity =2;
model.rotation.y = 600;
model.duration = 12000;
model.mirroredLoop = true;
model.castShadow = true;
model.receiveShadow = true;
scene.add(model);
}
);
// alert('hi'); if i remove this comment second model is loading perfectly
return true;
}
also tried to load the object's by id using Object3D.getObjectById() this is also fails
i know this is about the asynchronous problem, but i can't get ride of this, any help on this?
The problem are the globals.
Here a nice reading about Why is Global State so Evil?.
update
I played around a bit with a code similar to your, and I see now what could be what it seem a problem, but it isn't really, you can use an approach like this:
/* object declaration and initialization on load completed */
var model1;
load_file('object1', function(model) {
model1 = model;
model1.position.x = -2;
});
...
function laad_file(file, on_load_complete) {
...
loader.load("http://localhost/"+file+".js", function(geometry, object_material) {
...
scene.add(model);
/* call the callback to initialize your object */
if (on_load_complete !== undefined)
on_load_complete(model);
});
...
}
render() {
...
if (model1 !== undefined)
model1.rotation.x += 0.1;
...
}
Seems like your problem is that renderer not firing after model added to the scene. Try to call it after model added to the scene at your callback function:
scene.add(model);
renderer.render(scene, camera);
I have a problem with an object not drawing it's image. I've set the onload property of the image to the draw function..
//ctor
function Sprite(someargs,pContext)
this.setContext(pContext); //This could be the problem?
this.setX(px);
this.setY(py);
this.setTexture(pImagePath);
//I run this in the constructor
Sprite.prototype.setTexture = function(pImagePath){
this.texture = new Image();
this.texture.onload = this.draw();
this.texture.src = pImagePath;
};
Sprite.prototype.draw = function(){
this.getContext().drawImage(this.texture,this.getX(),this.getY(),100,100);
};
Sprite.prototype.setContext = function(pContext){
this.mContext = pContext;
};
No errors at runtime, image not drawn onto canvas though.
I'v put alerts in all the above methods, all of which are being executed.
Anyone got any ideas as to why it's not drawing?
Cheers
this.texture.onload = this.draw();
you are not setting onload to the draw function but to the result of draw function
this.texture.onload = this.draw;
also wouldn't be good because you will lose your context of this in here.
this inside of draw function will point to texture instead of Sprite
you need to bind the function draw to this (which is the Sprite at the moment) and pass it to onload
this.texture.onload = this.draw.bind(this);
or:
var that = this;
this.texture.onload = function() { that.draw(); }
I try load my simple stage from json file, I load images but it's all in one layer, and image is not in group, so resize not working, i don't know how i should to load all elements with layers and group;
This is my function to load(it's only image for now)
function load(loadStage) {
counter = 2;
activeStage = stage;
stage = Kinetic.Node.create(loadStage,'right');
var background = stage.get('.background');
var backgroundImage = stage.get('.backgroundImage');
var clipartsImage = stage.get('.image');
var text = stage.get('.text');
console.log(stage.getChildren());
for(i=0;i<clipartsImage.length;i++){
counter++;
(function() {
var image = clipartsImage[i];
groups[counter] = image.parent.get;
//console.log(image);
var imageObj = new Image();
imageObj.onload = function() {
imageObj.src = image.attrs.src;
console.log(image);
image.setImage(imageObj);
image.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
image.on('mouseout', function() {
document.body.style.cursor = 'default';
});
image.on('click', function(evt) {
this.children[0].children[3].show();
var shape = evt.targetNode;
this.moveToTop();
active = layers[shape.getId()];
objectId = shape.getId();
});
image.getLayer().draw;
};
imageObj.src = image.attrs.src;
})();
stage.draw();
}
stage.draw();
}
And this is my json file, http://wklej.org/id/1105520/ this is middle stage. I'll keep trying, but if someone has had a similar problem and solved it, I would be grateful for your help :)
1)
What is going on with your JSON file? the base64 string has blown up into a million lines...
For starters, KineticJS.Layer cannot have a layer as a child. References:
https://github.com/ericdrowell/KineticJS/wiki/Change-Log#455-july-28-2013
new add() validation. An error is thrown if invalid children are added to a parent, for example, when adding a layer to another layer.
https://github.com/ericdrowell/KineticJS/wiki
KineticJS event not fired for child of a grouped layer
Inside your JSON file, you have tons of layers layered within each other, this is definitely going to cause a problem. Actually it looks like you have a layer for EACH group that you have! This is completely wrong KineticJS structure.
You should do some research on how and when to use layers and groups, here are some references:
What are the differences between group and layer in KineticJs
https://github.com/ericdrowell/KineticJS/wiki (again, the data structure hierarchy for KineticJS)
2)
No need to call stage.draw() twice.
3)
JSON is a data format, it only stores object attributes. This means it does not store any references to events attached to objects.
What this means is that when you load your JSON string, you'll have to rebind the updateAnchor function to all your anchors again. (Similar to how you are rebinding click function to your images onload)
You'll have to do something like this inside your load function, after you create the stage with your JSON file:
var children = layer.getChildren(); //Use the layer that has all your groups with images/anchors. *REMEMBER you can't layers within layers!
for (var i=0; i<children.length; i++) {
//If name starts with 'anchor'
if (children.getName().indexOf('anchor') !== -1) {
children[i].on('dragmove', function(evt) {
updateAnchor(this);
layer.draw();
});
}
}
So, my goal is to have a simple function that allows me to just type something like:
var map = new Image();
map.onloadDraw();
map.src = "images/" + worldmapCanvasShapeImage;
which will automatically refresh the canvas when loaded.
This is what I already came up with:
Image.prototype.onloadDraw = function(){
this.onload() = function() {
drawMap();
drawMarkers();
drawArticles();
}
}
It doesn't seem to work, it's probably a small error but I can't find a lot of information about it.
Image.prototype.onloadDraw = function(){
this.onload = function() {
drawMap();
drawMarkers();
drawArticles();
}
}
Skip the pair of parens after onload. You are defining it, not invoking it. :)