3D perspective text on a webpage - javascript

How can I achieve 3D text transformations in perspective using Javascript/CSS.
Solutions using external libraries of Javascript/CSS are also possible

CSS transformations with perspective are only possible with Safari at this point. Alas Chrome, while based on Webkit, and seemingly supporting the proper CSS attributes, will not apply perspective transformations. They will be supported at some point on Firefox, no clue about IE.
Your only other option really is <canvas>. However, just like with CSS transforms, the canvas API only provides functions for "2D" affine transformations (scaling, rotation, skewing). With this the best you can get is an isometric perspective, as that can be achieved with just skewing.
However, since canvas gives you pixel level control over the image, you can fake perspective, though doing so is complex. The obvious way is to use the putImageData function and calculate each pixel using a 3D perspective transform matrix. Obviously you'd need to know some things about linear algebra and trigonometry. Regardless of your math skills, doing 3d transforms at such a low level is extremely costly performance wise, and highly variable between different browsers (Chrome is the fastest by far, Firefox will chug along at fairly low framerates, and Safari is somewhere in the middle).
A better solution performance wise, but similarly complex and math intensive, is to use drawImage to paint an image/text/whatever to canvas one line at a time, and in between each change the canvas's scaling transform values. This is exactly the method that was used to get perspective on the SNES with mode 7 that natively only supported 2D transformations.
Another method is detailed here.
As you can imagine none of this is trivial, and performance is spotty at best. So if you are not willing to delve into a mass of linear algebra, trigonometry and canvas API documentation, I would say you are pretty much out of luck. Any JS library that does as you ask is subject to all these limitations. I know of a handful of demos out there, but none that could really be called a library (though if someone knows of something I'd be happy to be corrected).
If anyone is interested in the nutty details of any of the approaches I mentioned, I'd be happy to try to lay them out more comprehensively. In the mean time, you can play around with my own demo that uses a combination of the first two techniques I specified.
http://bigmooworld.com/pwings/pilotwings/pilotwings.html
Some of you might recognize it...
Use WASD to pan, up/down to zoom, right/left to rotate, and Q/E to change perspective. Feel free to peruse the code, but be forewarned that it is not well organized or commented, and most of it is discarded junk code.
So anyway my answer is...Yes it is possible, easily in Safari, or with a great deal of effort and shoddy performance in other browsers (and there is probably a way in IE but I have no clue about how).

Related

CreateJS: poor/strange framerate in Firefox

I'm at the early stage of building my own game framework, based on CreateJS (especially on the feature of exporting everything from Flash IDE). And found out that framerate of CreateJS (EaselJS) is much worse in Firefox than in Chrome/IE.
Also, it seems that the framerate of app (which might be changed using Ticker.setFPS) doens't matter. It looks like Firefox has some problems with rendering (I've tried to use 60fps and 30fps, and in both cases there were problems, it looks like FF doesn't have any stable time/logic of rendering).
I've tried to play with Ticker.timingMode (set it to Ticker.RAF_SYNCHED), but it didn't help either.
And also, I've found a lot of similar topics/questions in the Internet, and no any clear answer.
So, I was wondering, if there is any way to improve framerate/rendering in FF or we should work with it as it is now?
P.S.: It looks like the problem, probably, partially might be on the CreateJS side, because I've found few nice HTML5 games (as I know they don't use CreateJS) with smooth and nice animations in FF. Here an example: https://www.netent.com/games/slots/dazzle-me/
EaselJS just facilitates Canvas drawing operations and updates. I have built a number of applications and games without FireFox-specific performance issues using the CreateJS framework, so while there might be something that is happening through CreateJS causing the issue, it is more likely related to the content and how CreateJS is used.
Different browsers have different issues and performance differences, including how they handle vectors, large images on the GPU, etc. Without seeing code or an example, it is hard to pinpoint where the performance is going.
What have you tried so far to isolate the performance?
Do you have a lot of large images, text, or vector content?
Are you using filters or Shadows?
How are you determining that the framerate is not working? RAF_SYNCHED attempts to normalize the computer's RAF framerate (usually about 60 fps, but dependent on lots of things).
Do you have a lot of children (like particles) going on?
Are you checking mouse position or hitTesting often?
If you can provide more info, code samples, working demos, etc you can likely get a better diagnosis of what is happpening.

Create shapes from Canny Edge Detection in Canvas

Does anybody have an idea on how I can create shapes from Canny Edge Detection in Canvas?
I assume here you already have the Canny edge detection implemented based on the way the question is formulated -
You can use an approach such as this (written in Java but should be easy enough to translate into JavaScript) and/or perhaps some limited use of line-fitting approaches (statistical).
The essence is that you will have to find out which pixels are connected and create polygon objects/arrays yourselves based on the result of the edge detection.
Once you have the connected pixels you can use point reduction algorithms such as the Ramer–Douglas–Peucker algorithm (JavaScript implementation here) to avoid the polygons to contain every single point of similar sloped lines and so forth.
You will run into a variety of challenges though such as short segmented lines due to too much noise in the original image or "weak lines", clusters of "lines" which makes it hard to find out how to connect them as polygons.
I don't know of any libraries for this, however you could:
Use getImageData() to access a byte[] of pixel data
Implement your own convolution filter on top of that data (examples for this may exist online)
In this way you can find areas of high contrast (edges.)
EDIT I agree with Ken -- I may have misread the question.
In addition to Ken's answer, if you know what kinds of shapes you're looking for then you might like to look at the Hough Transform which is well suited to detecting lines, ellipses and other shapes that can be geometrically defined using only a few parameters.

