How to assign variables in loop For NodeJS - node.js

I have an array called req.body.items, which contains always one or more items. And I have to assign some variables according to the quantity of items that it has, like this:
for (x in req.body.items.length) {
var width = req.body.items[x].dimensions.width * 100;
var height = req.body.items[x].dimensions.height * 100;
var weight = req.body.items[x].dimensions.weight;
var depth = req.body.items[x].dimensions.depth * 100;
var quantity = req.body.items[x].quantity;
var sku = req.body.items[x].sku;
};
The problem is that I will have as many "widthes" as items, so if I have 3 items, I must have 3 widthes. And I don't know how to do so. I have searched this, but I only found in Javascript for frontend, I need it to create an API.
It could be just like var width0, var width1, var width2, etc.

let req={
body: {
items: [
{
dimensions: {
width: 1,
height:3,
weight:4,
quantity:7
}
},
{
dimensions: {
width: 5,
height:2,
weight:6,
quantity:8
}
}
]
}
}
let dimensions = req.body.items.reduce((result,item)=>{
Object.entries(item.dimensions).map(([key,value])=>(!!result[key] ? result[key]=[...result[key], value*100]: result[key]=[value*100]));
return result;
},{});
console.log(dimensions);

I believe you need something like this:
var width = [];
var height = [];
var weight = [];
var depth = [];
var quantity = [];
var sku = [];
for (let x in req.body.items.length) {
width.push(req.body.items[x].dimensions.width * 100);
height.push(req.body.items[x].dimensions.height * 100);
weight.push(req.body.items[x].dimensions.weight);
depth.push(req.body.items[x].dimensions.depth * 100);
quantity.push(req.body.items[x].quantity);
sku.push(req.body.items[x].sku);
};
Now, width, height ... are arrays conaining your data.

Related

Make zoom images slideshow on canvas

i am trying to making zoomin images slideshow using pixijs on canvas from three images like this
I tried but not succeed. My question in how to add zoomin or zoomout image in pixijs for specific width and height, then second image and so on.
I am writing this code
var pixiapp;
var pixiloader = PIXI.Loader.shared;
initpixiapp();
function initpixiapp() {
pixiapp = new PIXI.Application({ width: 1280, height: 720 });
document.getElementById('canvas-container').appendChild(pixiapp.view);
pixiloader.add('images/img1.png').add('images/img2.png').add('images/img3.png').load(handleimagesload);
}
function handleimagesload() {
var imagessprites=[]
var img1 = new PIXI.Sprite(pixiloader.resources['images/img1.png'].texture);
var img2 = new PIXI.Sprite(pixiloader.resources['images/img2.png'].texture);
var img3 = new PIXI.Sprite(pixiloader.resources['images/img3.png'].texture);
imagessprites.push(img1)
imagessprites.push(img2)
imagessprites.push(img3);
for (let index = 0; index < imagessprites.length; index++) {
const element = imagessprites[index];
pixiapp.stage.addChild(element);
// here will the the code to run zoom image to specific width and heigth and then move to next image,
// here is my code, its only display zooming third image
var ticker = new PIXI.Ticker();
ticker.add(() => {
console.log('ticker called')
element.width += 1;
element.height += 1;
if(element.width==1500)
{
ticker.stop()
}
})
ticker.start()
}
}
One more things, how to display a box with text for three seconds before slideshow start.
Try something like this:
var pixiapp;
var pixiloader = PIXI.Loader.shared;
initpixiapp();
function initpixiapp() {
pixiapp = new PIXI.Application({ width: 1280, height: 720 });
document.getElementById('canvas-container').appendChild(pixiapp.view);
pixiloader
.add('images/img1.png')
.add('images/img2.png')
.add('images/img3.png')
.load(handleimagesload);
}
function handleimagesload() {
var imagessprites = [];
var img1 = new PIXI.Sprite(pixiloader.resources['images/img1.png'].texture);
var img2 = new PIXI.Sprite(pixiloader.resources['images/img2.png'].texture);
var img3 = new PIXI.Sprite(pixiloader.resources['images/img3.png'].texture);
imagessprites.push(img1);
imagessprites.push(img2);
imagessprites.push(img3);
// Put first image on stage:
var currentImageIndex = 0;
var currentImage = imagessprites[currentImageIndex];
pixiapp.stage.addChild(currentImage);
var ticker = new PIXI.Ticker();
// Start "main animation loop":
ticker.add(() => {
currentImage.width += 1;
currentImage.height += 1;
if (currentImage.width >= 1500) {
// remove current image from stage:
pixiapp.stage.removeChild(currentImage);
// Move to next image:
// Increase index - but if it reached maximum then go back to 0 (to first image)
currentImageIndex++;
if (currentImageIndex >= imagessprites.length) {
currentImageIndex = 0;
}
currentImage = imagessprites[currentImageIndex];
// Set initial width and height of image (TODO: adjust this)
currentImage.width = 1000;
currentImage.height = 1000;
// put image on stage:
pixiapp.stage.addChild(currentImage);
}
});
ticker.start()
}

