Stretching/distorting a background image from a single point - javascript

Usually when an image is being resized in javascript or css3(using background-size), it will stretch an image from the center point. I need an image to be stretched and distorted from a single point that could be anywhere. It's going to be dynamic so I don't want to resort to using separate images.
Here's a pic that illustrates what I mean:
Hopefully there's an answer out there!

You have a few options to achieve this effect.
The "correct" way would be to use canvas to draw the image: Skewing images individually using canvas
Another way would be to fake the effect using the CSS transform skew.
http://developerdrive.com/demo/skewing_elements/skewing_elements.html
You would do this inside an element with "overflow: hidden" to make it look like a background image.

It's not even clear to me what you want from the image you're linking too. Do you want it distorted or not? And is the distortion uniform?
I'm going to guess whatever you're doing can be approximated by drawing an ever decreasing set of (or maybe rectangles) clipped from the center of a some image and drawing them onto a "canvas" (think generic term not html5 term) given new coordinates for the center of each clipping. There may be a faster way to draw this than redrawing parts of the image multiple times, it's just how I visualize it possibly working.. at least maybe in some mathematical sense.

Related

kineticJS createImageHitRegion for sprites, not images

I am using KineticJS and wish to create a precise image hit region (ignore transparent pixels) for my sprites. I see how createImageHitRegion accomplishes this for images, but I don't see how to apply this to sprites. Said another way, while method createImageHitRegion is a method which accomplishes what I want for images, there appears no similar method for sprites. If I could create an image hit region on just one image of each of my sprite that could work for me, but a big rectangular region which encompasses the entire width and height of the image of the sprite can't work. Any ideas for a workaround? Perhaps I've missed something?
There's no easy way hit-test non-transparent pixels on sprites.
I can think of a couple of theoretical workarounds...
If you can draw a path outlining the pixels you want to hit.
The sprite object allows a custom drawHitFunc so you could use mySprite.afterFrame to redefine a custom hit area for each of your sprite images.
mySprite.afterFrame(0, function() {
mySprite.setDrawHitFunc(function(){
// draw the path you want used for frame#0
});
});
// repeat for all frames
If you can't draw a path outlining the pixels you want to hit.
Instead of using sprites, make your own sprites using individual images.
Do that by creating a series of images (including createImageHitRegion) and sequentially making one of those images visible so it appears to be playing a spritesheet.

Canvas - Sticking png images together without taking into account transparent pixels

I have big horizontal strip image in photoshop which is made of lots of smaller elements. The background is transparent and the strip goes from smaller elements (left) to bigger elements (right). My goal is to make this strip interactive to mouse events.
Each element is some kind of polygonal image which is trimmed left and right and then exported as a png. It is then imported into a canvas.
The problem is that I can put them side by side but since they are not rectangles I need a way to calculate the offset made up by the transparent pixels on each side of each element to make them stick together correctly... I am using KineticJs to get a precise hitarea for each element... So maybe there is a way to do it automatically with kineticjs,or there is some kind of operation I could do using each image data?
My problem illustrated:
Any ideas?
Also I am doing this simply because I would prefer precise mouseOver bounding box on each item (rather than a simple rectangle) and would rather avoid the solution to calculate each offset manually... But maybe that's not worth it?!
Ok, so you have yourself a custom shape you want to use, here is a tutorial for that: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-shape-tutorial/ , the simplest thing you can do, and even that seems fairly long, is to calculate the bounding lines for that shape. (Two somewhat vertical lines, and two somewhat horizontal lines). Then you test if the right vertical line of shape one crosses with the left vertical line of shape two, if they do, then set the coordinates of the images to be the same coordinate.
http://www.mathopenref.com/coordintersection.html
line1 = ax + b ..... line2 = cx+d //see possible tests
if(...intersection test...){ // or just test if some coordinate is left of some other coordinate
shape2.setX(shape1.getX()+shape1.getWidth()); //account for image width, so they don't overlap
shape2.setY(shape1.getY()) // no need to account for height
}
UPDATE: This is a very rough solution to the workings of the problem. The next step would be to do more fine tuning dependent on each image.
http://jsfiddle.net/9jkr7/15/
If you want precise areas, use an image map. With some clever finagling and a blank image gif you should be able to have the background you want whenever you hover over any particular area of the image map (might require javascript).
The other option I can think of would be to use SVG itself or one of the many libraries in existance to build interactive vector graphics into your page.
You could also write a function that calculates the left most, top most, right most, and bottom most pixel by looking at all of the pixels in the image data. Here's a tutorial on that:
http://www.html5canvastutorials.com/advanced/html5-canvas-get-image-data-tutorial/

HTML5: Rendering absolute images using canvas

I am experimenting with canvas as part of my HTML5 introduction. This constitutes as assignment work, but I am not asking for any help on the actual coursework at all.
I am trying to write a rendering engine, but having no luck because once the image is drawn on canvas it looks very distorted, and not at the right dimensions of the image itself.
I have made a animation engine that loads images into an array, and then iterates through them at a certain speed. This is not the problem, and I assume is not causing the issue as this was happening when I drawn an image to the canvas without the animation component.
I think this is natural behaviour for images to be scaled/skewed when the window is resized, so I conquered that by simply redrawing the whole thing once the window is resized.
The images I am using are isometric, and drawn at a pixel level. Would this cause the distortion? It seems setting the dimensions on the drawImage() function are not working are all. I am using JavaScript for the manipulation and rendering of the canvas.
I would normally try and work it out myself, but I do not have any time to ponder why because I have no idea why it is even scaling/skewing the image once it is drawn on the canvas. I cannot share the code for obvious reasons. I should also mention, the canvas's dimension is the total width of the viewport, as I am developing a game.
My question is: Has anyone encountered this and how would I correct it?
Thanks for your help.
Seems that you set dimensions of canvas with css.
Try defining them as html attributes. Example:
<canvas id="test" width="100" height="100">Fallback content</canvas>
Edit:
It will set width/height of canvas element to 100/100 pixels.
Yes, the problem was I was setting the canvas's dimensions with CSS. The canvas element is treated like an image, and I was actually scaling the canvas with CSS not resizing it. Thanks for the help. – Mark just now

How to simulate magnifying glass on Web-page image (Javascript)?

Google has the coolest effects - once it was a Pac-man game, today is apparently the 160th anniversary of the first World Fair, and Google's logo has an image of it. They also turn the mouse into a magnifying glass that can sweep over the picture (the gold ring).
I'm wondering how they do that. It's obviously Javascript, and I looked at the page source, but it's not especially readable (no surprise).
Looking at their source code, it seems they are using rather basic techniques to achieve this.
Ignoring all the embedded nifty animated gif's, there are basically two images - large, and small of the entire scene. The larger image is repeated thrice in the document. Look at the annotated image below to get a better idea of how the zoom works.
The portion inside the magnifying circle is split up in three div's - top, mid, and bottom. The overflow for each div should be hidden. Each div is relatively positioned inside the zoom circle. On mouse move, change the absolute position of the zoom circle to the mouse coordinates. Their example also uses CSS3 for the scaling and adding some animation delays.
Here's a sorta minimal reconstructed example.
Another example where we don't hide the div overflow to reveal the entire thing as a square.
Well, firstly, for anyone who wants to use such an effect, there are loads of jQuery plugins. Here are just a few:
Power Zoomer
Featured Image
Zoomer
Cloud Zoom
Secondly, it's quite easy to achieve. Just load the full-size image, but give it a width smaller than it's actual width, so it is scaled by CSS. Then, use JavaScript+CSS to create a Div (the magnifying glass) with the same image as background, but change the background-position property to the corresponding scaled x,y coordinate that the user's mouse is currently on.
There are other ways of doing it I suppose, and Google might be doing it differently, but this is the most obvious way for me that comes to mind.
Visit http://codeblab.com/glass/ for an real life example and in depth explanation of this technique. Flash and CSS v3 have ample functionality to construct a round magnifying glass.
However, simulate-a-circle-with-overlapping-rectangles works on (many) more platforms.
(DISCLOSURE: codeblab.com is my personal hobby blog with some weak links to my work in The Netherlands.)
There is a full example of magnifying any sort of HTML, including HTML5 at http://www.aplweb.co.uk/blog/js/magnifying-glass/. Works cross-browser too - although rounded corners are a bit iffy on most browsers - so you are going to have to use a box rather than circle.
Here is how to works:
Duplicate the content you want to zoom
Place the duplicated content into another element and set the visible width/height and overflow hidden
Use JavaScript to move the duplicated content so that it moves by the zoom amount * mouse movement. Also move the visible div by the mouse movement.
That is pretty much it too it. There are lots of little things to look out for though to make it work on all browsers.
I don't know how Google does it, since the logo is no longer showing in my area; but this effect can be achieved by clipping the enlarged animated GIF over the regular image using canvas. Alternatively, it is also possible to create create a circular clipping using CSS border-radius (commonly used to implement rounded corners).
EDIT: I've hacked this up together to show the basic technique that you need if you used CSS border-radius: http://jsfiddle.net/yjBuS/
Looks like they're using two images, one for the logo and one for the zoom (the zoomed one is actually sliced, to run the animations separately...?) They probably detect if the mouse is over the normal logo, then show the yellow circle and attach it to the mouse position. Then showing the other image, shifting it opposite of the mouse. Or something similar.

Javascript/JQuery Image Cutter

Okay my last question got no response. I think I didn't ask the way I should do.
Basically my requirement is similar to this one Programmatically Clip/Cut image using Javascript
But following that link will result in a rectangle view of any portion of the image but I want to clip it any direction (polygon). Would that be possible?
There is not a good way to make an arbitrary polygon shape with the HTML 4 DOM. If you were using canvas I'd say you could do it that way. Your other option would be to just have a transparent png (and gif for IE6) on top and then the image underneath that and absolute positioned similarly to the other answer you referenced.

Categories

Resources