How to properly repeat texture on .obj model? - opengl

When I load this picture on a sofa model:
I am getting this:
My texture parameters are like this:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
When I change gl.CLAMP_TO_EDGE to gl.REPEAT,
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
even this f picture is power of 2, I get the same muddy image.
Is this normal behaviour? I want to see this F repeated on the model. Such as this:

You need to show your .OBJ loading code.
Loading the same file in THREE.js and applying the same texture I get this
I used the example at the bottom of this page and then after loading the model I walked through all the nodes and applied the texture like this
const loader = new THREE.TextureLoader();
const texture = loader.load('resources/images/f-texture.png');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
root.traverse((node) => {
if (node.material) {
if (Array.isArray(node.material)) {
node.material.forEach((m) => {
m.map = texture;
});
} else {
node.material.map = texture;
}
}
});
I also wrote quick my own .OBJ loader
"use strict";
const vs = `
uniform mat4 u_worldViewProjection;
attribute vec4 position;
attribute vec2 texcoord;
varying vec2 v_texCoord;
void main() {
v_texCoord = texcoord;
gl_Position = u_worldViewProjection * position;
}
`;
const fs = `
precision mediump float;
varying vec2 v_texCoord;
uniform sampler2D u_diffuse;
void main() {
gl_FragColor = texture2D(u_diffuse, v_texCoord);
}
`;
function loadTextFile(url) {
return fetch(url).then(req => req.text());
}
function addModel(context) {
if (context.faces) {
const {faces, modelName, materialName} = context;
context.models.push({
faces, modelName, materialName,
});
context.faces = undefined;
}
}
function addDataFn(name) {
return function(context, args) {
addModel(context);
const {data} = context;
if (!data[name]) {
data[name] = {
numComponents: args.length,
data: [],
};
}
data[name].data.push(...args.map(parseFloat));
};
}
function addPropFn(name) {
return function(context, args) {
context[name] = args.join(' ');
};
}
function addFace(context, args) {
if (!context.faces) {
context.faces = [];
}
context.faces.push(args.map((vert) => {
return vert.split('/').map(v => v.length ? parseInt(v) : undefined);
}));
}
function noop() {
}
const objHandlers = {
mtllib: addPropFn('mtllib'),
v: addDataFn('position'),
vn: addDataFn('normal'),
vt: addDataFn('texcoord'),
g: addPropFn('modelName'),
o: addPropFn('modelName'),
usemtl: addPropFn('materialName'),
s: noop,
f: addFace,
};
function parseObj(objText) {
const context = {
data: {},
models: [],
};
objText.split('\n').forEach((origLine, lineNo) => {
const noCommentLine = origLine.replace(/#.*/, '');
const line = noCommentLine.trim();
if (line === '') {
return;
}
const parts = line.split(/\s+/);
const code = parts.shift();
const fn = objHandlers[code];
if (!fn) {
console.error('unknown code:', code, 'at line', lineNo + 1, ':', line);
} else {
fn(context, parts);
}
});
addModel(context);
const arrays = {};
const indices = [];
let numVerts = 0;
const vertIds = {};
const arrayNames = Object.keys(context.data);
for (const [name, src] of Object.entries(context.data)) {
arrays[name] = {
numComponents: src.numComponents,
data: [],
};
}
// for the f statement
// f v/vt/vn -> position/texcoord/normal
const channelNames = [
'position',
'texcoord',
'normal',
];
function addVertex(vertexPartIndices) {
const parts = [];
vertexPartIndices.forEach((partNdx, ndx) => {
if (partNdx !== undefined) {
parts.push(ndx, partNdx);
}
});
const vId = parts.join(',');
let vertNdx = vertIds[vId];
if (vertNdx === undefined) {
vertNdx = numVerts++;
vertIds[vId] = vertNdx;
vertexPartIndices.forEach((partNdx, ndx) => {
if (partNdx === undefined) {
return;
}
const name = channelNames[ndx];
const data = context.data[name];
const start = (partNdx - 1) * data.numComponents;
const end = start + data.numComponents;
if (end > data.data.length) {
debugger;
}
const values = data.data.slice(start, end);
if (values.length !== 3) {
debugger;
}
arrays[name].data.push(...values);
});
}
return vertNdx;
}
for (const model of context.models) {
for (const face of model.faces) {
const numVerts = face.length;
if (numVerts < 3) {
throw new Error('numVerts for face not at least 3');
}
if (numVerts > 4) {
debugger;
}
const vNdx0 = addVertex(face[0]);
for (let i = 1; i < numVerts - 1; ++i) {
indices.push(vNdx0);
indices.push(addVertex(face[i]));
indices.push(addVertex(face[i + 1]));
}
}
}
arrays.indices = {
data: new (indices.length > 65535 ? Uint32Array : Uint16Array)(indices),
};
return arrays;
}
async function main() {
const objText = await loadTextFile('models/obj/sofa/ROUND SOFA.obj');
const arrays = parseObj(objText);
const m4 = twgl.m4;
const gl = twgl.getContext(document.querySelector("#c"));
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
const bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
const tex = twgl.createTexture(gl, {
src: 'images/f-texture.png',
flipY: true,
});
const uniforms = {
u_diffuse: tex,
};
function render(time) {
time *= 0.001;
twgl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const fov = 30 * Math.PI / 180;
const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
const zNear = 1;
const zFar = 10000;
const projection = m4.perspective(fov, aspect, zNear, zFar);
const eye = [500, 2000, -3000];
const target = [0, 400, 0];
const up = [0, 1, 0];
const camera = m4.lookAt(eye, target, up);
const view = m4.inverse(camera);
const viewProjection = m4.multiply(projection, view);
const world = m4.rotationY(time);
uniforms.u_worldViewProjection = m4.multiply(viewProjection, world);
gl.useProgram(programInfo.program);
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
twgl.setUniforms(programInfo, uniforms);
twgl.drawBufferInfo(gl, bufferInfo);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
body { margin: 0; }
canvas { display: block; width: 100vw; height: 100vh; }
<canvas id="c"></canvas>
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
Sorry, can't include the model. But, it produced this
A completely random guess, looking in the .OBJ file the texture coordinates are 3D
Looking at the file itself I see the texture coordinates are 3D
vt -0.7657 0.1621 1.3290
vt -0.7585 0.1439 1.3329
vt 0.2553 0.1439 1.8866
vt 0.2553 0.1621 1.8866
vt 1.2742 0.5898 0.6789
...
Instead of the normal 2D. Checking the three.js loading code it appears to ignore the 3rd coordinate. Is it possible you're loading all 3 values for each coordinate but indexing them by 2?

Related

create custom IfcPolygonalFaceSet wall using xbim library

I want to create polygonfaceset wall using xbim toolkit library. Please let me know what I am doing wrong. It will be great help to me if anybody can provide sample code or some approach regarding polygonfaceset wall.
Below I provide scrennshot and samplecode.
static private IfcWallStandardCase CreateWall(IfcStore model, double length, double width, double height)
{
//
//begin a transaction
using (var txn = model.BeginTransaction("Create Wall"))
{
var wall = model.Instances.New();
wall.Name = "A Standard rectangular wall";
//represent wall as a rectangular profile
var rectProf = model.Instances.New<IfcRectangleProfileDef>();
rectProf.ProfileType = IfcProfileTypeEnum.AREA;
rectProf.XDim = width;
rectProf.YDim = length;
var insertPoint = model.Instances.New<IfcCartesianPoint>();
insertPoint.SetXY(0, 400); //insert at arbitrary position
rectProf.Position = model.Instances.New<IfcAxis2Placement2D>();
rectProf.Position.Location = insertPoint;
var polyfaceset = model.Instances.New<IfcPolygonalFaceSet>();
var coordinates2 = model.Instances.New<IfcIndexedPolygonalFace>();
//var coordinates = model.Instances.New<IfcCartesianPointList3D>(pl => {
// pl.CoordList.GetAt(0).AddRange(new IfcLengthMeasure[] { 0, 0, 0 });
// pl.CoordList.GetAt(1).AddRange(new IfcLengthMeasure[] { 1, 0, 0 });
// pl.CoordList.GetAt(2).AddRange(new IfcLengthMeasure[] { 0, 1, 0 });
// pl.CoordList.GetAt(3).AddRange(new IfcLengthMeasure[] { 0, 0, 1 });
//});
polyfaceset.Closed = true;
polyfaceset.Coordinates = model.Instances.New<IfcCartesianPointList3D>(pl => {
pl.CoordList.GetAt(0).AddRange(new IfcLengthMeasure[] { 0, 0, 1000 });
pl.CoordList.GetAt(1).AddRange(new IfcLengthMeasure[] { 3000, 0, 1000 });
pl.CoordList.GetAt(2).AddRange(new IfcLengthMeasure[] { 3000, 2000, 10000 });
pl.CoordList.GetAt(3).AddRange(new IfcLengthMeasure[] { 1000, 3000, 1000 });
pl.CoordList.GetAt(4).AddRange(new IfcLengthMeasure[] { 0, 2000, 1000 });
});
//model as a swept area solid
var body = model.Instances.New<IfcExtrudedAreaSolid>();
body.Depth = height;
body.SweptArea = rectProf;
body.ExtrudedDirection = model.Instances.New<IfcDirection>();
body.ExtrudedDirection.SetXYZ(0, 0, 1);
//parameters to insert the geometry in the model
var origin = model.Instances.New<IfcCartesianPoint>();
origin.SetXYZ(0, 0, 0);
body.Position = model.Instances.New<IfcAxis2Placement3D>();
body.Position.Location = origin;
//Create a Definition shape to hold the geometry
var shape = model.Instances.New<IfcShapeRepresentation>();
var modelContext = model.Instances.OfType<IfcGeometricRepresentationContext>().FirstOrDefault();
shape.ContextOfItems = modelContext;
shape.RepresentationType = "SweptSolid";
shape.RepresentationIdentifier = "Body";
shape.Items.Add(body);
//create visual style
model.Instances.New<IfcStyledItem> (styleItem => {
styleItem.Item = body;
styleItem.Styles.Add(model.Instances.New<IfcSurfaceStyle>(style => {
style.Side = IfcSurfaceSide.BOTH;
style.Styles.Add(model.Instances.New<IfcSurfaceStyleRendering>(rendering => {
rendering.SurfaceColour = model.Instances.New<IfcColourRgb>(colour => {
colour.Name = "Orange";
colour.Red = 1.0;
colour.Green = 0.5;
colour.Blue = 0.0;
});
}));
}));
});
//Create a Product Definition and add the model geometry to the wall
var rep = model.Instances.New<IfcProductDefinitionShape>();
rep.Representations.Add(shape);
wall.Representation = rep;
//now place the wall into the model
var lp = model.Instances.New<IfcLocalPlacement>();
var ax3D = model.Instances.New<IfcAxis2Placement3D>();
ax3D.Location = origin;
ax3D.RefDirection = model.Instances.New<IfcDirection>();
ax3D.RefDirection.SetXYZ(0, 1, 0);
ax3D.Axis = model.Instances.New<IfcDirection>();
ax3D.Axis.SetXYZ(0, 0, 1);
lp.RelativePlacement = ax3D;
wall.ObjectPlacement = lp;
// Where Clause: The IfcWallStandard relies on the provision of an IfcMaterialLayerSetUsage
var ifcMaterialLayerSetUsage = model.Instances.New<IfcMaterialLayerSetUsage>();
var ifcMaterialLayerSet = model.Instances.New<IfcMaterialLayerSet>();
var ifcMaterialLayer = model.Instances.New<IfcMaterialLayer>();
ifcMaterialLayer.LayerThickness = 10;
ifcMaterialLayerSet.MaterialLayers.Add(ifcMaterialLayer);
ifcMaterialLayerSetUsage.ForLayerSet = ifcMaterialLayerSet;
ifcMaterialLayerSetUsage.LayerSetDirection = IfcLayerSetDirectionEnum.AXIS2;
ifcMaterialLayerSetUsage.DirectionSense = IfcDirectionSenseEnum.NEGATIVE;
ifcMaterialLayerSetUsage.OffsetFromReferenceLine = 150;
// Add material to wall
var material = model.Instances.New<IfcMaterial>();
material.Name = "some material";
var ifcRelAssociatesMaterial = model.Instances.New<IfcRelAssociatesMaterial>();
ifcRelAssociatesMaterial.RelatingMaterial = material;
ifcRelAssociatesMaterial.RelatedObjects.Add(wall);
ifcRelAssociatesMaterial.RelatingMaterial = ifcMaterialLayerSetUsage;
// IfcPresentationLayerAssignment is required for CAD presentation in IfcWall or IfcWallStandardCase
var ifcPresentationLayerAssignment = model.Instances.New<IfcPresentationLayerAssignment>();
ifcPresentationLayerAssignment.Name = "some ifcPresentationLayerAssignment";
ifcPresentationLayerAssignment.AssignedItems.Add(shape);
// linear segment as IfcPolyline with two points is required for IfcWall
var ifcPolyline = model.Instances.New<IfcPolyline>();
var startPoint = model.Instances.New<IfcCartesianPoint>();
var midpoint = model.Instances.New<IfcCartesianPoint>();
var midpoint2 = model.Instances.New<IfcCartesianPoint>();
startPoint.SetXYZ(3000, 0, 1000);
midpoint.SetXYZ(3000, 2000, 1000);
midpoint2.SetXYZ(1000, 3000, 1000);
var endPoint = model.Instances.New<IfcCartesianPoint>();
endPoint.SetXYZ(0, 2000, 1000);
ifcPolyline.Points.Add(startPoint);
ifcPolyline.Points.Add(midpoint);
ifcPolyline.Points.Add(midpoint2);
ifcPolyline.Points.Add(endPoint);
var shape2D = model.Instances.New<IfcShapeRepresentation>();
shape2D.ContextOfItems = modelContext;
shape2D.RepresentationIdentifier = "Axis";
shape2D.RepresentationType = "Curve2D";
shape2D.Items.Add(ifcPolyline);
rep.Representations.Add(shape2D);
txn.Commit();
return wall;
}
}
This CreateWall function create Ifc wall. Please go throw it above code.

How to create custom brush paint with fabric.js?

I have been trying to create a custom brush paint with an image file using fabric JS . I have tried using the fabric.PatternBrush but this is not the exact thing that I was looking for because this creates a background pattern kind of paint and what I am trying to do is repeat the image wherever the mouse is dragged.
Can anyone please direct me towards the right way? It will be fine for me to switch to any other drawing library that does what I am looking for.
I found a solution to this problem. We can create a custom brush using fabric.BaseBrush as follows:
fabric.SprayBrush = fabric.util.createClass(fabric.BaseBrush, {
opacity: .2,
width: 30,
_baseWidth: 5,
_drips: [],
_dripThreshold: 15,
_inkAmount: 0,
_interval: 20,
_lastPoint: null,
_point: null,
_strokeId: 0,
brush: null,
brushCol : '/static/img/creation_room/textures/texture2.png',
initialize: function(canvas, opt) {
var context = this;
opt = opt || {};
this.canvas = canvas;
this.width = opt.width || canvas.freeDrawingBrush.width;
this.opacity = opt.opacity || canvas.contextTop.globalAlpha;
this.color = opt.color || canvas.freeDrawingBrush.color;
this.canvas.contextTop.lineJoin = "round";
this.canvas.contextTop.lineCap = "round";
this._reset();
fabric.Image.fromURL(this.brushCol, function(brush) {
console.log(brush);
context.brush = brush;
context.brush.filters = [];
context.changeColor(context.color || this.color);
}, { crossOrigin: "anonymous" });
},
changeColor: function(color) {
this.color = color;
this.brush.filters[0] = new fabric.Image.filters.Tint({ color: color });
this.brush.applyFilters(this.canvas.renderAll.bind(this.canvas));
},
changeOpacity: function(value) {
this.opacity = value;
this.canvas.contextTop.globalAlpha = value;
},
onMouseDown: function(pointer) {
this._point = new fabric.Point(pointer.x, pointer.y);
this._lastPoint = this._point;
this.size = this.width + this._baseWidth;
this._strokeId = +new Date();
this._inkAmount = 0;
this.changeColor(this.color);
this._render();
},
onMouseMove: function(pointer) {
this._lastPoint = this._point;
this._point = new fabric.Point(pointer.x, pointer.y);
},
onMouseUp: function(pointer) {
},
_render: function() {
var context = this;
setTimeout(draw, this._interval);
function draw() {
var point, distance, angle, amount, x, y;
point = new fabric.Point(context._point.x || 0, context._point.y || 0);
distance = point.distanceFrom(context._lastPoint);
angle = point.angleBetween(context._lastPoint);
amount = (100 / context.size) / (Math.pow(distance, 2) + 1);
context._inkAmount += amount;
context._inkAmount = Math.max(context._inkAmount - distance / 10, 0);
if (context._inkAmount > context._dripThreshold) {
context._drips.push(new fabric.Drip(context.canvas.contextTop, point, context._inkAmount / 2, context.color, context._strokeId));
context._inkAmount = 0;
}
x = context._lastPoint.x + Math.sin(angle) - context.size / 2;
y = context._lastPoint.y + Math.cos(angle) - context.size / 2;
context.canvas.contextTop.drawImage(context.brush._element, x, y, context.size, context.size);
if (context.canvas._isCurrentlyDrawing) {
setTimeout(draw, context._interval);
} else {
context._reset();
}
}
},
_reset: function() {
this._drips.length = 0;
this._point = null;
this._lastPoint = null;
}
});
Now, we just need to use this brush in the canvas.
var canvas = new fabric.Canvas('canvas');
canvas.freeDrawingBrush = new fabric.SprayBrush(canvas, { width: 70,opacity: 0.6, color: "transparent" });

Famous Engine Physics Collisions

I am building a site which requires a physics engine.
Having worked with a number of SPA apps i feel pretty confident with.
Unfortunately I am having trouble applying collision detection & walls to a physics simulation that famous has created.
You can see the editable example here.
https://staging.famous.org/examples/index.html?block=gravity3d&detail=false&header=false
What I would like to know is it possible to add collisions to the particles? I have tried this but it appears the collisions are not setup correctly. I was hoping someone has managed to do it successfully.
Thanks!
var FamousEngine = famous.core.FamousEngine;
var Camera = famous.components.Camera;
var DOMElement = famous.domRenderables.DOMElement;
var Gravity3D = famous.physics.Gravity3D;
var Gravity1D = famous.physics.Gravity1D;
var MountPoint = famous.components.MountPoint;
var PhysicsEngine = famous.physics.PhysicsEngine;
var Physics = famous.physics;
var Wall = famous.physics.Wall;
var Position = famous.components.Position;
var Size = famous.components.Size;
var Sphere = famous.physics.Sphere;
var Vec3 = famous.math.Vec3;
var Collision = famous.physics.Collision;
function Demo() {
this.scene = FamousEngine.createScene('#socialInteractive');
this.camera = new Camera(this.scene);
this.camera.setDepth(1000);
this.simulation = new PhysicsEngine();
this.items = [];
this.collision = new Collision();
var Wall = famous.physics.Wall;
var rightWall = new Wall({
direction: Wall.LEFT
}); // bodies coming from the left will collide with the wall
rightWall.setPosition(1000, 0, 0);
var ceiling = new Wall({
normal: [0, 1, 0],
distance: 300,
restitution: 0
});
var floor = new Wall({
normal: [0, -1, 0],
distance: 300,
restitution: 0
});
var left = new Wall({
normal: [1, 0, 0],
distance: 350,
restitution: 0
});
var right = new Wall({
normal: [-1, 0, 0],
distance: 350,
restitution: 0
});
var node = this.scene.addChild();
var position = new Position(node);
// this.simulation.attach([right, left, floor, ceiling])
// this.items.push([ceiling,position]);
for (var i = 0; i < 10; i++) {
var node = this.scene.addChild();
var size = new Size(node).setMode(1, 1);
var position = new Position(node);
if (i === 0) {
createLogo.call(this, node, size, position);
}
if (i !== 0) {
node.id = i;
createSatellites.call(this, node, size, position);
}
}
FamousEngine.requestUpdateOnNextTick(this);
console.log(this.collision)
for (var i = 0; i < this.collision.length; i++) {
this.simulation.attach(collision, balls, balls[i]);
}
this.simulation.addConstraint(this.collision);
}
Demo.prototype.onUpdate = function(time) {
this.simulation.update(time);
this.collision.update(time, 60);
if (this.items.length > 0) {
for (var i = 0; i < this.items.length; i++) {
var itemPosition = this.simulation.getTransform(this.items[i][0]).position;
this.items[i][1].set(itemPosition[0], itemPosition[1], 0);
}
}
FamousEngine.requestUpdateOnNextTick(this);
};
function createLogo(node, size, position) {
size.setAbsolute(50, 50);
var mp = new MountPoint(node).set(0.5, 0.5);
var el = new DOMElement(node, {
tagName: 'img',
attributes: {
src: './images/famous-logo.svg'
}
});
var sphere = new Sphere({
radius: 100,
mass: 10000,
restrictions: ['xy'],
position: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 5)
});
this.gravity = new Gravity3D(sphere);
this.simulation.add(sphere, this.gravity);
this.items.push([sphere, position]);
}
function createSatellites(node, size, position, i) {
size.setAbsolute(20, 20);
var radius = 200;
var x = Math.floor(Math.random() * radius * 2) - radius;
var y = (Math.round(Math.random()) * 2 - 1) * Math.sqrt(radius * radius - x * x);
var color = 'rgb(' + Math.abs(x) + ',' + Math.abs(Math.round(y)) + ',' + (255 - node.id) + ')';
var el = new DOMElement(node, {
properties: {
'background-color': color,
'border-radius': '50%'
}
});
var satellite = new Sphere({
radius: 20,
mass: 5,
position: new Vec3(x + window.innerWidth / 2, y + window.innerHeight / 2, 0)
});
satellite.setVelocity(-y / Math.PI, -x / Math.PI / 2, y / 2);
this.gravity.addTarget(satellite);
this.simulation.add(satellite);
this.items.push([satellite, position]);
this.collision.addTarget(satellite);
}
// Boilerplate
FamousEngine.init();
// App Code
var demo = new Demo();
Thanks for your help Talves, I think i found a solution that works with physics Spring instead of gravity3d. This also has the 4 walls included which seems to work well.
var famous = famous;
var FamousEngine = famous.core.FamousEngine;
var Camera = famous.components.Camera;
var DOMElement = famous.domRenderables.DOMElement;
var Gravity3D = famous.physics.Gravity3D;
var MountPoint = famous.components.MountPoint;
var PhysicsEngine = famous.physics.PhysicsEngine;
var Position = famous.components.Position;
var Size = famous.components.Size;
var Wall = famous.physics.Wall;
var Sphere = famous.physics.Sphere;
var Vec3 = famous.math.Vec3;
var math = famous.math;
var physics = famous.physics;
var collision = famous.physics.Collision;
var gestures = famous.components.GestureHandler;
var Spring = famous.physics.Spring;
console.log(famous)
var anchor = new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0);
//Create Walls
var rightWall = new Wall({
direction: Wall.LEFT
}).setPosition(window.innerWidth - 20, 0, 0);
var leftWall = new Wall({
direction: Wall.RIGHT
}).setPosition(window.innerWidth + 20, 0, 0);
var topWall = new Wall({
direction: Wall.DOWN
}).setPosition(0, 20, 0);
var bottomWall = new Wall({
direction: Wall.UP
}).setPosition(0, window.innerHeight - 20, 0);
function Demo() {
this.scene = FamousEngine.createScene('body');
this.camera = new Camera(this.scene);
this.camera.setDepth(1000);
this.collision = new collision([rightWall, leftWall, topWall, bottomWall]);
this.simulation = new PhysicsEngine();
this.simulation.setOrigin(0.5, 0.5);
this.simulation.addConstraint(this.collision);
this.items = [];
this.walls = [];
//Create Items
for (var i = 0; i < 30; i++) {
var node = this.scene.addChild();
node.setMountPoint(0.5, 0.5);
var size = new Size(node).setMode(1, 1);
var position = new Position(node);
if (i === 0) {
createLogo.call(this, node, size, position);
}
if (i !== 0) {
node.id = i;
createSatellites.call(this, node, size, position);
}
}
//Create Walls
var node = this.scene.addChild();
createWalls(node);
FamousEngine.requestUpdateOnNextTick(this);
Demo.prototype.onUpdate = function(time) {
this.simulation.update(time);
//Postition walls
var wallPosition = topWall.getPosition();
node.setPosition(wallPosition.x, wallPosition.y);
//Position elements
if (this.items.length > 0) {
for (var i = 0; i < this.items.length; i++) {
var itemPosition = this.simulation.getTransform(this.items[i][0]).position;
this.items[i][1].set(itemPosition[0], itemPosition[1], 0);
}
}
FamousEngine.requestUpdateOnNextTick(this);
};
}
function createWalls(wallNode) {
wallNode.setSizeMode('absolute', 'absolute', 'absolute').setAbsoluteSize(window.innerWidth, 10, 0);
var wallDOMElement = new DOMElement(wallNode, {
tagName: 'div'
}).setProperty('background-color', 'lightblue');
}
function createLogo(node, size, position) {
size.setAbsolute(50, 50);
var mp = new MountPoint(node).set(0.5, 0.5);
var el = new DOMElement(node, {
tagName: 'img',
attributes: {
src: './images/famous_logo.png'
}
});
var sphere = new Sphere({
radius: 100,
mass: 10000,
restrictions: ['xy'],
position: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 5)
});
// this.gravity = new Gravity3D(sphere);
// this.simulation.add(sphere, this.gravity);
this.simulation.add(sphere);
this.items.push([sphere, position]);
}
function createSatellites(node, size, position, i) {
size.setAbsolute(50, 50);
var radius = 100;
var x = Math.floor(Math.random() * radius * 2) - radius;
var y = (Math.round(Math.random()) * 2 - 1) * Math.sqrt(radius * radius - x * x);
var color = 'rgb(' + Math.abs(x) + ',' + Math.abs(Math.round(y)) + ',' + (255 - node.id) + ')';
var el = new DOMElement(node, {
properties: {
'background-color': color,
'border-radius': '50%'
}
});
var satellite = new Sphere({
radius: 25,
mass: 10,
position: new Vec3(x + window.innerWidth / 2, y + window.innerHeight / 2, 0)
});
// Attach the box to the anchor with a `Spring` force
var spring = new Spring(null, satellite, {
stiffness: 95,
period: 0.6,
dampingRatio: 1.0,
anchor: anchor
});
//console.log(color);
// satellite.setVelocity(-y / Math.PI, -x / Math.PI / 2, y / 2);
satellite.setVelocity(0.5, 0.5, 0);
// this.gravity.addTarget(satellite);
this.simulation.add(satellite, spring);
this.items.push([satellite, position]);
this.collision.addTarget(satellite);
}
// Boilerplate
FamousEngine.init();
// App Code
var demo = new Demo();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Famous :: Seed Project</title>
<link rel="icon" href="favicon.ico?v=1" type="image/x-icon">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html, body {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
body {
position: absolute;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
-webkit-perspective: 0;
perspective: none;
overflow: hidden;
}
</style>
</head>
<body>
<script src="http://code.famo.us/famous/0.6.2/famous.min.js"></script>
</body>
</html>

Kinetic JS Drawing Shapes and Zoom in and out

I am trying to draw different shapes on top of an image using KineticJS and zoom in and out using different buttons, each element works well by itsetlf but when I combine all functions on the same page none works. Here is the script for drawing a line:
if (drawnewline) {
document.getElementById('dLine').onclick = function() {
layer.on("mousedown", function () {
if (moving) {
moving = false;
layer.draw();
} else {
var mousePos = stage.getMousePosition();
x1 = mousePos.x;
y1 = mousePos.y;
line = new Kinetic.Line({
points: [0, 0, 50, 50],
stroke: "red"
});
layer.add(line);
line.getPoints()[0].x = mousePos.x;
line.getPoints()[0].y = mousePos.y;
line.getPoints()[1].x = mousePos.x;
line.getPoints()[1].y = mousePos.y;
moving = true;
layer.drawScene();
}
});
layer.on("mousemove", function () {
if (moving) {
var mousePos = stage.getMousePosition();
var x = mousePos.x;
var y = mousePos.y;
line.getPoints()[1].x = mousePos.x;
line.getPoints()[1].y = mousePos.y;
moving = true;
layer.drawScene();
}
});
layer.on("mouseup", function () {
moving = false;
var mousePos = stage.getMousePosition();
x2 = mousePos.x;
y2 = mousePos.y;
$("#distance").val(calculateDistance(x1, y1, x2, y2));
});
};
};
The complete script can be viewed at http://jsfiddle.net/MEQxq/. I would appreciate your suggestions, and thanks in advance.
I solved the issue by moving "if (drawnewline)" inside getElementById! Also remove mouse actions for example layer.off('mousemove');.

raphael plot points in europe map

Hi,
i have a european raphael map.Now I would like to plot points on
certain cities in the map.i tried by converting latitude n longitude
to plot points in it.But unfortunately it is plotting somewhere
else.is it like we should have world map to plot points??here is my
code.
script type="text/javascript" charset="utf-8">
$(document).ready(function() {
var rsr = Raphael('map', '631', '686');
var attr = {
fill: "#C0C0C0",
stroke: "#666",
"stroke-width": 1,
"stroke-linejoin": "round"
};
var world = {};
world.Portugal = rsr.path("56,0.133-1.32,0.527c-0.661,1.321-0.264,2.906- 0.925,4.228c-0.528,1.057-3.698,5.415-3.434,6.868c0.132,0.526,1.056-0.529,1.584-0.529c0.792-0.132,1.585,0.133,2.377,0c0.396,0,0.792-0.396,1.188-0.264
c2.113,0.527,8.981,5.019,9.906,4.887c0.396,0,4.49-1.981,4.754-2.113C57.876,621.536,58.537,621.536,59.197,621.536L59.197,621.536
z").attr(attr);
world.Spain = rsr.path(" M194.57,552.728c0.924,0.396,1.981,0.63.434,4.754c-,0,0.792,0 c0.661,0.133,1.453,0.133,1.849,0.528c0.66,0.528,0.264,1.717,0.924,2.113v0.132C190.74,552.066,190.476,553.916,194.57,552.728
L194.57,552.728z").attr(attr);
var current = null;
for(var country in world) {
(function (st, country) {
country = country.toLowerCase();
st[0].style.cursor = "pointer";
st[0].onmouseover = function () {
st.animate({fill:"#808080", stroke: "#ccc"}, 500);
};
st[0].onmouseout = function () {
st.animate({fill: "#C0C0C0", stroke: "#666"}, 500);
st.toFront();
R.safari();
};
st[0].onclick = function () {
st.toFront();
st.animate({
fill: '#808080',
transform: 's1.5 '
}, 1000);
};
})(world[country], country);
}
});
var cities = {};//here i define the cities with lat n long but both draws in thesame point all time
cities.rome = plot(55.70466,13.19101,1);
cities.copenhagen = plot(55.676097,12.568337,1);
var city_attr = {
fill:"#FF7F50",
stroke:"#666",
opacity: .3
};
function plot(lat,lon,size) {
size = size * .5 + 4;
return rsr.circle(lon2x(lon),lat2y(lat),size).attr(city_attr);
}
function lon2x(lon) {
var xfactor = 1.5255;
var xoffset = 263.58;
var x = (lon * xfactor) + xoffset;
return x; } function lat2y(lat) {
var yfactor = -1.5255;
var yoffset = 130.5;
var y = (lat * yfactor) + yoffset;
return y; }
});
var myMarker = rsr.ellipse(513.859,35.333, 7, 7).attr({
stroke: "none",
opacity: .7,
fill: "#f00"
});
The coordinates in which the map is coded seem rather arbitrary. If that is so, there is no [easy] way to determine the mapping automatically. I would suggest taking a bounding box of the vector image in it's own coordinate system and a corresponding bounding box in lat/long coordinates on a regular map and deriving the mapping from that, at least as a first approximation.