28

我尝试为 CSS 动画关键帧设置这个 LESS mixin:

.keyframes(@name, @from, @to) {;
  @-webkit-keyframes "@name" {
    from {
      @from;  
    }
    to {
      @to;
    }
  }
}

但是名称短语有一些问题,有什么选择可以正确地做到这一点吗?

4

6 回答 6

32

从 LESS >= 1.7 开始,您可以将变量用于关键帧关键字(名称)。

LESS 1.7 对指令的工作方式进行了一些更改,允许使用变量作为名称/关键字@keyframes(因此问题中的示例现在应该可以工作)。


不幸的是,关键帧名称不能在 LESS <= 1.6 中动态生成

因此,处理关键帧的正常方式将使用硬编码名称,并且您只需要调用特定的“for”和“to”mixin,如下所示:

.colors-mixin-frame(@from,@to){
from {color: @from;}
to {color: @to;}
}

.width-mixin-frame(@from,@to){
from {width: @from;}
to {width: @to;}
}

// keyframes with hardcoded names calling for specific mixin frames
@keyframes red-blue { .colors-mixin-frame(red, blue); }
@keyframes change-width { .width-mixin-frame(254px, 512px); }

但是您可以使用一种解决方法来动态生成名称

在将名称注入规则名称的地方,这需要声明下一个规则,该规则}在关键帧声明的末尾提供右括号。最方便的是,如果您只是构建调用该关键帧的动画

.animation-keyframes(@name, @from, @to, @anim-selector) {
  @keyf: ~"@keyframes @{name} { `'\n'`from ";
  @anim: ~"} `'\n'`.@{anim-selector}";
  @{keyf} {
      .from(@name,@from);
        }
      to {
        .to(@name,@to);
      }
  @{anim} {
    animation-name:@name;
  }
}

请注意,您还需要定义.from(){}.to(){}混入,而不仅仅是像您在示例中所做的那样使用@from@to(因为 LESS 也不允许动态生成的属性)......这个混入现在可以构造所需的属性和值......使用特定属性,您可以使用守卫或特定名称的 mixin,如下所示:

// name-specific from and to mixins that are used if first argument equals "colors"
.from (colors, @color) {
  color: @color;
}
.to (colors, @color) {
  color: @color;
} 

现在我们可以在LESS 中调用我们的 mixin:

// test
.animation-keyframes (colors, red, blue, my-colanim);

并获得CSS:

@keyframes colors { 
from {
  color: #ff0000;
}
to {
  color: #0000ff;
}
} 
.my-colanim {
  animation-name: colors;
}

这也适用于 LESS 1.4,但请注意,我们使用 javascript 插值来换行,这需要 LESS 的 javascript 实现。


编辑:关于前缀的附加问题

与供应商前缀混合

在这里,我做了两个 mixin ... 一个没有供应商前缀,一个同时调用通用.keyframesmixin:

.keyframes (@name, @from, @to, @vendor:"", @bind:"") {
  @keyf: ~"@{bind}@@{vendor}keyframes @{name} { `'\n'`from ";
  @{keyf} {
      .from(@name,@from);
        }
      to {
        .to(@name,@to);
      }
}

.animation-keyframes-novendor (@name, @from, @to, @anim-selector) {
  .keyframes (@name, @from, @to);
  @anim: ~"} `'\n'`.@{anim-selector}";
  @{anim} {
    animation-name:@name;
  }
}

.animation-keyframes (@name, @from, @to, @anim-selector) {
  @bind: "} `'\n'`";
  .keyframes (@name, @from, @to, "-moz-");
  .keyframes (@name, @from, @to, "-webkit-", @bind);
  .keyframes (@name, @from, @to, "-o-", @bind);
  .keyframes (@name, @from, @to, "-ms-", @bind);
  .keyframes (@name, @from, @to, "", @bind);
  @anim: ~"} `'\n'`.@{anim-selector}";
  @{anim} {
    -moz-animation: @name;
    -webkit-animation: @name;
    -o-animation: @name;
    -ms-animation: @name;
    animation: @name;
  }
}

.from (colors, @color) {
  color: @color;
}
.to (colors, @color) {
  color: @color;
}

/* keyframes with all vendor prefixes */
.animation-keyframes (colors, red, blue, my-colanim);

