how to add stroke and shadow only on mousemove in a canvas? - javascript

how can we give shadow and stroke for circle drawn using html canvas only during a mouse hover .
i have two cirles and want to have a shadow and stroke during mouse hover, but when i hover over the circles the code adds shadow and stroke, but once the mouse focuses out of the circles the shadow gets darker but doesnot go away.
<html>
<body>
<canvas id="myCanvas" width="1000" height="500" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
</body>
<script>
var canvas = document.getElementById("myCanvas"),
ctx = canvas.getContext("2d"),
circle = [
{x: 60, y: 50, r: 40, },
{x: 100, y: 150, r: 50,}// etc.
];
// render initial rects.
for (var i = 0; i < circle.length; i++) {
ctx.beginPath();
ctx.arc(circle[i].x, circle[i].y, circle[i].r,0,2*Math.PI);
ctx.fillStyle= "grey";
ctx.fill();
}
canvas.onmousemove = function (e){
// console.log("mouseover");
var cir = this.getBoundingClientRect(),
x= e.clientX - cir.left,
y = e.clientX - cir.top,
i = 0 , r;
console.log(r);
// ctx.clearRect(0, 0, c.width, c.height);
while (r = circle[i++])
{
ctx.beginPath();
ctx.arc(r.x,r.y,r.r,0,2*Math.PI)
if (ctx.isPointInPath(x, y))
{
ctx.shadowBlur= 10;
ctx.shadowColor = "grey";
ctx.lineWidth = 3;
ctx.strokeStyle = 'rgb(255,255,255)'
ctx.stroke();
}
else
{
ctx.arc(r.x,r.y,r.r,0,2*Math.PI)
}
}
};
</script>
</html>

canvas.onmousemove = function (e){
var cir = this.getBoundingClientRect(),
x= e.clientX - cir.left,
y = e.clientX - cir.top,
i = 0 , r;
/* add this */
ctx.clearRect(0, 0, canvas.width, canvas.height);
while (r = circle[i++])
{
ctx.beginPath();
ctx.arc(r.x,r.y,r.r,0,2*Math.PI)
if (ctx.isPointInPath(x, y))
{
ctx.shadowBlur= 10;
ctx.shadowColor = "grey";
ctx.lineWidth = 3;
ctx.strokeStyle = 'rgb(255,255,255)'
ctx.stroke();
}
else
{
ctx.arc(r.x,r.y,r.r,0,2*Math.PI)
}
}
/* add this */
for (var i = 0; i < circle.length; i++) {
ctx.beginPath();
ctx.arc(circle[i].x, circle[i].y, circle[i].r,0,2*Math.PI);
ctx.fillStyle= "grey";
ctx.fill();
}
};

I have modified your code to add stroke onmouse hover.
<html>
<body>
<canvas id="myCanvas" width="1000" height="500" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
</body>
<script>
var canvas = document.getElementById("myCanvas"),
ctx = canvas.getContext("2d"),
circle = [{
x: 60,
y: 50,
r: 40,
},
{
x: 100,
y: 150,
r: 50,
} // etc.
];
// render initial rects.
for (var i = 0; i < circle.length; i++) {
ctx.beginPath();
ctx.arc(circle[i].x, circle[i].y, circle[i].r, 0, 2 * Math.PI);
ctx.fillStyle = "blue";
ctx.fill();
}
canvas.onmousemove = function(e) {
var x = e.clientX,
y = e.clientY,
i = 0,
r;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < circle.length; i++) {
if ((x > circle[i].x - circle[i].r) && (y > circle[i].y - circle[i].r) && (x < circle[i].x + circle[i].r) && (y < circle[i].y + circle[i].r)) {
ctx.beginPath();
ctx.arc(circle[i].x, circle[i].y, circle[i].r, 0, 2 * Math.PI);
ctx.fillStyle = "blue";
ctx.fill();
ctx.shadowBlur = 10;
ctx.lineWidth = 3;
ctx.strokeStyle = 'rgb(255,255,255)';
ctx.shadowColor = 'grey';
ctx.stroke();
ctx.shadowColor = 'white';
ctx.shadowBlur = 0;
} else {
ctx.beginPath();
ctx.arc(circle[i].x, circle[i].y, circle[i].r, 0, 2 * Math.PI);
ctx.fillStyle = "blue";
ctx.fill();
ctx.shadowColor = 'white';
ctx.shadowBlur = 0;
}
}
};
</script>
</html>

