Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.
seen from China

seen from Canada

seen from United States
seen from China

seen from Malaysia

seen from Malaysia
seen from China
seen from China

seen from Belgium
seen from China

seen from United States
seen from Bosnia & Herzegovina

seen from Belgium

seen from Bosnia & Herzegovina
seen from Canada
seen from United Kingdom
seen from Netherlands
seen from France

seen from United States

seen from Poland
Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.
Railsで画面の一部をキャプチャして画像としてダウンロードできる機能をつけてみた。
(photo credit: Stuck in Customs via photopin cc)
絶賛運営中の「THE TOURNAMENT」ではトーナメント表をjsで出力してて、 これはこれでインタラクティブな感じにできたりといいんですが、やはり画像で保存したいというニーズも根強い。
そこで画面のこの部分だけを画像としてダウンロードできる機能をつけてみた。 よくある機能な気がしてたし余裕かと思ったけど意外とめんどくさかったです。。
Screenshots
One of our most requested features is the ability to have screenshots sent in with user feedback. So we're excited to announce that you can now enable this on your applications!
How to enable screenshots
Go to your application's setup page (open an app, click on the cog under your name in the top right corner, and select setup). From the left hand menu, select "Javascript", and you should see a new section called "Screenshots". Select the checkbox, and click save.
Now if you visit your site and click the feedback tab, you should see an extra checkbox where you can optionally attach a screenshot.
The screenshot is added as an attachment to the feedback thread.
Enjoy!
PS You can keep up to date either via this blog, or you can follow us on Twitter.
client-side ile screenshot
Şuan çalıştığınız projede önünüze bir ekran görüntüsü ile ilgili bir feature koysalar ne düşürdünüz? "acaba ne ile screenshot alsam?" dimi? Heh, bende yaklaşık olarak aynı sebepten ötürü bu konuda biraz araştırma yaptım ( poc amaçlı ). Bu tür konularda önünüze iki seçenek çıkıyor:
Client-side screenshot almak
Server-side screenshot almak
Server-side teknolojilere çok bakmadım. Ancak aklıma ilk olarak PhantomJS geldi. PhantomJS, aslında sadece screenshot almak değil ancak yapısı itibariyle bu işi gayet şukela bir şekilde yapabiliyor. PhantomJS kullanmakta işimi görüyordu, ancak server-side bu işi yaparsam kullanıcının etkileşimlerini çok yakalamıyordum. Yani; bir lightbox açıldığında, tab değiştiğinde vb.
Bunun içinde bu işi client-side yapmak daha mantıklıydı. Bunun içinde html2canvas diye bir library buldum. Bu arkadaş HTML5'n nimetlerinden son derece faydalanıyor diyebiliriz.
html2canvas(element, options);
element: HTMLElement sınıfından türeyen herhangi bir obje verilebilir. Bu sayede screenshot alınmak istenilen nesne / alan belirlenir.
"options" tarafını anlatmaya gerek yok zaten documentation içerisinden çok rahat bakılabilir ve araştırabilir. Burada sıkça kullanacağımız "onrendered" methodu var. Buraya bir fonksiyon tanımlayıp, screenshot sonucu oluşan base64 data'yı kullanıp, istersek sayfa üzerinden gösterim yapabilir istersekte veriyi back-end'e paslayıp işleyebiliriz.
Not olarak şunu belirtmem gerekiyor ki eğer çakallık yapayım "abi ben body element'ini verip ekranın komple görüntüsünü alayım" derseniz sorun yaşarsınız. Çünkü sadece visible alan üzerinden işlem yapıyorsunuz -- eğer sayfada scroll varsa --. Bu sorun üstüne çok durmadım. Belki bir çözümü vardır yada ben becerememişimdir.
Rendering webpages in 3D with JavaScript and WebGL
When I originally started working on the html2canvas project, I was trying to create a 3D representation of the webpage using WebGL. While I did end up getting a very elementary version created, it occurred to me that the real value of the project (if there was any) was in fact with a 2D representation of the webpage, or as some would call it, a "screenshot". That's where the project originally got started and the 3D rendering target eventually died off.
If you are familiar with browser render trees, and how they are formed, quite a lot of similarities can be found with html2canvas. The html2canvas library creates the "screenshot" of the page by evaluating the DOM. It iterates through every node on the page, evaluates the computed styles such as position, dimensions, borders, border-radius, colors, backgrounds, z-index, floats, overflows, opacity etc. Using this information, it forms a render queue which simply consists of calls to the canvas element, such as "draw shape with n-coordinates and fill it with x-color". The canvas doesn't eat CSS, so each CSS property that applies a style you want to render, needs to be implemented separately and as such, the projects scope is really never ending.
The fact that the text rendering methods available with canvas are slightly limited makes things just a bit more complicated. You can't for example set letter-spacing when rendering text, so to apply the effect, you'll need to calculate the position of each letter on a page manually and render them separately. Considering calculating the position of the text isn't trivial to begin with, and requires different approaches depending on the browser, it does have performance implications.
Another problem area lies with rendering images. You can render most images to a canvas without a problem, but if the images aren't from the same-origin as the page, they will end up tainting the canvas. In other words, the canvas won't be readable anymore (getImageData/toDataURL). This in fact isn't even limited to cross-origin images, but for example with Chrome, SVG images taint the canvas as well. To work around this problem, the library can attempt to sniff whether the image taints the canvas and ignore it if it does, or use a proxy to load the image so it can be safely drawn. The images can also be attempted to be loaded with CORS enabled, but unfortunately images are rarely served with the required headers.
With the render queue formed, its just a matter of applying the queue onto a canvas element and you'll get your 2D "screenshot" of the webpage. However, the purpose of this blog post was to illustrate how to create a 3D representation of the webpage. It is in fact very easy to form the 3D representation using the screenshot as a diffuse map and just creating a heightmap using the same rendering queue we formed earlier. However, instead of using the calculated colors, you swap them to a color based on the DOM tree-depth of the element that formed the render item.
Using the heightmap, we can then form the appropriates vertices and triangles based on where the depth changes. I decided to pre-calculate the vertex positions instead of doing it within the vertex shader to avoid forming unnecessarily many vertices. While forming the vertices, each vertex will be assigned a color based on the pixel color from the diffuse map. For the vertices forming the vertical faces (i.e. depth differences), I applied a shadow depending on the direction of the face, to slightly give it a feel of some lighting.
To form a better view for distance and to add artificial detail to the page, I formed the fragment shader to draw squares on the faces, to give the illusion of them being constructed of small cubes (1 cube is approximately 1x1 pixel). Additionally, a small fog is applied in the fragment shader as well to give the depth even further clarity, as it may not be as evident with single colored faces.
For the physics and collision detection I set up a very simple detection based on the heightmap map data which just checks whether the camera is on the floor and whether it crosses a boundary that has a higher heightmap level than where it currently resides.
When considering what the library goes through to form 3D representation of a webpage, I personally find it quite amazing how fast some of the browsers are able to process it. Keeping in mind that the library could be evaluating thousands of nodes, tens of thousands of letters, for each, processing lots of different CSS properties that can result up to hundred thousand calls to the canvas drawing context. From there, it forms the geometry which can easily end up of consisting over a million vertices, with half a million triangles, which it dumps into the GPU and a full 3D representation of the webpage pops up within a second or two.
Of course the type of page and the amount of content impacts a lot on the performance, as well as the type of computer/browser you use and how many images needs to be pre-loaded prior to parsing the DOM. If you want to give 3D browsing a go, I've added it to my own homepage, and its accessible with the hashtag #3d. If you want to try it on your own page, you can get the built script from here or view the sources at GitHub.
Please keep in mind the image cross-origin limitations. If you wish to try the script without hassle on any page, you can use it through this chrome extension, which works around the cross-origin image issue.
If injecting unknown scripts into your browsers console is your thing, here is a snippet ready for you:
(function(d) { var s = d.createElement("script"); s.src = "http://hertzen.com/js/domfps.min.js?v2"; d.body.appendChild(s); })(document);
Or you can execute it on this page by clicking here.
Corkboard: Online image pasting/collage making
So this weekend inspired by a project a couple of friends are doing I decided I fancied hacking around with the HTML5 paste API. This quickly and rapidly turned into Corkboard, which you can see at http://pastey.samatkinson.com. Here's a corkboard of some of the photos of me playing recently to satisfy my massive ego.
All in all I'd guess it's probably taken somewhere between 6-8 hours, of which most was due to my inability to RTFM and the fact Javascript hates me. Most of the project is just mashing up a bunch of pre existing ingredients.
STRd6 imgpaste plugin
When googling around for how to do it, most of the stackoverflow esque threads had been jumped on by STRd6 to point to the plugin he wrote, and I salute him, because it works a treat. You can find it at here. It binds to the paste command, checks it it's an image, and if it is calls your callback with the file and the img encoded as a dataurl (particularly awesome/handy). In no time I was pasting images to the top left of a blank page with a bit of jquery append() fun.
JQuery UI draggable and resizable
You can find these here and here respectively. They should pretty much work out the box which is nice. However, I wanted more than just images; If you mouse over an image you can remove it from corkboard. This was some CSS/JS magic lightly stolen from a friends project, but meant wrapping the image in a div. I wasted a lot of time trying to figure out how to make the img resize at the same time as the div. If you RTFM you'll discover this wonder:
$pasteimage .draggable() .resizable({ alsoResize: $pasteimage.find('img'), aspectRatio: true } )
Pay special attention to alsoResize. This is the key to the gold.
To avoid manually generating the HTML at this point I created a simple template in handlebars.
Bootstrap
So now we can drag and resize images, but it's fugly. Along comes bootstrap, the HTML5 UI starter package from the folks at Twitter. HIstorically I've always used foundation for making my sites pretty, but I wanted to branch out. I've not done anything advanced, just a nav bar with drop down and a little form; The form inside nav bar situation is hard to do in foundation, so I was relieved to see it's built in in bootstrap. I had my usual pebcak issues of incorrect ordering/import of CSS and JS, but once up and running, it was very easy to use, and I think overall looks nicer than foundation.
Save as an image
So one of the nice features about corkboard is that you can save it to your local machine as an image. This was a mashup of 2 plugins; HTML2Canvas and Canvas2Image. The first traverses the DOM of whatever element you pass it and renders it out as a Canvas; I imagine this may have issues if you're doing anything very funky in your code but it worked out the box on this. Canvas2Image then gives you a whole bunch of images for turning a canvas into an image, and for downloading it. Both plugins worked seemlessly, pretty much first time. Very impressive.
html2canvas($('#theFunStuff'), { onrendered: function (canvas) { Canvas2Image.saveAsPNG(canvas); } })
And that's basically the whole thing. There's tons more I want to do (being able to raise/lower layers, rotating, persistance), but that's for another day. There's also some issues on HTML2Canvas2Image depending on where the images are when the save happens I need to look into.
Render testing in html2canvas with webdriver
Automated testing for [html2canvas](http://html2canvas.herzen.com/) has been an issue for a long time already. The library has had a number of [qunit tests](https://github.com/niklasvh/html2canvas/tree/master/tests/qunit/unit) that check that different parsed DOM values are correctly calculated across all browsers, but they only touch the surface of the testing requirements of the library. ### Problem ### The purpose of html2canvas is to generate as close of a representation of the DOM, as it is rendered by the browser the script is ran on. In other words, there is no one clear result it should render for any given page, but instead it should attempt to represent the page as it is rendered with that particular browser on that particular screen with any browser specific issues that may be present. If the browser doesn't support some particular CSS properties, the result shouldn't render them either. This meant that there couldn't really be any premade screen renders that could be used to compare the results generated by html2canvas, as the results would and should vary between browsers and systems. ### Approach ### Version 0.4 will introduce testing capabilities with [webdriver](https://github.com/niklasvh/webdriver.js) which will allow automating the testing on a number of different browsers, while still taking into account the expected differences in results. The tests capture a screenshot of the actual browser, after which html2canvas runs and renders its representation of the page. The base64 encoded png images are then sent back to node where they are first converted into an arraybuffer and then into pixel arrays. It then calculates the percentage difference between the two images by comparing them pixel by pixel. The results are then compared to previous baseline values which allows us to analyze whether there has been any changes in the results. Sample results from the tests can be previewed [here](https://github.com/niklasvh/html2canvas/blob/develop/tests/readme.md). The reason the html2canvas render is sent as a base64 encoded string and converted into a pixel array in node instead of simply sending a [CanvasPixelArray](https://developer.mozilla.org/en-US/docs/DOM/CanvasPixelArray) is because it is a lot faster. ### Analyzing the results ### The results vary a lot depending on the browser, with Chrome generating the most accurate results. The slightly lower results in Firefox are mainly caused by slight displacement of some texts and some aliasing issues. For IE9, the results with text are lot worse, which is in part to be expected considering there is no support for [getBoundingClientRect](https://developer.mozilla.org/en-US/docs/DOM/element.getBoundingClientRect) for text ranges and a slightly less accurate method of finding text positions have to be used. With the automated tests in place, updating and improving the library is significantly easier and less time consuming, and will hopefully result in more frequent updates from me as well. Overall, it was satisfying to see that there were a number of tests that are 100% accurate to what the corresponding browser renders.
HTML2Canvas : Take Screenshots of Webpages http://ow.ly/5Zy8l WebDev HTML5 Canvas