If you take a a look at: http://jsfiddle.net/KA4dz/
In this demo, you can clearly see the inner element reaching outside of the outer element due to its rotation. The request is to scale down the inner element (while maintaining aspect ratio's and center positioning) just so it fits within its container.
The use-case is that the user can manually rotate such an inner element while ensuring that it stays within the outer element. (so simply scaling down until it fits for the eyes is not a solution).
This is a scenario where my math skills are clearly lacking. Posting what I've tried wont do much good at this stage. Can someone point me in the right direction?
Thanks!
One additional requirement is that the inner element only scales down whenever its required but never scales down when its not required (where required means leaving the boundaries of the outer element)
To save a click:
.outer{
border: 1px solid black;
width: 100px;
height: 50px;
margin: 100px;
}
.inner{
background: blue;
width: 100px;
height: 50px;
transform: rotate(-40deg);
-webkit-transform: rotate(-40deg);
}
<div class="outer">
<div class="inner">
</div>
</div>
This was interesting. Here's my solution: http://jsfiddle.net/fletiv/jrHTe/
And javascript looks like this:
(function () {
var setRotator = (function () {
var setRotation,
setScale,
offsetAngle,
originalHeight,
originalFactor;
setRotation = function (degrees, scale, element) {
element.style.webkitTransform = 'rotate(' + degrees + 'deg) scale(' + scale + ')';
element.style.transform = 'rotate(' + degrees + 'deg) scale(' + scale + ')';
};
getScale = function (degrees) {
var radians = degrees * Math.PI / 180,
sum;
if (degrees < 90) {
sum = radians - offsetAngle;
} else if (degrees < 180) {
sum = radians + offsetAngle;
} else if (degrees < 270) {
sum = radians - offsetAngle;
} else {
sum = radians + offsetAngle;
}
return (originalHeight / Math.cos(sum)) / originalFactor;
};
return function (inner) {
offsetAngle = Math.atan(inner.offsetWidth / inner.offsetHeight);
originalHeight = inner.offsetHeight;
originalFactor = Math.sqrt(Math.pow(inner.offsetHeight, 2) + Math.pow(inner.offsetWidth, 2));
return {
rotate: function (degrees) {
setRotation (degrees, getScale(degrees), inner);
}
}
};
}());
var outer = document.getElementById('outer'),
inner = document.getElementById('inner'),
rotator = setRotator(inner),
degrees = 0;
window.setInterval(function () {
degrees += 1;
if (degrees >= 360) {
degrees = 0;
}
rotator.rotate(degrees);
}, 50);
}());
Edit: Here's an image which tries to explain the logic of my code. :)
A simplified version of Matti's answer
var scaler = function (id, degrees) {
var inner = document.getElementById(id);
offsetAngle = Math.atan(inner.offsetWidth / inner.offsetHeight);
originalHeight = inner.offsetHeight;
originalFactor = Math.sqrt(Math.pow(inner.offsetHeight, 2) + Math.pow(inner.offsetWidth, 2));
var radians = degrees * Math.PI / 180,
sum, result;
if (degrees < 90) {
sum = radians - offsetAngle;
} else if (degrees < 180) {
sum = radians + offsetAngle;
} else if (degrees < 270) {
sum = radians - offsetAngle;
} else {
sum = radians + offsetAngle;
}
var result = (originalHeight / Math.cos(sum)) / originalFactor;
inner.style.webkitTransform = 'scale(' + result+ ')';
inner.style.transform = 'scale(' + result+ ')';
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With