Using CSS transforms for proportional sizing and spcing - javascript

I want to use CSS transforms to do some layouts of images, and have the image layouts be consistent across different screen widths. (For the purposes of this post, I’m only going to discuss widths and x (left) values.) All the data that I need to do these layouts are in a database.
Of course, if I could do an HTML layout with dedicated styles for each layout, I’d be fine. I could do it like I have it here in this pen. There are three boxes, 2 smaller ones and a larger one that is 3 times the size of the smaller ones. The smaller boxes are each 10% of the window width, the larger one is 30%. The boxes are equally spaced, the left-most one is 10% from the left, the larger middle one is 30% from the left and the last one is 70% from the left. This leaves an equal amount of space ( 10% ) between the boxes.
img#smallA { /* CSS for the first box */
position: absolute;
top: 10%;
left: 10%;
width: 10%;
}
The spacing is uniform when using CSS only.
On the above pen that uses CSS only, you can resize the window width all you want and the sizing and spacing stays consistent; proportional to the screen width, just as we have coded it to do.
So it seems logical that one should be able to do the same thing with a transform. You can get the window width with JS, you can set the width of the boxes with the transform and you can set the x values with the transform. But here’s the pen where I’ve tried to do it. Click the larger box to run the sizeAndPos() function. Now if you resize the window width to 1000 pixels (watch the little gizmo in the center of the CodePen screen), this JS / transform method works perfectly and the layout looks like the other one. But if you stretch it, the spacing starts going off immediately. (Remember to click the larger box after resizing). I think the reason it works at 1000 pixels wide, is b/c at that window width, the boxes are at their natural width. But I don’t understand why it only works in that case.
The spacing is off now; the between gap box 2 and 3 is too big.
For anybody how looks at the code, you may wonder why I’m passing the original width of each image (origWidth) to the function. This is because the CSS scale transform function sizes the image based on it’s original dimensions (scaling an image to 1 gives you 100% of the original size). So to do a proportional size, you first have to figure out how many pixels wide the box should be (10% or 30% of the screen width, depending on the box). Then you have to divide that amount by the original size to get the proper ratio to do the scaling. The small boxes are 100 pixels wide and the large one is 300 pixels wide.
Surely this is possible with transforms. I have tried setting the transform properties individually, to control the order of the operations, but it didn’t help. Can anyone tell me why this doesn’t work?

After trying to make this way too complicated, I found the answer. Change the transform-origin property of the elements. The default on this property is 'center' both axis. But we need our transformations to originate from the top left corner.
img#smallA {
transform-origin: left top;
position: absolute;
}

Related

Always the same size of image on all screens

I need that square image always be the same size on any screen (including mobile, tablet...). So if I take the ruler and measure image on any screen it have to be 5mm for example. It must be in JavaScript.
I wonder if the size of that image depends only of screen's DPI or it depends of screen resolution also? If in JavaScript I detect screen's DPI (and resolution if needed) is there any formula (or some JavaScript function) to calculate image size to get always the same result?
In the end, can I define image size in some unit which will ensure image to be always the same?
I asked the question here because it is connected to JavaScript, if you think that it is more suitable for some other forum please let me know.
Thanks...
If I understand correctly you want an image always to have a fixed absolute physical size. There is no way to achieve that. You can define a width with absolute units like inch, centimeter or millimeter, but the rendered result differs from one screen to another.
Every browser has set internally 1 inch = 96px, and with that base all other units are calculated. So only if a screen has a physical pixel-size of exactly 25.4 / 96 = 0.26458 mm
an element having width set to 5mm is really 5mm.
But the absolute physical size of a pixel differs widely on different screens and is not detectable by javascript.
EDIT According to your comment: Yes it is possible with your own screen. You can display an element with a width set to 200mm and measure the real width on screen in mm with a ruler. The quotient 200 / your_measurement gives you a conversion factor.
If you now want to set a width to a fixed value you have to multiply that value with the factor.
Display following file and measure the width of the red quadrat:
<!doctype html>
<head>
<style>
div {width: 200mm; height: 200mm; margin: 50px; background-color: red;}
</style>
</head>
<body>
<div></div>
</body>
</html>
The conversion factor is valid for all absolute units you want to use.
With some interaction of a user you can calibrate a users screen as they did on the ZEISS page you linked to. The user has to compare the element on screen against a fixed width (e.g. width of a credit card = 54mm). Since here the user is fixed and the code does the measurement, calculation of the factor is contrariwise: conversion factor f = code_result / 54.
I have made a FIDDLE here with 0.5mm-steps to get more accuracy.

Surrounding rectangle with and height of absolute rotated elements in Javascript

I have a few DIVs (can be images too) elements with absolute position and rotated and scaled using CSS.
How can I calculate the total width and height that the element occupy (the rectangle around then). Checking the offset() of position() doesn't give me the right results.
I need a solution in Javascript/Jquery if possible, or the Math so I can calculate it myself if there isn't any other options. Thanks.
What I've tried:
use offset, but it doesn't give me the right point
position(), but it doesn't take the rotation into account
CSS of an elements for example:
position:absolute;
-webkit-transform: rotate(-280deg);
-webkit-transform-origin: 43px 33px;
getBoundingClientRect() will be able to give you the position and dimensions of each of your elements, after any CSS transforms are applied to them.
From there, it's a matter of figuring out the total height (subtracting the minimum top from the maximum bottom) and width (subtracting the minimum left from maximum `right).
Here's a fiddle example and here's a semi-related question that should get you started.

Set bottom position of element based on rendered height of another element

