Как изменить анимацию рейтинга на основе холста? - PullRequest
0 голосов
/ 20 января 2019

Я хочу сделать систему рейтингов, теперь у меня есть эта система:

Click to open gif

вот код:

jQuery.fn.multirating = function() {
    let wrapper = $(this);

    let config = {
        grayColor: '#e3e3e3',
        grayWidth: 2,
        activeColor: '#4e5c7b',
        activeWidth: 2,
        fontSize: 23,
        fontColor: '#4e5c7b',
        gradientFill: ['#fff', '#f8f8f9'],
    };

    let rating = {};

    let rated = {};

    let error_timeout = null;

    function getRadians(degrees) {
        return (Math.PI/180)*(degrees - 90);
    }

    function buildCanvas(item, rate) {
        item = item.find('canvas');
        if (arguments.length == 1) {
            rate = parseFloat(item.text());
        }

        let canvas = item[0];
        let ctx = canvas.getContext('2d');
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        let percent = Math.round(360 * rate / 10);

        let grd = ctx.createLinearGradient(0, 0, 0, 60);
        grd.addColorStop(0, config.gradientFill[0]);
        grd.addColorStop(1, config.gradientFill[1]);

        ctx.beginPath();
        ctx.lineWidth = config.grayWidth;
        ctx.arc(canvas.width/2, canvas.height/2, (canvas.width-ctx.lineWidth)/2, 0, 7);
        ctx.strokeStyle = config.grayColor;
        ctx.fillStyle = grd;
        ctx.fill();
        ctx.stroke();

        ctx.font = "normal " + config.fontSize + "px Arial";
        ctx.fillStyle = config.fontColor;
        ctx.textAlign = "center";
        ctx.fillText(rate, canvas.width/2, canvas.height/2 + Math.floor(config.fontSize/1.35/2));

        ctx.beginPath();
        ctx.lineWidth = config.activeWidth;
        ctx.arc(canvas.width/2, canvas.height/2, (canvas.width-ctx.lineWidth)/2, getRadians(0), getRadians(percent));
        ctx.strokeStyle = config.activeColor;
        ctx.stroke();
    }

    function setRate(item, area, r) {
        item.find(area).removeClass('multirating-rate-active').eq(r-1).addClass('multirating-rate-active').prevAll('li').addClass('multirating-rate-active');
    }

    function showLog(page, init) {
        ShowLoading();
        $.ajax({
            url: dle_root + 'engine/mods/multirating/ajax.php',
            type: 'POST',
            data: {newsid: wrapper.data('id'), area: 'log', page: page},
        })
        .done(function(d) {
            $('.multirating-log').html(d);
            if (init) {
                let top = ($(window).height() - $('.multirating-log').outerHeight())/2;
                top += $(window).scrollTop();
                $('.multirating-log').css({
                    top: top
                }).fadeIn(200);
                $('.multirating-log').draggable({
                    handle: '.multirating-log-title',
                });
            }
        })
        .fail(function(d) {
            DLEalert(d.responseText, dle_info);
        })
        .always(function() {
            HideLoading();
        });
    }

    $(this).find('.multirating-item').each(function(){
        let r = parseFloat($(this).find('canvas').text());
        rating[$(this).data('area')] = r;

        buildCanvas($(this), r);

        r = parseFloat($(this).data('rated'));
        rated[$(this).data('area')] = r;
        if (r) {
            setRate($(this), '.multirating-item-rating li', r);
        }
    });

    $(document)
    .on('mouseenter', '.multirating-item-rating li', function(){
        if (wrapper.hasClass('multirating-rated')) {
            return;
        }
        let rate = $(this).index() + 1;
        buildCanvas($(this).parents('.multirating-item'), rate);
        $(this).siblings('li').removeClass('multirating-rate-active');
        $(this).addClass('multirating-rate-active').prevAll('li').addClass('multirating-rate-active');
    })
    .on('mouseleave', '.multirating-item-rating', function(){
        if (wrapper.hasClass('multirating-rated')) {
            return;
        }
        $(this).find('li').removeClass('multirating-rate-active');
        let item = $(this).parents('.multirating-item');
        let r = rating[item.data('area')] || rated[item.data('area')];
        if (r) {
            buildCanvas($(this).parents('.multirating-item'), r);
        } else {
            buildCanvas($(this).parents('.multirating-item'));
        }
        if (rated[item.data('area')]) {
            setRate($(this), 'li', rated[item.data('area')]);
        }
    })
    .on('click', '.multirating-item-rating li', function(e){
        e.preventDefault();
        if (wrapper.hasClass('multirating-rated')) {
            return;
        }
        rated[$(this).parents('.multirating-item').data('area')] = $(this).index()+1;

        let count = 0;
        $.each(rated, function(k, v) {
            if (v > 0) {
                count++;
            }
        });

        if (count == $('.multirating-item').length) {
            wrapper.addClass('multirating-rated multirating-loading');
            $('.multirating-error').remove();
            clearTimeout(error_timeout);
            $.ajax({
                url: dle_root + 'engine/mods/multirating/ajax.php',
                type: 'POST',
                dataType: 'json',
                data: {rating: rated, newsid: wrapper.data('id')},
            })
            .done(function(d) {
                if (d.revote) {
                    wrapper.removeClass('multirating-rated');
                }

                $('.multirating-itog-votes').html(d.votes);
                $('.multirating-itog-rateval').html(d.rateval);

                rating = d.rating;
                $.each(d.rating, function(k, v) {
                    buildCanvas($('.multirating-item[data-area='+k+']'), v);
                });
            })
            .fail(function(d) {
                wrapper.removeClass('multirating-rated');
                wrapper.append('<div class="multirating-error"><div class="multirating-error-text">' + d.responseText + '</div></div>');
                error_timeout = setTimeout(function(){
                    $('.multirating-error').fadeOut(300, function(){
                        $(this).remove();
                    })
                }, 3000);
            })
            .always(function() {
                setTimeout(function(){
                    wrapper.removeClass('multirating-loading');
                },200);
            });

        }
    })
    .on('click', '.multirating-error', function(){
        clearTimeout(error_timeout);
        $(this).fadeOut(200, function(){
            $(this).remove();
        })
    })
    .on('click', '.multirating-log-show', function(e){
        e.preventDefault();
        $('.multirating-log').remove();
        $('body').append('<div class="multirating-log" />');
        showLog(1, true);
    })
    .on('click', '.multirating-log-close', function(e){
        e.preventDefault();
        $('.multirating-log').fadeOut(100);
    })
    .on('click', '.multirating-log-list', function(e){
        e.preventDefault();
        $(this).siblings().find('.multirating-log-detail').slideUp(200);
        $(this).find('.multirating-log-detail').slideToggle(200);
    })
    .on('click', '.multirating-log-navigation span:not(.current)', function(e){
        e.preventDefault();
        let page = parseInt($(this).text());
        showLog(page, false);
    })

}

