Вращающееся изображение плохо помещается в родительский контейнер

0

Я создал директиву для поворота и изменения размера (масштабирования) изображения. В настоящее время я выполняю это, манипулируя встроенным стилем элемента. Я использую css transforms (rotate и scale).

Мой текущий подход к вращению изображения заключается в том, чтобы повернуть его в верхнем левом углу в качестве источника, а затем переместить изображение обратно в поле с полями. Для масштабирования я также пересчитываю новые эффективные размеры изображения, умножая исходные размеры на коэффициент масштабирования.

У меня есть масштабирование и вращение, но нестандартные вращения не помещаются в родительский контейнер. Например, при повороте на 180 градусов изображение имеет кучу лишних пробелов под ним, что расширяет его без видимых причин.

Директива:

function directive()  {
    return {
        restrict: 'A',
        scope: {
            options: '='
        },
        link: link
    };

    function link(scope, element, attributes) {
        element.bind('load', function()  {
            if (!scope.options.originalSize) {
                element.removeAttr('style'); //clear all previous styling

                //workaround for IE (it dumb, and I'd rather just use this element (element[0]) data)
                var img = document.createElement('img');
                img.src = element[0].src;
                scope.options.originalSize = {
                    height: img.height,
                    width: img.width
                };
                scope.options.scaling = 1.0;
                scope.options.rotation = 0;
            }
            transformWithCss();
        });

        scope.$watch('options.rotation', transformWithCss);
        scope.$watch('options.scaling', transformWithCss);

        function transformWithCss()  {
            if (!scope.options || !scope.options.originalSize)
                return;

            var width = scope.options.originalSize.width * scope.options.scaling;
            var height = scope.options.originalSize.height * scope.options.scaling;
            var marginTop, marginLeft;

            var effectiveRotation = (scope.options.rotation % 360 + 360) % 360;
            switch (effectiveRotation) {
                case 0:
                    marginTop = 0;
                    marginLeft = 0;
                    break;
                case 90:
                    marginTop = 0;
                    marginLeft = height * scope.options.scaling;
                    break;
                case 180:
                    marginTop = height * scope.options.scaling;
                    marginLeft = width * scope.options.scaling;
                    break;
                case 270:
                    marginTop = width * scope.options.scaling;
                    marginLeft = 0;
                    break;
                default:
                    //how did we get here? throw exception?
                    alert("something went wrong with rotation");
                    break;
            }

            element.css({
                "transform": 'scale(' + scope.options.scaling + ') rotate(' + scope.options.rotation + 'deg) ',
                "width": width + 'px',
                "height": height + 'px',
                "transform-origin": '0px 0px',
                "margin-top": marginTop + 'px',
                "margin-left": marginLeft + 'px'
            });
        }

    }
}

Использование в HTML:

<div class="parent-div col-md-10 col-lg-10">
  <p>Some other content</p>
  <div class="image-holder">
    <img scaling-rotating-image="" options="ctrl.imageOptions" src="//lorempixel.com/500/300/cats/" />
  </div>
</div>

Демоверсия плункера. Обратите внимание на разные цветные границы.

Почему моя директива не обрабатывает вращение грациозно? Почему его родительский div делает действительно странные вещи при изменении размера?

  • 0
    Вы рассматривали возможность использования абсолютного позиционирования на изображении, чтобы не было пробелов? Обратите внимание, что если этот подход будет принят, то вам придется обрабатывать размеры «держателя изображения», потому что абсолютное позиционирование удалит соответствующий элемент из потока документов.
  • 0
    @Todd Тодд спасибо за помощь. Если у вас есть время опубликовать ответ, это было бы здорово. Я получил это работает благодаря этому предложению. Если нет, я просто отвечу на свой вопрос.
Теги:
css-transforms

1 ответ

1
Лучший ответ

Благодаря совету Тодда я решил свои странные проблемы с пробелами, используя position: absolute. Чтобы компенсировать это, мне также пришлось переназначить родительский контейнер. Здесь обновленная функция transformWithCss:

function transformWithCss()  {
    if (!scope.options || !scope.options.originalSize)
        return;

    var width = scope.options.originalSize.width * scope.options.scaling;
    var height = scope.options.originalSize.height * scope.options.scaling;
    var marginTop, marginLeft;
    var parentHeight, parentWidth; //to redimension the parent container

    var effectiveRotation = (scope.options.rotation % 360 + 360) % 360;
    switch (effectiveRotation) {
        case 0:
            parentHeight = height * scope.options.scaling;
            parentWidth = width * scope.options.scaling;
            marginTop = 0;
            marginLeft = 0;
            break;
        case 90:
            parentHeight = width * scope.options.scaling;
            parentWidth = height * scope.options.scaling;
            marginTop = 0;
            marginLeft = parentWidth;
            break;
        case 180:
            parentHeight = height * scope.options.scaling;
            parentWidth = width * scope.options.scaling;
            marginTop = parentHeight;
            marginLeft = parentWidth;
            break;
        case 270:
            parentHeight = width * scope.options.scaling;
            parentWidth = height * scope.options.scaling;
            marginTop = parentHeight;
            marginLeft = 0;
            break;
        default:
            //how did we get here? throw exception?
            alert("something went wrong with rotation");
            break;
    }

    element.css({
        "position": "absolute", //absolute positions removes weird whitespace
        "transform": 'scale(' + scope.options.scaling + ') rotate(' + scope.options.rotation + 'deg) ',
        "width": width + 'px',
        "height": height + 'px',
        "transform-origin": '0px 0px',
        "margin-top": marginTop + 'px',
        "margin-left": marginLeft + 'px'
    });

    //redimension parent container
    element.parent().css({
        "height": parentHeight + 'px',
        "width": parentWidth + 'px'
    });

}

Обновлен рабочий плункер.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню