我要对答案的工作在一个时间步和大家分享一下,我去。
第一个简单的步骤是一些非常小的重新格式化,只是为了缩短行长度并使其更容易看到代码。在实践中,我可能就不会担心该导线长度在这一点上,但更短的行会显示更好地在这里:
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>"
);
两个项目跳出马上:它看起来像有一个遗漏<style>
标签在生成的代码开始(最后有一个</style>
)。axis = ...
声明中缺少var
。
这是显而易见的,接下来的事情就是发生了一遍又一遍在代码中这两种模式:
Math.floor(Math.random()*3)
Math.floor(Math.random()*180)
让我们写一些功能,使那些简单,做一个简单的搜索和替换,以改变现有的代码使用这些功能:
// 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>"
);
正如你看到的,代码已经多简单。
现在让我们来看看这五个相似的代码块之间有什么相同以及不同之处。将这些块加载到可逐字符(intraline)差异的程序中很有用。我为此使用Araxis Merge。 Beyond Compare是另一个不错的选择。这些都是商业产品;毫无疑问,这也是很好的免费选择。
这里是Araxis合并显示,当我们第一块与上次比较:
(如果你不喜欢的字体,不怪Araxis,这只是我的个人设置。并与自动换行宽度较窄只是为了使其适合在列这里)
我们可以看到,只有两个区别:第一行的百分比数,以及"(-"
与"("
第三线。的确,这些是所有区块中唯一的两个区别。
所以,我们现在可以做的是编写一个函数,返回这段代码,让我们插入这两个值。
// Return a transform:rotate string with the specified
// percent and flag
function makeTransform(percent, flag) {
return (
percent + "% {transform:rotate" +
axis[rand3()] +
"(" + flag + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg) rotate" +
axis[rand3()] +
"(" + rand180() + "deg)}"
);
}
现在看看这个函数,还有中的重复那几个东西。但是这一点非常简单,重复是相当小的。由于我们在这,但是,让我们看看我们如何重构代码多一点:
// 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()
。
我很想试着编辑这个答案,从一开始就采取这种方法,但让我们单独留下来,以显示重构可能带来的有点歪曲的路径。现在,我们将虽然删除它们,并直接从randAxisDegree()
调用randInt()
:
// 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>"
);
对于这样的问题,也许你最好关闭,以更好地http://codereview.stackexchange.com/ – Nobita 2013-03-11 00:47:11