$(function(){
    $('.multirating-wrapper').multirating();
})

Но я хочу изменить круг на такой: http://jsfiddle.net/xbenjii/s55KZ/29/ (ссылка содержит код нового круга и пример его работы)

Я очень старался, но ничего не произошло.

Мне нужно, чтобы оно было от 0 до 10 вместо 0 до 100.

Мне нужно сделать анимацию круга, как в примере по ссылке.

1 Ответ

0 голосов
/ 22 января 2019

Ниже находится отправная точка ...

Вы должны упростить эти примеры, убрать как можно больше, чтобы по-настоящему понять, что происходит за обложками. Надеюсь, это приблизит вас к тому, что вам нужно.

Я сохраняю maxPercentage до 100, а напечатанный текст делится на 10

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var segments = {};
segments['0'] = {
    last: 0,
    height: 15,
    distanceToOuter: 30,
    broke: false,
    incValue: 0.5
};
var percentage = 0;
var lastPercentage = 0;
var maxPercentage = 100;

//simulate download
(function loop() {
    setTimeout(function () {
        //set segment start size
        lastPercentage = percentage;
        percentage += 10; 
        
        //push segment into object stack
        segments[percentage] = {
            last: lastPercentage,
            height: 15,
            distanceToOuter: 30,
            broke: false,
            incValue: 0.5
        };
        //if percentage is under 100, continue to loop
        if (percentage === 100) {
            segments[100].broke = true;
            segments[segments[100].last].broke = true;
        } else if (percentage === 0) {
            segments[0].broke = true;
        } else {
            segments[lastPercentage].broke = true;
        }
        if (percentage < maxPercentage) {
            loop();
            draw(percentage);
            requestAnimationFrame(increaseDistanceToOuter);
        }
    }, 100);
}());

function draw(percentage) {
    //clear canvas
    ctx.clearRect(0, 0, 300, 300);
    
    //draw white circle
    ctx.beginPath();
    ctx.lineWidth = 15;
    ctx.strokeStyle = 'white';
    ctx.arc(150, 150, 120, toRadians(0), toRadians(360));
    ctx.stroke();

    //draw text
    ctx.fillStyle = 'green';
    ctx.font = "26pt Arial";
    ctx.textAlign = "center";
    ctx.fillText(percentage/10, 150, 158);
    
    //draw segments
    for (var key in segments) {
        circleSegment(
            Math.floor(segments[key].last * 3.6),
            Math.ceil(key * 3.6),
            segments[key].height,
            segments[key].distanceToOuter
        );
    }
}

function increaseDistanceToOuter() {
    for (var key in segments) {
        if (!segments[key].broke) {
            segments[key].height += segments[key].incValue;
            segments[key].incValue = segments[key].incValue / 2;
            segments[key].distanceToOuter += 0.05;
        } else {
            if (segments[key].distanceToOuter < 120) {
                segments[key].distanceToOuter++;
            } else if (segments[key].distanceToOuter >= 120) {
                segments[key].height = 15;
                segments[key].distanceToOuter = 120;
            }
        }
    }
    draw(percentage);
    requestAnimationFrame(increaseDistanceToOuter);
}

function toRadians(deg) {
    return deg * Math.PI / 180;
}

function circleSegment(degreesFrom, degreesTo, thickness, distanceToOuter) {
    ctx.beginPath();
    ctx.lineWidth = thickness;
    ctx.strokeStyle = 'green';
    ctx.arc(150, 150, distanceToOuter, toRadians(degreesFrom), toRadians(degreesTo));
    ctx.stroke();
}
html, body {
    background-color: lightgrey;
}
<canvas id="canvas" width="300" height="300"></canvas>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...