CSS Transform Math - 计算由skew引起的div高度

时间:2013-09-06 17:34:11

标签: javascript jquery css css3 math

我很难弄清楚如何计算因倾斜而导致的div容器的额外高度。我正在屏蔽容器内的图像并使用plugin调整其大小。

容器的高度和宽度并不总是相同,因此使用固定尺寸将不起作用。我对数学不太了解,所以任何方向或帮助我都会很感激。

请参阅我的demohttp://jsfiddle.net/RyU9W/6/

HTML

<div id="profiles" class="container">
        <div class="profile">
            <div class="image">
                <img src="http://placekitten.com/g/750/750" alt="">
            </div>
            <div class="detail">
            </div>
        </div>
        <div class="profile">
            <div class="image">
                <img src="http://placekitten.com/g/750/750" alt="">
            </div>          
            <div class="detail">
            </div>
        </div>        
        <div class="profile">
            <div class="image">
                <img src="http://placekitten.com/g/750/750" alt="">
            </div>          
            <div class="detail">
            </div>
        </div>
        <div class="profile">
            <div class="image">
                <img src="http://placekitten.com/g/750/750" alt="">
            </div>          
            <div class="detail">
            </div>
        </div>        
        <div class="profile">
            <div class="image">
                <img src="http://placekitten.com/g/750/750" alt="">
            </div>          
            <div class="detail">
            </div>
        </div>
        <div class="profile">
            <div class="image">
                <img src="http://placekitten.com/g/750/1200" alt="">
            </div>          
            <div class="detail">
            </div>
        </div>            
</div>

CSS

#profiles {
    margin-top: 300px;
    transform:skewY(-30deg);
    -ms-transform:skewY(-30deg); /* IE 9 */
    -webkit-transform:skewY(-30deg); /* Safari and Chrome */    
}
.profile {
    cursor: pointer;
    float: left;
    width: 32.25%;
    margin: 0.5%;
    position: relative;
}
.profile .image {
    position: relative;
    overflow: hidden;
    height: 400px;
    background: #000;
    backface-visibility:hidden;
    -webkit-backface-visibility:hidden; /* Chrome and Safari */
    -moz-backface-visibility:hidden; /* Firefox */
    -ms-backface-visibility:hidden; /* Internet Explorer */     
}
.profile .image * {
    position: relative;
    transform:skew(0deg,30deg);
    -ms-transform:skew(0deg,30deg); /* IE 9 */
    -webkit-transform:skew(0deg,30deg); /* Safari and Chrome */         
}

6 个答案:

答案 0 :(得分:3)

没关系数学,快速测试似乎显示了比例。

由-30deg倾斜的100px框变为100x160px。

偏向-20度的100像素盒变为100x140像素。

以-10度为偏差的100像素盒变为100x120像素。

所以它似乎在高度上加上(abs(deg)* 2)%。因此,如果你偏向-30度,则将你的起始高度乘以1.6作为总高度,1.3乘以高度+一边,或者仅仅偏移一边为0.3(即如果你想弄清楚有多远)抵消上限或其他)

答案 1 :(得分:3)

 在偏斜中,我们有一个直角三角形的情况,并且偏斜的新宽度等于“对面”,并且我们有该角度,反之,因此通过此方程式,我们可以得到相邻的对面=相邻* tan(angle);如果skewX相反,则是div的高度,如果倾斜skewY,则是div的宽度

选中此https://codepen.io/minaalfy/pen/exgvjb

[
  {
    "operation": "shift",
    "spec": {
      "types": {
        // get but don't match so next copy works. 
        // Using value of coupontype1.0.total|nextPage and set to types
        "@(coupontype1)": {
          "0": {
            "total": "types.&",
            "nextPage": "types.&"
          }
        },
        // copy everything
        "*": {
          "@": "types.&1"
        }
      }
    }
  },
  {
    //remove total and nextPage
    "operation": "remove",
    "spec": {
      "types": {
        "*": {
          "*": {
            "total": "",
            "nextPage": ""
          }
        }
      }
    }
  }
]
function calculateSkew(){
  var el = document.getElementById('bluebox');
  var skewX = document.getElementById('skewX');
    skewX.value = skewX.value || 0;
  var skewY = document.getElementById('skewY');
    skewY.value = skewY.value || 0;
    
  var yRadians = skewY.value * Math.PI / 180;
  var newHeight = el.offsetWidth * Math.tan(yRadians);
  var calculatedHeight = el.offsetHeight + newHeight;
  
  var xRadians = skewX.value * Math.PI / 180;
  var newWidth = calculatedHeight * Math.tan(xRadians);
  var calculatedWidth = el.offsetWidth + newWidth;
  
  el.style.transform = ("skewX(" + skewX.value + "deg ) skewY(" + skewY.value  + "deg )");
  var output = document.getElementById('output');
  output.innerHTML = "skewY by "+skewY.value+ " and new height calculated is "+calculatedHeight+ "<br> skewX by "+skewX.value+ " and the new calculated width is "+ calculatedWidth;
}
body {text-align:center}
#bluebox {width:100px;height:100px;background:blue;margin: 20px auto;}