Paper.js How to morph one path to another path?

So, i have 2 paths:
var path1 = "M2337.8,0.1c-346.8,7.6-415.8,270.8-934.3,244.7 c-330.4-16.6-389.1-110.8-677.8-101.3c-321,10.5-403.4,252.6-592.3,252.6C73,396.1,29.8,372.8,0,341.9v451.8h2778V200 C2692.9,103.1,2538.6-4.3,2337.8,0.1z",
path2 = M2337.8,326.3C1991,333.9,1845,45.9,1472,45.9 c-334.4,0-390,181.9-639,181.9C473,227.8,400.3,0,195.7,0C84.5,0,0,98.3,0,146.1v562.6h2778V62.9 C2686,199.8,2538.6,321.9,2337.8,326.3z
Can i animate it using paper.js?
Thank's.
Here is the algorithm I used in one of my previous project:
make sure both path has the same number of points
(optional) add extra points in both paths for a smoother morphing
interpolate each point and its handles based on original paths values
Look at this Sketch for a demonstration.
// create paths
var pathB = new Path.Circle(view.center, 200);
var pathA = new Path.Rectangle(view.center - 100, new Size(200));
var morphingPath = new MorphingPath(pathA, pathB);
// apply some styling
pathA.strokeColor = 'red';
pathB.strokeColor = 'blue';
morphingPath.path.fullySelected = true;
// animate morphing
function onFrame(event)
{
// with values from 0 to 1
morphingPath.morph(Math.abs(Math.sin(event.count * 0.01)));
}
/**
* A path that can be morphed between two other paths.
* #param {Path} path1
* #param {Path} path2
* #constructor
*/
function MorphingPath(path1, path2)
{
// internal variables
var self = this,
clone1,
clone2;
//
// API
//
// allow direct access to morphing path
self.path = null;
/**
* interpolate path from path1 to path2
* #param time must be a value from 0 to 1
*/
self.morph = function (time)
{
var segments = [];
for (var i = 0; i < self.path.segments.length; i++)
{
// morph segments
var segment1 = clone1.segments[ i ],
segment2 = clone2.segments[ i ],
point = rampPoint(segment1.point, segment2.point, time),
handleIn = rampPoint(segment1.handleIn, segment2.handleIn, time),
handleOut = rampPoint(segment1.handleOut, segment2.handleOut, time);
segments.push(new Segment(point, handleIn, handleOut));
}
self.path.segments = segments;
};
//
// INTERNAL METHODS
//
function init()
{
// store local copies of source paths
clone1 = path1.clone();
clone2 = path2.clone();
// hide them
clone1.visible = false;
clone2.visible = false;
// init morphing path
self.path = createMorphingPath();
}
/**
* Create the path that will later be morphed.
* Points are added when needed, for a smoother result.
* #returns {Path}
*/
function createMorphingPath()
{
var paths = [ clone1, clone2 ],
offsets = [ [], [] ];
// store paths segments offsets (except for first and last)
for (var i = 0; i < paths.length; i++)
{
var path = paths[ i ];
// loop segments
for (var j = 1; j < path.segments.length - 1; j++)
{
// store offset
offsets[ i ].push(path.segments[ j ].location.offset);
}
}
// add missing points
for (var i = 0; i < paths.length; i++)
{
// get current path offsets array
var pathOffsets = offsets[ i ];
// get a reference to the other path
var otherPath = i == 0 ? paths[ i + 1 ] : paths[ 0 ];
// loop current path offsets
for (var j = 0; j < pathOffsets.length; j++)
{
// add a corresponding point for that offset in the other path
otherPath.divideAt(otherPath.getLocationAt(pathOffsets[ j ]));
}
}
return clone1.clone();
}
function rampPoint(p1, p2, t)
{
return p1 + (p2 - p1) * t;
}
init();
}

