Страницы

Поиск по вопросам

воскресенье, 2 февраля 2020 г.

Часы отрисованные canvas

#javascript #html #css #svg #canvas


Подскажите как отрисовать циферблат для часов используя canvas. Знаю, что можно прописывать
координаты вручную, но это геморрой, хотел попробовать написать функцию, которая сама
будет рассчитывать градусы, и рисовать круг с цифрой. Должно было получится вот так:


Но столкнулся с проблемой, что не понимаю как и откуда отсчитывать 30 градусов и
там рисовать круг, потом вставлять туда число. Может у вас будут идее которые помогут
направить меня в правильно русло?



window.onload = function () {
            var drawingCanvas = document.getElementById('clock');
            if (drawingCanvas && drawingCanvas.getContext) {
                var context = drawingCanvas.getContext('2d');
                // Окружность 
                context.strokeStyle = "#000";
                context.fillStyle = "#fff";
                context.beginPath();
                context.arc(150, 150, 100, 0, 2 * Math.PI, false);
                context.closePath();
                context.stroke();
                context.fill();
                // задаем местоположение
                context.fillStyle = "#fff";
                context.beginPath();
                context.arc(150, 70, 16, 0, Math.PI * 2, true);
                context.closePath();
                context.stroke();
                context.fill();

                var Ygol = 30;
                with (Math) {
                    n = sin(Ygol * PI / 180);
                    context.fillStyle = "red";
                    context.beginPath();
                    // context.arc(116, 90, 12, 0, Math.PI * 2, true);
                    context.closePath();
                    context.stroke();
                    context.fill();
                }
            }
        }




    


Ответы

Ответ 1



Вот Вам часики на канве нарисовал =) все координаты рассчитываются в этом методе: current - текущее значение total - размер шкалы radius - это расстояние от центра, как это ни странно function xy(current, total, radius) { let angle = 2 * Math.PI / total * current - Math.PI/2; return [ Math.cos(angle) * radius, Math.sin(angle) * radius ]; } let center = 150; window.onload = function () { var drawingCanvas = document.getElementById('clock'); let ctx = drawingCanvas.getContext('2d'); ctx.font = "30px Arial"; ctx.textAlign = "center"; ctx.textBaseline = "middle"; draw(); function draw() { ctx.clearRect(0, 0, 400, 400); ctx.lineWidth = 1; circle(ctx, [0, 0], 140); // внешний круг Array(12).fill(0).map((e, i) => { // 12 делений let c = xy(i, 12, 111); circle(ctx, c, 22); ctx.strokeText(i||12, center + c[0], center + c[1]+2); }); let d = new Date(); let sec = d.getSeconds() + d.getMilliseconds()/1000; let min = d.getMinutes() + sec/60; let hour = d.getHours() + min/60; ctx.lineWidth = 2.0; line(ctx, xy(sec, 60, 77)); // секундная стрелка ctx.lineWidth = 3.0; line(ctx, xy(min, 60, 66)); // минутная стрелка ctx.lineWidth = 4.0; line(ctx, xy(hour, 12, 55)); // часовая стрелка requestAnimationFrame(draw); } } function circle(ctx, xy, r) { ctx.save(); ctx.beginPath(); ctx.translate(center + xy[0], center + xy[1]); ctx.arc(0, 0, r, 0, Math.PI * 2, true); ctx.closePath(); ctx.stroke(); ctx.restore(); } function line(ctx, xy) { ctx.save(); ctx.beginPath(); ctx.moveTo(center, center); ctx.lineTo(center + xy[0], center + xy[1]); ctx.closePath(); ctx.stroke(); ctx.restore(); } // положение на окружности function xy(current, total, radius) { let angle = 2 * Math.PI / total * current - Math.PI/2; return [ Math.cos(angle) * radius, Math.sin(angle) * radius ]; }

Ответ 2



В качестве бонуса версия на svg+d3.js let center = 150; let svg = d3.select('#clock'); let hours = svg.selectAll('circle.hour') .data(d3.range(12).map(i => xy(i, 12))) .enter() .append('g') .attr('transform', d => `translate(${d[0]*120}, ${d[1]*120})`); hours.append('circle') .classed('hour', true) .attr('r', 22); hours.append('text') .html((d,i) => i+1); let secLine = svg.append('path'); let minLine = svg.append('path'); let hourLine = svg.append('path'); draw(); function draw(){ let d = new Date(); let sec = d.getSeconds() + d.getMilliseconds()/1000; let min = d.getMinutes() + sec/60; let hour = d.getHours() + min/60; arrow(secLine, xy(sec, 60), 77); arrow(minLine, xy(min, 60), 66); arrow(hourLine, xy(hour, 12), 55); requestAnimationFrame(draw); } function arrow(line, data, len) { line.datum(data).attr('d', d => ` M${d[0]*20},${d[1]*20} L${d[0]*len},${d[1]*len} `) } function xy(current, total) { let angle = 2 * Math.PI / total * current - Math.PI/2; return [Math.cos(angle), Math.sin(angle)]; } path, circle { stroke-width:1.8; fill:none; stroke: black; } text { text-anchor:middle; alignment-baseline:middle; font-size:30px; font-family:monospace } Точки считаю той же функцией: function xy(current, total) { let angle = 2 * Math.PI / total * current - Math.PI/2; return [Math.cos(angle), Math.sin(angle)]; } хотя можно было обойтись только поворотами директивами самого svg d3.select('svg') .selectAll('g') .data(d3.range(12)) .enter().append('g') .attr('transform', d => `rotate(${360/12*d})`) .html(d => ` ${d||12}`); draw(); function draw(){ let d = new Date(); let sec = d.getSeconds() + d.getMilliseconds()/1000; let min = d.getMinutes() + sec/60; let hour = d.getHours() + min/60; arr('#hour', 12, hour); arr('#min', 60, min); arr('#sec', 60, sec); requestAnimationFrame(draw); } function arr(selector, total, current){ d3.select(selector).attr('transform', `rotate(${360/total*current})`) } path, circle { stroke-width: 1.8; fill: none; stroke: black; } text { text-anchor: middle; alignment-baseline: middle; font-size: 30px; font-family: monospace; }

Комментариев нет:

Отправить комментарий