首页>Program>source

我想知道如何称呼维兹威兹 通过 animate功能 仅在确实需要时.目前, requestAnimationFrame 一直被称为会产生开销的东西。

我已经在 animate内部尝试过 比较 animate的功能 和初始 targetRadius 相同时返回false.不幸的是,这根本不起作用。

有人可以解释我该如何解决吗?

jsfiddle

HTML:

radius

JS:

 <canvas id="ddayCanvas" width="288" height="288" data-image="http://www.topdesignmag.com/wp-content/uploads/2011/07/64.png">
    <div>
        <div class="product-image"></div>
        <div class="product-box">...</div>
        <a href="#" class="overlay">...</a>
    </div>    
  </canvas>
// Options var maxImageWidth = 250, maxImageHeight = 196; var canvas = $('#ddayCanvas'), canvasWidth = canvas.width(), canvasHeight = canvas.height(), sectorColor = $('.product-box').css('background-color'), context = canvas[0].getContext('2d'), imageSrc = canvas.data('image'), imageObj = new Image(), imageWidth, imageHeight, mouseover = false; imageObj.onload = function() { imageWidth = this.width; imageHeight = this.height; if (imageWidth > maxImageWidth){ imageHeight = imageHeight - (imageWidth - maxImageWidth); imageWidth = maxImageWidth; } if (imageHeight > maxImageHeight) { imageWidth = imageWidth - (imageHeight - maxImageHeight); imageHeight = maxImageHeight; } drawDday(90); }; imageObj.src = imageSrc; function drawDday (radius) { context.clearRect(0, 0, canvasWidth, canvasHeight); context.drawImage(imageObj, Math.ceil((canvasWidth - imageWidth) / 2), Math.ceil((canvasHeight - imageHeight) / 2), imageWidth, imageHeight); context.fillStyle = sectorColor; context.beginPath(); context.rect(0, 0, canvasWidth, canvasHeight); context.arc(canvasWidth/2, canvasHeight/2, radius, 0, Math.PI*2, true); context.closePath(); context.fill(); // Check out the console console.log('test'); } var radius = baseRadius = 90, targetRadius = 110, ease = 50, speed = 2; function animate(){ if(mouseover){ radius += ((targetRadius-radius)/ease)*speed; } else { radius -= ((radius-baseRadius)/ease)*speed; } if(radius > targetRadius) radius = targetRadius; if(radius < baseRadius) radius = baseRadius; drawDday(radius); requestAnimationFrame(animate); } requestAnimationFrame(animate); canvas.on('mouseover', function(e){ mouseover = true; }).on('mouseout', function(){ mouseover = false; });
最新回答
  • 1月前
    1 #

    您需要实现一个条件,以便您可以打破循环,例如(根据需要采用):

    var isRunning = true;
    function loop() {
        ... funky stuff here ...
        /// test condition before looping
        if (isRunning) requestAnimationFrame(loop);
    }
    

    现在当您设置 isRunningfalse 循环将中断.为了方便起见,建议您使用一种方法来启动和停止循环:

    function startLoop(state) {
        if (state && !isRunning) {
            isRunning = true;
            loop();             /// starts loop
        } else if (!state && isRunning) {
            isRunning = false;
        }
    }
    

    条件可以通过任何您需要设置的条件来设置,例如在动画结束后的回调等上设置。重要的是,条件标记对于使用它的两个作用域均可用(即,最常见的 在全球范围内)。

    UPDATE

    在这种情况下,更具体的是您的条件(半径)永远不会达到最终停止循环所需的条件。

    这是您可以用来解决此问题的方法:

    演示
    var isPlaying = false;
    function animate(){
        /**
         * To make sure you will reach the condition required you need
         * to either make sure you have a fall-out for the steps or the
         * step will become 0 not adding/subtracting anything so your
         * checks below won't trigger. Here we can use a simple max of
         * the step and a static value to make sure the value is always > 0
        */
        if(mouseover){
            radius += Math.max( ((targetRadius-radius)/ease)*speed, 0.5);
        } else {
            radius -= Math.max( ((radius-baseRadius)/ease)*speed,   0.5);
        }
        /**
         * Now the checks will trigger properly and we can use the
         * isPlaying flag to stop the loop when targets are reached.
        */
        if(radius >= targetRadius) {
            radius = targetRadius;
            isPlaying = false;              /// stop loop after this
        } else if (radius <= baseRadius) {
            radius = baseRadius;
            isPlaying = false;              /// stop loop after this
        }
        drawDday(radius);
        /// loop?
        if (isPlaying === true) requestAnimationFrame(animate);
    }
    

    为了触发循环,我们使用一种方法来检查循环是否正在运行,否则将重置 isPlaying 标记并开始循环.我们在两个 mouseover中都这样做 和 mouseout

    canvas.on('mouseover', function(e){
        mouseover = true;
        startAnim();
    }).on('mouseout', function(){
        mouseover = false;
        startAnim();
    });
    

    该方法只是检查 isPlaying 如果未设置,则将其设置为true并启动循环-这样循环仅启动一次:

    function startAnim() {
        if (!isPlaying) {
            isPlaying = true;
            requestAnimationFrame(animate);
        }
    }
    

    在演示中,我添加了控制台日志记录,以显示循环何时运行以及何时命中目标。

    希望这会有所帮助。

  • 1月前
    2 #

    您的 animate的原因 该函数被连续调用是因为您通过调用 requestAnimationFrame(animate);开始 然后每次致电 animate 无条件致电 requestAnimationFrame(animate); 再次.除非您使用 cancelAnimationFrame,否则这个周期永远不会中断 在某个时候(您不知道),或确保 animate 仅在需要时请求另一个框架。

    另一个问题是 radius 目前将永远不会到达 targetRadius 也不 baseRadius ,因此以下任何一项都不成立:

    if(radius > targetRadius) radius = targetRadius;
    if(radius < baseRadius) radius = baseRadius;
    

    这并不直接导致对 animate的连续呼叫 ,但自 targetRadiusbaseRadius 用来指示动画的终点,然后我们需要与它们形成某种合理的条件。

    因此,您可以执行以下操作:http://jsfiddle.net/PLDUq/9/

    var radius = baseRadius = 50,
        targetRadius = 110,
        ease = 50,
        speed = 12,
        currentAnim;
    function animate(){
        if(mouseover){
            radius += ((targetRadius-radius)/ease)*speed;
        } else {
            radius -= ((radius-baseRadius)/ease)*speed;
        }
        drawDday(radius);
        if(Math.round(radius) >= targetRadius) {
            // uses Math.round() to ensure condition can be fulfilled
            radius = targetRadius;
            return; // doesn't call next frame
        }
        if(Math.round(radius) <= baseRadius) {
            radius = baseRadius;
            return; // doesn't call next frame
        }
        requestAnimationFrame(animate);
    }
    canvas.on('mouseenter mouseleave', function (e) {
        if (currentAnim) {requestAnimationFrame(currentAnim);}
        // cancels current animation if one is playing to
        // prevent several concurrent loops calling animate()
        mouseover = (e.type === 'mouseenter');
        requestAnimationFrame(animate);
    });
    

  • objective c:iOS找到平均速度
  • Rails子控制器?