Related
Using CYpress I'm trying to simulate a signature action on one of the form I'm automating. Could someone help me understand how can I draw a line.
I'm trying below, doesn't work. Just puts a dot.
cy.get("[data-testid='xyz']").trigger('mousedown', 'center').click({release:false}).trigger('mouseup',5,5).trigger('mouseleave');
If you are getting a dot, you may get a line by adding a mousemove
cy.get("[data-testid='xyz']")
.trigger('mousedown', 'center')
.trigger('mousemove',5,5) // from center to just inside top left
.trigger('mouseup')
click({release:false}) isn't a valid option, but hopefully mousedown will stay down until mouseup,
Find your exact coordinates, Try It:
cy.get("[datatestid='xyz']").trigger('mousedown','center')
.click({release:false})
.trigger('mousemove',{ clientX: 200, clientY: 300 })
.trigger('mouseup',5,5)
.trigger('mouseleave');
Courtesy:https://softans.com/draw-a-line-using-cypress/
it's important to include the eventConstructor: 'MouseEvent' param
const draw = () => {
cy.get(CANVAS)
.should('exist')
.trigger('mousedown', {
x: 10,
y: 300,
force: true,
eventConstructor: 'MouseEvent',
})
.trigger('mousemove', {
x: 10,
y: 240,
force: true,
eventConstructor: 'MouseEvent',
})
.trigger('mouseup', {
x: 10,
y: 240,
force: true,
eventConstructor: 'MouseEvent',
});
};
I´ve been trying to enable tooltips on some imported 3D models, but it isnt working.
I already enabled tooltips in threbox, and I enabled tooltips in the options for the 3d element, as shown below.
tb = new Threebox(
map,
mbxContext,
{
realSunlight: true,
enableSelectingFeatures: true, //change this to false to disable fill-extrusion features selection
enableTooltips: true // change this to false to disable default tooltips on fill-extrusion and 3D models
}
);
var proptions = {
obj: './models/er.glb',
type: 'gltf',
scale: 10,
units: 'meters',
rotation: { x: 90, y: 0, z: 0 }, //default rotation
anchor: 'center',
adjustment: { x: 0, y: 0, z: 0.4 },
enableToltips: true
}
When i load the object i did the following:
tb.loadObj(proptions, function (model) {
model.setCoords(place);
model.addTooltip("A radar in the middle of nowhere", true);
model.setRotation({ x: 0, y: 0, z: Math.floor(Math.random() * 100) })
tb.add(model);
});
Although the object appears in the render, when I put the mouse above or i click it nothing shows the tooltip.
What am I missing ?
EDIT:
Following #jscastro response i changed the import in the top of my html page to <link href="./threebox-plugin/examples/css/threebox.css" rel="stylesheet" /> (the path is the correct to where the file is)
I also removed the enableTooltip: true in proptions.
Despite that it still does not work, Below i will leave the code as it is:
var origin = [-8.4, 41.20, 1];
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: origin,
zoom: 11,
pitch: 30,
antialias: true
});
//Things related to dateTime ommited
window.tb = new Threebox(
map,
map.getCanvas().getContext('webgl'),
{
realSunlight: true,
enableSelectingFeatures: true, //change this to false to disable fill-extrusion features selection
enableTooltips: true // change this to false to disable default tooltips on fill-extrusion and 3D models
}
);
map.on('style.load', async function () {
await importarLinhas();
// stats
// stats = new Stats();
// map.getContainer().appendChild(stats.dom);
animate();
map.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function (map, mbxContext) {
var eroptions = {
obj: './models/stationBus.fbx',
type: 'fbx',
scale: 0.01,
units: 'meters',
rotation: { x: 90, y: 20, z: 0 }, //default rotation
anchor: 'center',
adjustment: { x: -0.1, y: -0.1, z: 0.4 }
}
var poptions = {
obj: './models/Busstop.fbx',
type: 'fbx',
scale: 0.03,
units: 'meters',
rotation: { x: 90, y: 20, z: 0 }, //default rotation
anchor: 'center',
adjustment: { x: -0.1, y: -0.1, z: 0.1 }
}
var proptions = {
obj: './models/er.glb',
type: 'gltf',
scale: 2.7,
units: 'meters',
rotation: { x: 90, y: 0, z: 0 }, //default rotation
anchor: 'center',
adjustment: { x: 0, y: 0, z: 0.4 }
}
allNos.forEach((element) => { //For each one of a list that i fill first
//center of where the objects are
var place = [element.lng, element.lat, 0];
//cylinder as "base" for each one of the 3d Models
**//in here i cant do the Tooltip for the object**
const geometry = new THREE.CylinderGeometry(0.6, 0.6, 0.15, 32);
const material = new THREE.MeshLambertMaterial({ color: 0x5B5B5B });
const cylinder = new THREE.Mesh(geometry, material);
var baseOptions = {
obj: cylinder,
anchor: 'center',
adjustment: { x: 0, y: 0, z: -0.4 }
}
let base = tb.Object3D(baseOptions);
base.setCoords(place);
base.setRotation({ x: 90, y: 0, z: 0 })
//The text is just for the test
base.addTooltip("A radar in the middle of nowhere", true);
// base.castShadow = true;
window.tb.add(base);
//next i check what type of element it is
//it can only be one at the same time, so i use different models for each type
if (element.tipo === "p") {
window.tb.loadObj(poptions, function (model) {
model.setCoords(place);
model.addTooltip("A radar in the middle of nowhere", true);
model.setRotation({ x: 0, y: 0, z: Math.floor(Math.random() * 100) })
// model.castShadow = true;
window.tb.add(model);
});
}
if (element.tipo === "er") {
window.tb.loadObj(eroptions, function (model) {
model.setCoords(place);
model.addTooltip("A radar in the middle of nowhere", true);
model.setRotation({ x: 0, y: 0, z: Math.floor(Math.random() * 100) })
// model.castShadow = true;
window.tb.add(model);
});
}
if (element.tipo === "pr") {
window.tb.loadObj(proptions, function (model) {
model.setCoords(place);
model.addTooltip("A radar in the middle of nowhere", true);
model.setRotation({ x: 0, y: 0, z: Math.floor(Math.random() * 100) })
// model.castShadow = true;
window.tb.add(model);
});
}
});
},
render: function (gl, matrix) {
window.tb.setSunlight(date, origin.center);
window.tb.update();
}
})
map.addLayer(createCompositeLayer());
map.on('SelectedFeatureChange', onSelectedFeatureChange);
});
EDIT
I downloaded the page you shared in the chat, and I found many different issues and mistakes in your code.
1. You're using the wrong property to enable the selection of 3D objects, you use enableSelectingFeatures: true, //change this to false to disable fill-extrusion features selection, that is for Mapbox fill-extrusions features as said in the comment, but not for 3D models and objects, you have to use enableSelectingObjects: true. Only adding this, your problem with the tooltips on mouse over will be solved.
tb = new Threebox(
map,
mbxContext,
{
realSunlight: true,
enableSelectingObjects: true, //enable 3D models over/selection
enableTooltips: true // enable default tooltips on fill-extrusion and 3D models
}
);
But I have found other issues...
2. Your models scale initialization is too small, so you are hiding them below the big shapes you have created. The scale of your bus stop is scale: 0.01 and you define a place which is on the ground var place = [element.lng, element.lat, 0];, so it's hidden inside this CylinderGeometry
If you use scale: 1 you will see how your bus stops raises from the cylinder.
3. Same with the bus, you initialize them with scale: 1, which make them be hidden below the tubes and cylinders you have created. If you initialize them with scale: 10, and you elevate them 5 meters from the floor let truck = model.setCoords([lngB, latB, 4]); then you will see them raising.
4. Your models have a wrong initialization params mixing anchor and adjustment. anchor: center will center the pivotal center of your object properly, but then you apply negative values to x and y (which means decenter the object), and a z value that elevates the pivotal center adjustment: { x: -0.1, y: -0.1, z: 0.4 }. If you want your model on altitude use the 3rd coord in setCoords.
5. Your Cylinders and Tubes for the bus stops and bus lines are huge, and also they have the wrong init params, as you set them below the ground level -0.4 units adjustment: { x: 0, y: 0, z: -0.4 } (something supported by Mapbox but very bad resolved and producing weird effects. My recommendation would be to make them almost flat and at the ground level with no adjustment param. const geometry = new THREE.CylinderGeometry(0.6, 0.6, 0.01, 32);.
Summarizing, check all of these changes and let me know if it works.
I have a ThreeJS scene with 16 objects that are supposed to end up in a 4 by 4 square grid. However, when I run the code, I only see one of the objects. I wrote a "dump" function to show me all the current XYZ values of the mesh objects's position property, which you can see below. The values all look good to me and I believe I should see a nice 4 by 4 square grid of objects given the positioning those values present.
I am using this ThreeJS Javascript file for ThreeJS:
https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js
I am using this code to create the mesh. The mesh is a cube with initially the side facing the camera is a cat image:
function makeCatCube(catImageUrl, textureBackSide, locX, locY, locZ) {
let errPrefix = '(makeCatCube) ';
// TODO: Should we use BoxBufferGeometry here for greater speed?
let cubeGeometry = new THREE.BoxGeometry(2, 0.1, 2);
let loader = new THREE.TextureLoader();
let materialArray = [
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
// Card face.
new THREE.MeshBasicMaterial( { map: loader.load(catImageUrl) } ),
// Card back side.
new THREE.MeshBasicMaterial(
{
map: textureBackSide
}
),
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
new THREE.MeshBasicMaterial( { map: loader.load('/images/cards/white-square-400x400.png') } ),
];
cube = new THREE.Mesh( cubeGeometry, materialArray );
if (g_ShowGraphicsDebugInfo) {
console.log(errPrefix + `Setting cube position to - X: ${locX}, Y: ${locY}, Z: ${locZ}`);
}
cube.position.set(locX, locZ, locY);
// TODO: Magic number to set the cube's X rotation so it looks flat facing the viewer.
cube.rotation.x = THREE.Math.radToDeg(60);
return cube;
}
Here is the main promise that builds all the game assets and shows where I add the mesh objects to the scene. The global g_aryCatCards array that contains all the cat cards that were built is prepared in a much larger module elsewhere. It contains each of the cat cards and each card has a meshThreeJS property that contains the ThreeJS mesh object (i.e. - the cube) that was built using the makeCatCube() function shown above :
function initializeGameAssets_promise(gameAreaDomElementID, threeJSCanvasAreaDomElementID, catCardWidth, catCardHeight) {
let errPrefix = '(initializeGameAssets_promise) ';
return new Promise(function(resolve, reject) {
try {
buildAllCatCards_promise(gameAreaDomElementID, threeJSCanvasAreaDomElementID, 1, catCardWidth, catCardHeight)
.then(result => {
g_Scene = new THREE.Scene();
g_Scene.background = new THREE.Color('yellow');
initCamera();
initRenderer();
for (let cardLabelKey in g_aryCatCards) {
let catCard = g_aryCatCards[cardLabelKey];
g_Scene.add(catCard.meshThreeJS);
}
let threeJSCanvasAreaDOMElement = document.getElementById(threeJSCanvasAreaDomElementID);
if (!threeJSCanvasAreaDOMElement)
throw new Error(errPrefix + `Unable to find the DOM element for the cat cards underlay table using ID: ${threeJSCanvasAreaDomElementID}`);
threeJSCanvasAreaDOMElement.appendChild(g_Renderer.domElement);
let catCardsTableElementOffset = getElementOffsetById(ELEMENT_ID_CAT_CARDS_TABLE);
threeJSCanvasAreaDOMElement.left = catCardsTableElementOffset.left;
threeJSCanvasAreaDOMElement.top = catCardsTableElementOffset.top;
// Start the rendering process.
render();
resolve(true);
})
.catch(err => {
reject(err);
});
}
catch(err) {
reject(err);
}
});
}
Here are the functions I use to initialize the camera and the renderer:
function initCamera() {
g_Camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 10);
g_Camera.position.set(0, 3.5, 5);
g_Camera.lookAt(g_Scene.position);
}
function initRenderer() {
g_Renderer = new THREE.WebGLRenderer(
{
antialias: true
});
}
This dump shows the XYZ values of the mesh object's position property:
------------- DUMPING MESH POSITIONS -------------
[label: A1] - X: 2, Y: 0, Z: 2
[label: A2] - X: 176, Y: 0, Z: 2
[label: A3] - X: 350, Y: 0, Z: 2
[label: A4] - X: 525, Y: 0, Z: 2
[label: E1] - X: 2, Y: 0, Z: 364
[label: E2] - X: 176, Y: 0, Z: 364
[label: E3] - X: 350, Y: 0, Z: 364
[label: E4] - X: 525, Y: 0, Z: 364
[label: L1] - X: 2, Y: 0, Z: 183
[label: L2] - X: 176, Y: 0, Z: 183
[label: L3] - X: 350, Y: 0, Z: 183
[label: L4] - X: 525, Y: 0, Z: 183
[label: X1] - X: 2, Y: 0, Z: 545
[label: X2] - X: 176, Y: 0, Z: 545
[label: X3] - X: 350, Y: 0, Z: 545
[label: X4] - X: 525, Y: 0, Z: 545
I really don't know what to do at this point to debug this problem. Can anyone give me some general tips on what to inspect, or what diagnostic code I could write to try and figure this out?
Your camera can only see 9 units deep
new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 10);
but your objects are up to 545 units away
Try
const near = 1;
const far = 1000;
new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, near, far);
see
You also seem to have the camera looking in the wrong direction.
g_Camera.position.set(0, 3.5, 5);
g_Camera.lookAt(g_Scene.position);
AFAIK g_scene.position is 0, 0, 0 which means the camera is at z = 5 looking toward Z = 0 but your list of objects are almost all behind the camera.
Try
g_Camera.position.set(0, 3.5, -50);
g_Camera.lookAt(g_Scene.position);
As I understand I have to use one canvas for both mapbox Gl and p5.
But how to do this? And what if I have p5 animation will it overwrite the canvas with map?
Any example or hint? Thanks.
My code, but nothing serious
mapboxgl.accessToken = 'pk.***';
var mapGL = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
center: [-120.36603539685188, 50.68667605749022],
zoom: 11.6
});
var mainCanvas;
function setup() {
mainCanvas = createCanvas(720, 400, WEBGL);
}
function draw() {
background(102);
rotate(frameCount / 100.0);
rect(30, 20, 25, 25);
}
Different drawing libraries don't usually play nice with each other on the same canvas. You could try something like overlaying the P5.js canvas on top of the mapbox canvas.
Better yet, use a map library that's already compatible with P5.js, like Mappa or p5.tiledmap. That allows you to draw a map inside P5.js, which makes drawing on top of it much easier.
This is a very old question, but for whoever revisits this question looking for an option... nowadays this could be easily done with the latest version of threebox and a few lines of code. The result looks like this:
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoianNjYXN0cm8iLCJhIjoiY2s2YzB6Z25kMDVhejNrbXNpcmtjNGtpbiJ9.28ynPf1Y5Q8EyB_moOHylw';
var origin = [2.294514, 48.857475];
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/satellite-v9',
center: origin,
zoom: 18,
pitch: 60,
bearing: 0
});
map.on('style.load', function () {
map
.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function (map, mbxContext) {
window.tb = new Threebox(
map,
mbxContext,
{
defaultLights: true,
}
);
// import tower from an external glb file, downscaling it to real size
// IMPORTANT: .glb is not a standard MIME TYPE, you'll have to add it to your web server config,
// otherwise you'll receive a 404 error
var options = {
obj: '/3D/eiffel/eiffel.glb',
type: 'gltf',
scale: 0.01029,
units: 'meters',
rotation: { x: 0, y: 0, z: 0 }, //default rotation
adjustment: { x: -0.5, y: -0.5, z: 0 } // place the center in one corner for perfect positioning and rotation
}
tb.loadObj(options, function (model) {
model.setCoords(origin); //position
model.setRotation({ x: 0, y: 0, z: 45.7 }); //rotate it
tb.add(model);
})
},
render: function (gl, matrix) {
tb.update();
}
});
})
</script>
I'm using Phaser 2.3.0 and I want to know the bounds of a rotated sprite.
But when I change sprite.rotation, the values of sprite.getBounds() don't change:
sprite = game.add.sprite(0, 0, "img"); // game.load.spritesheet("img", "grid.png", 32, 32);
console.log(sprite.getBounds()); // Object { x: 0, y: 0, width: 32, height: 32, type: 22 }
sprite.rotation = 0.52; // 30°
console.log(sprite.getBounds()); // Object { x: 0, y: 0, width: 32, height: 32, type: 22 }
What's wrong?
How can I get the correct bounds?
As far as I know, getBounds() will return the smallest possible rectangle that the object fits in and since Phaser.Rectangle doesn't have a rotation property, you will get the same rectangle both times.
It's being 6 years since this question, but just for the people who end up here after a Google search, the right answer is that the getBounds() is based on the object's worldTransform which is updated at the end of the render() cycle. So changing something in the object and in the next line trying to get its bounds will give you the old value. The solution is to wait a frame or call updateTransform():
const sprite = game.add.sprite(0, 0, "img");
console.log(sprite.getBounds());
// Phaser.Rectangle { x: 0, y: 0, width: 32, height: 32, type: 22 }
sprite.rotation = 0.52; // 30°
sprite.updateTransform();
console.log(sprite.getBounds());
// Phaser.Rectangle {x: -15.900164410999576, y: 0, width: 43.67037816068437, height: 43.67037816068437, type: 22}
https://photonstorm.github.io/phaser-ce/Phaser.Sprite.html#getBounds
Keep in mind that if the object is inside an hierarchy of objects, you should call updateTransform() in the highest object.