答案 2 :(得分:2)

我使用这个解决方案。

var degrees = 30;
var radians= degrees*Math.PI/180;
var newHeight = parentWidth*Math.tan(radians);
var newOffset = newHeight / 2;
var parentHeight = parentHeight + newHeight;

这是我更新的小提琴,可选择选择度

http://jsfiddle.net/bhPcn/5/

答案 3 :(得分:1)

两个可以帮助你的功能。

function matrixToArray(matrix) {
    return matrix.substr(7, matrix.length - 8).split(', ');
}

function getAdjustedHeight(skewedObj){
    var jqElement = $(skewedObj);
    var origWidth= jqElement.width();
    var origHeight= jqElement.height();
    var matrix = matrixToArray(jqElement.css('transform'))
    var alpha = matrix[2];
    var adjusted = Math.sin(alpha)*origWidth/Math.sin(Math.PI/2-alpha);
    return origHeight+Math.abs(adjusted);
}

function getAdjustedWidth(skewedObj){
    var jqElement = $(skewedObj);
    var origWidth= jqElement.width();
    var origHeight= jqElement.height();
    var matrix = matrixToArray(jqElement.css('transform'))
    var alpha = matrix[1];
    var adjusted = Math.sin(alpha)*origHeight/Math.sin(Math.PI/2-alpha);
    return origWidth+Math.abs(adjusted);
}

用法(http://jsfiddle.net/x5her/18/):

 // if you use scewY
 console.log(getAdjustedWidth($(".image")[0]))


 // if you use scewX
 console.log(getAdjustedHeight($(".image")[0]))

答案 4 :(得分:0)

取决于高度的动态skew角度示例。


成角度:

  // We use a mathematical expression to define the degree required in skew method
  // The angle depend on the height and width of the container

  // We turn the answer from atan which is in radian into degrees
  //
  // DEGREES = RADIAN * 180 / PI
  const degrees = Math.atan(
                    parent.nativeElement.clientWidth / parent.nativeElement.clientHeight
                  ) * 180 / Math.PI;

  parent.nativeElement.children[0].style.transform = `skew(${degrees}deg)`;
  parent.nativeElement.children[1].style.transform = `skew(${degrees}deg)`;

在Jquery中摘录:

$(document).ready(() => {
  const parent = $('.duo:first');

  const degrees = Math.atan(parent.width() / parent.height()) * 180 / Math.PI;

  $('.first').css('transform', `skew(${degrees}deg)`);
  $('.second').css('transform', `skew(${degrees}deg)`);
});
.container {
  width: 10em;
  height: 10em;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
}

.one-square {
  height: 100%;
  width: 0;
  flex-grow: 1;
  display: flex;
}

.duo {
  height: 100%;
  width: 0;
  flex-grow: 1;
  display: flex;
  flex-direction: row;
  position: relative;
  overflow: hidden;
}

.first {
  width: 100%;
  height: 100%;
  background-color: red;
  transform: skew(0deg);
  transform-origin: 0 0;
  position: absolute;
}

.second {
  width: 100%;
  height: 100%;
  background-color: yellow;
  transform: skew(0deg);
  transform-origin: 100% 100%;
  position: absolute;
}

.a {
  background-color: grey;
}

.b {
  background-color: green;
}

.c {
  background-color: lightgrey;
}

.d {
  background-color: #444444;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div class="one-square a"></div>
  <div class="one-square b"></div>

  <div class="duo">
    <div class="first">
    </div>

    <div class="second">
    </div>
  </div>

  <div class="one-square c"></div>
  <div class="one-square d"></div>
</div>

答案 5 :(得分:0)

现在是 2021 年,只需使用 el.getBoundingClientRect().height。它需要 css 变换到它的计算中。