【问题标题】:CSS rotate element while staying inside containerCSS 在容器内旋转元素
【发布时间】:2013-11-16 15:11:20
【问题描述】:

如果你看看:http://jsfiddle.net/KA4dz/

在这个演示中,您可以清楚地看到内部元素由于其旋转而延伸到外部元素之外。请求是缩小内部元素(同时保持纵横比和中心位置),使其适合其容器。

用例是用户可以手动旋转这样的内部元素,同时确保它留在外部元素内。 (所以简单地缩小直到适合眼睛不是解决方案)。

这是我的数学技能明显缺乏的情况。在这个阶段发布我尝试过的内容不会有多大好处。有人能指出我正确的方向吗?

谢谢!

另一个要求是内部元素仅在需要时缩小,而在不需要时从不缩小(需要意味着离开外部元素的边界)

保存点击:

.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>        

【问题讨论】:

  • 好吧,如果你想先发制人地缩小,这样它就永远不会离开容器,而不是你需要斜边与短边的比率。 50 / sqrt(100^2 + 50^2)
  • 内部块是否应该随着用户旋转项目而改变大小?
  • 这样的? jsfiddle.net/KA4dz/18
  • 那么,就是边旋转边缩放,如果确定旋转会超出外框的范围?
  • 到目前为止,我已经在 J​​S 中提出了这个问题。我知道这还不是 100%(老实说,更像是 50%),但应该给你一个开始。现在不能再花时间了。 jsfiddle.net/KA4dz/20

标签: javascript css rotation transform


【解决方案1】:

这很有趣。这是我的解决方案:http://jsfiddle.net/fletiv/jrHTe/

而 javascript 看起来像这样:

(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);

}());

编辑:这是一张试图解释我的代码逻辑的图像。 :)

【讨论】:

  • 您似乎做得很好,先生!我很乐意接受这个答案。你介意解释一下你的解决方案吗?虽然它很容易从发布的代码中推导出来,但它会帮助我和未来的读者理解逻辑!
  • 当然!添加了一张图片来解释,因为我不擅长用文字解释。 :)
  • 你的图片做得很好!
【解决方案2】:

马蒂回答的简化版

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+ ')';
}

【讨论】: