CSS转换元素大小调整

Gus*_*Gus 52 css css3 css-transforms

我发现了这个:变换后的宽度/高度

还有其他几个,但没有什么不是我想要的.我想要的是将某些东西缩放到它的大小的50%(当然有很好的动画过渡)并让页面布局重新调整到元素的新(可视)大小.默认情况下似乎发生的是元素仍然在布局结构中保留其原始大小,并且仅使用关联的转换绘制.

基本上我希望用户点击一个文本块(或其他内容),然后将该文本缩放到它的大小的50%(或其他),并将其粘贴在下面的面板中以指示它已被选中.移动它后,我不希望元素周围有50%的空白.

我已经尝试重新设置高度/宽度,但这会导致元素自身进行新的布局,然后将比例应用于新布局,这仍然会在完成后留下50%的空白区域.我的mozilla特定(为简单起见)代码如下所示:

<script type="text/javascript">
 function zap(e) {

  var height = e.parentNode.offsetHeight/2 + 'px';
  var width = e.parentNode.offsetWidth/2 + 'px';
  e.parentNode.style.MozTransform='scale(0.0)'; 
  e.parentNode.addEventListener(
    'transitionend', 
    function() { 
      var selectionsArea = document.getElementById("selected");
      selectionsArea.appendChild(e.parentNode);
      e.parentNode.style.MozTransform='scale(0.5,0.5)'; 
      e.parentNode.style.display = 'inline-block';
      e.parentNode.style.height = height;
      e.parentNode.style.width = width;
    },
    true) 
}
</script>
Run Code Online (Sandbox Code Playgroud)

我真的希望我不必为了达到这个目的而弄清楚负利润或相对定位......

编辑:自写这篇文章以来,我发现了一个非常相似的问题,没有评论或答案.它略有不同,因为我不关心它是一个html5特定的解决方案,我怀疑解决方案要么不存在,要么在CSS/javascript中,无论html级别如何.

使用CSS3变换scale()缩放/缩放DOM元素及其占用的空间

编辑2 :(另一次非工作尝试)

我也尝试过这个,但是缩放和平移函数似乎以一种使最终位置无法预测的方式相互作用......并且变换前的缩放似乎与变换然后缩放相同.不幸的是,这不仅仅是通过比例因子调整翻译的问题......

function posX(e) {
    return e.offsetLeft + (e.offsetParent ? posX(e.offsetParent) : 0)
}

function posY(e) {
    return e.offsetTop + (e.offsetParent ? posY(e.offsetParent) : 0)
}

function placeThumbNail(e, container, x, y, scale) {
    var contX = posX(container);
    var contY = posY(container);
    var eX = posX(e);
    var eY = posY(e);
    var eW = e.offsetWidth;
    var eH = e.offsetHeight;

    var margin = 10;
    var dx = ((contX - eX) + margin + (x * eW * scale));
    var dy = ((contY - eY) + margin + (y * eH * scale));

    // assumes identical objects     
    var trans = 'translate(' + dx + 'px, ' + dy + 'px) ';
    var scale = 'scale(' + scale + ',' + scale + ') ';
    e.style.MozTransform =  trans + scale ; 
}
Run Code Online (Sandbox Code Playgroud)

即使它的工作,上面仍然需要我运行此代码(摆脱空白的)之前,首先移动元素到页面的底部,而且我需要重新计算变换上重新大小..所以我对这种尝试开始并不太满意.

另请注意,如果您使用scale + transvs trans + scale,则结果会有很大差异.

编辑3:我想出了放置问题...变换按照指定的顺序应用,并且scale(0.5,0.5)基本上将像素的大小更改为原来的一半(可能暗示它们如何在内部实现它).如果我把翻译放在第一位,稍微翻译一下来考虑由比例引起的左上角位置的变化就可以解决问题,但是当dom改变时,管理对象的位置并调整变换.合理的态度仍在逃避我.这种感觉是错误的,因为我正朝着在javascript中编写我自己的布局管理器的方向漂移,只是为了获得这种效果.

Sóf*_*fka 40

我注意到的问题是,当元素缩放时,浏览器会改变其像素比例,而不是像素数量.元素较小但不会改变DOM中的实际像素大小.因此我不认为只存在CSS解决方案.

我将可扩展元素放入容器中,与其他元素保持相同的像素比率.使用Java Script我只需更改容器的大小.一切仍然基于CSS3变换:规模.也许JS代码可能更简单,但现在它完全是关于这个想法(只是一个概念证明);)提供两个例子:http://jsfiddle.net/qA5Tb/9/

HTML:

