cloning element javascript - javascript

var canvas = document.createElement('canvas')
canvas.width = 900
canvas.height = 600
canvas.style.backgroundColor = '#d9d9d9'
document.body.appendChild(canvas)
var ctx = canvas.getContext('2d')
//defining the moving square
var RADIUS = 7
var SPEED = 1.5
//startposition
let pos = [Math.floor(Math.random() * 900) + 1, Math.floor(Math.random() * 600) + 1]
//coordinates
let direction = [0, 1]
//defining what will happen if the square touches the borderlines
setInterval(function() {
if(pos[0] <= RADIUS || pos[0] >= canvas.width - RADIUS ||
pos[1] <= RADIUS || pos[1] >= canvas.height - RADIUS) {
pos =[Math.floor(Math.random() * 900) + 1, Math.floor(Math.random() * 600) + 1]
}
pos[0] += direction[0] * SPEED
pos[1] += direction[1] * SPEED
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = "#6666ff"
ctx.fillRect(pos[0] - RADIUS, pos[1] - RADIUS, 2 * RADIUS, 2 * RADIUS)
}, 20)
setInterval(function() {
const randomAngle = Math.random() * 2 * Math.PI
direction = [Math.cos(randomAngle), Math.sin(randomAngle)]
}, 500)
So I have this Code and now want that the box that moves around can duplicate after lets say 15 seconds. also the duplication also has to duplicate again after the same amount of time. I came across this:
var item01 = item.cloneNode(true);
but don't find a proper way to implement it.

Related

Is there a way to initialized Canvas api?

I am now making Customize roulette, and players can input the text what they wanted.
when I click button, the renderRoulette function is work. And this is the inner context of renderRoulette function
rouletteCanvas.style.display = "block"; // the initial state of rouletteCanvas's display is 'none'
// #customize elements are the inputs of the text that users made.
let customize = document.querySelectorAll("#customize");
let len = customize.length;
const canvas = document.querySelector(".roulette-panel"); // I want to draw here.
let width = canvas.width;
let height = canvas.height;
const ctx = canvas.getContext("2d");
// ctx Initialization
ctx.clearRect(0, 0, width, height);
const devide = len;
const degree = 360;
const goalDegree = 270 + degree / devide;
for (let i = 0; i < devide; i++) {
let json = {
first: (degree / devide) * i,
last: (degree / devide) * (i + 1),
text: `${i + 1}`,
};
data.push(json);
}
// Draw a circular sector
data.forEach((item) => {
ctx.save();
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = "gray";
ctx.moveTo(width / 2, height / 2);
ctx.arc(
width / 2,
height / 2,
width / 2,
degreesToRadians(item.first),
degreesToRadians(item.last),
false
);
ctx.closePath();
ctx.stroke();
ctx.restore();
ctx.save();
let half = Math.abs(item.first - item.last) / 2;
let degg = item.first + half;
let xx = ((Math.cos(degreesToRadians(degg)) * width) / 2) * 0.7 + width / 2;
let yy =
((Math.sin(degreesToRadians(degg)) * width) / 2) * 0.7 + height / 2;
let minus = ctx.measureText(item.text).width / 2;
ctx.font = "bold 15px sans-serif";
ctx.fillText(item.text, xx - minus, yy);
ctx.restore();
});
Every time I click the button, I want to delete all the previously drawn circular sector shapes and redraw them, so I used the code, ctx.clearRect(0, 0, width, height); . However, even if you click the button after, it will be drawn over the existing picture. How do I initialize it?
I get a feeling that the save and restore in your code are causing some problems for you, I tried a simpler version of your code and the ctx.clearRect(0, 0, width, height) works just fine.
Here is the code:
const canvas = document.querySelector(".roulette-panel");
const ctx = canvas.getContext("2d");
let width = height = 100;
const devide = 8;
let data = []
for (let i = 0; i < devide; i++) {
data.push({
first: (360 / devide) * i,
last: (360 / devide) * (i + 1)
});
}
function draw() {
ctx.clearRect(0, 0, width, height);
ctx.beginPath();
data.forEach((item) => {
ctx.moveTo(width / 2, height / 2);
ctx.arc(50, 50, 45,
item.first * Math.PI / 180,
item.last * Math.PI / 180
);
item.first += 0.5
item.last += 0.5
});
ctx.stroke();
}
setInterval(draw, 40)
<canvas class="roulette-panel"></canvas>
This code uses setInterval to delete all the previously drawn circular sector shapes and draw new one on a new position creating the effect of movement
Here is that same code but with the clearRect commented:
const canvas = document.querySelector(".roulette-panel");
const ctx = canvas.getContext("2d");
let width = height = 100;
const devide = 8;
let data = []
for (let i = 0; i < devide; i++) {
data.push({
first: (360 / devide) * i,
last: (360 / devide) * (i + 1)
});
}
function draw() {
//ctx.clearRect(0, 0, width, height);
ctx.beginPath();
data.forEach((item) => {
ctx.moveTo(width / 2, height / 2);
ctx.arc(50, 50, 45,
item.first * Math.PI / 180,
item.last * Math.PI / 180
);
item.first += 0.5
item.last += 0.5
});
ctx.stroke();
}
setInterval(draw, 40)
<canvas class="roulette-panel"></canvas>
We can clearly see a different effect

