javascript - Circliful jquery 插件基于滚动的动画问题

标签 javascript jquery html5-canvas jquery-animate

我正在使用一个名为“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));

这会产生一种无限循环,它会一直循环,直到我滚动并且我明白其原因。 我通过更改插件本身的代码尝试了其他方法,但似乎没有任何效果。

我希望默认显示半圆的灰色背景色,并在滚动一些像素并到达该点后启动前景色(橙色)动画。 有人能帮助我吗?

最佳答案

好吧。

所以我认为你可以做的是添加一个简单的 bool 标志,例如 hasCreatedObjects 的名称,最初设置为 false 但一旦时机成熟,您将其设置为 true 并使用此 bool 值来添加任何其他 circliful() 对象。

其中的jsFiddle可以找到here 和 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();
            }
        }
    });
});

关于javascript - Circliful jquery 插件基于滚动的动画问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31349401/

相关文章:

javascript - 从键盘输入时,每 n 个字符后加破折号

javascript - 如何翻转 HTML Canvas 上绘制的路径

javascript - Html 5 Canvas 的麻烦

javascript - 如何在没有自定义 HTML 标签的情况下使用 AngularJS?

java - 如何从日期时间中仅获取时间(2011-04-23 09 :30:51:01) in java or javascript or jquery

javascript - 将分隔字符串转换为 JavaScript 中的对象

jquery - 循环插件ie8的问题

javascript - ag-grid-react 在基本组件导入时崩溃 : missing react-dom-factories

javascript - HTML5 视频 : Overriding fullscreen

javascript - HTML5 - createPattern(..) - 动态位置(x,y)