【问题标题】:How can I add a pulse animation to a div in an array of divs, in Javascript?如何在 Javascript 中将脉冲动画添加到 div 数组中的 div?
【发布时间】:2014-07-31 05:59:20
【问题描述】:

我有一个以编程方式创建的 div 数组,如下所示:

// Create grid of pads dynamically, 16x16 in size
var padIdCount = 0;
for (var i = 0; i < 16; i++) {
    for (var j = 0; j < 16; j++) {
        var newPad = document.createElement("div");
        WinJS.Utilities.addClass(newPad, "pad");
        WinJS.Utilities.addClass(newPad, "row" + i);
        WinJS.Utilities.addClass(newPad, "col" + j);
        newPad.id = "pad" + padIdCount;
        document.getElementById("padContainer").appendChild(newPad);
        padIdCount++;
    }

    // Add a single line break after 16 pads
    var newLineBreak = document.createElement("br");
    document.getElementById("padContainer").appendChild(newLineBreak);
}

Pads 是深灰色的,但是如果用户点击一个 pad,它就会变成一个“active pad”

// Assign handler to pads, to toggle activation on click
var pads = document.querySelectorAll(".pad");
for (var padCount = 0; padCount < pads.length; padCount++) {
   pads[padCount].addEventListener("click", togglePadActivation, false);
}

function togglePadActivation(e) {
    // Get id of pad in question
    var padId = e.target.id;

    // Change pad from active to inactive and vice versa
    var clickedPad = document.getElementById(padId);
    WinJS.Utilities.toggleClass(clickedPad, "activePad");
}

样式

    /* dark grey */
    .pad {
        height: 40px;
        width: 40px;
        margin: 1px;
        padding: 0px;
        background-color: #363636;
        display: inline-table;
    }

    /* dark orange */
.activePad {
    background-color: orangered;
    opacity: 0.6;
}

.playingPad {
    background-color: orangered;
    opacity: 0.6;
    /* workaround for pulse bug */
    animation: pulselightonanimation 3.2s ease-out;
    animation-iteration-count: infinite;
}

@keyframes pulselightonanimation {
    0% {opacity: 1.0;}
    50% {opacity: 0.8;}
    100% {opacity: 0.6;}
}

现在设置已完成,并且事件处理程序已连接,用户可以单击一个按钮,开始循环遍历所有活动焊盘(首先是第 1 行,同时,然后是第 2 行,依此类推)。为此,我实现了一个 setTimeout。

// Run this method every 200ms
function playActiveNotes(rowCount) {
    timer = setTimeout(function () {

        // Reset after the last row, because we are looping indefinitely
        if (rowCount === 16) {
            rowCount = 0;
        }

        // Select all pads from the same row at once
        var currentRow = ".row" + rowCount;
        var currentRowPads = document.querySelectorAll(currentRow);

        // Cycle through each pad, animate and play it if active
        for (var padCount = 0; padCount < currentRowPads.length; padCount++) {

            // If the pad is active play the note
            if (WinJS.Utilities.hasClass(currentRowPads[padCount], "activePad")) {

                // Show the pulse animation
                WinJS.Utilities.addClass(currentRowPads[padCount], "playingPad");

                // TODO: Play short mp3 file here

                // Remove the animation class. This is where it fails
                //currentRowPads[padCount].addEventListener("animationend", callback(currentRowPads[padCount]), false);
                //currentRowPads[padCount].addEventListener("transitionend", callback(currentRowPads[padCount]), false);

                // If I use a nested setTimeout, this removeClass code never gets called. If I comment it out, I don't see the pulse, i.e. add + remove happens too quickly
                //setTimeout(function () {
                    if (padCount < 16)
                        WinJS.Utilities.removeClass(currentRowPads[padCount], "playingPad");
                //}, 1000);

            }
        }

        // Go to the next row
        rowCount++;

        // Then call self to setup a recursive loop.
        playActiveNotes(rowCount);
    }, 200);
}

function callback(element) {
    element.classList.remove('playingPad');
}

当活动打击垫正在播放时(我播放一个简短的 mp3 文件),我希望它有脉冲,即快速变为亮橙色(但不是瞬间),然后淡出回到原来的深橙色。我怎样才能做到这一点?我尝试使用带有 css 动画的播放垫类,并在 transitionend/animation 结束时删除该类,但这不起作用。

除了 Javascript,还允许使用 WinJS,但不能使用 JQuery。

【问题讨论】:

  • 请附上您的尝试并告诉我们出了什么问题。您发布的代码似乎与脉冲动画无关。
  • 你用的是什么浏览器?也许您需要在 animation@keyframes 定义中包含供应商前缀? developer.mozilla.org/en-US/docs/Web/CSS/…
  • 这是example with vendor prefixes。它对我有用,你呢?
  • 我使用的是 IE。我认为我在问这个问题之前尝试了 -ms 前缀,但让我绝对确定并回复你。
  • 顺便提一下,IEcaniuse.com/css-animation

标签: javascript html css animation css-transitions


【解决方案1】:

我认为如果你能以某种方式让 CSS 动画运行,那仍然是最好的解决方案。

不过,这是一种替代解决方案,使用 CSS 过渡:

/* dark grey */
.pad {
    height: 40px;
    width: 40px;
    margin: 1px;
    padding: 0px;
    background-color: #363636;
    display: inline-table;
}

/* dark orange */
.activePad {
    background-color: #B2371B;
    transition: background-color .5s;
    -webkit-transition: background-color .5s;
}

/* bright orange */
.brightPad {
    background-color: #FFFFFF;
    transition: background-color .1s;
    -webkit-transition: background-color .1s;
}

这应该使得如果您将.brightPad 类添加到垫子,它会迅速变为亮橙色(在 0.1 秒内)。一旦您删除该类并再次设置.activePad,它应该会慢慢变回深橙色(0.5 秒)。您必须在触摸时设置.brightPad,然后使用 100 毫秒或更长时间的超时再次将其删除。

这是一个快速的 JSFiddle:http://jsfiddle.net/R5VjH/1/

(对不起,用白色代替了漂亮的亮橙色)

【讨论】:

  • 酷,但 OP 希望它在声音文件的整个持续时间内“脉冲”。这只会脉冲一次。
  • 好点。但是,如果 Javascript 是处理时间的主要系统,那么我认为最好让它根据播放的音频文件来处理单个脉冲。在我之前做过的其他实验中,Javascript 的超时和 CSS 的动画很容易达到毫秒级的不同步。如果在多个循环之后 JS 和 CSS 可能会变得非常糟糕......但当然测试它会显示它是否很明显,我猜。
  • 这是有道理的。我想知道 OP 打算用什么来播放声音并检测到声音正在播放......
  • 只要一个脉搏就完美了,谢谢。声音文件快速而简短,就像鼓声或音符一样。这是删除我一直在努力的类,因为它涉及嵌套的 setTimeout 调用,我无法在调试器中捕获它。让我先试试这个方法,谢谢你的小提琴
  • 这对我不起作用。激活打击垫的点击很慢(需要 0.5 秒而不是瞬时),一旦变成亮橙色,它就会保持亮橙色,不会恢复为深橙色。我已经用我的代码更新了你的 JSFiddle:jsfiddle.net/R5VjH/4
猜你喜欢
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
相关资源
最近更新 更多