Вопрос по css, css-transforms, css3 – CSS Transform с изменением размера элемента

50

Я нашел это:ширина / высота после преобразования

и несколько других, но ничего не совсем то, что я ищу. То, что я хочу, это масштабировать что-то до 50% от его размера (с хорошим анимированным переходом, конечно) и чтобы макет страницы перенастроился на новый (визуальный) размер элемента. Кажется, что по умолчанию происходит то, что элемент все еще сохраняет свой первоначальный размер в структуре макета и просто рисуется с соответствующими преобразованиями.

По сути, я хочу, чтобы пользователь щелкнул блок текста (или другой контент), а затем изменил размер этого текста до 50% (или любого другого) его размера и прикрепил его к панели ниже, чтобы указать, что он выбран. , Я не хочу, чтобы 50% пробела вокруг элемента после его перемещения.

Я пытался заново установить высоту / ширину, но это приводит к тому, что элемент iself подвергается новой компоновке, а затем масштаб применяется к новой компоновке, и после этого все еще остается 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>

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

Edit: С тех пор, как я написал это, я нашел очень похожий вопрос без комментариев и ответов. Он немного отличается, так как меня не волнует, что это решение, специфичное для html5, я подозреваю, что решение либо не существует, либо находится в CSS / javascript независимо от уровня html.

Масштабировать / масштабировать элемент DOM и занимаемое им пространство с помощью CSS3 transform scale ()

Edit 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 ; 
}

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

Также обратите внимание, что если вы используетеscale + trans противtrans + scale выше результат резко отличается.

Edit 3: Я разобрался с вопросами размещения ... преобразования применяются в указанном порядке, иscale(0.5,0.5) существенно изменяет размер пикселя до половины того, что было изначально (вероятно, намекает на то, как они реализовали его внутри). Если я поставлю translate is first, то перевод немного меньше / больше, чтобы учесть изменение положения верхнего левого угла, вызванное масштабом, сделает свое дело, но управляет расположением объектов и корректирует преобразования, когда dom изменяется в разумным образом все еще ускользает от меня. Такое чувство кажется неправильным, потому что я двигаюсь в направлении написания своего собственного менеджера компоновки в javascript, чтобы получить этот эффект.

Вы хотите что-то вроде этого -jsfiddle.net/qA5Tb ? Zoltan Toth
Не уверен, что это поможет, но я недавно наткнулся на этоricostacruz.com/jquery.transit для анимации jQuery с помощью css3. Christopher Marshall
Не совсем, это более или менее то, чего я хочу избежать, потому что я должен управлять высотой и шириной для каждого подэлемента. Я собираюсь масштабировать часть контента, которая является более сложной, чем текстовая область. Кроме того, макет во время перехода делает забавные вещи с текстом, поскольку он масштабируется, что довольно неприятно. Преобразование scale () намного красивее. (Я планирую сделать подобный переход, хотя я не упомянул об этом выше) Gus
увидеть:stackoverflow.com/questions/7565542/… ;) abernier
Как показано ниже, это просто воспроизводит мою проблему. Gus

Ваш Ответ

3   ответа
0

Мне пришлось немного подправить мой код сверху.

Теперь он работает со всех сторон (не только вверх и вниз). Я вижу небольшое изменение, я думаю, что это проблема CSS (вы можете добавить еще один пиксель в код для решения этой проблемы).

Вот рабочая ссылка Codepen. Не стесняйтесь, дайте мне знать, если вы используете его. Было приятно наконец понять это.

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

пс. Я разветвляю свой кодекс, чтобы добавить подвижный 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
<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>

39

Проблема, которую я заметил, заключается в том, что при масштабировании элемента браузер меняет соотношение пикселей, а не количество пикселей. Элемент меньше, но он не меняет свой фактический размер в пикселях в DOM. Из-за этого я не думаю, что существует решение только для CSS.

Я поместил масштабируемый элемент в контейнер, который поддерживает то же соотношение пикселей, что и остальные элементы. Используя Java Script, я просто изменяю размер контейнера. Все по-прежнему основано на CSS3 transform: scale. Может быть, код 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>

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;}

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');
}​
Ах, я только что заметил, что примерdoes работа в webkit ... Я запустил пример в firefox и даже не читал код, так как он, похоже, не работает ... Хотя я не знаю, есть ли способ исправить награду. Gus
Так не является ли абсолютное позиционирование души? Вы хотели, чтобы весь контент был гибким и масштабируемым. И это именно то, что я и сделал. Куда вы хотите переместить масштабированный элемент в конце концов?
Нет, я все еще хочу, чтобы масштабированный элемент эффективно перетекал с dom, если размер страницы изменяется или выполняются дополнительные манипуляции с dom ... Просто сделайте его меньше и не оставляйте его плавающим в море пробелов ... звучит просто ... но это не так. Gus
: D Когда вы ответили, что это не то, что вы ожидали, я оставил эту тему, потому что я действительно не понимал, что еще нужно делать здесь. Я заметил, что многие люди используют Chrome для разработки здесь и пишут только префикс -webkit- :) В конце концов, я рад, что это то, что вам нужно! Достаточно добавить -moz- и -o- префиксы к стилям, и это также должно работать в FF и Opera :)
Также не то, что я ищу. Думайте об этом так. Я хочу превратить часть страницы в миниатюру (все содержимое отображается, но меньшие изображения, текст и все еще видно, но меньше) и переместить ее в другой регион. Gus
1

I finally figured out a simple solution and it is much similar than where I started from.

Я признаю, что потребовалось много попыток выяснить это (за последний год или около того), чтобы наконец понять это. Я действительно искал ответ на этот вопрос. У меня были проблемы с этим раньше. В любом случае, я снова начал работать над этим и нашел простое решение.

В любом случае, хитрость заключалась в том, чтобы использовать нижнюю границу вместе со скриптом CSS calc.

Кроме того, вы должны иметь абсолютную высоту, объявленную для объекта (div). Я не думаю, что это сработает, если div сможет расширяться, иначе, после многих попыток и часов на этом у меня, наконец, будет очень простое, чистое, рабочее решение.

Так, например, высота = 300 пикселей (не 30% или нет высоты). Я бы даже установил overflow-y = hidden, если вы можете. Если вы хотите, чтобы div рос (не имел абсолютной высоты), я думаю, вам понадобится JavaScript. Я не пробовал это. В противном случае это работает правильно во всех тестах.

Я уверен, что это будет хорошо работать с SASS или LESS, так как вы можете объявить некоторые повторяющиеся вещи, используя переменные в CSS. Я еще не пробовал это.

Some important comments on my solution:

Notice I am using the height of the object and a CSS calc method together with the transform size to figure out the bottom margin. I color coded my work to help show what is happening. the wrap div does have padding are there only to show it is working. They are absolute and it does not affect the internal object. If you were building a responsive page, like I am, you can use media queries vs classes to get the same affect. I am using transform-origin: 50% 0; This code ended up not being as important as I originally thought it would be. I am using the bottom margin to resolve the problems I had had. In this example, I am just centering the div in the parent div. If you need to place the div, it is a little more complicated, but a similar solution will work. I did not attempt it. You could use this same solution with jQuery vs CSS. The idea is the same. You would search for all elements with the transform in the page and add the CSS as needed.

Я также настроил 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
<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>

Похожие вопросы