I want have some very large objects present on canvas, but there seems to be a distance limit of about 2000 and anything further is not visible at all.
Is there a way to disable this option or reassign the border value?
I couldn't find any mention in any documentation.
In the picture I am almost in the center of a ball with radius 4000 and the grey circle in the middle grows or shrinks based on me zooming in or out.
You might be experiencing camera clipping: geometry that gets cuts off when it's to close (near clipping plane) or too far (far clipping plane) from the view frustum (imagine the base section of a pyramid with the center of the camera as the tip).
(Image credits: MithrandirMage - Own work This W3C-unspecified vector image was created with Inkscape.)
You can play with the frustum() or perspective() methods to adjust the near/far clipping distance: which ever makes more sense for your setup
Related
I was working on a real time whiteboard.
I want to create an Infinite canvas, which can be zoomed using the mouse wheel and panned using drag, using javascript.During the zoom and pan the items drawn on the canvas must also be affected. Is there a was to achieve this without using any external library?
Yes, but it'll take a bit of work. The general idea of what you'll do is the following:
You will need to keep track of the position of the "camera", as well as how close it is to the content - a zoom factor
You will need to attach event listeners to different mouse actions to cause the camera's state to change
When you drag or zoom, you will need to redraw your canvas with the new positions and sizes of all the content. Some math will have to be done to know what the new canvas content is.
There may or may not be certain performance issues you have to address if there's a lot of content on the canvas.
An alternative, possibly quicker approach, but maybe less powerful, would be to not use canvas, and use some CSS magic instead with plain HTML. The basic concept here is that you'll have a 0x0 div as your plane. That div will contain your content, which may include content such as custom SVGs. Each of its children will break out of the div, and will be positioned relative to it. When you drag, you just move the div (through transform: translate()). When you zoom, you just scale the div (through transform: scale()).
Some useful references if taking the second approach:
CSS transform - to move and scale the whiteboard
CSS position - to position content on the whiteboard, and for the general layout
CSS overflow - to crop the whiteboard
The canvas element itself won't be infinite, I guess that's clear enough. What will change when you drag and zoom is the mapping of the real coordinates of your whiteboard elements to the drawing coordinates on the canvas. There's some work to do with detecting the mouse events and doing the calculations for updating the mapping, so there are too many specifics to really put in an answer. But yes of course this is possible without an external library.
Basically canvas could not be set to infinite sized. All you can do is to draw the portion that should be visible in the canvas.
first of all you should store all the points you have drawn to an array.
whenever you pan your canvas , track the offset that you have panned. this offset values can be used to reposition your stored points in your canvas.
eg. suppose you have drawn a line from (50 , 50) to (100 , 100).
let the offsets be {x:0 , y:0}
x , y offsets shows how much x and y distances you have panned in total
then update the points by adding the offsets and redraw
https://github.com/TomHumphries/InfiniteCanvasWhiteboard
here is a simple html5 whiteboard created by Tom Humphries which has infinite zoom and pan.
I am currently trying to build an overlay layer for leaflet. The overlay is supposed to display 3D contents (e.g. buildings). However, I have trouble with keeping the movements on the leaflet map in sync with the ones in the scene in the overlay.
So far the canvas is as large as the map container and it will always overlay the map (like a position: fixed). In order to move around when the user is panning on the map I want to move the camera in the scene (instead of moving all geometries around). For position I use the distance from lat:0, lng:0 as THREE seems to struggle with fractal positions (e.g. when using decimal gps coordinates). Unfortunately I am struggling to find the correct formula to get the correct positions for the camera (x,y,z).
My attempt so far:
https://jsfiddle.net/hg474d6r/7/ (the _handleMove function is the relevant one)
The black dot is the center and for your reference. The red dot should remain static - relative to the map - which it doesn't.
So is there just a small issue in my formula/"calculations" or will this approach not even work at all?
Update: updated fiddle with progress and so on
It looks like that the Camera will points to a fixed Point.
If you move the Camera the Direction of the Camera Vector will be changed.
So You will see this Parallaxe Effekt.
I have a plane inside of a sphere in Three.js that I am rendering a shader to so that I can get effects on the sphere. I also use lookAt to align the plane with the camera. The issue I am experiencing is that if the camera gets too close to the sphere the plane seems to shrink into the sphere. I have determined the problem to be from the perspective nature of the camera as when the camera gets too close to the sphere its rays don't align with the edge of the plane anymore.
Here is a picture visualizing this: Perspective clipping
Also here is a JSFiddle that demonstrates this: https://jsfiddle.net/k8tc8ex6/1/
I know why this issue occurs, what I want to know is some possible solutions, what I am trying to achieve is that the edge of the plane will always appear to touch the edge of the sphere after the render.
Thanks so much in advance!
if I am right you are trying to "perfectly" fit mid section of a sphere into frustum of a perspective camera. What you are trying to achieve is impossible with a perspective view. As you said (demonstrated) the plane will exceed the bounds of the screen or there will be gaps with the edges of the plane and the screen.
If you badly want to "perfectly" fit the midsection of a sphere into the screen, you have 2 options:
1-) switch to orthographic camera
2-) stick to perspective camera, make your FOV very close to 0, give a huge distance to far plane so that your perspective camera will actually act as an orthographic camera.
I'm making a canvas-based game engine and am wondering if anyone has any good info on how to achieve an overhead view perspective. What I'm looking for is somewhere halfway between the traditional birds eye view and the old SNES mode7 view. Just a slight angle to give the illusion of 3D.
I'm trying to figure out what is going to be the best way to deal with the perspective skewing. I'm not doing rotations so 3D matrix stuff would be going overboard, but I need to be able to deal with rendering the map layers at a consistent angle and it'd be nice if the angle was adjustable. I also need to deal with the depth warp. Basically, the bottom row of pixels should be 1:1 pixel width and height, then for each row it'd get, for example, 5% smaller or something like that. What I'd like is to be able to supply a large canvas as a texture and then supply a camera angle between 0 and 90 where 0 is perfectly horizontal and 90 is birds eye view.
Anyone have any related tutorials or sample code? I've searched online a bit, but everything I've found seems to either be unsuitable for use in this particular application or overly complex, doing all sorts of crazy 3D skewing and rotation stuff. All I want is to take the normal tiled grid and lean it back a bit, no rotations or complicated stuff like that.
Here's an example of what I want;
Here's an example. http://img801.imageshack.us/img801/2176/perspectivesample.jpg
The bottom pixel row is 1:1 pixel ratio, and each row above that progressively gets shorter horizontally and vertically. The source texture of the top center region is normally about half the height of the bottom center region, but it has been shrunk vertically and horizontally to fit the perspective.
What I'm thinking might work best is to render the current viewport state to another canvas in flat, birds eye view, with approximately 50% extra space on the top and sides, then slice an upside triangular region from that and draw that to the actual visible canvas.
Only problem is, I suck at math when it comes to calculating angles and such.
if i understand you right, you just want a simple trapeze transformation. if so, maybe this or this link helps you out. for images that aren't centered it would just be an additional rhomboid tranformation, wich is easily possible with canvas, as far as i know.
What you're talking about is something that can be done simply with any 3D api. However since you've decided to try to stick to 2D canvas, you have to do everything in the 2D world which means working with rectangles, rotation, scaling, skewing, etc. Also know as affine transformations as mentioned the other answer.
What you want to do is possible, but since you want to use 2D you have to think in terms of 2D functions.
Generate your initial image.
Add a slice from the bottom of the original image to the bottom of the canvas, very slightly positioned to the left so the center of the image matches up with the center of the current canvas.
Very slightly increase the scale of the entire image
Repeat until you get to the top of the image.
The Pseudo code would look like this...
imgA = document.getElementById('source');
// grab image slices from bottom to top of image
for (var ix=height-slice_height;ix>=0;ix-=slice_height)
{
// move a section of the source image to the target canvas
ctx.drawImage(imgA, 0,ix,width,slice_height,
0-half_slice_width_increase,width,slice_height);
// stretch the whole canvas
ctx.scale(scale_ratio, 1);
}
This will take lots of tweaking, but that is the general solution.
scale_ratio will be a number slightly larger, but very close to 1.
ctx is the standard canvas 2D context
half_slice_width_increase is the 1/2 the amount the canvas will grow when scaled by the scale ratio. This keeps the scaled image centered.
To look correct you would want to transform the background tiles first before you add the icon overlays.
I'm creating an utility application that should detect and report the coordinates of the corners of a transparent rectangle (alpha=0) within an image.
So far, I've set up a system with Javascript + Canvas that displays the image and starts a floodfill-like operation when I click inside the transparent rectangle in the image. It correctly determines the bounding box of the floodfill operation and as such can provide me the correct coordinates.
Here's my implementation so-far: http://www.scriptorama.nl/image/ (works in recent Firefox / Safari ).
However, the bounding box approach breaks down then the transparent rectangle is rotated (CW or CCW) as the resulting bounding box no longer properly represents the proper width and height. I've tried to come up with a few alternatives to detect to corners, but have not been able to think up a proper solution.
So, does anyone have any suggestions on how I might approach this so I can properly detect the coordinates of 4 corners of the rotated rectangle?
I think you can do this with a simple extension to your existing solution: walk along each of the 4 edges of the bounding box, looking for transparent pixels:
In the non-rotated case, all the pixels along each edge of the box will be transparent.
In the rotated case, there must be one corner touching each edge of the box. This will be at the transparent pixel furthest away from the middle of the edge (there may be more than one due to aliasing, e.g. if the rectangle is only very slightly rotated).