Task: there is a vertical line with its coordinates, and there are concentric circles of different colors (like a target in a dash), you need to drag the circles to the line to change the color of only that part of the circle that is behind the line using JS. How to drag an object using JS, I know, help to realize the change of color.
1 answer
Why you can not just try and if something does not work, then ask. At least try. Yet.
Plan for solving the problem:
- Drawing a circle
- Circle movement
- Make a different color in the intersection of the circle and the line
Drawing a circle. Comments in 3 functions, as it is the most normal.
function drawCircle1(x,y, radius, stripesAmount, stripesColor, circleColor) { ctx.save() ctx.beginPath() ctx.fillStyle = circleColor ctx.arc(x,y, radius+radius/4/stripesAmount, 0,Math.PI*2) ctx.closePath();ctx.fill() var stripeWidth = radius/2/stripesAmount ctx.lineWidth = stripeWidth ctx.strokeStyle = stripesColor for(let rad=stripeWidth; rad < radius; rad += stripeWidth*2) { ctx.beginPath() ctx.arc(x,y, rad, 0,Math.PI*2) ctx.closePath();ctx.stroke() } ctx.restore() } function drawCircle2(x,y, radius, stripesAmount, stripesColor, circleColor) { ctx.beginPath() ctx.fillStyle = circleColor ctx.arc(x,y, radius-radius/4/stripesAmount, 0,Math.PI*2) ctx.closePath();ctx.fill() var stripeWidth = radius/2/stripesAmount ctx.lineWidth = stripeWidth ctx.strokeStyle = stripesColor for(let rad=stripeWidth*2; rad < radius; rad += stripeWidth*2) { ctx.beginPath() ctx.arc(x,y, rad, 0,Math.PI*2) ctx.closePath();ctx.stroke() } } function drawCircle3(x,y, radius, stripesAmount, stripesColor, circleColor) { ctx.save() // рисуем подложку в виде красного круга ctx.beginPath() ctx.fillStyle = circleColor ctx.arc(x,y, radius, 0,Math.PI*2) ctx.closePath();ctx.fill() // рисуем полоски, узнаем как их будем рисовать... // будем рисовать полоски через большую толщину линий(stroke...) var stripeWidth = radius/2/stripesAmount ctx.lineWidth = stripeWidth ctx.strokeStyle = stripesColor //рисуем сразу все полоски через цикл с готовым радиусом // если радиус поставим без / 2 то все полоски съедут на stripeWidth/2 и будет некрасиво for(let rad=stripeWidth/2; rad < radius; rad += stripeWidth*2) { ctx.beginPath() ctx.arc(x,y, rad, 0,Math.PI*2) ctx.closePath();ctx.stroke() } ctx.restore() } function drawCircle4(x,y, radius, stripesAmount, stripesColor, circleColor) { ctx.beginPath() ctx.fillStyle = circleColor ctx.arc(x,y, radius, 0,Math.PI*2) ctx.closePath();ctx.fill() var stripeWidth = radius/2/stripesAmount ctx.lineWidth = stripeWidth ctx.strokeStyle = stripesColor for(let rad=stripeWidth/2+stripeWidth; rad < radius; rad += stripeWidth*2) { ctx.beginPath() ctx.arc(x,y, rad, 0,Math.PI*2) ctx.closePath();ctx.stroke() } } The movement of the circle.
canv.addEventListener("mousedown", e=>{//стрелочная функция(this не используем значит ею можно воспользоваться) var drag = false; var dist, x,y; var circleX = circle.x var circleY = circle.y canv.onmousemove = e=> { //внутри евента при использовании другого евента можно использовать только onEvent, так как при использовании addEventListener функции будут накладываться сами на себя, но правда можно в конце написать deleteEventListener, но я привык так dist = getDist(e.pageX,e.pageY, circle.x,circle.y) if(dist < circle.radius && !drag) { drag = true; x=e.pageX;y=e.pageY; } if(drag) { circle.x = circleX + e.pageX-x circle.y = circleY + e.pageY-y } } }) canv.addEventListener("mouseup", ()=>{ canv.onmousemove = undefined; //убираем евент, чтобы он реагировал только, когда зажали мышку }) Another color.
function anim() { ctx.clearRect(0,0, w,h) drawCircle3(circle.x,circle.y, circle.radius, 5, '#fff', '#f00') //выбирай какой круг нравится, так как способов несколько // обьяснения в 3 круге, так как он самый нормальный для меня ctx.beginPath() ctx.moveTo(line.start.x, line.start.y) ctx.lineTo(line.end.x, line.end.y) ctx.closePath();ctx.stroke() ctx.save() ctx.beginPath() ctx.moveTo(0, line.start.y) ctx.lineTo(line.start.x, line.start.y) ctx.lineTo(line.end.x, line.end.y) ctx.lineTo(0, line.end.y) ctx.lineTo(0, line.start.y) //создали фигуру и обрезали ее, то есть то что мы будем рисовать, будет рисоваться только в той области, которую обрезали. Оно будет рисоваться только в том прямоугольнике. ctx.clip() // ну и рисуем в этой области //drawCircle3(circle.x,circle.y, circle.radius, 5, '#000', '#00f') drawCircle3(circle.x,circle.y, circle.radius, 5, '#f00', '#fff') ctx.restore() window.requestAnimationFrame(anim) } anim() All that was not mentioned.
Canvas
<canvas id="canv" style="position: absolute;"></canvas> Some variables, functions.
var canv = document.getElementById("canv"), ctx = canv.getContext("2d"), w = canv.width = window.innerWidth, h = canv.height = window.innerHeight, log = val=>console.log(val) var und; var circle = { radius: 150, x: w/2, y: h/2 // остальное не будем записывать так, как ипользуем их всего 1 раз(смысла нет) } var line = { start: {x:240, y:150}, end: {x:240, y:400} } function getDist(x1,y1,x2,y2) { return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) // обычная функция получения расстояния } - Thanks for the answer, but mene has already helped: ru.stackoverflow.com/questions/826711/… - Dmitriy Kasyanchuk
|
canvas- Dmytryk