CSS JQuery Rotate image inside container

Viewed 701

I am trying to rotate an image inside a container.

The container width must have a limit, and so should the height.

I was able to accomplish it with the following code, but there is an issue with one of the images.

When image 2 is rotated sideways, or 45 degrees, it jumps outside of the borders.

It works fine for the other images.

What am I doing wrong?

var   degrees = 0;

function x () {

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('testImg'),
    rotator = setRotator(testImg);

 degrees += 45;
 if (degrees >= 360) {
        degrees = 0;
    }
rotator.rotate(degrees);
}

$('#btn1').click(function(){
x()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button onclick=document.getElementById('testImg').src='https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/smile.svg'>Img1</button>
<button onclick=document.getElementById('testImg').src='https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/juanmontoya_lingerie.svg'>Img2</button>
<button onclick=document.getElementById('testImg').src='https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/php.svg'>Img3</button>
<button type="button" id="btn1" >Rotate Div</button>

<DIV id="container" style=" width:60%;">

  <DIV id="outer" width="100%" style=" position: relative;border-style:dotted;">
    <img id ="testImg" src="https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/smile.svg"   style="width:100%;height:100%;border-style:dotted;border-color:red;">
  </DIV>
</DIV>

1 Answers

You'll need to position the image absolutely within the div and edit the scale so that it's positive and never greater than 1. I have a working version here: https://jsfiddle.net/e9h30w1z/

I've added this CSS

img {
    max-width: 100%;
    max-height: 100%;
    height: auto;
    width: auto;
    position: absolute;
    object-fit: contain;
    left: 50%;
    transform: translate(-50%);
}

#outer {
  height: 0;
  padding-bottom: 100%;
}

I edited the CSS rule being added within the setRotation method to include translate(-50%) (this is part of the image positioning)

And I changed the return statement of the getScale method to the following:

scale = (originalHeight / Math.cos(sum)) / originalFactor;
return (Math.abs(scale) > 1) ? 1 : Math.abs(scale);

As a note, negative scale flips the image which is why one of my attempts started skipping positions.

Related