html5 svg vs canvas for granite like background - html

i want to make to make a granite like background like http://www.tivli.com/ with a gradient at the center. i have found how to do gradient with both in the w3c tutorials, but are there any tutorials on how to make granite backgrounds in html5 canvas or svg? Thanks.

The site you referenced actually uses a simple 'noize.png' and then uses css3 radial gradients to buildup that background. I know you already knew that, I'm mentioning this for future readers.
Given this fact, I'll assume in the rest of my answer you want to learn, not a copy-pasta solution.
I've given up on svg looong time ago. But in canvas it's easy and fun... (especially now flash is FINALLY officially dead. Hurray).
So as others have already suggested in the comments to your question, why not use a seamless noise image? (you know where to find one :P).
You could still embed this image as 'DATA' in the html(, HINT: even or even feed image-data straight into canvas that will render it as your 'noise.php').
But then.. you are right: what if you wanted to change the noize-size?
And you want to know how to make granite/noise anyway..
And is mathematically/programmatically describing this noise lower in character-count (file-size) than supplying a ready-made image(-fragment)?
Start UPDATE 2 part 1:
Actually, after some good night sleep I realized/remembered that visual noise is one of the BEST way's to determine randomness. Humans are notoriously good at finding visual patterns, even professionals use this (and as such this is also heavily used in cryptography where one would need -for instance- a useful one time pad).
Also see 'commander' Crockford's YUI-lecture 'Principles of Security' from 19m07s to 22m37s.
Now why is this important? Well ECMA-script (aka javascript) defines a loose Math.random() function:
"returns a number value with positive sign, greater than or equal to 0 but less than 1, chosen randomly or pseudo randomly with
approximately uniform distribution over that range, using an
implementation-dependent algorithm or strategy"
Re-read the italic/bold part and welcome yourself to reality: each and every browser (brand/version) has it's own random-routine!!
"But what does it mean?" Well.. simply put.. Depending on browser(version)'s ES-Script implementation (cough cough IE): Noise based on Math.random() will/might render visible patterns in your noise (independently of possible tile-size)!!
So for the rest of this answer we are going to assume either an ideal world where browsers spit-out proper random numbers, or that you took control and use a stronger 'predictable' random-solution as is discussed on this wonderful article that google's bubble accidentally leaked :)
End Update 2 part 1
So let's start with the radial gradient-part. You already figured that one out.
Ok, then follows the noise-function in canvas (you could you could do this before the radial gradient, but this order gives a nicer grain and diffuses color banding the gradient produces -on a average lcd you would see them anyway since they're not true color-) : this is done by generating random pixels.
There would be a lot of different algorithms to use, I've used a straight-forward one that you can understand without math..
Note that generating noise for a modern day full-screen resolution is easily larger than 1 mega-pixel in resolution, so this would be slow! To overcome this we need to generate and RE-USE a small seamless tile. We use this as a pattern-fill in our full-size image that already has the radial gradient.
I also assume you want the radial gradient liquidly placed in the middle of the view-port, so if you want to go the fixed way (as opposed to the noize.png/css3 way you referenced), you'll also need an extra eventhandler 'onResize()' to have canvas render a new background.
Why? Well if you where to let the browser scale this background-image (created upon page-load) automatically, then the nice grain-size of your noise would change to, EVEN leading to visible PATTERNS that you would not want..
(Since I desperately want to go to sleep now..): The rest is thoroughly explained in the source-code of the function I wrote for you..
Here is the link to the fully documented code I wrote for you: jsfiddle.net/sU74C/ and here you can see it in full-screen preview.   UPDATE 1: function genNoise 80% FASTER!!
Use it if you like (retaining the link to this answer) or learn from it and do your own thing.
PLEASE DON'T FORGET to accept AN answer to this question (hopefully mine :))
Hope this helps!
UPDATE 2 part 2:
There are more way's to interact with canvas. One could also calculate/(re-)use/generate/save/import pixel-maps/array's (as png or base64 or jpg or ...) for instance, see this excellent article on faster 8bit and even faster 32bit (if the browser supports 'Uint8ClampedArray' as the type of the data property of the ImageData object) pixel-array's, including a proper solution to account for the endianness of the processor!!
So after giving this some considerable thought, it turns out that to do this 'right' is actually a challenge and should be divided in 2 parts:
Where do I get my noise-data (Math.random() or custom random or pre-defined external (image, json-string, random.com) or embedded (packed?) data)?
What is the fastest way to build/store/re-use this noise on full-screen size/canvas.
Given the statements in part 1 of this update and that we don't want patterns in our visible noise, I'm starting to lean to using some pre-rendered 'random' noise data (meant to tile seamlessly) that is embedded in the noise-generator: otherwise there is the overhead of running your own none-engine-optimized random function (times..a lot..).
Also I think one might get away with just black and white and transparency afterwards.. This might considerably speed-up things up AND reduce embedded pixel-data.
Think about it: black or white equals 0 or 1..
In base 64 one character can represent 6 bits. So a 30x30px image has 900 px divided by 6 bits = 150 characters (sweet-spot increments by 6px, so next is 36px*36px is 216 characters).

Related

Fast and responsive interactive charts/graphs: SVG, Canvas, other?

I am trying to choose the right technology to use for updating a project that basically renders thousands of points in a zoomable, pannable graph. The current implementation, using Protovis, is underperformant. Check it out here:
http://www.planethunters.org/classify
There are about 2000 points when fully zoomed out. Try using the handles on the bottom to zoom in a bit, and drag it to pan around. You will see that it is quite choppy and your CPU usage probably goes up to 100% on one core unless you have a really fast computer. Each change to the focus area calls a redraw to protovis which is pretty darn slow and is worse with more points drawn.
I would like to make some updates to the interface as well as change the underlying visualization technology to be more responsive with animation and interaction. From the following article, it seems like the choice is between another SVG-based library, or a canvas-based one:
http://www.sitepoint.com/how-to-choose-between-canvas-and-svg/
d3.js, which grew out of Protovis, is SVG-based and is supposed to be better at rendering animations. However, I'm dubious as to how much better and what its performance ceiling is. For that reason, I'm also considering a more complete overhaul using a canvas-based library like KineticJS. However, before I get too far into using one approach or another, I'd like to hear from someone who has done a similar web application with this much data and get their opinion.
The most important thing is performance, with a secondary focus on ease of adding other interaction features and programming the animation. There will probably be no more than 2000 points at once, with those small error bars on each one. Zooming in, out, and panning around need to be smooth. If the most recent SVG libraries are decent at this, then perhaps the ease of using d3 will outweigh the increased setup for KineticJS, etc. But if there is a huge performance advantage to using a canvas, especially for people with slower computers, then I would definitely prefer to go that way.
Example of app made by the NYTimes that uses SVG, but still animates acceptably smoothly:
http://www.nytimes.com/interactive/2012/05/17/business/dealbook/how-the-facebook-offering-compares.html . If I can get that performance and not have to write my own canvas drawing code, I would probably go for SVG.
I noticed that some users have used a hybrid of d3.js manipulation combined with canvas rendering. However, I can't find much documentation about this online or get in contact with the OP of that post. If anyone has any experience doing this kind of DOM-to-Canvas (demo, code) implementation, I would like to hear from you as well. It seems to be a good hybrid of being able to manipulate data and having custom control over how to render it (and therefore performance), but I'm wondering if having to load everything into the DOM is still going to slow things down.
I know that there are some existing questions that are similar to this one, but none of them exactly ask the same thing. Thanks for your help.
Follow-up: the implementation I ended up using is at https://github.com/zooniverse/LightCurves
Fortunately, drawing 2000 circles is a pretty easy example to test. So here are four possible implementations, two each of Canvas and SVG:
Canvas geometric zooming
Canvas semantic zooming
SVG geometric zooming
SVG semantic zooming
These examples use D3's zoom behavior to implement zooming and panning. Aside from whether the circles are rendered in Canvas or SVG, the other major distinction is whether you use geometric or semantic zooming.
Geometric zooming means you apply a single transform to the entire viewport: when you zoom in, circles become bigger. Semantic zooming in contrast means you apply transforms to each circle individually: when you zoom in, the circles remain the same size but they spread out. Planethunters.org currently uses semantic zooming, but it might be useful to consider other cases.
Geometric zooming simplifies the implementation: you apply a translate and scale once, and then all the circles are re-rendered. The SVG implementation is particularly simple, updating a single "transform" attribute. The performance of both geometric zooming examples feels more than adequate. For semantic zooming, you'll notice that D3 is significantly faster than Protovis. This is because it's doing a lot less work for each zoom event. (The Protovis version has to recalculate all attributes on all elements.) The Canvas-based semantic zooming is a bit more zippy than SVG, but SVG semantic zooming still feels responsive.
Yet there is no magic bullet for performance, and these four possible approaches don't begin to cover the full space of possibilities. For example, you could combine geometric and semantic zooming, using the geometric approach for panning (updating the "transform" attribute) and only redrawing individual circles while zooming. You could probably even combine one or more of these techniques with CSS3 transforms to add some hardware acceleration (as in the hierarchical edge bundling example), although that can be tricky to implement and may introduce visual artifacts.
Still, my personal preference is to keep as much in SVG as possible, and use Canvas only for the "inner loop" when rendering is the bottleneck. SVG has so many conveniences for development—such as CSS, data-joins and the element inspector—that it is often premature optimization to start with Canvas. Combining Canvas with SVG, as in the Facebook IPO visualization you linked, is a flexible way to retain most of these conveniences while still eking out the best performance. I also used this technique in Cubism.js, where the special case of time-series visualization lends itself well to bitmap caching.
As these examples show, you can use D3 with Canvas, even though parts of D3 are SVG-specific. See also this force-directed graph and this collision detection example.
I think that in your case the decision between canvas and svg is not like a decision between »riding a Horse« or driving a »Porsche«. For me it is more like the decision about the cars color.
Let me explain:
Assuming that, based on the framework the operations
draw a star,
add a star and
remove a star
take linear time. So, if your decision of the framework was good it is a bit faster, otherwise a bit slower.
If you go on assuming that the framework is just fast, than it becomes totally obvious that the lack of performance is caused be the high amount of stars and handling them is something none of the frameworks can do for you, at least I do not know about this.
What I want to say is that the base of the problem leads to a basic problem of computational geometry, namely: range searching and another one of computer graphics: level of detail.
To solve your performance problem you need to implement a good preprocessor which is able to find very fast which stars to display and is perhaps able to cluster stars which are close together, depending on the zoom. The only thing that keeps your view vivid and fast is keeping the number of stars to draw as low possible.
As you stated, that the most important thing is performance, than I would tend to use canvas, because it works without DOM operations. It also offers the opportunity to use webGL, what increases graphic performance a lot.
BTW: did you check paper.js? It uses canvas, but emulates vector graphics.
PS: In this Book you can find a very detailed discussion about graphics on the web, the technologies, pros and cons of canvas, SVG and DHTML.
I recently worked on a near-realtime dashboard (refresh every 5 seconds) and chose to use charts that render using canvas.
We tried Highcharts(SVG based JavaScript Charting library) and CanvasJS(Canvas based JavaScript Charting library). Although Highcharts is a fantastic charting API and offers way more features we decided to use CanvasJS.
We needed to display at least 15 minutes of data per chart (with option to pick range of max two hours).
So for 15 minutes: 900 points(data point per second) x2(line and bar combination chart) x4 charts = 7200 points total.
Using chrome profiler, with CanvasJS the memory never went above 30MB while with Highcharts memory usage exceeded 600MB.
Also with refresh time of 5 seconds CanvasJS rendering was allot more responsive then Highcharts.
We used one timer (setInterval 5 seconds) to make 4 REST API calls to pull the data from back end server which connected to Elasticsearch. Each chart updated as data is received by JQuery.post().
That said for offline reports I would go with Highcharts since its more flexible API.
There's also Zing charts which claims to use either SVG or Canvas but haven't looked at them.
Canvas should be considered when performance is really critical. SVG for flexibility. Not that canvas frameworks aren't flexible, but it takes allot more work for canvas framework to get the same functionality as an svg framework.
Might also look into Meteor Charts, which is built on top of the uber fast KineticJS framework: http://meteorcharts.com/
I also found when we print to PDF a page with SVG graphics, the resulting PDF still contains a vector-based image, while if you print a page with Canvas graphics, the image in the resulting PDF file is rasterized.

Is there a trick to creating an animated gif of tv static that will allow it to be relatively small?

Apologies in advance, but this isn't really a photoshop question. Rather, I'm trying to come up with something that is convincing but exploits the compression and features of the gif format as best as possible to produce the smallest possible file for the animation.
Some constraints:
It needs to be at least 20 or 30 frames. I've tried with fewer (and since they're largely uncompressable 15 frames is half the size of 30, generally speaking)
Size needs to be no less than about 256x192
It doesn't need to be color though, nor even full grayscale. I've seen convincing stills with as few as about 16 grays
It can have a pattern, but not one that is instantly obvious to the human eye. If someone takes a single frame and after a minute or two can spot the pattern (which makes it compressable?) that's ok
Frames 2 through n can use quite a bit of alpha, but when I started using big horizontal stripes of alpha, it was instantly noticeable to my eyes. So you don't get to rack up a bunch of RLE with the easy cheat.
All of the above and still needs to look good at 30-33ms frame speed. No variable speed or relying on anything significantly faster than that.
Also acceptable: an apng that complies with the above constraints. Possibly even mpeg, if you can come up with that (I'm ignorant of how the DCT does its magic).
Ideally I could get something down in the 250kbyte range, but I'd settle for anything significantly smaller than the 9 meg monstrosity I cooked up last week.
Oh, and one last thing: obviously I don't expect anyone to supply the graphic for me. I'm just looking for some trick(s) that will let me get there myself eventually.
This is a very interesting question.
Static (random noise) by its nature is actually highly incompressible. Information theory says that true noise is basically incompressible, and the more patterns something contains the more compressible it becomes (to the point of a solid line of 1's or 0's being perfectly compressible.
The ideal would be to create a true noise generator (just random numbers), but that doesn't help within the constraints of your problem.
The best thing I can think of is storing a number of small tiles of static and displaying them in staggered fashion to prevent the eye catching on to any patterns. Aside from that, you won't have much luck compressing this beyond 256 x 192 x 20 / 2 or about 500 kilobytes ( assuming 20 frames with resolution of 256 x 192, using 4 bit color depth ).
Simply encoding your animated gif in 16 color mode should get you to that point.
Well old but still unanswered answer (not checked anyway)
so create the NoSignal image data
If it is not obvious how read this:
NoSignal in asm and C++
encode into gif
Had played with it a bit so I used resolution 320x240, the lowest bit resolution usable is 3 bit per pixel. Lower does not look good. Single global palette only (obvious) here 300KB example
[Notes]
if this is just for some app then generate the image on the run it is really just few lines of code see that linked answer in bullet #1
Yes, you can achieve that with a lossy GIF compression, or rather a specifically rigged compressor that outputs noisy LZW stream.
A best-case scenario for LZW compression is to output X pixels, then X+1 pixels, then X+2 pixels, etc. It's easy to make that noisy.
Try screwing up the gfc_lookup function to (almost) always return longest dictionary item and compress series of noisy frames with it:
https://github.com/pornel/giflossy/blob/master/src/gifwrite.c#L270
Not easily normally. Good randomness (high entropy) by definition does not compress well. Having it greyscale may help, but not much.
If you want to do this on a web page and you have (some) control, you can always write a very small bit of JS to help... if you can do this, then you can do the following:
Create a gif about 1.5x the size you need with high-entropy static.
Set the clipping to the size you want.
Then you randomly move it around by changing the starting offset.
As long as your offsets are a decent distance away from one another (and don't repeat patterns) it is usually difficult to discern it as movement, and it looks truly like static.
I did this trick about 20 years ago on an Amiga to emulate static on a limited-memory demo, and it worked remarkably well... it also does not require fast low-level code as all was done by changing offsets and the co-processor bitblit-ed the rest.

How to mark up speedometer/gauge in HTML/CSS?

As a front-end developer, I've been given a mock-up design to implement. This design features several tachograph-style icons, which have me stumped as to the best way to mark them up in HTML and CSS.
The images look like the following:
Obviously these assets represent the empty state and the full state respectively.
My issue is this: how can I mark-up these images so that I can show varying levels of completion, i.e. 10% full, 60% full etc?
Waiting in anticipation to hear your answers.
I would seriously recommend looking into the Raphael javascript library. You can knock something like this up in just a few lines of code.
See also this question: Drawing a half gauge/speedometer (JavaScript Canvas or Java Swing Example needed) where I gave an answer including a four-line code sample using Raphael, which provides an animated fuel gauge. You'll need to tweak it for your design, but even then it's only going to be a few lines of code.
The great thing about using Raphael to draw things like this is that it is fully compatible with older browsers, even IE (as far back as IE6 if you need it), without you having to do any special code to support it. It's a great little library.
Hope that helps.
Given that the image reprisents actual data and isn't purely a design mechanism, I'd mark the image up as an HTML image.
<img ... alt="10%">
If your concern is about showing portions of the image, one way you could do this would be to set the image as a background to some container and use width and height to identify the amount of the image to show.
i'm not an expert on html5 /css3, but would you not use the html5 arc command to create a mask to reveal the full state.
As you have a 270 degree rotation from empty to full, you'd just map the value as percentage of 270 to create the value of the arc that would mask the appropriate value.
I believe that there is a java script Math.PI that might help to.

HTML5 Canvas - Banding with low alpha?

Introduction
I'm currently developing a small drawing application similar to MugTug's Sketchpad. There's one pretty annoying issue I haven't managed to get around yet, though.
Drawing Algorithm
My basic draw algorithm is similar to the one used by MugTug. Basically it just stamps images using drawImage while the user is drawing. There's one serious handicap. The algorithm begins to fail with low alpha.
You can see this easily in the MugTug's tool by setting brush settings in the following way: diameter -> 100, hardness -> 1, flow -> 100, opacity -> 2 (1 is too small! bug in the app?).
There are two main issues: 1. Visible banding. 2. Color shifts (give different colors a go to see how this works...)
Questions
Could the issue have something to do with color precision? It seems to me the Canvas API treats colors using 8 bit channels (ie. 0-255). Is there any way around this limitation? I would prefer to use pure float colors (0.0-1.0) instead if possible.
Any ideas on how to deal with this are welcome. If color is indeed limited to 8 bit channels I guess I'm out of luck...
This problem seems entirely due to color precision. I think most Canvas API implementations use 8 bit RGBA channels. 1% or 2% opacity means that you are applying a very small amount of color to the image, only about 2-5 levels of difference - so even after a lot of repeated applications of the brush, any colors you use will end up being quantised down to a smaller number.
You could make your own a floating point canvas and copy it into a normal canvas after every change. That will make the problem completely unnoticeable for most operations. You'd have to implement your own drawing operations (not too bad if you only use drawImage) and they are likely to be slower than the canvas ones.
Do you see similar issues on MugTug's Sketchpad?
I tried with a 4% alpha blue brush over an orange background, and there is banding and such.
If it does better than you code then you are doing something wrong.
I've always seen canvas working with 32bit graphics (24 for color + 8 for alpha) so I doubt this can be solved.

idea for morphing captcha

I've been thinking of a dynamic way of creating a CAPTCHA that uses morphing shapes or dynamic colors.
My first idea is to have a graphic, flash or something, that gradually changes from, say a square into a sphere. The user will be required to click the button when it becomes spherical enough.
Second idea is to have an area of color that slowly changes from, say, red to blue and the user will be required to press a button when it becomes blue enough.
Third idea is a combination of both methods.
I'd say the difficulty will be to match the clicks with the transitions. But it should be hard for automated code to detect shades or shapes.
Can people please offer some comments on my idea.
edit -
Thanks for the feedback. I'm now considering using a flash based video playback of a server fed video feed of a few colored shapes that morph into other colored shapes. The user will be required to pause the feed when the colors and shapes match some canned questions: such as : click on the video when you see two green squares turn into 3 blue triangles. The shapes will be amongst over overlapping and moving morphing shapes. Fun for the whole family!
Color is a bad idea as (a) its very easy for a computer to detect; (b) very hard for some humans — the color blind — to detect. Even if you're OK with denying access to the disabled, you'd have to worry about different monitors, systems, lighting conditions, etc. giving rise to different color perceptions.
How hard do you think it is for a computer to compare the red component and blue component in a pixel (or averaged over several pixels)? Trivial. So this isn't a problem for a computer.
Similarly, it isn't that hard to program the difference between a square and a circle. One has strait lines, one doesn't!
Good idea, you could also do it so that the shapes keep turning or moving.
I don't know if it would be safer than a regular letter capcha tho.
I'm not sure why you think color would be any harder to detect than text. Shapes possibly, but they would have to be more complex than n-sided polygons. The gradual animation is a good idea however. But if you can code it to show, someone can code something that watches it.
The real test is to prove humanness by identifying semantic meanings, rather than syntactic meanings.
For instance show pictures of animals and make the user click when a bird shows up. Or just say "click on the thing that can fly." And show some pictures of animals. This would be rather unbeatable by a machine until all images had been cataloged. The trouble with CAPTCHA of course is trying to make semantics with syntax. Therefore defeating itself from the onset.
You're on the right track, and I'm sure your proof of concepts are interesting. But remember: made by a computer: solved by a computer.
Although these ideas will almost certainly work, it's a security-through-obscurity effect. Classic CAPTCHA images are "one-way" in that the correct answer can't (theoretically) be deduced by a computer. The problem with saying "click here when the image turns blue" is that a computer could easily do this, if somebody considered the stakes to be worth developing a program for.
Additionally, unusual captchas will force your users to think. Depending on your audience this may mean losing some users.
I did a fair bit of research when developing a CAPTCHA system, and the classic method of printing text to an image seems to be the most effective. The trick is not in having lots of "background noise" behind the text, or different colours. It's about the following two things:
1) Random text kerning, with most or all letters slightly overlapping each other.
2) Random distortion, translation and rotation of the text.
If you have a look at Google's CAPTCHA, they pretty well only have those two features: https://www.google.com/accounts/NewAccount?service=mail