Drawing lots of hexagons and distorting them

I'm starting a web game, and I would like to know the best way to do it.
The game is a field of hexagons seen from the above, that can be rotated/inclined.
What's the best way to do it? What I was going to do was use a canvas and use 2d transforms to simulate 3d rotations, the problem is that:
The game must work on smartphones
For every rotation i must redraw all the canvas, and there could be 200 hexagons on the screen to redraw many times, so i think canvas are too expensive in terms of resources...
There's two ways I can think of:
Using canvas only. This means quite wide browser support, will have few quirks and generally "just work". Potential problems: Performance on low-end machines like you mentioned. But is rotating the game critical to gameplay? If not, you could consider turning that off on slow smartphones. Users will most likely not miss that feature if it's not important to gameplay.
A combination of canvas and CSS3 transforms (rotating cube example). Could give you better performance than pure canvas solution. Potential problems: requires "mixing" of techniques, which always means a risc of running into unexpected problems or quirks.
You should look at www.kineticjs.com
Canvas is the way to go for drawing 100's of shapes because it doesn't write to the DOM for every path like SVG does.
It has several examples where shapes are programmatically drawn in the 1000s. I recently used it for a similar animation here:
http://movable.pagodabox.com

How to generate simple 3D images in JavaScript

I like to generate a simplified version of the following static image in pure JavaScript. It should work with 2010 vintage browsers, so I can't wait for Firefox 4 and WebGL.
I do not need any fancy textures - the task is just to visualise how to stack some boxes.
BTW: the current image is generated with POV-Ray which is overkill for the job - and does not run in the browser ;-)
As you say you don't need fancy textures I'd recommend for vintage support that you stack images like mentioned earlier. I made an example for you: http://jsfiddle.net/andersand/5RsEx/
The simple function is just to illustrate, and does the drawing of a segmented box. Of course you may need to figure out box placement, orientation, and so on if that is your business goal.
That approach could help you with boxes of various height (z axis). If your boxes also vary in width (x and/or y) you'd need to create more images to suit your needs.
If you can do without IE support, or require a plug-in for IE users, or provide server-side rasterization for IE users, you could use computed svg files.
You could do a very basic projection of the vertices of the boxes, maybe start with a simple isometric projection and then go to a perspective projection. Use simple 4x4 matrix math as used in OpenGL for this and represent the 3D coordinates as [x, y, z, w] vectors. Since the images are small and simple enough you can get away with simply using a smart rendering order, i.e. bottom to top, back to front, which will make sure you don't have to worry about mucking about with a depth buffer or other such things. Should be fairly simple to implement, you don't need third party libs and it will be natively supported in most of the contemporary browsers.
Okay, I thought this to be an interesting experiment, so I made a working version of what I described above. It works in all major browsers with the notable exception of IE. SVG support should come to IE with the introduction of IE9. I've tested in Opera, Firefox and Safari under OS X and Opera and Firefox under Linux. It might be possible to add IE support by making VML output possible, though I must say that I do not know whether IE permits inlining of VML in XHTML using namespaces like I used here.
Computed SVG rendering of 3D stacked boxes
Right now it only does isometric projection. I might just spend a bit more time on this to add a perspective projection option as well. That would seem fun and should not be much more than adding another matrix multiplication.
Searching for Collada (XML based 3d file) support may be your best bet. Now that canvas has landed, lots of 3d routines are being ported from Flash Actionscript to Javascript.
You can export Collada files from all of the major 3D applications, as well as blender ;)
Try the following as an example;
http://www.rozengain.com/blog/2007/11/21/parsing-collada-3d-assets-with-javascript-in-the-html-5-canvas-element/
If you want to rotate a 3D scene using javascript, you may have a few months wait until the engines get released. They will most likely be HTML5 dependent.
There are a few WebGL implementations doing the rounds but they are for the bleeding edge browsers and are very unstable.

How to deskew a fisheye panorama using css3?

I feel that it has come time to convert my flash panoramas to js/html5/css3. I've seen some elegant solutions using separate flat images, but mine are all fisheye...
My intuition tells me that it's doable using -webkit-transform: matrix3d but I'm not quite hitting it.
Any ideas if this can really be done in css3?
Thanksya kindly.
Yes, it can be done, but you better know your mathematics. Note that you are not using CSS3 but rather a proprietary extension, this will only work in webkit browsers. You'll probably be better off using a Canvas element for the job, not only is it supported by more browsers, it also gives you far greater freedom to do whatever transformation you desire.
Edit:
Well then, cut your image into a number of thin vertical slices, each slice should be scaled by approx 1/cos([angle off centre]), and skewed to account for the angle being different at the right and the left side of the slice. This way you should end up with an "inverse fisheye" shape where the top and the bottom of the image is concave, you might want to cut it to a square.
I discovered three.js.
It looks promising.

Categories