Related

Animate line graph on canvas

i,m new in js, i ve got task, where i have to animate line graph, but i can't understand how to make it re-render onClick with animation, pls, help me
there's code that's ,make random graph with random points, i need to make smooth animation on click's with new point's
const canvas = document.getElementById('graph')
const ctx = canvas.getContext('2d')
function drawCords() {
ctx.fillStyle = "black";
ctx.lineWidth = 2.0;
ctx.beginPath();
ctx.moveTo(30, 10);
ctx.lineTo(30, 480);
ctx.lineTo(680, 480);
ctx.stroke();
}
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
const rndInt = randomIntFromInterval(2, 10)
const counterForX = (650/rndInt).toFixed()
var rndIntForX = 0
const oneLineX = [];
const oneLineY = [];
canvas.addEventListener('click',()=>start())
function start() {
drawFrame()
}
function drawPoint() {
for (let i = 0; i < rndInt; i++) {
rndIntForX += +counterForX
const rndIntForY = randomIntFromInterval(10, 480)
oneLineX.push(rndIntForX)
oneLineY.push(rndIntForY)
ctx.beginPath();
ctx.arc(rndIntForX, rndIntForY, 4, 0, 2*Math.PI, false);
ctx.fillStyle = 'white';
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = 'black';
ctx.stroke();
}
}
function drawLine(){
ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = '1';
ctx.moveTo(oneLineX[0],oneLineY[0]);
for (let i=1; i<10; i++){
ctx.lineTo(oneLineX[i],oneLineY[i]);
ctx.lineCap = "round";
}
ctx.stroke();
ctx.closePath();
}
function drawFrame() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawCords()
drawPoint()
drawLine()
setTimeout("drawFrame()", 20);
}
drawCords()
i, ve tried many things, but the didn't worked

how to spin and stop wheel has custom position with jquery

