it-swarm.com.ru

Как смешать свойства преобразования CSS3 без переопределения (в режиме реального времени)?

Есть ли способ объединить (смешать) свойства преобразования CSS без переопределения? Например, там я хочу повернуть и масштабировать . http://jsfiddle.net/hyzhak/bmyN3/

hTML

<div class="item rotate-90 tiny-size">
    Hello World!
</div>

cSS

.rotate-90 {
    -webkit-transform: rotate(90deg);
}
.tiny-size {
    -webkit-transform: scale(0.25, 0.25);
}

PS

У меня просто много элементов и много простых классов для преобразования вида элементов. И я просто хочу настроить их вид, добавив и удалив некоторые классы. Объединение всех классов не работает, потому что это будут сотни комбинаций.

Также я хочу сделать это в реальном времени.

Количество трансформаций может быть примерно 5, и каждое из них может содержать около 10 состояний - поэтому просто опишите все их комбинации руками, чтобы получить примерно

10*10*10*10*10 = 100000 cases

Это плохое решение.

24
Eugene Krevenets

Вот попытка решить проблему с Javascript: http://jsfiddle.net/eGDP7/

Я использую атрибут данных в HTML, чтобы перечислить классы с преобразованиями, которые мы хотим применить:

<div class="compoundtransform" data-transformations="scaletrans2, rotatetrans1">Test subject</div>

Я перебираю классы и выясняю, какие правила CSS они представляют:

function getCSSRulesForClass( selector ) {
    var sheets = document.styleSheets;
    var cssRules = [];
    for (var i = 0; i<sheets.length; ++i) {
        var sheet = sheets[i];
        if( !sheet.cssRules ) { continue; }
        for (var j = 0; j < sheet.cssRules.length; ++j ) {
            var rule = sheet.cssRules[j];
            if (rule.selectorText && rule.selectorText.split(',').indexOf(selector) !== -1) {
                var styles = rule.style;
                for( var k = 0; k<styles.length; ++k ) {
                    var style = styles[k];
                    cssRules.Push( { 
                        property: style,
                        value: styles[style]
                    } );
                }
            }
        }
    }
    return cssRules;
}

Я нахожу любые преобразования и применяю преобразования к матрице:

function convertTransformToMatrix( source, transformValue ) {
    var values = transformValue.split(") "); // split into array if multiple values
    var matrix = cloneObject( source );
    for ( var i = 0; i<values.length; ++i ) {
        var value = values[i];
        if( isRotate( value ) ) {
            var rotationValue = cssRotationToRadians( value );
            var cosValue = Math.cos( rotationValue );
            var sinValue = Math.sin( rotationValue );
            var a = matrix.a;
            var b = matrix.b;
            var c = matrix.c;
            var d = matrix.d;
            var tx = matrix.tx;
            var ty = matrix.ty;
            matrix.a = a*cosValue - b*sinValue;
            matrix.b = a*sinValue + b*cosValue;
            matrix.c = c*cosValue - d*sinValue;
            matrix.d = c*sinValue + d*cosValue;
            matrix.tx = tx*cosValue - ty*sinValue;
            matrix.ty = tx*sinValue + ty*cosValue;
        } else if ( isScale( value ) ) {
            var scale = cssScaleToObject( value );
            matrix.a *= scale.x;
            matrix.b *= scale.y;
            matrix.c *= scale.x;
            matrix.d *= scale.y;
            matrix.tx *= scale.x;
            matrix.ty *= scale.y;
        } else if ( isTranslate( value ) ) {
            var translate = cssTranslateToObject( value );
            matrix.tx += translate.x;
            matrix.ty += translate.y;
        }
    }
    return matrix;
}

И, наконец, я применяю эту матрицу к узлу как преобразование.

В настоящее время:

  • Код немного грязный
  • Синтаксический анализ CSS ограничен масштабом (x, y), переводом (x, y) и поворотом со значениями степени или радиана. 
  • И это будет работать только с префиксом поставщика WebKit

Я мог бы привести его в порядок и превратить в утилиту, если она кому-нибудь пригодится.

7
BrettJephson

Хм ... насколько я знаю, вам придется создать новый класс и объединить их следующим образом (через пробел):

-webkit-transform: rotate(90deg) scale(0.25, 0.25);
9
m59

Чтобы обойти эту проблему, нужно добавить класс-оболочку к тому, который я хочу. Например, у меня есть оболочка, чья позиция установлена ​​с помощью javascript, а затем внутренняя часть, на которую влияют анимации css - оба свойства transform.

Я знаю, что добавление DOM-узлов не является идеальным, но оно позволяет обойти решение, насыщенное сценариями, и позволяет браузеру оптимизировать анимацию и переходы, как обычно.

5
Hugo Scott-Slade

В настоящее время нет способа сделать это, он принимает только одну команду для transform за раз и не может добавлять или вычитать, как вы хотели бы. Таким образом, вам придется добавить или удалить класс в зависимости от того, что является первым и вторым типом, и написать собственный transform для этого элемента.

Использование языка препроцессора CSS, такого как SASS или LESS, может упростить комбинирование переходов, следующее позволяет объединять любое количество transition в один, но требует указания, какие из них добавить (это SCSS)

.item {
  width:500px;
  height:500px;
  font-size:150px;
  background:blue;
}

$firstTransform: rotate(90deg);
$secondTransform: scale(0.25, 0.25);

@mixin transform($transform...) {
  -webkit-transform: $transform;
     -moz-transform: $transform;
      -ms-transform: $transform;
       -o-transform: $transform;
          transform: $transform;
}
.rotate-90 {
  @include transform($firstTransform);
}
.tiny-size {
  @include transform($secondTransform);
}
.both {
  @include  transform($firstTransform $secondTransform);
}

Демо

Действительно, единственный способ сделать это в настоящее время состоит в том, чтобы использовать javascript, по существу добавляя класс с преобразованием, сохраняя переменную преобразования этого класса, удаляя класс и делая то же самое с другим классом, затем комбинируя две матрицы класса трансформируется. РЕДАКТИРОВАТЬ: См. ответ Javascript Брежепа Подробнее об этом подходе

4
Zach Saucier

Вместо поворота и масштабирования вы можете использовать матричную функцию.

transform: matrix(a, b, c, d, tx, ty);

В приведенном примере, я полагаю, следующее даст желаемый результат:

transform: matrix(0,-0.25,0.25,0,0,0);

Для объяснения матричных расчетов:

И существуют некоторые полезные инструменты для расчета этих матриц как CSS, такие как:

2
BrettJephson

Одна вещь, которую вы могли бы сделать, это получить вычисленный стиль преобразования в JS и объединить ваше вторичное значение преобразования:

HTML

<div class="rotate-scale"></div>

CSS

.rotate-scale {
   transform: rotate(90deg);
}

JS

var el = document.querySelector('.rotate-scale'),
    // rotation will get the transform value declared in css
    rotation = window.getComputedStyle(el).getPropertyValue('transform');

el.style.transform = rotation + 'scale(0.25, 0.25)';
0
Taylor Plante