I am making an application using the express framework of node.js. I have to use OOP features like inheritance in my application.
I created a simple class in routes/model folder.
exports.Rectangle = function(x,y)
{
this.x = x;
this.y = y;
}
Rectangle.prototype.getArea = function()
{
return (this.x * this.y);
}
Rectangle.prototype.toString = function()
{
var tmp = "Rectangle " + this.x + " : " + this.y;
return tmp;
}
My routes/index.js is like this:
exports.index = function(req, res){
var RectangleClass = require('./model/Rectangle.js');
var rect1 = new RectangleClass.Rectangle(4,6);
console.log(rect1.getArea());
console.log("Rect: " + rect1);
res.send("hello");
};
When I run the app I get the error: 500 ReferenceError: Rectangle is not defined
The error is shown at the Rectangle.prototype.getArea = function() line in routes/model/Rectangle.js
However, if I copy paste the Rectangle class structure in my index.js file, then it is all working. But I have many classes and I do not want to define them all in one file. How can I reference objects defined in other files?
This is the problem in your initial setup:
exports.Rectangle = function(x, y) {
...
}
Rectangle.prototype.getArea = ...
exports.Rectangle doesn't magically create a variable called Rectangle in the current module, hence the undefined error when you try to use Rectangle.prototype.
There are a couple of solutions:
// one solution
var Rectangle = exports.Rectangle = function(x, y) { ... }
Rectangle.prototype.getArea = ...
// another solution
var Rectangle = function(x, y) { ... }
Rectangle.prototype.getArea = ...
exports = Rectangle;
// yet another solution
exports.Rectangle = function(x, y) { ... }
exports.Rectangle.prototype.getArea = ...
Or the one you found out yourself, although creating such a factory function isn't really necessary :)
This suddenly occurred to me. I used a getter method to create and return a Rectangle object. The following changes were made in Rectangle.js.
exports.getRectangle = function(x,y)
{
var r = new Rectangle(x,y);
return r;
}
Rectangle = function(x,y)
{
this.x = x;
this.y = y;
}
The other methods were left unchanged.
In my index.js file, instead of
var r = new RectangleClass.Rectangle(6,4);
I used
var r = RectangleClass.getRectangle(6,4);
Related
I am trying to draw a straight line making x fix using freeDrawingBrush.
For example:
canvas.isDrawingMode = 1;
canvas.freeDrawingBrush.color = "purple";
canvas.freeDrawingBrush.width = 10;
canvas._onMouseMoveInDrawingMode = function (e) {
var pointer = canvas.getPointer(e);
pointer.x = 100;
this.freeDrawingBrush.onMouseMove(pointer);
}
this doing the work but it is drawing continuously on mousemove. I want user to be able to draw multiple lines at a fix (for e.g.) x=100 at distances on y-axis.
Update:
I added following code :
canvas._onMouseUpInDrawingMode = function (e) {
this._isCurrentlyDrawing = false;
//canvas.selection = true;
canvas.isDrawingMode = 0;
this.freeDrawingBrush.onMouseUp();
this._handleEvent(e, 'up');
}
This stops drawing continuously but new problem raised. When I enable drawing mode again and try to draw new line it also add previous line to new line
After a lot of research I found the way:
var brush = new fabric.PencilBrush(canvas);
canvas.isDrawingMode = 1;
brush.width = 10;
canvas._onMouseMoveInDrawingMode = function (e) {
var pointer = canvas.getPointer(e);
pointer.x = 100;
brush.onMouseDown({x:pointer.x, y:pointer.y});
}
I'm trying to make a sketch in which a sprite animation appears when I click on another sprite. It appears on the middle of the screen and it should be able to be pushed by the mouse which also has a sprite attached to it.
As soon as I want to add the appearing-onMousePressed sprites to a group or to the mouseBlock.displace(), I get an error saying "Uncaught Error: overlap can only be checked between sprites or groups". I don't understand what I'm doing wrong. Is it because the sprites are created through a function? Or is my order of things wrong? Please help me.
var movingBlocks;
var mouseBlock;
var bb1;
var b1;
function preload() {
mouseBlock = loadImage('mouse.png');
}
function setup() {
createCanvas(windowWidth, windowHeight);
mouseBlock = createSprite(200,200);
mouseBlock.addAnimation('normal', 'mouse.png');
movingBlocks = new Group()
var b1 = createSprite(windowWidth-200,100);
b1.addAnimation('normal', 'stamps/static/BB1/1BuildingBlock0000.png','stamps/static/BB1/1BuildingBlock0001.png','stamps/static/BB1/1BuildingBlock0002.png','stamps/static/BB1/1BuildingBlock0003.png','stamps/static/BB1/1BuildingBlock0004.png','stamps/static/BB1/1BuildingBlock0005.png','stamps/static/BB1/1BuildingBlock0006.png','stamps/static/BB1/1BuildingBlock0007.png','stamps/static/BB1/1BuildingBlock0008.png','stamps/static/BB1/1BuildingBlock0009.png','stamps/static/BB1/1BuildingBlock0010.png','stamps/static/BB1/1BuildingBlock0009.png','stamps/static/BB1/1BuildingBlock0008.png','stamps/static/BB1/1BuildingBlock0007.png','stamps/static/BB1/1BuildingBlock0006.png','stamps/static/BB1/1BuildingBlock0005.png','stamps/static/BB1/1BuildingBlock0004.png','stamps/static/BB1/1BuildingBlock0003.png','stamps/static/BB1/1BuildingBlock0002.png','stamps/static/BB1/1BuildingBlock0001.png','stamps/static/BB1/1BuildingBlock0000.png');
b1.scale = 0.15;
b1.onMousePressed= function() {
var bb1 = createSprite(windowWidth/2,windowHeight/2);
bb1.addAnimation('normal', 'stamps/move/BB1Move/1BBMove0000.png','stamps/move/BB1Move/1BBMove0001.png','stamps/move/BB1Move/1BBMove0002.png','stamps/move/BB1Move/1BBMove0003.png','stamps/move/BB1Move/1BBMove0004.png','stamps/move/BB1Move/1BBMove0005.png','stamps/move/BB1Move/1BBMove0006.png','stamps/move/BB1Move/1BBMove0007.png','stamps/move/BB1Move/1BBMove0008.png','stamps/move/BB1Move/1BBMove0009.png','stamps/move/BB1Move/1BBMove0010.png','stamps/move/BB1Move/1BBMove0009.png','stamps/move/BB1Move/1BBMove0008.png','stamps/move/BB1Move/1BBMove0007.png','stamps/move/BB1Move/1BBMove0006.png','stamps/move/BB1Move/1BBMove0005.png','stamps/move/BB1Move/1BBMove0004.png','stamps/move/BB1Move/1BBMove0003.png','stamps/move/BB1Move/1BBMove0002.png','stamps/move/BB1Move/1BBMove0001.png','stamps/move/BB1Move/1BBMove0000.png');
tint(255,127);
bb1.scale = 0.4;
}
// movingBlocks.add(bb1);
}
function draw() {
background(240,240,240);
mouseBlock.position.x = mouseX;
mouseBlock.position.y = mouseY;
mouseBlock.scale=0.3;
// mouseBlock.displace(bb1);
drawSprites();
}
I've found it! I needed to change things about the order of my code. The place where I add a sprite to a group had to be relocated and then I could say mouseBlock.displace(movingBlocks);
var movingBlocks;
var mouseBlock;
var bb1;
var b1;
function preload() {
mouseBlock = loadImage('mouse.png');
}
function setup() {
createCanvas(windowWidth, windowHeight);
mouseBlock = createSprite(200,200);
mouseBlock.addAnimation('normal', 'mouse.png');
movingBlocks = new Group()
var b1 = createSprite(windowWidth-200,100);
b1.addAnimation('normal', 'stamps/static/BB1/1BuildingBlock0000.png','stamps/static/BB1/1BuildingBlock0001.png','stamps/static/BB1/1BuildingBlock0002.png','stamps/static/BB1/1BuildingBlock0003.png','stamps/static/BB1/1BuildingBlock0004.png','stamps/static/BB1/1BuildingBlock0005.png','stamps/static/BB1/1BuildingBlock0006.png','stamps/static/BB1/1BuildingBlock0007.png','stamps/static/BB1/1BuildingBlock0008.png','stamps/static/BB1/1BuildingBlock0009.png','stamps/static/BB1/1BuildingBlock0010.png','stamps/static/BB1/1BuildingBlock0009.png','stamps/static/BB1/1BuildingBlock0008.png','stamps/static/BB1/1BuildingBlock0007.png','stamps/static/BB1/1BuildingBlock0006.png','stamps/static/BB1/1BuildingBlock0005.png','stamps/static/BB1/1BuildingBlock0004.png','stamps/static/BB1/1BuildingBlock0003.png','stamps/static/BB1/1BuildingBlock0002.png','stamps/static/BB1/1BuildingBlock0001.png','stamps/static/BB1/1BuildingBlock0000.png');
b1.scale = 0.15;
b1.onMousePressed= function() {
var bb1 = createSprite(windowWidth/2,windowHeight/2);
bb1.addAnimation('normal', 'stamps/move/BB1Move/1BBMove0000.png','stamps/move/BB1Move/1BBMove0001.png','stamps/move/BB1Move/1BBMove0002.png','stamps/move/BB1Move/1BBMove0003.png','stamps/move/BB1Move/1BBMove0004.png','stamps/move/BB1Move/1BBMove0005.png','stamps/move/BB1Move/1BBMove0006.png','stamps/move/BB1Move/1BBMove0007.png','stamps/move/BB1Move/1BBMove0008.png','stamps/move/BB1Move/1BBMove0009.png','stamps/move/BB1Move/1BBMove0010.png','stamps/move/BB1Move/1BBMove0009.png','stamps/move/BB1Move/1BBMove0008.png','stamps/move/BB1Move/1BBMove0007.png','stamps/move/BB1Move/1BBMove0006.png','stamps/move/BB1Move/1BBMove0005.png','stamps/move/BB1Move/1BBMove0004.png','stamps/move/BB1Move/1BBMove0003.png','stamps/move/BB1Move/1BBMove0002.png','stamps/move/BB1Move/1BBMove0001.png','stamps/move/BB1Move/1BBMove0000.png');
tint(255,127);
bb1.scale = 0.4;
movingBlocks.add(bb1);
// mouseBlock.displace(bb1);
}
}
function draw() {
background(240,240,240);
mouseBlock.position.x = mouseX;
mouseBlock.position.y = mouseY;
mouseBlock.scale=0.3;
// for(var i=0; i<allSprites.length;i++){
// var block1 = allSprites[i];
// }
mouseBlock.displace(movingBlocks);
drawSprites();
}
Since from co#4.0+ we can use below statement
var fn = co.wrap(fn*)
to convert a generator into a regular function that returns a Promise.
Then I face a problem
a.js
var F = function *(a,b,c){
this.a = yield this.getA(a);
this.b = yield this.getB(b);
this.c = yield this.getC(c);
}
F.prototype.getA = function * (a){
//........
}
F.prototype.getB = function * (b){
//........
}
F.prototype.getC = function * (c){
//........
}
exports.F = F;
how to create a instance in b.js by co .
#Bergi said it`s a bad practice
then I want to ask anthor question
function* F(){
yield this.x = 2;
yield this.y = 3;
}
var obj = {};
var f = F.bind(obj)();
f.next();
f.next();
f.next();
console.log(obj);
// { x: 2, y: 3 }
is it a bad practice ?
I've managed to successfully drag a rectangle taking into account the mouse location using the following code (demonstrated by the small square)
When the rectangle is rotated the rectangle is dragged in parallel to the shape, please could someone show me how to correct this. I thought this could be done with a bit of trigonometry but haven't been successful to calculate the opposite (x) and adjacent(y)
A demo can be seen here http://jsbin.com/tihobu/2/edit?html,js,output
var s = Snap(400,400);
var smallSquare = s.rect(100, 100, 50,50).attr({fill:"#ffcc00"});
var bigSquare = s.rect(100,20,150,150).attr({fill:"#ff6600"});
var startx, starty;
var t = bigSquare.transform().localMatrix;
t.rotate(45);
bigSquare.transform(t);
var moveFunc = function (dx, dy, posx, posy) {
var xadj = startx - (0 - dx);
var yadj = starty - (0 - dy);
this.attr('x',xadj);
this.attr('y',yadj);
};
var startFunc = function(){
startx = this.attr('x');
starty = this.attr('y');
console.log("Move started");
};
var stopFunc = function(){};
bigSquare.drag( moveFunc,startFunc,stopFunc );
smallSquare.drag( moveFunc,startFunc,stopFunc );
thanks David
The problem is the coordinate space has been rotated, so you have a couple of options. Either work out where the new x,y would be, or use a drag with transforms rather than changing x,y. I personally would use transforms, but there may be good reasons why you want to change the x,y attributes.
Note, if you keep on working with changing the x,y attributes, you then have added issues that not all elements have this. Eg circles are positioned with cx, cy, you may have other complex elements.
Here is some code I used to make a transform handler...(edit: have changed code to cope with complex groups)
example
Snap.plugin( function( Snap, Element, Paper, global ) {
Element.prototype.globalToLocal = function( globalPoint ) {
var globalToLocal = this.node.getTransformToElement( this.paper.node ).inverse();
globalToLocal.e = globalToLocal.f = 0;
return globalPoint.matrixTransform( globalToLocal );
};
Element.prototype.getCursorPoint = function( x, y ) {
var pt = this.paper.node.createSVGPoint();
pt.x = x; pt.y = y;
return pt.matrixTransform( this.paper.node.getScreenCTM().inverse());
}
Element.prototype.altDrag = function() {
return this.drag( altMoveDrag, altStartDrag );
};
function altMoveDrag( xxdx, xxdy, ax, ay ) {
var tdx, tdy;
var cursorPoint = this.getCursorPoint( ax, ay );
var pt = this.paper.node.createSVGPoint();
pt.x = cursorPoint.x - this.data('op').x;
pt.y = cursorPoint.y - this.data('op').y;
var localPt = this.globalToLocal( pt );
this.transform( this.data('ot').toTransformString() + "t" + [ localPt.x, localPt.y ] );
};
function altStartDrag( x, y, ev ) {
this.data('ibb', this.getBBox());
this.data('op', this.getCursorPoint( x, y ));
this.data('ot', this.transform().localMatrix);
};
});
After reading a lot in order to manipulate the position of the ports, I found another problem: when I select a port that is positioned below the figure, as shown in the images.
My question is: How can I keep the ports on the top of the figure?
This is my code:
var leftLocator = new draw2d.layout.locator.InputPortLocator();
var rightLocator = new draw2d.layout.locator.OutputPortLocator();
leftLocator.relocate = function(index, figure) {
var width = figure.getParent().getWidth();
var height = figure.getParent().getHeight();
var x = width / 4;
var y = height / 2;
figure.setPosition(x, y);
}
rightLocator.relocate = function(index, figure) {
var width = figure.getParent().getWidth();
var height = figure.getParent().getHeight();
var x = width * 3 / 4;
var y = height / 2;
figure.setPosition(x, y);
}
elemento.createPort("input", leftLocator);
elemento.createPort("output", rightLocator);
I found a solution using the "toFront" method at onDragStart event:
OutputPortFigure = draw2d.OutputPort.extend({
NAME: 'OutputPortFigure',
init: function() { ... },
onMouseEnter: function() { ... },
onMouseLeave: function() { ... },
onDragStart: function(x, y, shiftKey, ctrlKey) {
this._super(x, y, shiftKey, ctrlKey);
this.toFront(this.getParent());
},
});
I was having the same problem with some of my figures.
I found a solution that can help but it's not the best one i think.
I create a hidden figure that holds the Ports (Implement repaint method to re-size the child figure when the parent one changes)
var Hidden = draw2d.SetFigure.extend({
NAME: "Hidden",
init : function()
{
this._super();
this.addPort(new draw2d.InputPort('port1'), new draw2d.layout.locator.InputPortLocator());
this.addPort(new draw2d.OutputPort('port2'), new draw2d.layout.locator.OutputPortLocator());
this.setDimension(300,150);
this.setAlpha(0);
},
onDoubleClick: function(){
}
});
var Test = draw2d.SetFigure.extend({
NAME: "Test",
init : function()
{
this._super();
this.hidden = new Hidden();
this.addFigure(this.hidden, new draw2d.layout.locator.CenterLocator(this));
this.setAlpha(0.8);
this.setDimension(300,150);
this.setRadius(10);
this.setStroke(3);
this.label.setColor("#0d0d0d");
this.label.setFontColor("#0d0d0d");
this.addFigure(this.label, new draw2d.layout.locator.CenterLocator(this));
this.tooltip = null;
},
repaint: function(attributes){
this._super(attributes);
if(this.hidden != undefined) this.hidden.setDimension(this.getWidth(), this.getHeight());
},
onDoubleClick: function(){
}
});
if you have a better solution i'll be happy to see it :)
i discovered this when i was implementing a figure that can have a loop connexion