this i my code.
I am using this CSS code I want to spin my wheel:
now i want to spin and stop wheel has custom position with jquery?
like lucky wheeel in https://hockey-empire.com/
i'm a newbie, please help me :)
var color = ['#FF0000','#FF0000','#FF0000','#FF0000','#FF0000','#FF0000'];//list color
var label = ['googluck', '10%','Thank','10$','5$','10$',"20%"]; //list lable name
var slices = color.length;
var sliceDeg = 360/slices;
var deg = -90;
var ctx = canvas.getContext('2d');
var width = canvas.width; // size
var center = width/2; // center
var slices = color.length;
var sliceDeg = 360 / slices;
var deg = -90;
var ctx = canvas.getContext('2d');
var width = canvas.width;// size
var center = width / 2; // center
function deg2rad(deg) {
return deg * Math.PI / 180;
}
function drawSlice(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.lineWidth = 2;
ctx.strokeStyle = "#ffffff";
ctx.moveTo(center, center);
ctx.arc(center, center, width / 2, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
ctx.stroke();
}
function drawPoin(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(center, center);
ctx.arc(center, center, 50, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
}
function drawText(deg, text) {
ctx.save();
ctx.translate(center, center);
ctx.rotate(deg2rad(deg));
ctx.textAlign = "right";
ctx.fillStyle = "#fff";
ctx.font = '18px Arial';
ctx.shadowColor = "#000000";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 20;
ctx.fillText(text, center - 25, 10);
ctx.restore();
}
for (var i = 0; i < slices; i++) {
drawSlice(deg, color[i]);
drawPoin(deg, '#fff');
drawText(deg + sliceDeg / 2, label[i]);
deg += sliceDeg;
}
<canvas id="canvas" width="500" height="500"></canvas>
image
i want spin like it :)
You can do it using setInterval method by changing the degree in each interval, you can modify incrementer value and time setInterval to suit your speed and also break the interval using some flags or conditions
window.setInterval(draw, 1);
var color = ['#FF0000','#FF0000','#FF0000','#FF0000','#FF0000','#FF0000'];//list color
var label = ['googluck', '10%','Thank','10$','5$','10$',"20%"]; //list lable name
var slices = color.length;
var sliceDeg = 360/slices;
var deg = -90;
var ctx = canvas.getContext('2d');
var width = canvas.width; // size
var center = width/2; // center
var slices = color.length;
var sliceDeg = 360 / slices;
var deg = -90;
var ctx = canvas.getContext('2d');
var width = canvas.width;// size
var center = width / 2; // center
function deg2rad(deg) {
return deg * Math.PI / 180;
}
function drawSlice(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.lineWidth = 2;
ctx.strokeStyle = "#ffffff";
ctx.moveTo(center, center);
ctx.arc(center, center, width / 2, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
ctx.stroke();
}
function drawPoin(deg, color) {
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(center, center);
ctx.arc(center, center, 50, deg2rad(deg), deg2rad(deg + sliceDeg));
ctx.lineTo(center, center);
ctx.fill();
}
function drawText(deg, text) {
ctx.save();
ctx.translate(center, center);
ctx.rotate(deg2rad(deg));
ctx.textAlign = "right";
ctx.fillStyle = "#fff";
ctx.font = '18px Arial';
ctx.shadowColor = "#000000";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 20;
ctx.fillText(text, center - 25, 10);
ctx.restore();
}
function draw() {
deg++;
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < slices; i++) {
drawSlice(deg, color[i]);
drawPoin(deg, '#fff');
drawText(deg + sliceDeg / 2, label[i]);
deg += sliceDeg;
}
if(deg == 0) {
degreeMultiplier = 0;
deg=-90;
}
}
<canvas id="canvas" width="500" height="500"></canvas>

Isometric 3d collision detection

I'm making an isometric map for a game, I can draw it, but I don't know how to implement a sort of 3d collision detection without Threejs or other 3d library.
It is possible? Maybe make the block an Object can help? I have searched, but I found only libraries.
This is my JavaScript code:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
stop = false;
var tw, th;
var player;
setup();
draw();
function setup(){
ctx.translate(width/2,50);
tw = 60; //tile width
th = 30; // tile height
player = new Player(2,3,3);
};
function draw(){
ctx.clearRect(-width/2,-50,width*1.5,height+50);
for(var i = 0; i < 5; i++){
for(var j = 0; j < 5; j++){
drawBlock(i,j,1,tw,th);
}
}
if(!stop){
requestAnimationFrame(draw);
}
}
function drawBlock(x,y,z,w,h){
var top = "#eeeeee",
right = '#cccccc',
left = '#999999';
ctx.save();
ctx.translate((x-y)*w/2,(x+y)*h/2);
ctx.beginPath();
ctx.moveTo(0,-z*h);
ctx.lineTo(w/2,h/2-z*h);
ctx.lineTo(0,h-z*h);
ctx.lineTo(-w/2,h/2-z*h);
ctx.closePath();
ctx.fillStyle = "black";
ctx.stroke();
ctx.fillStyle = top;
ctx.fill();
ctx.beginPath();
ctx.moveTo(-w/2,h/2-z*h);
ctx.lineTo(0,h-z*h);
ctx.lineTo(0,h);
ctx.lineTo(0,h);
ctx.lineTo(-w/2,h/2);
ctx.closePath();
ctx.fillStyle = "black";
ctx.stroke();
ctx.fillStyle = left;
ctx.fill();
ctx.beginPath();
ctx.moveTo(w/2,h/2-z*h);
ctx.lineTo(0,h-z*h);
ctx.lineTo(0,h);
ctx.lineTo(0,h);
ctx.lineTo(w/2,h/2);
ctx.closePath();
ctx.fillStyle = "black";
ctx.stroke();
ctx.fillStyle = right;
ctx.fill();
ctx.restore();
}
function drawTile(x,y,stroke,col){
ctx.save();
ctx.translate((x-y)*tw/2,(x+y)*th/2);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(tw/2,th/2);
ctx.lineTo(0,th);
ctx.lineTo(-tw/2,th/2);
ctx.closePath();
if(stroke){
ctx.stroke();
}else{
ctx.fillStyle = col;
ctx.fill();
}
ctx.restore();
}
function Player(x,y,z){
this.x = x;
this.y = y;
this.z = z;
this.w = 10; //width
this.h = 10; //height
}
canvas{
width:100%;
height:100%;
}
<canvas id="canvas"></canvas>
What you're after is cube collision. The first result I get for googling that is an article on MDN named 3D collision detection:
Mathematically this would look like so:
f(A,B) = (AminX <= BmaxX ∧ AmaxX >= BminX) ∧ (AminY <= BmaxY ∧ AmaxY >= BminY) ∧ (AminZ <= BmaxZ ∧ AmaxZ >= BminZ)
And in JavaScript, we'd use this:
function intersect(a, b) {
return (a.minX <= b.maxX && a.maxX >= b.minX) &&
(a.minY <= b.maxY && a.maxY >= b.minY) &&
(a.minZ <= b.maxZ && a.maxZ >= b.minZ);
}

Create a new object on button click

I am making an animation with Javascript. It is a ball that has a set speed and travels around inside a box. The animation works, and I have a button that increases the speed of the animations. I want to make a new button that creates a new ball when I click on it.
My Javascript code is the following:
var canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
var fart = document.getElementById("fart")
var ny = document.getElementById("ny")
var circle = {
x:40,
y:50,
r:40,
}
var dx=5;
var dy=5;
var color = ["green", "blue", "yellow", "red", "orange", "pink"]
fart.onclick = function circleto (x,y,r) {
circle.x += 0;
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.beginPath();
ctx.arc(circle.x, circle.y, circle.r, 0, 2*Math.PI);
ctx.closePath();
ctx.fillStyle = color[Math.floor(Math.random()*color.length)];
ctx.fill();
requestAnimationFrame(circleto);
if( circle.x<0+circle.r || circle.x>canvas.width-circle.r) dx=-dx;
if( circle.y<0 + circle.r || circle.y>canvas.height-circle.r) dy=-dy;
circle.x+=dx;
circle.y+=dy;
}
This is my HTML code:
<button id="fart">øk hastigheten</button>
<button id="ny">ny ball</button>
<canvas id="canvas" width="600px" height="400px"></canvas>
What you should do is storing circles inside an array.
And then loop through each item and change them seperatly.
I hope the following code can help as an example:
var
animationRunning = false,
circles = [{ x : 0, y : 0, r : 0 }]; // array
...
function step() {
if(animationRunning === true) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(var i = O, length = circles.length; i < length; i++) {
var circle = circles[i];
ctx.beginPath();
ctx.arc(circle.x, circle.y, circle.r, 0, 2*Math.PI);
ctx.closePath();
ctx.fillStyle = color[Math.floor(Math.random()*color.length)];
ctx.fill();
if( circle.x<0+circle.r || circle.x>canvas.width-circle.r) dx=-dx;
if( circle.y<0 + circle.r || circle.y>canvas.height-circle.r) dy=-dy;
circle.x+=dx;
circle.y+=dy;
circles[i] = circle; // overide the previous version
}
requestAnimationFrame(circleto);
}
}
fart.onclick = function circleto (x,y,r) {
if(animationRunning === false) {
step();
}
}
ny.onclick = function circleto (x,y,r) {
circles.push({ x : 0, y : 0, r : 0 });
if(animationRunning === false) {
step();
}
}
<button id="fart">øk hastigheten</button>
<button id="ny">ny ball</button>
<canvas id="canvas" width="600px" height="400px"></canvas>
<script>
var canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
var fart = document.getElementById("fart")
var ny = document.getElementById("ny")
var color = ["green", "blue", "yellow", "red", "orange", "pink"]
var circles = [
{
x:40,
y:50,
r:40,
dx:5,
dy:5,
},
];
fart.onclick = function circleto (x,y,r) {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.beginPath();
for (i in circles){
var circle = circles[i];
circle.x += 0;
ctx.arc(circle.x, circle.y, circle.r, 0, 2*Math.PI);
ctx.closePath();
ctx.fillStyle = color[Math.floor(Math.random()*color.length)];
ctx.fill();
if( circle.x<0+circle.r || circle.x>canvas.width-circle.r) circle.dx=-circle.dx;
if( circle.y<0 + circle.r || circle.y>canvas.height-circle.r) circle.dy=-circle.dy;
circle.x+=circle.dx;
circle.y+=circle.dy;
}
requestAnimationFrame(circleto);
}
ny.onclick = function newcircleto (x,y,r) {
var newcircle = {
x:40,
y:50,
r:40,
dx:5,
dy:5,
};
circles.push(newcircle);
}
</script>