<div class="overall-scalable">
    <div class="scalable" scalex='0.5' scaley='0.5'>
        Nunc et nisi ante. Integer in blandit nisi. Nulla facilisi. Vestibulum vulputate sapien eget mauris elementum sollicitudin. Nullam id lobortis dolor. Nulla vitae nibh vitae sem volutpat pretium. Nunc et nisi ante. Integer in blandit nisi. Nulla facilisi. Vestibulum vulputate sapien eget mauris elementum sollicitudin. Nullam id lobortis dolor. Nulla vitae nibh vitae sem volutpat pretium.
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

CSS:

.overall-scalable {width: 350px; height: 150px; overflow: hidden; -webkit-transition: all 1s;}
.scalable {color: #666; width: 350px; height: 150px; -webkit-transform-origin: top left; -webkit-transition: all 1s;}
Run Code Online (Sandbox Code Playgroud)

JS:

$('button').click(function() {
    $('.scalable').each(function(){
        rescale($(this));
    })
});

function rescale(elem) {

    var height = parseInt(elem.css('height'));
    var width = parseInt(elem.css('width'));
    var scalex = parseFloat(elem.attr('scalex'));
    var scaley = parseFloat(elem.attr('scaley'));

    if (!elem.hasClass('rescaled')){
        var ratioX = scalex;
        var ratioY = scaley;
    }else{          
        var ratioX = 1;
        var ratioY = 1;
    }

    elem.toggleClass('rescaled');
    elem.css('-webkit-transform', 'scale('+ratioX +', '+ratioY+')');        
    elem.parent().css('width', parseInt(width*ratioX) + 'px');
    elem.parent().css('height', parseInt(height*ratioY) + 'px');
}?
Run Code Online (Sandbox Code Playgroud)

  • 所以灵魂不是绝对定位吗?您希望使所有内容对缩放元素具有灵活性.而这正是我所做的.你想在哪里移动缩放元素? (2认同)

Nat*_*rfi 8

我终于想出了一个简单的解决方案,它与我开始的地方非常相似。

我承认,(在过去一年左右的时间里)花了很多次尝试才最终弄明白。我实际上是在寻找这个问题的答案。我以前遇到过这个问题。无论如何,我再次开始解决这个问题,我确实找到了一个简单的解决方案。

无论如何,诀窍是将边距底部与 CSS calc 脚本一起使用。

此外,您必须为对象 (div) 声明绝对高度。如果 div 可以扩展,我认为这不会起作用,否则,经过多次尝试和数小时后,我终于有了一个非常简单、干净、有效的解决方案。

因此,例如,高度 = 300 像素(不是 30%,或没有高度)。如果可以的话,我什至会设置 overflow-y = hidden。如果您希望 div 增长(没有绝对高度),我相信您将需要 JavaScript。我没有尝试。否则这在所有测试中都能正常工作。

我相信这将适用于 SASS 或 LESS,因为您可以使用 CSS 中的变量声明一些重复的内容。我还没有尝试过。

关于我的解决方案的一些重要评论:

  1. 请注意,我使用对象的高度和 CSS calc 方法以及变换大小来计算底部边距。
  2. 我对我的工作进行了颜色编码,以帮助显示正在发生的事情。
  3. wrap div 确实有填充,只是为了表明它正在工作。它们是绝对的,不会影响内部对象。
  4. 如果您正在构建响应式页面,就像我一样,您可以使用媒体查询与类来获得相同的效果。
  5. 我正在使用变换原点:50% 0; 这段代码最终没有我原先想象的那么重要。我正在使用底部边距来解决我遇到的问题。
  6. 在这个例子中,我只是将 div 放在父 div 中。如果需要放置 div,则稍微复杂一些,但类似的解决方案会起作用。我没有尝试。
  7. 您可以在 jQuery 与 CSS 中使用相同的解决方案。这个想法是一样的。您将搜索页面中具有转换的所有元素并根据需要添加 CSS。

我还设置了一个 Codepen 来测试和共享。

https://codepen.io/cyansmiles/details/yvGaVP

.box-wrap {
  display: block;
  position: relative;
  box-sizing: border-box;
  width: 100%;
  margin: auto;
  text-align: center;
  margin: 30px 10px;
  padding: 40px;
  background: yellow;
}

.box-wrap:before {
  content: "";
  display: block;
  box-sizing: border-box;
  position: absolute;
  background: rgba(0, 0, 0, 0.5);
  width: calc(100% - 80px);
  height: calc(100% - 80px);
  top: 40px;
  left: 40px;
}

.box {
  display: inline-block;
  box-sizing: border-box;
  position: relative;
  transform-origin: 50% 0;
  width: 300px;
  height: 150px;
  background: red;
}

.box.size-80 {
  transform: scale(0.8);
  margin: 0 auto calc(-150px * (1 - 0.8));
}

.box.size-70 {
  transform: scale(0.7);
  margin: 0 auto calc(-150px * (1 - 0.7));
}

.box.size-60 {
  transform: scale(0.6);
  margin: 0 auto calc(-150px * (1 - 0.6));
}

.box.size-50 {
  transform: scale(0.5);
  margin: 0 auto calc(-150px * (1 - 0.5));
}

//etc
Run Code Online (Sandbox Code Playgroud)
<div class="box-wrap">
  <div class="box">
    <h1>Box at 100%</h1>
  </div>
</div>

<div class="box-wrap">
  <div class="box size-80">
    <h1>Box at 80%</h1>
  </div>
</div>

<div class="box-wrap">
  <div class="box size-70">
    <h1>Box at 70%</h1>
  </div>
</div>

<div class="box-wrap">
  <div class="box size-60">
    <h1>Box at 60%</h1>
  </div>
</div>

<div class="box-wrap">
  <div class="box size-50">
    <h1>Box at 50%</h1>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)


Nat*_*rfi 5

我必须从上面稍微调整我的代码。

现在它可以在各个方面发挥作用(不仅仅是上下)。我看到了一些编辑,我认为这是 CSS 问题(您可以在代码中添加另一个像素来解决此问题)。

这是有效的 Codepen 链接。如果您使用它,请随时告诉我。终于弄清楚这一点的感觉很好。

https://codepen.io/cyansmiles/pen/bLOqZo

附:我正在分叉我的 codepen 以添加可移动的 CSS。

.box-wrap {
  display: block;
  position: relative;
  box-sizing: border-box;
  width: 100%;
  margin: auto;
  text-align: center;
  margin: 30px 10px;
  padding: 40px;
  background: yellow;
}

.box-wrap:before {
  content: "";
  display: block;
  box-sizing: border-box;
  position: absolute;
  background: rgba(0, 0, 0, 0.5);
  width: calc(100% - 80px);
  height: calc(100% - 80px);
  top: 40px;
  left: 40px;
}

.box {
  display: inline-block;
  box-sizing: border-box;
  position: relative;
  transform-origin: 50% 0;
  width: 300px;
  height: 150px;
  background: red;
  color: #fff;
}

.box.size-80 {
  background: red;
  transform: scale(0.8);
  margin: 0 calc((-300px * (1 - 0.8)) / 2) calc(-150px * (1 - 0.8));
}

.box.size-70 {
  background: blue;
  transform: scale(0.7);
  margin: 0 calc((-300px * (1 - 0.7)) / 2) calc(-150px * (1 - 0.7));
}

.box.size-60 {
  background: green;
  transform: scale(0.6);
  margin: 0 calc((-300px * (1 - 0.6)) / 2) calc(-150px * (1 - 0.6));
}

.box.size-50 {
  background: orange;
  transform: scale(0.5);
  margin: 0 calc((-300px * (1 - 0.5)) / 2) calc(-150px * (1 - 0.5));
}

//etc
Run Code Online (Sandbox Code Playgroud)
<div class="box-wrap">
  <h1>This is a bunch of boxes!</h1>
  <div class="box size-50">
    <h1>Box at 50%</h1>
  </div>
  <div class="box size-60">
    <h1>Box at 60%</h1>
  </div>
  <div class="box size-80">
    <h1>Box at 80%</h1>
  </div>
  <div class="box size-70">
    <h1>Box at 70%</h1>
  </div>
  <div class="box size-50">
    <h1>Box at 50%</h1>
  </div>
  <div class="box size-60">
    <h1>Box at 60%</h1>
  </div>
  <div class="box size-50">
    <h1>Box at 50%</h1>
  </div>
  <div class="box size-60">
    <h1>Box at 60%</h1>
  </div>
  <div class="box size-80">
    <h1>Box at 80%</h1>
  </div>
  <div class="box size-70">
    <h1>Box at 70%</h1>
  </div>
  <div class="box size-50">
    <h1>Box at 50%</h1>
  </div>
  <div class="box size-60">
    <h1>Box at 60%</h1>
  </div>
</div>

<div class="box-wrap">
  <div class="box">
    <h1>Box at 100%</h1>
  </div>
</div>

<div class="box-wrap">
  <div class="box size-80">
    <h1>Box at 80%</h1>
  </div>
</div>

<div class="box-wrap">
  <div class="box size-70">
    <h1>Box at 70%</h1>
  </div>
</div>

<div class="box-wrap">
  <div class="box size-60">
    <h1>Box at 60%</h1>
  </div>
</div>

<div class="box-wrap">
  <div class="box size-50">
    <h1>Box at 50%</h1>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)