/* keyframes with no vendor prefix */
.animation-keyframes-novendor (colors, red, blue, my-colanim);

现在.animation-keyframes将为所有供应商前缀和具有供应商前缀属性的动画选择器生成关键帧。正如预期的那样,.animation-keyframes-novendor它给出了与上述简单解决方案相同的输出(没有供应商前缀)。


一些注意事项:

  • 为了使您的动画真正起作用,您需要设置其他动画参数,例如计时函数、持续时间、方向、迭代计数(除了我们已经设置的名称之外,至少还需要持续时间)。

    例如:

   animation: @name ease-in-out 2s infinite alternate;
  • 如果您在命名空间中包装上述混入,请确保将其他混入中的混入引用更改为它们的整个路径(包括命名空间)。

    例如:

   #namespace > .keyframes () // see .less source in the demo for details
于 2013-04-22T12:23:05.577 回答
6

我目前正在研究一个 mixin 库

源代码可以在这里找到https://github.com/pixelass/more-or-less

我的关键帧混合如下所示:

适用于更少的 1.7.x

米心

.keyframes(@name) { 
    @-webkit-keyframes @name {
        .-frames(-webkit-);
    }
    @-moz-keyframes @name {
        .-frames(-moz-);
    }
    @keyframes @name {
        .-frames();
    }
}

输入

& {
    .keyframes(testanimation);.-frames(@-...){
        0% {
            left: 0;
            @{-}transform: translate(10px, 20px);
        }

        100% {
            left: 100%;
            @{-}transform: translate(100px, 200px);
        }
    }
}

输出

@-webkit-keyframes testanimation {
  0% {
    left: 0;
    -webkit-transform: translate(10px, 20px);
  }
  100% {
    left: 100%;
    -webkit-transform: translate(100px, 200px);
  }
}
@-moz-keyframes testanimation {
  0% {
    left: 0;
    -moz-transform: translate(10px, 20px);
  }
  100% {
    left: 100%;
    -moz-transform: translate(100px, 200px);
  }
}
@keyframes testanimation {
  0% {
    left: 0;
    transform: translate(10px, 20px);
  }
  100% {
    left: 100%;
    transform: translate(100px, 200px);
  }
}
于 2014-02-04T22:14:34.493 回答
2

这个怎么样:

@-webkit-keyframes some-animation {.mixi-frames;}
@-moz-keyframes some-animation {.mixi-frames;}
@-ms-keyframes some-animation {.mixi-frames;}
@-o-keyframes some-animation {.mixi-frames;}
@keyframes some-animation {.mixi-frames;}

.mixi-frames () {
    from {width: 254px;}
    to {width: 512px;}
}

您需要为每个动画执行此操作。取自:http ://radiatingstar.com/css-keyframes-animations-with-less

于 2013-11-14T12:48:40.890 回答
1

还要感谢Martin Turjak的出色回答,(谢谢)我只是在 github 上放了一个 less mixin,它可以在没有 hack 的情况下以灵活的方式生成关键帧和动画的 css 代码,你可以在这里找到它github.com/kuus/动画me.less

使用这个 mixin,你可以编写这段代码来获取有效的跨浏览器 css(请参阅 github repo 以获得完整的解释):

.animate-me(ComplexAnimation; 0.4s ease; '.complex-animation';
    '50%, 100%'; '%stransform: translateZ(-250px) rotateY(30deg)';
    70%; '%stransform: translateZ(-250px) rotateY(30deg); opacity: .5; background:   green';
    30%; '%stransform: translateZ(-250px) rotateY(30deg); opacity: .2; background: yellow';
    80%; '%stransform: translateZ(-250px) rotateY(30deg); opacity: 1; background: red'
);
于 2013-11-12T23:14:45.860 回答
0

前面提到的https://github.com/kuus/animate-me.less做事!

你也可以看看我写的这个(看起来更整洁): https ://github.com/thybzi/keyframes

于 2013-11-29T00:05:46.950 回答
0

我认为你应该这样做

@-webkit-keyframes @name 
{
 code...
}

更改"@name"@name

;你应该在之后删除

.keyframes(@name, @from, @to) {
于 2013-04-12T14:45:25.717 回答