add border to the outer area of slice in pie

http://jsfiddle.net/wm7pwL2w/8/
How can I add border to the outer area of slice in pie? Please check my jsfiddle. I have implemented Polar Area Chart here. I need each border to be of different color which I can specify. For example refer to this image
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
console.log(ctx);
var center = {
x: 200,
y: 150
};
var myColor = ["#ccc", "#ccc", "#ccc", "#ccc", "#c01c3f"];
var myData = [20, 40, 50, 70, 100];
var myRadius = [150, 120, 80, 100, 70];
var myDistance = [5, 5, 2, 2, 2];
var myText = ['first', 'second', 'third', 'fourth', 'fifth'];
function getTotal(data) {
var myTotal = 0;
for (var j = 0; j < data.length; j++) {
myTotal += (typeof data[j] == 'number') ? data[j] : 0;
}
return myTotal;
}
function plotData() {
var lastend = 0;
var myTotal = getTotal(myData);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
//ctx.strokeStyle = 'rgba(255,255,255,0.5)';
ctx.lineWidth = 1;
ctx.font="15px Arial";
for (var i = 0; i < myData.length; i++) {
ctx.save();
ctx.fillStyle = myColor[i];
ctx.beginPath();
ctx.translate(center.x, center.y);
var thisAngle = (Math.PI * 2 * (myData[i] / myTotal));
ctx.rotate(lastend + thisAngle / 2);
ctx.translate(myDistance[i], 0);
ctx.moveTo(0, 0);
ctx.arc(0, 0, myRadius[i], -(thisAngle / 2), thisAngle / 2, false);
ctx.closePath();
ctx.fill();
// ctx.stroke();
ctx.fillStyle = '#fff';
ctx.translate(0.6 * myRadius[i], 0);
ctx.rotate(-(lastend + thisAngle / 2));
ctx.fillText(myText[i], 0, 0);
ctx.restore();
lastend += thisAngle;
}
}
plotData();
Thanks for all the help.
You need to do it in two steps, first fill the shape then stroke just an arc. To do so you need to use a beginPath() for the outer border after filling it so to not stroke the complete shape.
...
ctx.closePath();
ctx.fill();
// original code stops
// insert this code
ctx.beginPath();
ctx.strokeStyle = '#079';
ctx.lineWidth = 9;
ctx.arc(0, 0, myRadius[i], -(thisAngle / 2), thisAngle / 2);
ctx.stroke();
// original code continues...
// ctx.stroke();
ctx.fillStyle = '#fff';
...
Updated fiddle
Use strokeStyle. JSFiddle
var lineColor = ["blue", "green", "purple", "pink", "aqua"];
for (var i = 0; i < myData.length; i++) {
............................
ctx.strokeStyle = lineColor[i];
ctx.fillStyle = myColor[i];
........
.............
ctx.fill();
ctx.stroke();
......................
}

Categories