Select a new number from array every second randomly

var canvas = document.createElement("canvas");
b = canvas.getContext("2d");
canvas.id = "canvas"
canvas.width = 900;
canvas.height = 600;
document.body.appendChild(canvas);
var posX = 430;
posY = 300;
var myArray = [-3.5,0,3.5];
var dX = myArray[Math.floor(Math.random()*myArray.length)];
var dY = myArray[Math.floor(Math.random()*myArray.length)];
setInterval(function (){
b.fillStyle = "steelblue";
b.fillRect(0, 0, canvas.width, canvas.height);
posX += dX;
posY += dY;
if (posX > 875){
dX = 0;
posX = 875;
}
if (posX < 5){
dx = 0;
posX = 5;
}
if (posY > 575){
dY = 0;
posY = 575;
}
if (posY < 5){
dY = 0;
posY = 5;
}
b.fillStyle = "snow";
b.fillRect(posX, posY, 20, 20);
}, 20)
This is all my Code. I want to move the cube on the background randomly. Right now it moves in just one random direction. but I want it to change this direction every second. for that dX and dY have to change every each second.
Do it this way:
If you have any questions about the code. Feel free to write a comment.
const canvas = document.createElement('canvas')
canvas.width = 100
canvas.height = 100
canvas.style.backgroundColor = 'steelblue'
document.body.appendChild(canvas)
const ctx = canvas.getContext('2d')
const RADIUS = 5
const SPEED = 0.6
let pos = [canvas.width / 2, canvas.height / 2]
let direction = [0, 0]
setInterval(function() {
pos[0] += direction[0] * SPEED
pos[1] += direction[1] * SPEED
if(pos[0] <= RADIUS || pos[0] >= canvas.width - RADIUS ||
pos[1] <= RADIUS || pos[1] >= canvas.height - RADIUS) {
pos = [canvas.width / 2, canvas.height / 2]
}
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = "snow"
ctx.fillRect(pos[0] - RADIUS, pos[1] - RADIUS, 2 * RADIUS, 2 * RADIUS)
}, 20)
setInterval(function() {
const randomAngle = Math.random() * 2 * Math.PI
direction = [Math.cos(randomAngle), Math.sin(randomAngle)]
}, 1000)
use setInterval() https://javascript.info/settimeout-setinterval
var myArray = [-3.5,0,3.5];
var dX, dY
setInterval(() => {
dX = myArray[Math.floor(Math.random()*myArray.length)];
dY = myArray[Math.floor(Math.random()*myArray.length)];
}, 1000)
I would personally opt to use Array.prototype to add a method which will get a random element of the array, and then use setInterval to update the values evey second:
Array.prototype.getRandom = function() {
let index = Math.floor(Math.random() * this.length);
return this[index];
}
var myArray = [-3.5,0,3.5];
var dX, dY;
function updateDerivatives() {
dX = myArray.getRandom(),
dY = myArray.getRandom();
console.log("Updated values:", { dX, dY });
}
setInterval(updateDerivatives, 1000);
var myArray = [-3.5,0,3.5];
var dX;
var dY;
setInterval(() => { // you could also use setInterval(function(){...},...)
dX = myArray[Math.floor(Math.random()*myArray.length)];
dY = myArray[Math.floor(Math.random()*myArray.length)];
}, 1000) // 1000 milliseconds