Following is the url to my website
http://projectilepixels.com/beta/
I need the space shuttle to appear "naturally positioned" i.e slightly below the grass at all resolutions above 786 x 1024. However as the grass image as it's width set to 100%, the height is dynamic. Thus the bottom value for the shuttle would also be dynamic. I had initially tried using a simple css % value but that didn't help.
My current attempt uses JavaScript. Following is the code
<script>
$(document).ready(function() {
var grass = $( '#grass' );
var grassHeight = grass.outerHeight() - grass.outerHeight()/100 * 74;
$( '#shuttle_1' ).css("bottom",grassHeight);
});
</script>
The initial script just used
var grassHeight = grass.outerHeight();
however it ended up really messed up.
So, as a temp fix I added the mathematics's that calculates 74% (a solution I didn't really want to use as it uses magic numbers), it seemed to work "fine" on Mozilla at 786 x 1024, however I tested it on chrome at a slightly higher resolution (Can't remember it right now, will check the specific resolution and edit this part soon). I'm new to JavaScript and am under as to what would be the best practice to solve this problem across all browsers and resolutions
Would really appreciate if someone guided me around this problem. I'm open to using css,Javascript as well as jquery.
i would have deffently use $.position in here,
$("#Grass").position({
of: $(shuttle),
my: "top center",
at: "bottom center"
});
that will locate the the grass top line of the grass (its center), below the center of the bottom line on the shuttle
Why dont you develop a few constant values that can be applied to the actual rendered values of the grass image to adjust the placement. Something like:
Lets say the grass image is 500px x 237px but the height of the grass is only 158px – If we want the shuttle to sit right at the crown of the grass, it needs to be offset from the bottom of the screen by 158px – 158 divided by 237 works out (almost magically) to .66667
Since this is a fixed ratio, we can use .66667 to calculate the offset from the bottom of the screen for any size grass image, as long as we know the dimensions of the grass image by multiplying the height and .6667
$(function(){
var OFFSET = .66667; //this value is our shuttle adjustment constant
$( '#shuttle_1' ).css("bottom",($('#grass').height() * OFFSET)); //sets the bottom offset of the shuttle
$( '#shuttle_1' ).css("left",(($('#grass').width()/2)-($( '#shuttle_1' ).width()/2))); //centers the shuttle
});
Here is a JSfiddle demonstrating it.

Display X through div of different sizes

Problem
How would you go about displaying an X through div's of different sizes so it hits all four corners? I want one solid 1px black line to go from the top left to the bottom right of the div, and another solid 1px black line to go from the top right to the bottom left.
Example
If you're not following what I'm talking about, check out my mockup here.
Thoughts
The only solution I can think of for this problem, isn't a solution at all, but just a starting point for thinking about how to implement it. I figure I'd have two solid 1px black lines in the center of the div, and then use CSS to transform: rotate (45deg) on one line, and transform: rotate (-45deg) the other. Of course this isn't a solution that will work with any size div, since the rotation of 45 degrees will only work for a square <div>. I have a feeling I'm going to need some javascript to calculate the rotation angles. I'd really prefer a pure CSS solution, but I'm not sure CSS would be able to achieve this.
Code
Here is the code I currently have. The X is going to be placed through the .overlay class.
Edit
Edit #1: If it helps, all of my images are the same width.
Edit #2: Is there a way to use HTML Canvas lineTo() to reference corners of divs as values?
I think one possible solution for this is a CSS linear-gradient:on the background:. You create a gradient with two color breaks positioned near 50%. Se the middle break to black, and the rest to transparent. This leaves a thin black line for us to angle however we want. Then you just replicate the gradient it and mirror the angle. Something like the CSS below:
.image:hover .overlay {
//your other exising styles
background-image: -webkit-gradient(linear, left top, right bottom,
color-stop(49%,transparent),
color-stop(49%,#000000),
color-stop(50%,transparent)),
-webkit-gradient(linear, right top, left bottom,
color-stop(49%,transparent),
color-stop(49%,#000000),
color-stop(50%,transparent));
}
EXAMPLE DEMO FIDDLE
The only remaining issue is that since your images vary in aspect ratio, you can't have your "X" always hit the corners of your image. You'll need to standardize the ratio of your images, or code some javascript that will dynamically do it for each image.
Hope that helps.

Adding a scroll-bar to the raphael canvas

I am able to generate the raphael diagram , but it is exceeding the specified width and height of the Raphael canvas.
How can i add a scroll-bar to the Raphael canvas to accommodate the entire diagram within the given width and height of the Raphael canvas?
Are there any other ways or workarounds to handle the above case?
Please help. Thanks in Advance.
I was running into a similar case, and I found a way that works, although it's a bit kludgy. My first try was setting a height and overflow:auto on the container div, along with setting the Raphael paper height to 100%. However, this didn't work; it appears that if you set the paper to 100%, it grabs the height of the div as it is before the chart is inserted, so that's no good.
However, a workaround is to do the following, assuming that the container div has an id of "holder", that I need the scrollable area to be 100px high, and that the Raphael paper object should be 800px wide:
var paper = Raphael('holder', 800, '100%');
// add your graphics to the paper object here
var height = $(paper.canvas).outerHeight();
paper.setSize(800, height);
$(paper.canvas).parent().height("100px");
I used jQuery to get and set the heights, but you could do that however you wish. The important point is to not set any restrictions on the height until after you've already created all the Raphael objects, then set the height of the paper object and the containing div to whatever you wish.
Note that if you simply want everything to show up, and don't need to fit the graphic into a specific height using scroll bars, you can just pass 100% as the height to the paper constructor, and forget everything after the first line of the sample above.

Categories