I'm working on a website which mixes html and WebGL/canvas. We're using WebGL/canvas to draw a graph with many elements, which proved to be too slow if drawn using html or svg.
The problem is that not our whole page is made in WebGL/canvas. The browser remembers the zoom from the html part of the website where zooming is fine, and then applies it to the part which uses WebGL, making the raster graph there blurry and too large for the window.
This is a major setback and a huge blow to the user experience. The worst part is that the browser won't even let me READ the zoom value so that I could AT LEAST notify the user about the issue, or even adjust the drawing based on the zoom.
Has anyone else run into this problem? How did you solve it?
Related
The setup
As part of a web vector editing tool written in Javascript, I'm implementing hit testing using a hit canvas strategy similar to that of Concrete.js.
For most of it, it works pretty well: I'm drawing my shapes twice (once on the display canvas, and once on a hit canvas).
When querying the canvas, I check the hovered pixel of the hit canvas and extract interaction information (i.e. which object id is stored there).
The problem
This works well inside shapes, but is painfully flawed at the boundaries where anti-aliasing makes the stored data invalid (it gets mixed with whatever background data was there before).
Are there good strategies for dealing with this data boundary problem?
Without disabling anti-aliasing for canvas methods, then we're bound to have some boundary regions across overlapping regions that will store merged data from multiple regions.
The simple scenario
In a binary scenario (some foreground vs the background), then this can be mitigated as we can assume the background to have no value, and any value becomes some foreground.
The real scenario
However, in a general scenario with multiple shapes overlapping each other on top of the background, is there any reasonable strategy for error detection? (or error correction, but I assume that's harder)
If I can tell that the data is invalid (i.e. it consists of perturbed data due to anti-aliasing), then I can use a different strategy for those few pixels at the boundaries. But I feel that it's impossible to tell whether the data I'm extracting is valid in the general scenario where we can have many overlapping shapes.
Of course, one solution is to NOT use a hit canvas. But I was wondering whether people had found a solution using hit canvases since they seem great for dealing with complex geometries.
Anti-aliasing
The ideal solution would be to disable anti-aliasing, which I don't think is possible for canvas methods [*].
[*] I know we can disable filtering when rendering images (e.g. that question) such as with imageSmoothingEnabled=false or rescaling with image-rendering: pixelated, but those don't solve the problem of anti-aliasing when drawing shapes / paths.
I have a SVG generated map for the game I am developing. I have no problems with the game being open-source and it uses open web technologies such as HTML and SVG. No problems there.
But at the same time I want the players not to be able to see or reverse engineer a map of the whole world (to retain true exploration). For now I generate map using a seed that is secret and not version controlled. So even though the algorithm is known curious players can use open-sourced code to generate "game-like worlds" but not that exact one. This solves the "global" problem.
But since SVG is rendered on a page as a single Voronoi diagram all the data (I don't mind the coordinates of points) would be extractable. Data like resources, land types, biomes, climate etc. could be fetched from SVG to gain an upper hand in finding good locations for settlements.
Any idea how to prevent that? Players have limited vision so I thought about either:
not rendering the whole Voronoi diagram at all (just the visible part), but that could be potentially tricky to do (maybe, haven't looked into it yet),
inserting the resource/land tile data into SVG graph only to visible locations
I can see the benefits of both approaches and if done correctly it could even boost the performance (not rendering the whole thing/rendering with less data) and lead to bigger worlds without impacting performance.
Any other ideas/programming/architectural approaches to help with the issue?
(I am using Vue.js, d3.js, svg-pan-zoom and Laravel backend just in case it helps.)
The ideas that you gave are perfect, but for implementing them, you need to make hard work, and spend much time.
I have a suggestion. Is will work for most of the users. Maybe some users will "hack" it. But I believe it will work for 95% of the times.
You can create a very big rectangle, from the top left point 0,0 until the right bottom point. The rectangle will be white, and it will be over all other shapes.
This way if someone will download the SVG, we will see nothing. Just a big white rectangle.
In you game HTML, you can add a CSS selector, to hide this rectangle.
If you following this method, most of the users (who don't have a photo editing software) will not be able to see the map.
Users who knows how to inspect elements in HTML may see the map. But I believe that most of them who will see a white box, will not believe that there is something behind.
I think that this is a simple temporary approach that you can do, before doing other more defensive ways.
I want to make an interactive globe 3D and I found this site that seems to be perfect to what I want, but I'm have some problems with the code.
1- I downloaded the source code but he don't open in my browser, it stop in the loading...
2- Are There best way to map the click on countries? The current code is using segments but if I want to click on some little country I will have to increase the amount of segments and this make some performance problems to some computers or cellphones.
I am using javascript svg-pan-zoom.js (https://github.com/ariutta/svg-pan-zoom) libary to zoom and pan svg in web application. Zooming in Firefox is very slow and laggy, while zooming in Chrome and IE11 works very well (tested with 5MB .svg file that presents floor plan - if file is smaller, this issue is not that noticeable). Panning is working fine. I've read many topics on this issue on forum but I haven't find any solution yet. Does anybody know what is causing this problem and how to fix it?
Example: http://jsfiddle.net/coz3fd0L/3/
Check your refreshRate option. Maybe you set a high number.
If not then you may set a low number (ex. 10 which means max 10 frames per second) and if may improve your problem.
Other than that I don't know of any other problems in svg-pan-zoom. At least if pan is smooth then zoom should be the same.
Maybe your SVG has a lot of edges/curves/nodes and Firefox is simply bad at resizing such things. Or it is bad at resizing large SVGs when matrix transform is used (matrix transform is used for zoom/pan in svg-pan-zoom).
Update: From what I see this is purely a Firefox problem (or the way it is). Just opening the SVG from your example http://imgh.us/test_51.svg takes 100% of CPU (for page scroll).
Also I did try to change matrix transform values manually (to test if it is svg-pan-zoom issue) and it is anyway very slow.
The only solution I see is to try to optimize your SVGs (maybe it is possible to make them simpler: less edges, nodes, do not render white elements...).
I noticed that when you move a canvas around or when you resize it, everything inside gets erased. I remember having a similar problem in windows forms applications in C#.
Anyway, what's the best way to keep the graphics on canvas, even after it moves etc.? (using javascript)
I've been working on a paint using canvas and websockets, you can see my problem here: http://students.info.uaic.ro/~tudor.berechet/ (just go to Coboards, select the Brush tool, click a bunch of times on canvas and then resize the window or enlarge the canvas)
One more thing I noticed, running the site off my HDD, this problem doesn't occur. which makes me wonder if there's some strange error somewhere.
I definitely need a persistent canvas, because I'm gonna have to implement the hand tool to move it around...
What say you?
The problem seems to have gone after cleaning up my code a bit. I still don't know what was causing it, but it seems that the canvas drawings now remain intact even after I move/resize the canvas.
Please confirm. [EDIT] confirmed.
The point is, my original assumption that canvas graphics are not persistent seems to have been wrong. There was most likely some coding error that was "erasing" my canvas.