Make a JavaScript canvas background transparent

Am trying to make the background of this Codepen transparent https://codepen.io/scorch/pen/BZjbmW. I would like to have the Swirls on the a different backgrounds, instead of the colored background that is on the stated Codepen.
I have tried add css code but that did not seem to do anything. I tried messing with the Canvas RGB and that did not seem to do anything either.
// create a canvas element
var canvas = document.createElement("canvas")
// attach element to DOM
document.getElementsByTagName("body")[0].appendChild(canvas)
// background color [r, g, b]
var bg = [20, 0, 30]
var wh = window.innerHeight
// get the canvas context (this is the part we draw to)
var ctx = canvas.getContext("2d")
function setup() {
// setup the canvas size to match the window
canvas.width = window.innerWidth
canvas.height = window.innerHeight
wh = window.innerWidth < window.innerHeight ? window.innerWidth : window.innerHeight
// set the 0,0 point to the middle of the canvas, this is not necessary but it can be handy
ctx.translate(canvas.width / 2, canvas.height / 2)
fill(bg, 1)
}
// fill entire canvas with a preset color
function fill(rgb, amt) {
ctx.beginPath(); // start path
ctx.rect(-canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height) // set rectangle to be the same size as the window
ctx.fillStyle = `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${amt})` // use the rgb array/color for fill, and amt for opacity
ctx.fill() // do the drawing
}
function drawCircle(x, y, r, color) {
ctx.beginPath()
ctx.arc(x, y, r, 0, 2 * Math.PI)
ctx.fillStyle = color || 'white'
ctx.fill()
ctx.closePath()
}
function Particle() {
// initialize loopers with random trange and offset
this.loop1 = new Looper(500 + 200 * Math.random(), 860 * Math.random())
this.loop2 = new Looper(320 + 70 * Math.random(), 20 * Math.random())
this.loop3 = new Looper(120 + 20 * Math.random(), 140 * Math.random())
this.history = []
this.history_max = 40
// this.x = null
// this.y = null
this.offset = Math.random() // some color offset for the color
this.draw = function() {
// set x,y, radius, and color params
var x = this.loop1.sin * (wh / 4 - 10) + this.loop2.sin * (wh / 6 - 10) + this.loop3.sin * 60
var y = this.loop1.cos * (wh / 4 - 10) + this.loop2.cos * (wh / 6 - 10) + this.loop3.cos * 10
var r = 0.2 + 3 * this.loop3.sinNorm * this.loop3.cosNorm // set the radius
var c = `hsla(${280 + 60 * (this.loop3.cosNorm + this.offset) * this.loop2.sinNorm}, ${100}%, ${50 + 10 * this.loop3.sin}%, ${1})`
ctx.beginPath()
ctx.strokeStyle = c
ctx.lineCap = 'round'
ctx.lineWidth = r
var tx = x
var ty = y
for (var i = 0; i < Math.min(this.history_max * this.loop3.cosNorm, this.history.length); i++) {
ctx.moveTo(tx, ty)
tx = this.history[i][0]
ty = this.history[i][1]
ctx.lineTo(tx, ty)
}
ctx.stroke()
drawCircle(x, y, r * 2 + 3, c); // draw the circle
this.loop1.update() // update looper
this.loop2.update() // update looper
this.loop3.update() // update looper
this.history.unshift([x, y])
if (this.history.length > this.history_max) {
this.history.pop()
}
}
}
// initialize a set of particle
var particles = []
for (var i = 0; i < 90; i++) {
particles.push(new Particle())
}
function draw() {
// fill context with background color
fill(bg, 0.36)
// update all the particles
for (var i = 0; i < particles.length; i++) {
particles[i].draw() // do it once
}
// this is a draw loop, this will execute frequently and is comparable to EnterFrame on other platform
window.requestAnimationFrame(function() {
draw()
})
}
// start enterFrame loop
window.requestAnimationFrame(draw);
// force running setup
setup()
// re-setup canvas when the size of the window changes
window.addEventListener("resize", setup)
// create a class to hold value and have built in incrementing functionality
function Looper(steps, start) {
this.val = start || 0 // set value to start value if defined, or 1
this.steps = steps || 100 // set steps to passed value or default to 100
this.norm = this.val / this.range // initialize normalized value (between 0 and 1)
this.sin = Math.sin(this.norm * Math.PI * 2) // get sine value from norm normalized to [0, 2PI]
this.sinNorm = (this.sin + 1) / 2 // normalize sin to [0,1]
this.cos = Math.cos(this.norm * Math.PI * 2) // get cosine value from norm normalized to [0, 2PI]
this.cosNorm = (this.cos + 1) / 2 // normalize cos to [0,1]
this.update = function() {
this.val = (this.val + 1) % this.steps // update value
this.norm = this.val / this.steps // update normalize value (between 0 and 1)
this.sin = Math.sin(this.norm * Math.PI * 2) // get sine value from norm normalized to [0, 2PI]
this.sinNorm = (this.sin + 1) / 2 // normalize sine to [0,1]
this.cos = Math.cos(this.norm * Math.PI * 2) // get cosine value from norm normalized to [0, 2PI]
this.cosNorm = (this.cos + 1) / 2 // normalize cos to [0,1]
}
}
ctx.fillStyle = rgba(255,255,255,0)
// create a canvas element
var canvas = document.createElement("canvas")
// attach element to DOM
document.getElementsByTagName("body")[0].appendChild(canvas)
// background color [r, g, b]
var bg = [20, 0, 30]
var wh = window.innerHeight
// get the canvas context (this is the part we draw to)
var ctx = canvas.getContext("2d")
function setup() {
// setup the canvas size to match the window
canvas.width = window.innerWidth
canvas.height = window.innerHeight
wh = window.innerWidth < window.innerHeight ? window.innerWidth : window.innerHeight
// set the 0,0 point to the middle of the canvas, this is not necessary but it can be handy
ctx.translate(canvas.width / 2, canvas.height / 2)
fill(bg, 1)
}
// fill entire canvas with a preset color
function fill(rgb, amt) {
ctx.beginPath(); // start path
ctx.rect(-canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height) // set rectangle to be the same size as the window
ctx.fillStyle = `rgba(255,255,255,0)` // use the rgb array/color for fill, and amt for opacity
ctx.fill() // do the drawing
}
function drawCircle(x, y, r, color) {
ctx.beginPath()
ctx.arc(x, y, r, 0, 2 * Math.PI)
ctx.fillStyle = color || 'white'
ctx.fill()
ctx.closePath()
}
function Particle() {
// initialize loopers with random trange and offset
this.loop1 = new Looper(500 + 200 * Math.random(), 860 * Math.random())
this.loop2 = new Looper(320 + 70 * Math.random(), 20 * Math.random())
this.loop3 = new Looper(120 + 20 * Math.random(), 140 * Math.random())
this.history = []
this.history_max = 40
// this.x = null
// this.y = null
this.offset = Math.random() // some color offset for the color
this.draw = function() {
// set x,y, radius, and color params
var x = this.loop1.sin * (wh / 4 - 10) + this.loop2.sin * (wh / 6 - 10) + this.loop3.sin * 60
var y = this.loop1.cos * (wh / 4 - 10) + this.loop2.cos * (wh / 6 - 10) + this.loop3.cos * 10
var r = 0.2 + 3 * this.loop3.sinNorm * this.loop3.cosNorm // set the radius
var c = `hsla(${280 + 60 * (this.loop3.cosNorm + this.offset) * this.loop2.sinNorm}, ${100}%, ${50 + 10 * this.loop3.sin}%, ${1})`
ctx.beginPath()
ctx.strokeStyle = c
ctx.lineCap = 'round'
ctx.lineWidth = r
var tx = x
var ty = y
for (var i = 0; i < Math.min(this.history_max * this.loop3.cosNorm, this.history.length); i++) {
ctx.moveTo(tx, ty)
tx = this.history[i][0]
ty = this.history[i][1]
ctx.lineTo(tx, ty)
}
ctx.stroke()
drawCircle(x, y, r * 2 + 3, c); // draw the circle
this.loop1.update() // update looper
this.loop2.update() // update looper
this.loop3.update() // update looper
this.history.unshift([x, y])
if (this.history.length > this.history_max) {
this.history.pop()
}
}
}
// initialize a set of particle
var particles = []
for (var i = 0; i < 90; i++) {
particles.push(new Particle())
}
function draw() {
// fill context with background color
fill(bg, 0.36)
// update all the particles
for (var i = 0; i < particles.length; i++) {
particles[i].draw() // do it once
}
// this is a draw loop, this will execute frequently and is comparable to EnterFrame on other platform
window.requestAnimationFrame(function() {
draw()
})
}
// start enterFrame loop
window.requestAnimationFrame(draw);
// force running setup
setup()
// re-setup canvas when the size of the window changes
window.addEventListener("resize", setup)
// create a class to hold value and have built in incrementing functionality
function Looper(steps, start) {
this.val = start || 0 // set value to start value if defined, or 1
this.steps = steps || 100 // set steps to passed value or default to 100
this.norm = this.val / this.range // initialize normalized value (between 0 and 1)
this.sin = Math.sin(this.norm * Math.PI * 2) // get sine value from norm normalized to [0, 2PI]
this.sinNorm = (this.sin + 1) / 2 // normalize sin to [0,1]
this.cos = Math.cos(this.norm * Math.PI * 2) // get cosine value from norm normalized to [0, 2PI]
this.cosNorm = (this.cos + 1) / 2 // normalize cos to [0,1]
this.update = function() {
this.val = (this.val + 1) % this.steps // update value
this.norm = this.val / this.steps // update normalize value (between 0 and 1)
this.sin = Math.sin(this.norm * Math.PI * 2) // get sine value from norm normalized to [0, 2PI]
this.sinNorm = (this.sin + 1) / 2 // normalize sine to [0,1]
this.cos = Math.cos(this.norm * Math.PI * 2) // get cosine value from norm normalized to [0, 2PI]
this.cosNorm = (this.cos + 1) / 2 // normalize cos to [0,1]
}
}

