web-dev-qa-db-ja.com

Javascriptを使用して動的スタイル変換を正確に設定するにはどうすればよいですか?

変換の設定方法は知っていますが、回転を設定し、スケールやスキューなどを維持したいと思います。

おそらく、次のように関数を書くことができます。

// A variable of element, not parameter. separate out it make more clear.
var el = document.getElementById('el');
function setTransform (p_name, p_value) {
  // how to write some code to set the el transform style...
}

さらに、私は要素を持っています:

<div id="el" style="transform: rotate(45deg) skew(45deg);"></div>

そして私たちにとって、関数setTransform:

setTransform('rotate', '30deg');

要素がこれであることを願っています:

<div id="el" style="transform: rotate(30deg) skew(45deg);"></div>

だから私の質問は、関数setTransformのコンテンツをどのように書くかです。

7
Tychio

注:skewの代わりにskewXまたはskewY、あるいはその両方を使用する必要があります。 MDN情報はこちら を参照してください。

変数内の変換を追跡する方が簡単です。

var elRot,    // the rotation 'counter' for the element 'el'
    elScale,  // the scale 'counter' for the element 'el'
    elSkewX,  // the skewX 'counter' for the element 'el'
    elSkewY;  // the skewY 'counter' for the element 'el'

// initialize values
elRot = 0;
elScale = 1;
elSkewX = 0;
elSkewY = 0;

またはオブジェクト:

var elTranform = {
    rot: 0,   // the rotation 'counter' for the element 'el'
    sca: 1,   // the scale 'counter' for the element 'el'
    skx: 0,   // the skewX 'counter' for the element 'el'
    sky: 0    // the skewY 'counter' for the element 'el'
};

これで、関数から始めることができます(要素には引き続きvar elを使用します)。最初のステップは値を取得することなので、関数に指定された引数を変更します。

// use this with separate vars
function setTransform (element, rotationArg, scaleArg, skewXArg, skewYArg) {
    // how to write some code to set the el transform style...
}

// use this with the object
function setTransform (element, elTransformArg) {
    // how to write some code to set the el transform style...
}

次に、「滞在中」の他の変換を再指定します。指定した例では、skewXは45度のままです。

function setTransform (element, rotationArg, scaleArg, skewXArg, skewYArg) {
    // the brackets cause the string to be evaluated before being assigned
    element.style.transform = ("rotate() scale() skewX() skewY()");
}

または

function setTransform (element, elTransformArg) {
    element.style.transform = ("rotate() scale() skewX() skewY()");
}

次に、引数を文字列に入れる必要があります。

function setTransform (element, rotationArg, scaleArg, skewXArg, skewYArg) {
    element.style.transform = ("rotate(" + rotationArg + "deg ) scale(" + scaleArg
        + ") skewX(" + skewXArg + "deg ) skewY(" + skewYArg + "deg )");
}

または

function setTransform (element, elTransformArg) {
    element.style.transform = ("rotate(" + elTransformArg.rot + "deg ) scale("
        + elTransformArg.sca + ") skewX(" + elTransformArg.skx + "deg ) skewY("
        + elTransformArg.sky + "deg )");
}

少し面倒なので、その文字列を変数に入れます(これはプレフィックスに役立ちます):

function setTransform (element, rotationArg, scaleArg, skewXArg, skewYArg) {
    var transfromString = ("rotate(" + rotationArg + "deg ) scale(" + scaleArg
        + ") skewX(" + skewXArg + "deg ) skewY(" + skewYArg + "deg )");

    // now attach that variable to each prefixed style
    element.style.webkitTransform = transfromString;
    element.style.MozTransform = transfromString;
    element.style.msTransform = transfromString;
    element.style.OTransform = transfromString;
    element.style.transform = transfromString;
}

または

function setTransform (element, elTransformArg) {
    var transfromString = ("rotate(" + elTransformArg.rot + "deg ) scale("
        + elTransformArg.sca + ") skewX(" + elTransformArg.skx + "deg ) skewY("
        + elTransformArg.sky + "deg )");

    // now attach that variable to each prefixed style
    element.style.webkitTransform = transfromString;
    element.style.MozTransform = transfromString;
    element.style.msTransform = transfromString;
    element.style.OTransform = transfromString;
    element.style.transform = transfromString;
}

次に、関数を呼び出します。

setTransform(el, elRot, elScale, elSkewX, elSkewY);

または

setTransform(el, elTransform);

値を変更するには、変数またはオブジェクトの値を変更して、以下を呼び出します。

elRot = 45;
elSkewX = 30;
setTransform(el, elRot, elScale, elSkewX, elSkewY);

または

elTransform.rot = 45;
elTransform.skx = 30;
setTransform(el, elTransform);

この方法では、各変換の「counter」値を変更し、関数を呼び出して変換を適用するだけです。上記のように、変更されていない変換は保持することが重要です。これは、変換の以前のCSS値を新しいものに置き換えるだけだからです。複数の値を指定すると、最後の値(CSSのC部分)のみが使用されます。

15
thisiate

ここでの絶対的な最善の答えは、値を解析することなく、計算されたスタイルの既存の値に影響を与えることができる実際のAPIです。このようなものは、 WebkitCSSMatrix API およびW3Cの「公式」同等物 DOMMatrix を使用して、放棄された非クロスブラウザー形式で存在します。これら2つのAPIの再フォーマットと統合についての話を見てきましたが、実装については同意していないようです。クロスブラウザで動作させるためのシムは次のとおりです: github user arianのCSSMatrixクラス

これがどのように機能するかは、計算された変換文字列(例:"translsate3d(0px, 0px, 100px) scale(1.2) skew(2)")を渡すことができ、回転、変換、変換、傾斜関数で操作できるオブジェクトを返すことです。すべての関数は、新しく操作された値を使用してそれ自体の既存のインスタンスを返し、その「toString」値を要素スタイルプロパティに再適用するだけです。

たくさんの言葉がありますが、ここに例があります(WebkitCSSMatrixを使用しているためにChromeとSafariのみ):

var computedStyle = window.getComputedStyle(document.querySelector('.btn'));
var matrix = new WebKitCSSMatrix(computedStyle.transform);

// Every second, we add +6 degrees of rotation, no need to read the initial value since WebkitCSSMatrix has parsed it for us
window.setInterval(function(){
  matrix = matrix.rotate(6);
  // matrix = matrix.translate(2, 0, 0);
  // matrix = matrix.scale(1.8);
  document.querySelector('.btn').style.transform = matrix.toString();
}, 1000);
body{
                        padding-top: 100px;
                        text-align: center;
                }

                .btn{
                        text-transform: uppercase;
                        border-radius:200%;
                        border:1px solid #000;
                        width: 2em;
                        height: 2em;
                        display: inline-block;
                        text-align: center;
                        line-height: 2em;
                        text-decoration: none;
                        font-family: sans-serif;
                        color: #000;
      
      // It is already rotated and scaled
                        transition: transform 1000ms cubic-bezier(.28,.73,.31,1);
      transform: rotate(45deg);
      -webkit-transform: rotate(45deg);
                }

                .btn:hover{
                        background:#000;
                        color:#fff;
      
      transform: rotate(0deg) scale(1.5);
                }
<a class="btn" href="#">|</a>
1
David Lapointe

フォローすることがあなたを助けるかもしれません...

el.style.webkitTransform = "";
el.style.MozTransform = "";
el.style.msTransform = "";
el.style.OTransform = "";
el.style.transform = "";
1
nik