Calculate the bounding box of STL file with JavaScript

So I am using this npm package: node-stl
And its working great. However the regexp syntax, mathematics and geometrical calculations are somewhat confusing to me. Especially all at the same time.
Basically what I want to achieve is to extend the script to calculate the bounding box of the STL.
Here is the main file that calculates the volume and weight of the STL being parsed/read.
var fs = require('fs');
// Vertex
function Vertex (v1,v2,v3) {
this.v1 = Number(v1);
this.v2 = Number(v2);
this.v3 = Number(v3);
}
// Vertex Holder
function VertexHolder (vertex1,vertex2,vertex3) {
this.vert1 = vertex1;
this.vert2 = vertex2;
this.vert3 = vertex3;
}
// transforming a Node.js Buffer into a V8 array buffer
function _toArrayBuffer (buffer) {
var
ab = new ArrayBuffer(buffer.length),
view = new Uint8Array(ab);
for (var i = 0; i < buffer.length; ++i) {
view[i] = buffer[i];
}
return ab;
}
// calculation of the triangle volume
// source: http://stackoverflow.com/questions/6518404/how-do-i-calculate-the-volume-of-an-object-stored-in-stl-files
function _triangleVolume (vertexHolder) {
var
v321 = Number(vertexHolder.vert3.v1 * vertexHolder.vert2.v2 * vertexHolder.vert1.v3),
v231 = Number(vertexHolder.vert2.v1 * vertexHolder.vert3.v2 * vertexHolder.vert1.v3),
v312 = Number(vertexHolder.vert3.v1 * vertexHolder.vert1.v2 * vertexHolder.vert2.v3),
v132 = Number(vertexHolder.vert1.v1 * vertexHolder.vert3.v2 * vertexHolder.vert2.v3),
v213 = Number(vertexHolder.vert2.v1 * vertexHolder.vert1.v2 * vertexHolder.vert3.v3),
v123 = Number(vertexHolder.vert1.v1 * vertexHolder.vert2.v2 * vertexHolder.vert3.v3);
return Number(1.0/6.0)*(-v321 + v231 + v312 - v132 - v213 + v123);
}
// parsing an STL ASCII string
function _parseSTLString (stl) {
var totalVol = 0;
// yes, this is the regular expression, matching the vertexes
// it was kind of tricky but it is fast and does the job
var vertexes = stl.match(/facet\s+normal\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+outer\s+loop\s+vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+endloop\s+endfacet/g);
vertexes.forEach(function (vert) {
var preVertexHolder = new VertexHolder();
vert.match(/vertex\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s+([-+]?\b(?:[0-9]*\.)?[0-9]+(?:[eE][-+]?[0-9]+)?\b)\s/g).forEach(function (vertex, i) {
var tempVertex = vertex.replace('vertex', '').match(/[-+]?[0-9]*\.?[0-9]+/g);
var preVertex = new Vertex(tempVertex[0],tempVertex[1],tempVertex[2]);
preVertexHolder['vert'+(i+1)] = preVertex;
});
var partVolume = _triangleVolume(preVertexHolder);
totalVol += Number(partVolume);
})
var volumeTotal = Math.abs(totalVol)/1000;
return {
volume: volumeTotal, // cubic cm
weight: volumeTotal * 1.04 // gm
}
}
// parsing an STL Binary File
// (borrowed some code from here: https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/STLLoader.js)
function _parseSTLBinary (buf) {
buf = _toArrayBuffer(buf);
var
headerLength = 80,
dataOffset = 84,
faceLength = 12*4 + 2,
le = true; // is little-endian
var
dvTriangleCount = new DataView(buf, headerLength, 4),
numTriangles = dvTriangleCount.getUint32(0, le),
totalVol = 0;
for (var i = 0; i < numTriangles; i++) {
var
dv = new DataView(buf, dataOffset + i*faceLength, faceLength),
normal = new Vertex(dv.getFloat32(0, le), dv.getFloat32(4, le), dv.getFloat32(8, le)),
vertHolder = new VertexHolder();
for(var v = 3; v < 12; v+=3) {
var vert = new Vertex(dv.getFloat32(v*4, le), dv.getFloat32((v+1)*4, le), dv.getFloat32( (v+2)*4, le ) );
vertHolder['vert'+(v/3)] = vert;
}
totalVol += _triangleVolume(vertHolder);
}
var volumeTotal = Math.abs(totalVol)/1000;
return {
volume: volumeTotal, // cubic cm
weight: volumeTotal * 1.04 // gm
}
}
// NodeStl
// =======
// > var stl = NodeStl(__dirname + '/myCool.stl');
// > console.log(stl.volume + 'cm^3');
// > console.log(stl.weight + 'gm');
function NodeStl (stlPath) {
var
buf = fs.readFileSync(stlPath),
isAscii = true;
for (var i=0, len=buf.length; i<len; i++) {
if (buf[i] > 127) { isAscii=false; break; }
}
if (isAscii)
return _parseSTLString(buf.toString());
else
return _parseSTLBinary(buf);
}
module.exports = NodeStl;
If anyone could help me with this it would be great. I know and it feels like it simple. That I just need to know max/min of the different directions(x,y,z) and could then calculate the bounding box.
But I do not understand what the max/min for x,y and z is here. Please answer if you have an idea.
I've made a new branch https://github.com/johannesboyne/node-stl/tree/boundingbox could you please verify whether the applied algorithm works?
Best,
Johannes
Edit: If the branch is stable -> works I'll push it into v.0.1.0 (don't know why it is still 0.0.1)