In round range slider, how can i change background color of the changed path?

I have got this function but i am unable to get the path to which the slider when dragged should change the background color of the circle...
$(document).ready(function () {
$("#circle").append('<canvas id="slideColorTracker" class="slideColor"></canvas>');
var canvas = document.getElementById("slideColorTracker");
var context = canvas.getContext('2d');
var $circle = $("#circle"),
$handler = $("#handler"),
$p = $("#test").val(),
handlerW2 = $handler.width() / 2,
radius = ($circle.width()/2)+10,
offset = $circle.offset(),
elementPos = { x: offset.left, y: offset.top },
mHold = 0,
PI = Math.PI / 180
$handler.mousedown(function () {
mHold = 1;
var dim = $("#slideColorTracker");
if ($(".slideColor").length > 1) {
$("#slideColorTracker").remove();
}
});
$(document).mousemove(function (e){
move(e);
}).mouseup(function () { mHold = 0 });
function move(e) {
if (mHold) {
debugger
var deg = 180;
var startAngle = 4.72;
var mousePos = { x: e.pageX - elementPos.x, y: e.pageY - elementPos.y }
var atan = Math.atan2(mousePos.x - radius, mousePos.y - radius);
var deg = -atan / PI + 180;
var percentage = (deg * 100 / 360) | 0;
var endAngle = percentage;
var X = Math.round(radius * Math.sin(deg * PI)),
Y = Math.round(radius * -Math.cos(deg * PI));
var cw = X + radius - handlerW2 - 10; //context.canvas.width /2;
var ch = Y + radius - handlerW2 - 10;
$handler.css({
left: X + radius - handlerW2 - 10,
top: Y + radius - handlerW2 - 10,
})
context.beginPath();
context.arc(($circle.width() / 2), ($circle.height() / 2), radius+20, startAngle, endAngle, false);
context.lineWidth = 15;
context.strokeStyle = 'black';
context.stroke();
$("#test").val(percentage);
$circle.css({ borderColor: "hsl(200,70%," + (percentage * 70 / 100 + 30) + "%)" });
}
}
});
I do not want to use any plugin!
Any help will be much appreciated, since i am new to jquery!
Your $handler does not drag for me unless I change it to this:
$handler.css({
left: mousePos.x,
top: mousePos.y,
position:'absolute'
})
When dragged passed $cirlce.width / 2 it does stroke it correctly.

