基于滚动的动画问题的循环jquery插件

Scroll based animation issue for Circliful jquery plugin

本文关键字:动画 问题 jquery 插件 循环 于滚动 滚动      更新时间:2023-09-26

我使用一个名为'Circliful'的插件来根据百分比动画半圆。动画效果很好。我想在屏幕向下滚动到动画点后触发动画。我尝试的HTML代码如下所示:

<!doctype html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="js/jquery.circliful.js"></script>
<style>
.one {background:black; height:300px; color:white;}
.two {background:green; height:300px; color:white;}
</style>
</head>
<body>
<div class="one">300px Height</div>
<div class="two">300px Height</div>
<div class="one">300px Height</div>
<div id="myStathalf1" data-dimension="250" data-width="30" data-fontsize="38" data-percent="95" data-fgcolor="#fab702" data-bgcolor="#eee" data-type="half" data-icon="fa-task"></div>
<div id="myStathalf2" data-dimension="250" data-width="30" data-fontsize="38" data-percent="90" data-fgcolor="#fab702" data-bgcolor="#eee" data-type="half" data-icon="fa-task"></div>
<script>
$(document).ready (function (){
    $(window).scroll(function(){
        var y=$(this).scrollTop();
        if(y>=100) {                
            $('#myStathalf1').circliful();  
            $('#myStathalf2').circliful();  
        }
    }); 

})
</script>
</body>
</html>

插件的代码如下:

"use strict";
(function ($) {
    $.fn.circliful = function (options, callback) {
        var settings = $.extend({
            // These are the defaults.
            startdegree: 0,
            fgcolor: "#000000",
            bgcolor: "#eee",
            fill: false,
            width: 15,
            dimension: 200,
            fontsize: 15,
            percent: 50,
            animationstep: 0.5,
            iconsize: '20px',
            iconcolor: '#999',
            border: 'default',
            complete: null,
            bordersize: 10
        }, options);
        return this.each(function () {
            var customSettings = ["fgcolor", "bgcolor", "fill", "width", "dimension", "fontsize", "animationstep", "endPercent", "icon", "iconcolor", "iconsize", "border", "startdegree", "bordersize"];
            var customSettingsObj = {};
            var icon = '';
            var percent;
            var endPercent = 0;
            var obj = $(this);
            var fill = false;
            var text, info;
            obj.addClass('circliful');
            checkDataAttributes(obj);

                if (obj.data('type') != undefined) {
                    type = $(this).data('type');
                    if (type == 'half') {
                        addCircleText(obj, 'circle-text-half', (customSettingsObj.dimension / 1.45));
                    }
                }  
                if ($(this).data("percent") != undefined) {
                    percent = $(this).data("percent") / 100;
                    endPercent = $(this).data("percent");
                } else {
                    percent = settings.percent / 100;
                }
            var size = customSettingsObj.dimension,
                canvas = $('<canvas></canvas>').attr({
                    width: size,
                    height: size
                }).appendTo($(this)).get(0);
            var context = canvas.getContext('2d');
            var container = $(canvas).parent();
            var x = size / 2;
            var y = size / 2;
            var degrees = customSettingsObj.percent * 360.0;
            var radians = degrees * (Math.PI / 180);
            var radius = size / 2.5;
            var startAngle = 2.3 * Math.PI;
            var endAngle = 0;
            var counterClockwise = true;
            var curPerc = customSettingsObj.animationstep === 0.0 ? endPercent : 0.0;
            var curStep = Math.max(customSettingsObj.animationstep, 0.0);
            var circ = Math.PI * 2;
            var quart = Math.PI / 2;
            var type = '';
            var fireCallback = true;
            if ($(this).data('type') != undefined) {
                type = $(this).data('type');
                if (type == 'half') {
                    startAngle = 2.0 * Math.PI;
                    endAngle = 3.13;
                    circ = Math.PI;
                    quart = Math.PI / 0.996;
                }
            }

            /**
             * adds text to circle
             *
             * @param obj
             * @param cssClass
             * @param lineHeight
             */
            function addCircleText(obj, cssClass, lineHeight) {
                $("<span></span>")
                    .appendTo(obj)
                    .addClass(cssClass)
                    .html(text)
                    .prepend(icon)
                    .css({
                        'line-height': lineHeight + 'px',
                        'font-size': customSettingsObj.fontsize + 'px'
                    });
            }

            /**
             * checks which data attributes are defined
             * @param obj
             */
            function checkDataAttributes(obj) {
                $.each(customSettings, function (index, attribute) {
                    if (obj.data(attribute) != undefined) {
                        customSettingsObj[attribute] = obj.data(attribute);
                    } else {
                        customSettingsObj[attribute] = $(settings).attr(attribute);
                    }
                    if (attribute == 'fill' && obj.data('fill') != undefined) {
                        fill = true;
                    }
                });
            }
            /**
             * animate foreground circle
             * @param current
             */
            function animate(current) {
                context.clearRect(0, 0, canvas.width, canvas.height);
                context.beginPath();
                context.arc(x, y, radius, endAngle, startAngle, false);
                context.lineWidth = customSettingsObj.width + 1;
                context.strokeStyle = customSettingsObj.bgcolor;
                context.stroke();
                context.beginPath();
                context.arc(x, y, radius, -(quart), ((circ) * current) - quart, false);
                context.strokeStyle = customSettingsObj.fgcolor;
                context.stroke();               
                if (curPerc < endPercent) {
                    curPerc += curStep;
                    requestAnimationFrame(function () {
                        animate(Math.min(curPerc, endPercent) / 100);
                    }, obj);
                }
            }
            animate(curPerc / 100);
        });
    };
}(jQuery));

这是一个无限循环,一直循环,直到我滚动,我知道为什么。我通过改变插件本身的代码尝试了其他方法,但似乎没有任何工作。

我想在默认情况下显示半圆的灰色背景色,在我滚动一些像素并到达该点后开始前景色(橙色)动画。有人能帮帮我吗?

好的。

所以我认为你可以做的是添加一个简单的布尔标志,比如通过hasCreatedObjects的名称,最初设置为false,但一旦时机合适,你将其设置为true,并使用这个布尔值而不是添加任何进一步的circliful()对象。

jsFiddle可以在和JavaScript中找到,如下:

$(document).ready(function () {
    var hasCreatedObjects = false;
    $(window).scroll(function () {
        var y = $(this).scrollTop();
        if (y >= 100) {
            if (!hasCreatedObjects) {
                hasCreatedObjects = true;
                $('#myStathalf1').circliful();
                $('#myStathalf2').circliful();
            }
        }
    });
});