How to get individual object's width, height, left and top in selection:created event?

I am getting the values of the properties of an object(top,width...) as an object is being scaled/moved by using this function :
canvas.on('object:scaling', onObjectModification);
canvas.on('object:moving', onObjectModification);
canvas.on('object:rotating', onObjectModification);
function onObjectModification(e) {
var activeObject = e.target;
var reachedLimit = false;
objectLeft = activeObject.left,
objectTop = activeObject.top,
objectWidth = activeObject.width,
objectHeight = activeObject.height,
canvasWidth = canvas.width,
canvasHeight = canvas.height;
}
How can I get the same for each object that are being moved as a group? I need the values to be constantly changing as the object:scaling event provide.
I know of the event selection:created but I am lost how to use that to attain what I want. Any help from you guys would be highly appreciated.
Thanks
during object scaling width and height will not change. They will be the same all the time, just scaleX and scaleY will change.
You have to write a function that will iterate on possibile group sub objects.
canvas.on('object:scaling', onObjectModification);
canvas.on('object:moving', onObjectModification);
canvas.on('object:rotating', onObjectModification);
function onObjectModification(e) {
var activeObject = e.target;
if (!activeObject) {
return;
}
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var reachedLimit = false;
var objectLeft = activeObject.left;
var objectTop = activeObject.top;
// this provide scaled height and width
var objectWidth = activeObject.getWidth();
var objectHeight = activeObject.getHeight();
if (activeObject._objects) {
objs = activeObject._objects;
for (var i= 0; i < objs.length; i++) {
var obj = objs[i];
var objWidth = activeObject.getWidth() * activeObject.scaleX;
var objHeight = activeObject.getHeight() * activeObject.scaleY;
}
}
}

Draw2d js: How can I keep the ports on the top of the figure?

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

Resources