2016-11-14 3 views
0

Я создаю спидометр, как полукруг, и мне удалось создать полукруг со всеми цветами. См. Схему ниже:Создайте спидометр, как Semi Circle

Проблема, с которой я сталкиваюсь, заключается в создании треугольника, который будет действовать как указатель. Он будет перемещаться вокруг значения от 300 до 850. То, что когда-либо будет в этом диапазоне, укажет там.

JS Fiddle Link

enter image description here

<canvas id="myCanvas" height="350" width="666"> 
       </canvas> 

JS:

window.onload = function(){ 

var canvas = document.getElementById("myCanvas"); 
var context = canvas.getContext("2d"); 

context.font = "14px Trebuchet MS"; 
context.fillStyle = "#aaaaaa"; 
context.fillText("300", 60, 218); 

context.font = "14px Trebuchet MS"; 
context.fillStyle = "#aaaaaa"; 
context.fillText("850", 280, 218); 

// drawArcShadow x y rad sAng eAng clockwise line fill 
drawArcShadow(180, 200, 100, 0, 180, true, "#eeeeee","white"); 

function drawArcShadow(xPos, yPos, radius, startAngle, endAngle, clockwise, lineColor, fillColor) { 
    var startAngle = startAngle * (Math.PI/180); 
    var endAngle = endAngle * (Math.PI/180); 

    var radius = radius; 

    context.strokeStyle = lineColor; 
    context.fillStyle = fillColor; 
    context.lineWidth = 20; 
    context.beginPath(); 
    context.arc(xPos, yPos, radius, startAngle, endAngle, clockwise); 
    context.fill(); 
    context.stroke(); 
} 

// drawArc x y rad sAng eAng clockwise line fill 
drawArc(180, 200, 110, 0, 180, true, "#c1634a","rgba(255, 255, 255, 0)"); 
drawArc(180, 200, 110, 0, 263, true, "#ab5741","rgba(255, 255, 255, 0)"); 
drawArc(180, 200, 110, 0, 264, true, "#e59636","rgba(255, 255, 255, 0)"); 
drawArc(180, 200, 110, 0, 288, true, "#ce8631","rgba(255, 255, 255, 0)"); 
drawArc(180, 200, 110, 0, 289, true, "#e8d932","rgba(255, 255, 255, 0)"); 
drawArc(180, 200, 110, 0, 302, true, "#d0c52d","rgba(255, 255, 255, 0)"); 
drawArc(180, 200, 110, 0, 303, true, "#aecd9c","rgba(255, 255, 255, 0)"); 
drawArc(180, 200, 110, 0, 320, true, "#8db872","rgba(255, 255, 255, 0)"); 

function drawArc(xPos, yPos, radius, startAngle, endAngle, clockwise, lineColor, fillColor) { 
    var startAngle = startAngle * (Math.PI/180); 
    var endAngle = endAngle * (Math.PI/180); 

    var radius = radius; 

    context.strokeStyle = lineColor; 
    context.fillStyle = fillColor; 
    context.lineWidth = 20; 
    context.beginPath(); 
    context.arc(xPos, yPos, radius, startAngle, endAngle, clockwise); 
    context.fill(); 
    context.stroke(); 
} 

};

+0

проверить это: а как реализовать это с моим кодом: http://jsfiddle.net/n1rxcoue/ – Veer

+0

Вам нужны методы 'ctx.translate (x, y)' и 'ctx.rotate (rad)'. – Kaiido

+0

Любой хороший учебник или примеры, которые у вас есть? Что будет здорово. – Veer

ответ

2

Этот вопрос уже был дан ответ много раз, но я чувствовал, что вам нужны дополнительные исправления в логике вашего кода.

Чтобы повернуть фигуру вокруг точки в холсте, используйте translate(x,y) и rotate(radian) методов. Сначала вы перемещаете свой контекст в точку привязки вращения, затем поворачиваете соответственно, и, наконец, вы снова переводите, чтобы дать требуемое смещение.
Подумайте о своем контексте как лист бумаги, который вы можете перемещать и поворачивать.

В вашем фрагменте у вас были большие артефакты сглаживания. Это связано с тем, что все ваши дуги начинаются с угла 0. При рисовании дуги браузер будет создавать полупрозрачные пиксели, чтобы линия выглядела гладко. Но если вы рисуете несколько дуг в тех же позициях, эти пиксели становятся все более непрозрачными, что приводит к этим видимым артефактам.