How to draw/Form circle with two points?

I need to draw a circle and i have only two points.Now i need to find center point and radius of the circle? You can form the circle in clock wise direction.
Thanks in advance
Here is a Brute Force approach to the problem.
EDIT
Added a max iterations limit to cut off calculations if the line between the two points is almost straight along x (meaning a radius would be nearing Infinity)
Also animations, because that makes everything better :)
var canvas = document.body.appendChild(document.createElement("canvas"));
var ctx = canvas.getContext("2d");
canvas.width = 1000;
canvas.height = 1000;
var points = [
{ x: parseInt(prompt("x1", "110")), y: parseInt(prompt("y1", "120")), r: 5 },
{ x: parseInt(prompt("x2", "110")), y: parseInt(prompt("y2", "60")), r: 5 },
];
function calculateRemainingPoint(points, x, precision, maxIteration) {
if (x === void 0) { x = 0; }
if (precision === void 0) { precision = 0.001; }
if (maxIteration === void 0) { maxIteration = 100000; }
var newPoint = {
x: x,
y: (points[0].y + points[1].y) / 2,
r: 50
};
var d0 = distance(points[0].x, points[0].y, x, newPoint.y);
var d1 = distance(points[1].x, points[1].y, x, newPoint.y);
var iteration = 0;
//Bruteforce approach
while (Math.abs(d0 - d1) > precision && iteration < maxIteration) {
var oldDiff = Math.abs(d0 - d1);
var oldY = newPoint.y;
iteration++;
newPoint.y += oldDiff / 10;
d0 = distance(points[0].x, points[0].y, x, newPoint.y);
d1 = distance(points[1].x, points[1].y, x, newPoint.y);
var diff_1 = Math.abs(d0 - d1);
if (diff_1 > oldDiff) {
newPoint.y = oldY - oldDiff / 10;
d0 = distance(points[0].x, points[0].y, x, newPoint.y);
d1 = distance(points[1].x, points[1].y, x, newPoint.y);
}
}
var diff = (points[0].x + points[1].x) / points[0].x;
newPoint.r = d0;
return newPoint;
}
points.push(calculateRemainingPoint(points));
function distance(x1, y1, x2, y2) {
var a = x1 - x2;
var b = y1 - y2;
return Math.sqrt(a * a + b * b);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(-canvas.width, canvas.height / 2);
ctx.lineTo(canvas.width, canvas.height / 2);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(canvas.width / 2, -canvas.height);
ctx.lineTo(canvas.width / 2, canvas.height);
ctx.stroke();
ctx.closePath();
for (var pointIndex = 0; pointIndex < points.length; pointIndex++) {
var point = points[pointIndex];
ctx.beginPath();
ctx.arc(point.x + canvas.width / 2, canvas.height / 2 - point.y, point.r, 0, Math.PI * 2);
ctx.arc(point.x + canvas.width / 2, canvas.height / 2 - point.y, 2, 0, Math.PI * 2);
ctx.stroke();
ctx.closePath();
}
}
setInterval(function () {
points = points.slice(0, 2);
points[Math.floor(Math.random() * points.length) % points.length][Math.random() > 0.5 ? 'x' : 'y'] = Math.random() * canvas.width - canvas.width / 2;
setTimeout(function () {
points.push(calculateRemainingPoint(points));
requestAnimationFrame(draw);
}, 1000 / 60);
}, 1000);
draw();
No that is impossible.
Create two circles with the same radius at centerpoints A + B. At the intersection of these two circles create an circle with the same radius....
Then make the same with an other radius....

Categories