I'd like to make a minimap of OrthographicView and draw the bounds path.
I can get the viewState which has its width, height, target, and zoom.
But how can I get or compute the bounds (top, right, bottom, left coordinates of current view)?
When you receive a viewState, you can get the bounds with the following code:
const viewportBounds = () => {
const { width, height } = viewState.main;
if (!width) return null;
const view = new OrthographicView(viewState.main);
const viewport = view._getViewport();
const topLeft = viewport.unproject([0, 0]);
const topRight = viewport.unproject([width, 0]);
const bottomLeft = viewport.unproject([0, height]);
const bottomRight = viewport.unproject([width, height]);
return [[topLeft, topRight, bottomRight, bottomLeft, topLeft]];
}
Related
I am writing react-native app. The font size should be dynamically changed based on the screen resolution. Is there any approach to achieve this? In web world I am using rem values but in this case is not possible.
To get some help? It's very important.
You can create some helper function that will update the font size based on the device screen size using the standard device width and height as base to resize from. Or use this library https://www.npmjs.com/package/react-native-responsive-fontsize which is doing something similar.
import {Dimensions} from 'react-native';
const screenWidth = Dimensions.get('window').width;
const screenHeight = Dimensions.get('window').height;
const GuidelineBaseHeight = 844;
const GuidelineBaseWidth = 390;
const verticalScale = (size, floor = true, setMax = false) => {
size = parseFloat(size);
let result = Dimensions.common.WINDOW_HEIGHT / GuidelineBaseHeight * size;
let newSize = floor ? Math.floor(result) : result;
return setMax && newSize > size ? size : newSize;
};
const horizontalScale = (size, floor = true, setMax = false) => {
size = parseFloat(size);
let result = Dimensions.common.WINDOW_WIDTH / GuidelineBaseWidth * size;
let newSize = floor ? Math.floor(result) : result;
return setMax && newSize > size ? size : newSize;
};
export {verticalScale, horizontalScale};
<Text fontSize={verticalScale(14)} />
Also, you can create your Text component which will wrap React's text component and apply the vertical scale to the font size style.
I have model prediction which detects the end box of verses of quran. I need to shade the area between them as shown in pictures which when the endbox hits the edge it start again from the another edge and the two drawn shadows have the same id. I know it seems complicated but you will save my day if you figure it out here is some of my code to help you reference
"use client";
import LABELS from "#app-datasets/coco/classes.json";
import {
Box,
Button,
ButtonGroup,
Center,
chakra,
Container,
Heading,
Icon,
Text,
useBoolean,
VisuallyHiddenInput,
VStack,
} from "#app-providers/chakra-ui";
import * as tf from "#tensorflow/tfjs";
import "#tensorflow/tfjs-backend-webgl";
import { useEffect, useRef, useState } from "react";
import { FaTimes } from "react-icons/fa";
const ZOO_MODEL = [{ name: "yolov5", child: ["yolov5n", "yolov5s"] }];
function Home() {
// LET RHE USEWER CHOOSE THE MINIMUM SCORE TO SHOW
const [model, setModel] = useState(null);
const [aniId, setAniId] = useState(null);
const [modelName, setModelName] = useState(ZOO_MODEL[0]);
const [loading, setLoading] = useState(0);
const imageRef = useRef(null);
const videoRef = useRef(null);
const canvasRef = useRef(null);
const inputImageRef = useRef(null);
const [singleImage, setSingleImage] = useBoolean();
const [liveWebcam, setliveWebcam] = useBoolean();
useEffect(() => {
tf.loadGraphModel(`/model/${modelName.name}/${modelName.child[1]}/model.json`, {
onProgress: (fractions) => {
setLoading(fractions);
},
}).then(async (mod) => {
// warming up the model before using real data
const dummy = tf.ones(mod.inputs[0].shape);
const res = await mod.executeAsync(dummy);
// clear memory
tf.dispose(res);
tf.dispose(dummy);
// save to state
setModel(mod);
});
}, [modelName]);
// helper for drawing into canvas //IoU threshold 0.5
const renderPrediction = (boxesData, scoresData, classesData , ) => {
const ctx = canvasRef.current.getContext("2d");
// clean canvas
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
const font = "16px sans-serif";
ctx.font = font;
ctx.textBaseline = "top";
// LET RHE USEWER CHOOSE minval SCORE TO SHOW
const minval = 0.5;
for (let i = 0; i < scoresData.length; ++i) {
if (scoresData[i] < minval) continue;
const klass = LABELS[classesData[i]];
const score = (scoresData[i] * 100).toFixed(1);
let [x1, y1, x2, y2] = boxesData.slice(i * 4, (i + 1) * 4);
x1 *= canvasRef.current.width;
x2 *= canvasRef.current.width;
y1 *= canvasRef.current.height;
y2 *= canvasRef.current.height;
const width = x2 - x1;
const height = y2 - y1;
// draw the bounding box
ctx.strokeStyle = "#C53030";
ctx.lineWidth = 2;
ctx.strokeRect(x1, y1, width, height);
// fill the area between the boxes
const label = klass + " - " + score + "%";
const textWidth = ctx.measureText(label).width;
const textHeight = parseInt(font, 10); // base 10
// draw the label background
ctx.fillStyle = "#C53030";
ctx.fillRect(x1 - 1, y1 - (textHeight + 4), textWidth + 6, textHeight + 4);
// draw the label text
ctx.fillStyle = "#FFFFFF";
ctx.fillText(label, x1 + 2, y1 - (textHeight + 2));
}
};
I was expecting a shade with the method above
Hello everyone,I have meet a strange problem which is that I loaded a gltf model in three.js and set color for it.When zooming in it has colors, but when zooming out,it is all black.And when I directly set color for it's material,it can works well.
Thank you.
here is the sample sreenphotos and code.
loadGlbModel() {
const loader = new GLTFLoader();
loader.load(
`/three/eiffel-tower.gltf`,
(gltf) => {
const geometry = gltf.scene.children[0].geometry;
const positions = geometry.attributes.position;
const count = positions.count;
geometry.setAttribute(
"color",
new THREE.BufferAttribute(new Float32Array(count * 3), 3)
);
const color = new THREE.Color();
const colors = geometry.attributes.color;
const radius = 200;
debugger;
for (let i = 0; i < count; i++) {
color.setHSL(positions.getY(i) / radius / 2, 1.0, 0.5);
colors.setXYZ(i, 1, 0, 0);
}
const material = new THREE.MeshPhongMaterial({
color: 0xffffff,
flatShading: true,
vertexColors: true,
shininess: 0,
});
const wireframeMaterial = new THREE.MeshBasicMaterial({
color: 0x000000,
wireframe: true,
transparent: true,
});
let mesh = new THREE.Mesh(geometry, material);
let wireframe = new THREE.Mesh(geometry, wireframeMaterial);
mesh.add(wireframe);
mesh.scale.set(0.1, 0.1, 0.1);
const redColor = new THREE.Color(1, 0, 0);
console.log(mesh);
// mesh.children[0].material.color = redColor;
const light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 0, 1);
this.scene.add(light);
this.scene.add(mesh);
},
(xhr) => {
console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
},
(error) => {
console.error(error);
}
);
},
You are rendering the wireframe version too, which consists of lines in screen-space. As you zoom out, these lines maintain the same width in pixels, thus covering everything else.
Do you wish to render the fireframe too? If not, don't. If you do, then consider hiding it as the user zooms out.
I have an app, where i need to get known ratio of picture for resizing it later. User can take pictures horizontal and vertical. And of course, ratio changes. So i need to get two different ratios.
There is problem with updating let horizontalImageRatio = 0;
How can i solve this, any tips?
my code:
Image.getSize(data.uri, (width, height) => { // Pickuping size of the picture
let imageWidth = width;
let imageHeight = height;
let stringImageWidth = '' + imageWidth; // Make double to string for storing to asyncstorage
let stringImageHeight = '' + imageHeight;
let horizontalImageRatio = 0; // this value should be updated
let verticalImageRatio = 0;
// For updating let horizontalImageRatio, but not working outside of this <-- PROBLEM
const horizontalRatioCalc = () => {
horizontalImageRatio = imageWidth/imageHeight;
console.log('horizontal_update', horizontalImageRatio);
};
const verticalRatioCalc = () => {
verticalImageRatio = imageWidth/imageHeight;
console.log('vertical_update', verticalImageRatio);
};
let stringHorizontalImageRatio = '' + horizontalImageRatio;
let stringVerticalImageRatio = '' + verticalImageRatio;
console.log(`Size of the picture ${imageWidth}x${imageHeight}`); // Tells size of the image for the console
horizontalRatio = async () => {
if (imageHeight>imageWidth) {
verticalRatioCalc();
try {
AsyncStorage.setItem("imageVerticalRatio", stringVerticalImageRatio),
AsyncStorage.setItem("asyncimageWidth", stringImageWidth)
AsyncStorage.setItem("asyncimageHeight", stringImageHeight)
console.log(`Vertical ratio saved! It's ${stringVerticalImageRatio}`)
console.log(`Image Width saved! It's ${stringImageWidth}`)
console.log(`Image height saved! It's ${stringImageHeight}`)
} catch (e) {
console.log(`AsyncStorage saving of image vertical ratio cannot be done.`)
}
}else {
horizontalRatioCalc();
try {
AsyncStorage.setItem("imageHorizontalRatio", stringHorizontalImageRatio),
AsyncStorage.setItem("asyncimageWidth", stringImageWidth)
AsyncStorage.setItem("asyncimageHeight", stringImageHeight)
console.log(`Horizontal ratio saved! It's ${stringHorizontalImageRatio}`)
console.log(`Image Width saved! It's ${stringImageWidth}`)
console.log(`Image height saved! It's ${stringImageHeight}`)
} catch (e) {
console.log(`AsyncStorage saving of image vertical ratio cannot be done.`)
}
}
}
horizontalRatio();
So, apparently, you don't have access to horizontalImageRatio inside of horizontalRatioCalc, the method horizontalRatioCalc has a different scope.
What you can do is change horizontalRatioCalc to receive a parameter and return a value, just like I've done in this example: https://stackblitz.com/edit/react-xiysai
This is good because now you have a function that can be tested independently.
Or you can also do it this way:
https://stackblitz.com/edit/react-variable-scope
This way you have access to both the variable and the method.
I'm trying to place a sketch on a building on the map with Leaflet. I succeeded in this as well, I can place and scale an image in svg format on the map. But when I add a new sketch to the map, I want the old sketch to be deleted from the map.
map.removeLayer(sketchLayer)
sketchLayer.removeFrom(map)
map.removeLayer(L.sketchLayer)
i tried these
My codes,
splitCoordinate (value) {
const topLeftCoordinates = value.top_left.split(',')
const topRightCoordinates = value.top_right.split(',')
const bottomLeftCoordinates = value.bottom_left.split(',')
this.initMap(topLeftCoordinates, topRightCoordinates, bottomLeftCoordinates)
},
initMap (topLeftCoordinates, topRightCoordinates, bottomLeftCoordinates) {
let map = this.$refs.map.mapObject
map.flyTo(new L.LatLng(topLeftCoordinates[0], topLeftCoordinates[1]), 20, { animation: true })
const vm = this
var topleft = L.latLng(topLeftCoordinates[0], topLeftCoordinates[1])
var topright = L.latLng(topRightCoordinates[0], topRightCoordinates[1])
var bottomleft = L.latLng(bottomLeftCoordinates[0], bottomLeftCoordinates[1])
var sketchLayer = L.imageOverlay.rotated(vm.imgUrl, topleft, topright, bottomleft, {
opacity: 1,
interactive: true
})
map.addLayer(sketchLayer)
}
Fix:
The error was related to the javascript scope. I defined the sketchLayer in the data and my problem solved.