问答详情
源自:5-2 径向渐变

老师你好,我有一个问题求教

老师,您好,我想把您第一节课讲的倒计时的例子中的“圆形”换为“笛卡尔心形线”,我只需要修改绘制“圆形”的方法就OK了,但是怎么绘制“笛卡尔心形线”,主要是坐标值不知道如何使用。求指教

http://img.mukewang.com/592adb340001972b11440453.jpg

提问者:等她下班 2017-05-28 22:14

个回答

  • 等她下班
    2017-05-31 09:39:33

    这个我换了,没有效果

    http://img.mukewang.com/592e1ebe0001678f11220508.jpg

  • 慕先生4149723
    2017-05-31 04:40:00

    把画出小球的代码换成我给你的心型公式 这都不理解我就服了你了

  • 慕先生4149723
    2017-05-31 04:38:47

    <!DOCTYPE html>

    <html>

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

        <title></title>

    <meta charset="utf-8" />

        <style type="text/css">

            .container {

                padding: 0px;

                margin: 0px;

                width: 100%;

                text-align: center;

            }

            .countdown {

                border: 1px solid #ccc;

            }

        </style>

        <script type="text/javascript" src="js/digit.js"></script>

    </head>

    <body>

        <div id="container" class="container">

            <canvas id="countdown" class="countdown" width="1400" height="700"></canvas>

        </div>

        <script>

            function Clock(targetId, countTime) {

                var canvas = document.getElementById(targetId);

                var ctx = canvas.getContext("2d");

                var width = canvas.width;

                var height = canvas.height;

                var scale = width / 1400;

                var now = new Date();

                var endTime = countTime;

                var balls = [];

                var ballMax = 500;

                var last_hour;

                var last_minute;

                var last_second;


                function drawDigit(left, top, num, size, color, pushBall) {

                    var number = digit[num];

                    var dotScale = num === 10 ? size / 72 : size / 126;

                    var dotRadius = 8 * dotScale;

                    var dotPadding = 1 * dotScale;

                    var dotSize = 2 * (dotRadius + dotPadding);

                    ctx.save();

                    ctx.fillStyle = color;

                    var row = number.length;

                    for (var i = 0; i < row; i++) {

                        var col = number[i].length;

                        for (var j = 0; j < col; j++) {

                            var value = number[i][j];

                            if (value === 1) {

                                var x = (j + 0.5) * dotSize + left;

                                var y = (i + 0.5) * dotSize + top;

                                ctx.beginPath();

                                ctx.moveTo(x, y);

                                ctx.arc(x, y, dotRadius, 0, 2 * Math.PI, false);

                                if (pushBall === true) {

                                    balls.push(Ball(x, y, Math.random() * 8 * scale - 4 * scale, Math.random() * -5 * scale, dotRadius, 2 * scale, 0.8));

                                }

                                ctx.fill();

                            }

                        }

                    }

                    ctx.restore();

                }


                const colors = ["#33B5E5", "#0099CC", "#AA66CC", "#9933CC", "#99CC00", "#669900", "#FFBB33", "#FF8800", "#FF4444", "#CC0000"]

                function Ball(x, y, vx, vy, r, g, k) {

                    var start_x = x;

                    var start_y = y;

                    var end_x;

                    var end_y;

                    var start_v_x = vx;

                    var start_v_y = vy;

                    var end_v_x;

                    var end_v_y;

                    var r = r;  //小球半径

                    var g = g; //重力加速度

                    var k = k; //弹性系数

                    var interval = 1; //时间间隔 相当于调整速度快慢

                    var color = colors[Math.floor(Math.random() * colors.length)];

                    var dead = false;


                    return {

                        isDead: function () { return dead },

                        draw: function () {

                            end_v_x = start_v_x;

                            end_v_y = start_v_y + interval * g;

                            end_x = start_x + 0.5 * (start_v_x + end_v_x) * interval;

                            end_y = start_y + 0.5 * (start_v_y + end_v_y) * interval;

                            if (end_y + r > height) {

                                //求根公式求出小球起始位置到落地时间

                                var param = Math.pow(2 * start_v_y, 2) + 8 * g * (height - start_y - r);

                                var t1 = (-2 * start_v_y + Math.pow(param, 0.5)) / (2 * g);

                                var t2 = (-2 * start_v_y - Math.pow(param, 0.5)) / (2 * g);

                                var pt = t1 > 0 ? t1 : t2;

                                collision_v_y = -(start_v_y + pt * g) * k;

                                end_v_y = collision_v_y + (interval - pt) * g;

                                end_y = height - r + 0.5 * (collision_v_y + end_v_y) * (interval - pt);

                            }

                            //弹性势能小于重力势能小球平稳着地

                            if (end_y + r > height) {

                                end_y = height - r;

                                end_v_y = 0;

                                g = 0;

                            }

                            if ((end_x < 0) || (end_x > width)) {

                                dead = true;

                            }

                            //重新定义起点和初始速度

                            start_x = end_x;

                            start_y = end_y;

                            start_v_x = end_v_x;

                            start_v_y = end_v_y;

                            //画出小球

                            ctx.save();

                            ctx.beginPath();

                            ctx.fillStyle = color;

                            ctx.moveTo(end_x, end_y);

                            ctx.arc(end_x, end_y, r, 0, 2 * Math.PI, false);

                            ctx.fill();

                            ctx.restore();

                        }

                    }

                }


                function cleanScreen() {

                    ctx.clearRect(0, 0, width, height);

                }


                function drawClock(x, y, difference, style) {

                    var digitSize = 126 * scale;

                    var colonSize = 72 * scale;

                    var margin = 18 * scale;

                    var hour = Math.floor(difference / 3600000) % 24;

                    var minute = Math.floor(difference / 60000) % 60;

                    var second = Math.floor(difference / 1000) % 60;

                    //时

                    drawDigit(x, y, Math.floor(hour / 10), digitSize, style,

                        Math.floor(last_hour / 10) !== Math.floor(hour / 10));

                    drawDigit(x + digitSize + margin, y, hour % 10, digitSize, style,

                        last_hour % 10 !== hour % 10);

                    //分

                    drawDigit(x + 2 * digitSize + 2 * margin, y, 10, colonSize, style);

                    drawDigit(x + 2 * digitSize + 3 * margin + colonSize, y, Math.floor(minute / 10), digitSize, style,

                        Math.floor(last_minute / 10) !== Math.floor(minute / 10));

                    drawDigit(x + 3 * digitSize + 4 * margin + colonSize, y, minute % 10, digitSize, style, 

                        last_minute % 10 !== minute % 10);

                    //秒

                    drawDigit(x + 4 * digitSize + 5 * margin + colonSize, y, 10, colonSize, style);

                    drawDigit(x + 4 * digitSize + 6 * margin + 2 * colonSize, y, Math.floor(second / 10), digitSize, style,

                        Math.floor(last_second / 10) !== Math.floor(second / 10));

                    drawDigit(x + 5 * digitSize + 7 * margin + 2 * colonSize, y, second % 10, digitSize, style,

                        last_second % 10 !== second % 10);


                    last_second = second;

                    last_minute = minute;

                    last_hour = hour;

                }


                return {

                    draw: function draw() {

                        var difference = endTime.getTime() - new Date().getTime();

                        cleanScreen();

                        drawClock(188 * scale, 50 * scale, difference, "rgb(0, 102, 153)");

                        if (balls.length > ballMax) {

                            balls.splice(0, balls.length - ballMax);

                        }

                        balls.forEach(function (ball, index) {

                            ball.draw();

                        });

                    }

                }

            }


            var date = new Date();

            //倒计时1小时

            date.setTime(date.getTime() + 1000 * 60 * 60 * 1);

            var clock = Clock("countdown", date);


            setInterval(function () { clock.draw(); }, 50);

        </script>

    </body>

    </html>


  • 慕先生4149723
    2017-05-31 04:36:13

    球的方法可以这么解 

    var ballMax = 500;

    if (balls.length > ballMax) {

            balls.splice(0, balls.length - ballMax);

    }

    就是球超过了最大数 就把这个数组中的前一部分去掉


  • 慕先生4149723
    2017-05-29 15:01:43

    看着挺好玩的我就写了个demo可以运行希望能帮到你

    function drawCardioid(x, y, w, h, p) { 

                p = p || 100;

                ctx.save();

                ctx.translate(x, y);

                for (var i = -p; i <= p; i++) {

                    var y1 = Math.pow(1 - Math.pow(i / p, 2), 0.5) + Math.pow(Math.pow(i / p, 2), 1 / 3);

                    if (i == -p) {

                        ctx.moveTo(i / p * w * 0.5, -y1 * h * 0.5 * 0.8);

                    } else {

                        ctx.lineTo(i / p * w * 0.5, -y1 * h * 0.5 * 0.8);

                    };

                };

                for (var i = p; i >= -p; i--) {

                    var y2 = -Math.pow(1 - Math.pow(i / p, 2), 0.5) + Math.pow(Math.pow(i / p, 2), 1 / 3);

                    ctx.lineTo(i / p * w * 0.5, -y2 * h * 0.5 * 0.8);

                };

                ctx.closePath();

                ctx.stroke();

            };