|
|
|
|
| Advertise on this site |
Friday, the 7th of August, the opening of the artistic project WebWeb, in which I took part took its place. Don`t ask me what this all means, I don`t know it myself; it`s a kind of high art. The most interesting part for me was Death: if you move the cursor left-right, you can see how the shadow falls at a horse circumscribing its outline.
In this post I`ll tell how the technical part of this page was created.
A designer sent me the model, where he draw 33 shadow states.
In principle it suited him that the shadow was changing discretely, that is it was possible just to show 33 pictures depending on cursor position and not to worry about it. But I don`t like this variant, as it has obviously lacked some sex. That`s why it was decided to make a smooth shadow shift.
Watch the shadow itself closely. Per se these are two non-intersecting lines, first, a cross bar, is simplicity itself, as for the second, one can imagine it as a common curve, redrawn by an outline (stroke). The solution of this task will look like this: we create the curves, which circumscribe each state of the shadow…
…and then we`ll calculate a new line between coordinates depending on the cursor position.
It`s important to remember that points set must be the same (that is there can`t be more or less points in one line than in another). I made it this way: have drawn the first shadow, have duplicated the path and moved the points into another position. And the same 31 times again.
We`ve drawn the lines, now it`s necessary to think of how we`ll serialize them and use them in JS. Two types of lines are possible: common, straight line and the Bezier curve. The shadow counter itself represents an array of such lines. To make it convenient and brief two proxy-functions are created, which will return the object and the coordinates:
Well, we`ve sorted it out with the format. But there is one nuance: besides the counter coordinates it`s necessary to conserve the slope angle of the line to make it possible to reckon on the new dynamic line between two already given. That`s why we create a new proxy-function, which is to create the line object according to the given coordinates.
As you see, I use the array of angles of lines shadow.degs and the hash of the lines themselves shadow.lines, where the slope angle is the key. All this is needed in order to find quickly two neighbour lines. Additionally I reckon the minimum and maximum angle to know the limits in which calculation should be done.
Ex facte, it`s the most routine and boring part of the work: now we must transfer all 33 shadow counters from the Photoshop into JS, and in the format we`ve chosen. Brute-force is to point the cursor at each point of the curve, to remember the coordinates and put them down in JS. I`ve spent an hour just to write 3-4 lines (and even those with mistakes). This is no deal, it needs to automate this process somehow.
I remember that the Adobe Illustrator has the option of the curves export into SVG, and the Photoshop has the function of the curves export into Illustrator (File → Export → Paths to Illustrator). Anyway that's something. As I don`t have the Illustrator I send the exported file to a designer and ask him to resave in SVG.
But all the same SVG isn`t the most convenient format for my task. Firstly, its Path Data has two types of data, absolute and relative. For instance, the record l10,20 means the 10 pixels shift across and the 20 pixels shift upright relative to the previous point, and the record L10,20 already means the shift into the coordinate x=10, y=20. Secondly, there is a short record of one kind instructions in SVG: for instance, L10,20 L30,40 L0,60 can be written down as L10,20,30,40,0,60 and the Illustrator is fond of using it. in general, the parsing from SVG is far from being a trivial task.
It turns that the format .ai is rather textual. Moreover, the curves coordinates are written there in a rather simple format and this is exactly what I need.
...
%Adobe_Photoshop_Path_Begin:<< /defaultFill false >>
*u
%AI3_Note:<< /operation /xor /defaultFill false >>
1 XR
551.5000 248.5000 m
596.0000 283.5000 L
601.0000 285.5000 595.5000 299.5000 607.0000 303.0000 C
616.0000 309.0000 626.0000 317.5000 634.0000 323.5000 c
642.0000 329.5000 662.5000 339.0000 670.0000 345.5000 c
677.5000 352.0000 690.5000 376.5000 699.0000 384.5000 C
711.0000 398.5000 719.0000 379.5000 y
854.5000 487.0000 l
N
*U
%Adobe_Photoshop_Path_End
...
We are to write a simple parser, which will transform the coordinates set into our format (for those who are interested here it is) and in half an hour I have got the set of all the counters.
It`s time to proceed to programming the logic itself. The algorithm of work will be the following: during the mouse is moving we`re calculating the slope angle of the line, which joins the cursor and the starting point (in our case that is a pole), we`re adding 180? to this angle and get the slope angle of the shadow. Then we find two static counters, between which the got angle is placed, we build a new counter and draw it. Simplicity itself, isn`t it? :)
Before we start, we are to remember the school course of maths and geometry. The majority of my teachers have had the common Soviet-style outlook: when I asked “what is that for?” I received an answer like “it`s necessary for you to enter the university” ,and they passed over the knowledge application in silence. If I knew I would take up programming animations and graphics, I would have been more attentive to my studies. So if you`re still studying, sit up and make notice and do not repeat my mistakes :)
The first you have to cope with is the coordinate space. It`s a little bit different in computer graphics than it is taught at school, that`s why for want of habbit I still cannot calculate normally on the paper:
As you see, the same line and its slope angle are calculated in different ways in Cartesian and computer coordinate system.
Moving the mouse we know its X and Y coordinates, correspondingly we can calculate theslope angle of the line connecting the cursor and the starting point through the arctangent. Then we just transfer this angle into another coordinate system with the help of rotation (I do not claim for the solution refinement as I have forgotten geometry and algebra):
You should remember that all the calculations with angles through Math.xxx functions must be led in radians not in angles.
Thus we have got the necessary angle, now this remains to create the shadow counter on its base. As stated above the algorithm is the following: we find two statis counters, between which the sought-for counter is located, and calculate a new one. The calculation is led this way: the segment connecting two equal points is taken, and its length is multiplied by a certain coefficient. This coefficient is calculated proceeding from the sought-for counter proximity to one of those static. Foe instance, if the sought-for counter is placed absolutely in the middle, then the coefficient will be 0.5, if it`s closer to the first one, then it will be for example 0.2 and so on. In practice, everything is simple:
He basic elements of logic are stated, we are just to gather them in one whole. For drawing I will use Canvas and for IE, correspondingly VML with the help of the layer excanvas. We write the intermediate class CanvasAdapter, which will draw the graghics according to the chosen earlier format of writing the counters, we write the auxiliary functions, tracing the movements of the cursor and the screen size changes (in order not to waste the resources to calculate the starting point coordinates of the contour) and check:
Looks not bad. Now we should pay attention to the fact that the shadow contour as it is a simple curve looks unnaturally on the horse buttocks:
We need to cut the projective contour piece. To solve this task it`s needed to create a construction from three layers. As for the first layer, we draw a straight line from the beginning till the end of the shadow as though there is no horse at all and there is naked floor. As for the second layer, it is the horse itself in PNG, it will hide the very part of the shadow which is situated under the horse. And finally the third layer, it is a full-colour shadow contour, on which the mask is put over. That is we have got two canvas-elements, between which the picture is situated.
We remember, that we`ve got a splendid converter, which can transform our inner format from ai-format, that`s why we quickly draw the mask in the Photoshop and export it into JS.
The Particular accuracy isn`t needed, here is what I`ve got:
Gather it together and look:
There isn`t much left: to cut the shadow top for it to look naturally. We can use the canvas.clearRect() method, however in IE it won`t work because of the limited excanvas support. That is why we put
And the finishing stroke is to draw a cross bar. It is a simple rectangle, which must be distorted in the right way depending on the calculated slope angle of the shadow. We solve this task the following way: we find the crossing of the current shadow contour (of a rather straight line, we don`t need any path) and of horizontal cross bar line, we distort the current coordinate space with the help of matrix transformation and draw a rectangle:
That`s it. We make the final tuning for everything to work properly and watch the final result. It remains to add that excanvas does not support masks that`s why the shadow in IE looks homely, but it`s not crucial for this project. Those who are interested may explore the source code of the page to see all the details and the awful Opera bug concerning the masks usage in canvas.
This article was written by Sergey Chikuyonok front-end developer and author of Good Sense in Web Development blog.
123213
Is there a widget for blogger
Excellent Posting, Great
hi admin . i think this post
cancel pitiable
eliminate see
Awesome Awesome Awesome!!!!!
Hi All,
THis is the very
Wichita
Nice collections!
hi buddy,
I want to this
Comments