如何使JavaScript/CSS随机动画代码更简单?

如何使JavaScript/CSS随机动画代码更简单?,javascript,css,refactoring,document.write,Javascript,Css,Refactoring,Document.write,下面的JavaScript代码生成CSS以使用随机值设置动画。代码复杂且重复。如何才能更优雅地编写此代码 axis=["X","Y","Z"]; document.write("@keyframes tumble { "+ "12% {transform:rotate"+axis[Math.floor(Math.random()*3)]+"(-"+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3

下面的JavaScript代码生成CSS以使用随机值设置动画。代码复杂且重复。如何才能更优雅地编写此代码

axis=["X","Y","Z"];
document.write("@keyframes tumble { "+
"12% {transform:rotate"+axis[Math.floor(Math.random()*3)]+"(-"+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3)]+
"("+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3)]+"("+Math.floor(Math.random()*180)+"deg)}"+
"32% {transform:rotate"+axis[Math.floor(Math.random()*3)]+"(-"+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3)]+
"("+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3)]+"("+Math.floor(Math.random()*180)+"deg)}"+
"50% {transform:rotate"+axis[Math.floor(Math.random()*3)]+"( "+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3)]+
"("+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3)]+"("+Math.floor(Math.random()*180)+"deg)}"+
"66% {transform:rotate"+axis[Math.floor(Math.random()*3)]+"( "+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3)]+
"("+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3)]+"("+Math.floor(Math.random()*180)+"deg)}"+
"84% {transform:rotate"+axis[Math.floor(Math.random()*3)]+"( "+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3)]+
"("+Math.floor(Math.random()*180)+"deg) rotate"+axis[Math.floor(Math.random()*3)]+"("+Math.floor(Math.random()*180)+"deg)}"+"}</style>");
轴=[“X”、“Y”、“Z”]; document.write(“@关键帧翻滚{”+ “12%{transform:rotate”+轴[Math.floor(Math.random()*3)]+“(“+Math.floor(Math.random()*180)+”deg)rotate”+轴[Math.floor(Math.random()*3)]+ “(“+Math.floor(Math.random()*180)+”deg)旋转“+轴[Math.floor(Math.random()*3)]+”(“+Math.floor(Math.random()*180)+”deg)}”+ “32%{transform:rotate”+轴[Math.floor(Math.random()*3)]+“(“+Math.floor(Math.random()*180)+”deg)rotate”+轴[Math.floor(Math.random()*3)]+ “(“+Math.floor(Math.random()*180)+”deg)旋转“+轴[Math.floor(Math.random()*3)]+”(“+Math.floor(Math.random()*180)+”deg)}”+ “50%{transform:rotate”+轴[数学地板(数学随机()*3)]+”(“+数学地板(数学随机()*180)+”deg)rotate”+轴[数学地板(数学随机()*3)]+ “(“+Math.floor(Math.random()*180)+”deg)旋转“+轴[Math.floor(Math.random()*3)]+”(“+Math.floor(Math.random()*180)+”deg)}”+ “66%{transform:rotate”+轴[数学地板(数学随机()*3)]+”(“+数学地板(数学随机()*180)+”deg)rotate”+轴[数学地板(数学随机()*3)]+ “(“+Math.floor(Math.random()*180)+”deg)旋转“+轴[Math.floor(Math.random()*3)]+”(“+Math.floor(Math.random()*180)+”deg)}”+ “84%{transform:rotate”+轴[数学地板(数学随机()*3)]+”(“+数学地板(数学随机()*180)+”deg)rotate”+轴[数学地板(数学随机()*3)]+ “(“+Math.floor(Math.random()*180)+”deg)旋转“+轴[Math.floor(Math.random()*3)]+”(“+Math.floor(Math.random()*180)+”deg)}”+”;
我将一步一步地编写一个答案,并与您分享

第一个简单的步骤是一些非常小的重新格式化,只是为了缩短行长度,使代码更容易查看。在实践中,我可能不会担心此时的线条长度,但较短的线条在此处显示得更好:

axis = [ "X","Y","Z" ];

document.write(
    "@keyframes tumble { "+

    "12% {transform:rotate" +
    axis[Math.floor(Math.random()*3)] +
    "(-" + Math.floor(Math.random()*180) + "deg) rotate" +
    axis[Math.floor(Math.random()*3)] + 
    "(" + Math.floor(Math.random()*180) + "deg) rotate" +
    axis[Math.floor(Math.random()*3)] +
    "(" + Math.floor(Math.random()*180) + "deg)}" +

    "32% {transform:rotate" +
    axis[Math.floor(Math.random()*3)] +
    "(-" + Math.floor(Math.random()*180) + "deg) rotate" +
    axis[Math.floor(Math.random()*3)] + 
    "(" + Math.floor(Math.random()*180) + "deg) rotate" +
    axis[Math.floor(Math.random()*3)] +
    "(" + Math.floor(Math.random()*180) + "deg)}" +

    "50% {transform:rotate" +
    axis[Math.floor(Math.random()*3)] +
    "( " + Math.floor(Math.random()*180) + "deg) rotate" +
    axis[Math.floor(Math.random()*3)] + 
    "(" + Math.floor(Math.random()*180) + "deg) rotate" +
    axis[Math.floor(Math.random()*3)] +
    "(" + Math.floor(Math.random()*180) + "deg)}" +

    "66% {transform:rotate" +
    axis[Math.floor(Math.random()*3)] +
    "( " + Math.floor(Math.random()*180) + "deg) rotate" +
    axis[Math.floor(Math.random()*3)] + 
    "(" + Math.floor(Math.random()*180) + "deg) rotate" +
    axis[Math.floor(Math.random()*3)] +
    "(" + Math.floor(Math.random()*180) + "deg)}" +

    "84% {transform:rotate" +
    axis[Math.floor(Math.random()*3)] +
    "( " + Math.floor(Math.random()*180) + "deg) rotate" +
    axis[Math.floor(Math.random()*3)] + 
    "(" + Math.floor(Math.random()*180) + "deg) rotate" +
    axis[Math.floor(Math.random()*3)] +
    "(" + Math.floor(Math.random()*180) + "deg)}" +

    "}</style>"
);
因此,让我们编写一些函数来简化这些函数,并进行简单的搜索和替换,以更改现有代码以使用这些函数:

// Return a random integer n in the range 0 <= n < limit
function randInt( limit ) {
    return Math.floor( Math.random() * limit );
}

// Return a random integer n in the range 0 <= n < 3
function rand3() {
    return randInt( 3 );
}

// Return a random integer n in the range 0 <= n < 180
function rand180() {
    return randInt( 180 );
}

var axis = [ "X","Y","Z" ];

// Write a <style> tag to the document with a random animation
document.write(
    "<style>@keyframes tumble { "+

    "12% {transform:rotate" +
    axis[rand3()] +
    "(-" + rand180() + "deg) rotate" +
    axis[rand3()] + 
    "(" + rand180() + "deg) rotate" +
    axis[rand3()] +
    "(" + rand180() + "deg)}" +

    "32% {transform:rotate" +
    axis[rand3()] +
    "(-" + rand180() + "deg) rotate" +
    axis[rand3()] + 
    "(" + rand180() + "deg) rotate" +
    axis[rand3()] +
    "(" + rand180() + "deg)}" +

    "50% {transform:rotate" +
    axis[rand3()] +
    "( " + rand180() + "deg) rotate" +
    axis[rand3()] + 
    "(" + rand180() + "deg) rotate" +
    axis[rand3()] +
    "(" + rand180() + "deg)}" +

    "66% {transform:rotate" +
    axis[rand3()] +
    "( " + rand180() + "deg) rotate" +
    axis[rand3()] + 
    "(" + rand180() + "deg) rotate" +
    axis[rand3()] +
    "(" + rand180() + "deg)}" +

    "84% {transform:rotate" +
    axis[rand3()] +
    "( " + rand180() + "deg) rotate" +
    axis[rand3()] + 
    "(" + rand180() + "deg) rotate" +
    axis[rand3()] +
    "(" + rand180() + "deg)}" +

    "}</style>"
);
现在看看这个函数,它仍然有一些重复的东西。但在这一点上,它真的很简单;这种重复相当轻微。不过,既然我们已经做到了,那么让我们看看如何进一步重构代码:

// Return a random axis and degree string
function randAxisDegree( flag ) {
    return axis[rand3()] + "(" + flag + rand180() + "deg)";
}

// Return a transform:rotate string with the specified
// percent and flag
function makeTransform( percent, flag ) {
    return (
        percent + "% {transform:rotate" +
            randAxisDegree(flag) + " rotate" +
            randAxisDegree("") + " rotate" +
            randAxisDegree("") +
        "}"
    );
}
当然,现在我们可能会注意到,我前面所做的
rand3()
rand180()
函数并不是真正必要的,因为它们现在只在一个位置使用,实际上根本不需要是单独的函数

事实上,回顾代码,这两个函数即使在多个位置调用也没有真正的帮助:
rand3()
几乎不比
randInt(3)
好,或者为了保持同样的简洁性,甚至可以将该函数重命名为
rand()
,这样我们就可以说
rand(3)
而不是
rand3()

我很想编辑这个答案,从一开始就采用这种方法,但让我们先把它放在一边,展示一下重构可能会走的有点曲折的道路。我们现在将删除它们,并直接从
randaxisdege()
调用
randInt()

现在我们可以看到这一切是如何结合在一起的:

// Return a random integer n in the range 0 <= n < limit
function randInt( limit ) {
    return Math.floor( Math.random() * limit );
}

var axis = [ "X", "Y", "Z" ];

// Return a random axis and degree string
function randAxisDegree( flag ) {
    return axis[randInt(3)] + "(" + flag + randInt(180) + "deg)";
}

// Return a transform:rotate string with the specified
// percent and flag
function makeTransform( percent, flag ) {
    return (
        percent + "% {transform:rotate" +
            randAxisDegree(flag) + " rotate" +
            randAxisDegree("") + " rotate" +
            randAxisDegree("") +
        "}"
    );
}

// Write a <style> tag to the document with a random animation
document.write(
    "<style>@keyframes tumble { " +
        makeTransform( 12, "-" ) +
        makeTransform( 32, "-" ) +
        makeTransform( 50, " " ) +
        makeTransform( 66, " " ) +
        makeTransform( 84, " " ) +
    "}</style>"
);

//返回0范围内的随机整数n谢谢Michael,非常优雅!我一直在努力想出这样的办法。不客气,加巴,我很高兴知道这很有帮助。一定要看一下我继续简化过程的最新版本的答案。如果我自己这么说的话,新代码很好而且干净。:-)唉,由于某种原因,你的问题已经结束了。这对我来说毫无意义:我认为这是一个非常好的问题。我很高兴在它关闭之前我有机会回答它。很棒的思维过程的穿行。保留最初的“rand3”和“rand180”是一个很好的方式,可以展示最初的简化在以后如何被逆转或消除,但这是过程中的一个关键部分。有时候,你只需要把事情弄得更清楚一点,这样你就可以开始认真思考了,即使这些变化后来被考虑进去了
// Return a random axis and degree string
function randAxisDegree( flag ) {
    return axis[rand3()] + "(" + flag + rand180() + "deg)";
}

// Return a transform:rotate string with the specified
// percent and flag
function makeTransform( percent, flag ) {
    return (
        percent + "% {transform:rotate" +
            randAxisDegree(flag) + " rotate" +
            randAxisDegree("") + " rotate" +
            randAxisDegree("") +
        "}"
    );
}
// Return a random axis and degree string
function randAxisDegree( flag ) {
    return axis[randInt(3)] + "(" + flag + randInt(180) + "deg)";
}
// Return a random integer n in the range 0 <= n < limit
function randInt( limit ) {
    return Math.floor( Math.random() * limit );
}

var axis = [ "X", "Y", "Z" ];

// Return a random axis and degree string
function randAxisDegree( flag ) {
    return axis[randInt(3)] + "(" + flag + randInt(180) + "deg)";
}

// Return a transform:rotate string with the specified
// percent and flag
function makeTransform( percent, flag ) {
    return (
        percent + "% {transform:rotate" +
            randAxisDegree(flag) + " rotate" +
            randAxisDegree("") + " rotate" +
            randAxisDegree("") +
        "}"
    );
}

// Write a <style> tag to the document with a random animation
document.write(
    "<style>@keyframes tumble { " +
        makeTransform( 12, "-" ) +
        makeTransform( 32, "-" ) +
        makeTransform( 50, " " ) +
        makeTransform( 66, " " ) +
        makeTransform( 84, " " ) +
    "}</style>"
);