Вот ваш код, немного переработан:

var canvas = document.getElementById("myCanvas"); 
 
var context = canvas.getContext("2d"); 
 

 
function drawTriangle() { 
 

 
    var ratio = Math.PI/(slider.max - slider.min); 
 
    var angle = ((slider.value - slider.min) * ratio) + Math.PI; 
 
    var radius = 110; 
 
    // first move our cursor to the center of our arcs 
 
    context.translate(180, 200); 
 
    // then rotate the whole context 
 
    context.rotate(angle); 
 
    // move our cursor to our arc's radius 
 
    context.translate(radius, 0); 
 
    // draw the triangle 
 
    context.fillStyle = 'black'; 
 
    context.beginPath(); 
 
    // this draws the triangle around its center point 
 
    context.lineTo(10, -5); 
 
    context.lineTo(10, 5) 
 
    context.lineTo(-10, 0) 
 
    context.closePath(); 
 
    context.fill(); 
 
    // place back our context's transfrom to its default 
 
    context.setTransform(1, 0, 0, 1, 0, 0); 
 
} 
 

 
function drawArcShadow(xPos, yPos, radius, startAngle, endAngle, clockwise, lineColor, fillColor) { 
 
    var startAngle = startAngle * (Math.PI/180); 
 
    var endAngle = endAngle * (Math.PI/180); 
 

 
    var radius = radius; 
 

 
    context.strokeStyle = lineColor; 
 
    context.fillStyle = fillColor; 
 
    context.lineWidth = 20; 
 
    context.beginPath(); 
 
    context.arc(xPos, yPos, radius, startAngle, endAngle, clockwise); 
 
    context.fill(); 
 
    context.stroke(); 
 
} 
 

 
function draw() { 
 
    // clear the canvas 
 
    context.clearRect(0, 0, canvas.width, canvas.height); 
 
    // text 
 
    context.font = "14px Trebuchet MS"; 
 
    context.fillStyle = "#aaaaaa"; 
 
    // since we don't change the properties, no need to tell the browser to do so 
 
    context.fillText("300", 60, 218); 
 
    context.fillText("850", 280, 218); 
 

 
    // drawArcShadow x y rad sAng eAng clockwise line fill 
 
    drawArcShadow(180, 200, 100, 0, 180, true, "#eeeeee", "white"); 
 
    // drawArc x y rad sAng eAng ANTIclockwise line fill 
 
    // be careful, 6th argument of arc() is ANTI-clockwise boolean 
 
    // here I changed all start angle to avoid anti-aliasing artifacts + I removed the transparent fill parameter 
 
    drawArc(180, 200, 110, 263, 180, true, "#c1634a", null); 
 
    drawArc(180, 200, 110, 264, 263, true, "#ab5741", null); 
 
    drawArc(180, 200, 110, 288, 264, true, "#e59636", null); 
 
    drawArc(180, 200, 110, 289, 288, true, "#ce8631", null); 
 
    drawArc(180, 200, 110, 302, 289, true, "#e8d932", null); 
 
    drawArc(180, 200, 110, 303, 302, true, "#d0c52d", null); 
 
    drawArc(180, 200, 110, 320, 303, true, "#aecd9c", null); 
 
    drawArc(180, 200, 110, 0, 320, true, "#8db872", null); 
 

 
    drawTriangle(); 
 
} 
 

 
function drawArc(xPos, yPos, radius, startAngle, endAngle, clockwise, lineColor, fillColor) { 
 
    var startAngle = startAngle * (Math.PI/180); 
 
    var endAngle = endAngle * (Math.PI/180); 
 

 
    context.strokeStyle = lineColor; 
 
    context.fillStyle = fillColor; 
 
    context.lineWidth = 20; 
 
    context.beginPath(); 
 
    context.arc(xPos, yPos, radius, startAngle, endAngle, clockwise); 
 
    // instead of filling transparent, which produces nothing, just don't pass the fillColor parameter and don't call fill(). 
 
    fillColor && context.fill(); 
 
    context.stroke(); 
 
} 
 
slider.oninput = draw; 
 
draw();
<input type="range" id="slider" min="300" max="850"> 
 
<canvas id="myCanvas" height="350" width="666"></canvas>

+0

Большое спасибо, фантастика. Я просто сейчас вижу, как интегрировать значение min value max со значением сервиса, чтобы оно указывало на правильное место на кривой. Еще раз спасибо. – Veer

Смежные вопросы