【问题标题】:CSS Transform Math - Calculate height of div caused by skewCSS 变换数学 - 计算由倾斜引起的 div 的高度
【发布时间】:2021-03-26 08:47:43
【问题描述】:

我很难弄清楚如何计算由于倾斜而导致的 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 */         
}

【问题讨论】:

    标签: javascript jquery css math


    【解决方案1】:
    在倾斜中,我们有一个直角三角形的情况,倾斜的新宽度等于“Opposite”,我们有角度和相反,所以通过这个等式我们可以得到相邻的 Opposite = Adjacent * tan(angle);在 skewX 的情况下相反的是 div 的高度,在 skewY 的情况下是 div 的宽度

    查看https://codepen.io/minaalfy/pen/exgvjb

    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;}
    <h4>Enter any numeric value for skewX or skewY to calculate the new width&height for the box</h4>
    <div id="bluebox"></div>
    <input type="number" placeholder="skewX" id="skewX" onkeyup="calculateSkew()" />
    <input type="number" placeholder="skewY" id="skewY" onkeyup="calculateSkew()" />
    <h1 id="output"></h1>

    【讨论】:

      【解决方案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/

      【讨论】:

      • 正是我所需要的。感谢您发布解决方案!
      • 完美,正是我所需要的。有错别字,应该是:var parentHeight = parentHeight + newOffset;
      • parentHeight 只是没有应用skew 的容器的原始高度吗?
      • @oldboy 正确。 parentHeight 是父容器的高度。
      【解决方案3】:

      两个可以帮助你的功能。

      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】:

        取决于高度的动态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 中为 sn-p :

        $(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】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-07-14
            • 1970-01-01
            • 2015-09-24
            • 1970-01-01
            • 1970-01-01
            • 2012-11-15
            相关资源
            最近更新 更多