I would like to create a spark lines with the various lengths and animate them by moving them from center to end of the canvas and the process has to loop on a canvas. To achieve this i started with a particle system.
Please check the below code and here is the codepen link https://codepen.io/yesvin/pen/XPKNYW
window.onload = function() {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
centerX = w / 2,
centerY = h / 2,
speed = 0,
time = 0,
numObjects = 5,
x, y, vx, vy, life, maxLife;
var lines = {},
lineIndex = 0;
function Line() {
this.x = centerX;
this.y = centerY;
this.vx = Math.random() * 16 - 8;
this.vy = Math.random() * 16 - 8;
this.life = 0;
this.maxLife = Math.random() * 10 + 20;
lineIndex++;
lines[lineIndex] = this;
this.id = lineIndex;
}
Line.prototype.draw = function() {
this.x += this.vx;
this.y += this.vy;
this.life++;
if (this.life >= this.maxLife) {
delete lines[this.id];
}
context.fillStyle = "#000";
context.fillRect(this.x, this.y, 3, 3)
}
setInterval(function() {
context.fillStyle = 'rgba(255,255,255,.05)';
context.fillRect(0, 0, w, h);
new Line();
for (var i in lines) {
lines[i].draw();
}
}, 30)
};
body {
overflow: hidden;
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
So, How do we create this same effect using the lineTo(), and moveTo() methods? I tried with the following code (which is commented in a codepen)
context.beginPath();
context.moveTo(centerX, centerY);
context.lineTo(this.x * Math.random() * w, this.y * Math.random() * h);
context.lineWidth = 1;
context.stroke();
context.strokeStyle = "#000";
Sample GIF
Thanks in advance.
Here is one approach...
With lines you will get a more continuous effect:
The change I'm making to your code is to keep track of the start and end points.
window.onload = function() {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
w = canvas.width = window.innerWidth,
h = canvas.height = window.innerHeight,
centerX = w / 2,
centerY = h / 2;
var lines = {},
lineIndex = 0;
function Line() {
this.start = { x: centerX, y: centerY };
this.end = { x: centerX, y: centerY };
this.vx = Math.random() * 16 - 8;
this.vy = Math.random() * 16 - 8;
this.life = 0;
this.maxLife = Math.random() * 10 + 20;
lineIndex++;
lines[lineIndex] = this;
this.id = lineIndex;
}
Line.prototype.draw = function() {
this.end.x += this.vx;
this.end.y += this.vy;
this.life++;
if (this.life >= this.maxLife) {
delete lines[this.id];
}
//context.fillStyle = "#000";
//context.fillRect(this.x, this.y, 1, 1)
context.beginPath();
context.moveTo(this.start.x, this.start.y);
context.lineTo(this.end.x, this.end.y);
context.lineWidth = 1;
context.stroke();
context.strokeStyle = "#000";
}
setInterval(function() {
context.fillStyle = 'rgba(255,255,255,.05)';
context.fillRect(0, 0, w, h);
new Line();
for (var i in lines) {
lines[i].draw();
}
}, 30)
};
body {
overflow: hidden;
margin: 0;
padding: 0;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
Related
Im new to this area and hope some off you can help me.
I am super inspired be this site and the particle animation / function they have http://www.giantstepsmedias.com/
I found this one that are close to the inspiration. But i can't figure out how to change it to an images instead of the value in the input field.
var canvas = document.querySelector("#scene"),
ctx = canvas.getContext("2d"),
particles = [],
amount = 0,
mouse = {x:0,y:0},
radius = 1;
var colors = ["rgba(255,255,255,1)","rgba(255,255,255,.5)", "rgba(255,255,255,.25)","rgba(255,255,255,.1)"];
var copy = document.querySelector("#copy");
var ww = canvas.width = window.innerWidth;
var wh = canvas.height = window.innerHeight;
function Particle(x,y){
this.x = Math.random()*ww;
this.y = Math.random()*wh;
this.dest = {
x : x,
y: y
};
this.r = Math.random()*5 + 2;
this.vx = (Math.random()-0.5)*20;
this.vy = (Math.random()-0.5)*20;
this.accX = 0;
this.accY = 0;
this.friction = Math.random()*0.05 + 0.94;
this.color = colors[Math.floor(Math.random()*6)];
}
Particle.prototype.render = function() {
this.accX = (this.dest.x - this.x)/1000;
this.accY = (this.dest.y - this.y)/1000;
this.vx += this.accX;
this.vy += this.accY;
this.vx *= this.friction;
this.vy *= this.friction;
this.x += this.vx;
this.y += this.vy;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, Math.PI * 2, false);
ctx.fill();
var a = this.x - mouse.x;
var b = this.y - mouse.y;
var distance = Math.sqrt( a*a + b*b );
if(distance<(radius*70)){
this.accX = (this.x - mouse.x)/100;
this.accY = (this.y - mouse.y)/100;
this.vx += this.accX;
this.vy += this.accY;
}
}
function onMouseMove(e){
mouse.x = e.clientX;
mouse.y = e.clientY;
}
function onTouchMove(e){
if(e.touches.length > 0 ){
mouse.x = e.touches[0].clientX;
mouse.y = e.touches[0].clientY;
}
}
function onTouchEnd(e){
mouse.x = -9999;
mouse.y = -9999;
}
function initScene(){
ww = canvas.width = window.innerWidth;
wh = canvas.height = window.innerHeight;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = "bold "+(ww/10)+"px sans-serif";
ctx.textAlign = "center";
ctx.fillText(copy.value, ww/2, wh/2);
var data = ctx.getImageData(0, 0, ww, wh).data;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "screen";
particles = [];
for(var i=0;i<ww;i+=Math.round(ww/150)){
for(var j=0;j<wh;j+=Math.round(ww/150)){
if(data[ ((i + j*ww)*4) + 3] > 150){
particles.push(new Particle(i,j));
}
}
}
amount = particles.length;
}
function onMouseClick(){
radius++;
if(radius ===5){
radius = 0;
}
}
function render(a) {
requestAnimationFrame(render);
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < amount; i++) {
particles[i].render();
}
};
copy.addEventListener("keyup", initScene);
window.addEventListener("resize", initScene);
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("touchmove", onTouchMove);
window.addEventListener("click", onMouseClick);
window.addEventListener("touchend", onTouchEnd);
initScene();
requestAnimationFrame(render);
canvas{
background: black;
width: 100vw;
height: 100vh;
}
<canvas id="scene"></canvas>
<input id="copy" type="text" value="Hello Codepen ♥" />
The animation is based on whatever has been rendered to the canvas.
In your code that is
ctx.font = "bold "+(ww/10)+"px sans-serif";
ctx.textAlign = "center";
ctx.fillText(copy.value, ww/2, wh/2);
instead, change this to render an image:
const img = document.getElementById('img');
ctx.drawImage(img, ww/2, wh/2);
you might like to adjust the positions for .drawImage: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage
Using HTML:
<canvas id="scene"></canvas>
<div style="display:none;">
<img id="img"
src="http://www.giantstepsmedias.com/img/logos/giant_steps_small.png">
</div>
However, rendering an image from a different server to your ctx gives The canvas has been tainted by cross-origin data so I can't give you a working snippet.
Use an image that is on the same server as the page or, as suggested, use a data: url:
var canvas = document.querySelector("#scene"),
ctx = canvas.getContext("2d"),
particles = [],
amount = 0,
mouse = {
x: 0,
y: 0
},
radius = 1;
var colors = ["rgba(255,255,255,1)", "rgba(255,255,255,.5)", "rgba(255,255,255,.25)", "rgba(255,255,255,.1)"];
var ww = canvas.width = window.innerWidth;
var wh = canvas.height = window.innerHeight;
function Particle(x, y) {
this.x = Math.random() * ww;
this.y = Math.random() * wh;
this.dest = {
x: x,
y: y
};
this.r = Math.random() * 5 + 2;
this.vx = (Math.random() - 0.5) * 20;
this.vy = (Math.random() - 0.5) * 20;
this.accX = 0;
this.accY = 0;
this.friction = Math.random() * 0.05 + 0.94;
this.color = colors[Math.floor(Math.random() * 6)];
}
Particle.prototype.render = function() {
this.accX = (this.dest.x - this.x) / 1000;
this.accY = (this.dest.y - this.y) / 1000;
this.vx += this.accX;
this.vy += this.accY;
this.vx *= this.friction;
this.vy *= this.friction;
this.x += this.vx;
this.y += this.vy;
ctx.fillStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, Math.PI * 2, false);
ctx.fill();
var a = this.x - mouse.x;
var b = this.y - mouse.y;
var distance = Math.sqrt(a * a + b * b);
if (distance < (radius * 70)) {
this.accX = (this.x - mouse.x) / 100;
this.accY = (this.y - mouse.y) / 100;
this.vx += this.accX;
this.vy += this.accY;
}
}
function onMouseMove(e) {
mouse.x = e.clientX;
mouse.y = e.clientY;
}
function onTouchMove(e) {
if (e.touches.length > 0) {
mouse.x = e.touches[0].clientX;
mouse.y = e.touches[0].clientY;
}
}
function onTouchEnd(e) {
mouse.x = -9999;
mouse.y = -9999;
}
function initScene() {
ww = canvas.width = window.innerWidth;
wh = canvas.height = window.innerHeight;
ctx.clearRect(0, 0, canvas.width, canvas.height);
//ctx.font = "bold "+(ww/10)+"px sans-serif";
//ctx.textAlign = "center";
//ctx.fillText(copy.value, ww/2, wh/2);
const img = document.getElementById('img');
ctx.drawImage(img, ww / 2 - 75, (wh / 2) - 75, 150, 150);
var data = ctx.getImageData(0, 0, ww, wh).data;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = "screen";
particles = [];
for (var i = 0; i < ww; i += Math.round(ww / 150)) {
for (var j = 0; j < wh; j += Math.round(ww / 150)) {
if (data[((i + j * ww) * 4) + 3] > 150) {
particles.push(new Particle(i, j));
}
}
}
amount = particles.length;
}
function onMouseClick() {
radius++;
if (radius === 5) {
radius = 0;
}
}
function render(a) {
requestAnimationFrame(render);
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < amount; i++) {
particles[i].render();
}
};
window.addEventListener("resize", initScene);
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("touchmove", onTouchMove);
window.addEventListener("click", onMouseClick);
window.addEventListener("touchend", onTouchEnd);
initScene();
requestAnimationFrame(render);
canvas {
background: black;
width: 100vw;
height: 100vh;
}
<canvas id="scene"></canvas>
<div style="display:none;">
<img id="img" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAsCAYAAAAJpsrIAAAC9UlEQVR42syZSWgUQRSGezJJ0IhLwIDLRQkumEMOihdFPOghcd9QEEREiIokHkQRISAKRsUdEUxAL2pGxV08iQt40QgexAUNiBgFSQY0EjEzk/J/8kqHobvrRat76sE3E7prar55vdTrl4RS6oXneaNBzvsbSdAPjoATYMCzFw3gAMj6zEvf2w2mlOJlPBgVMAmJTQY7Qa8lsQowMmR/iX7JhAxKgM0gBSZaEjNlP/PHThB14BaY48UUJYMYW8NyG1wToxgB2sA+MNQlMX3e7QZnwTiXxHSsBjfBTNfEKKaDa2BF3GIK/DSMocN5ke91ZXGKHQPthnEk1ALO8CoSuRjtfwvWg1bBfDTuMpgaxzk2nA8nrXHbQZ9h/FxwG8yPWkzlvR/mrHwyfKaaM7clzquSvnAZeG4YRwv1KXAcDItCrN9n2xOwiA+ZKRr5qtVFQLktsTVgks/2j7zvqKBioB9xndfbPlHKUCh+UeZ4DWYDL4BG0CuYpxPcAwMhY8hHLEbRAzaGyNWBD+r/Y9Biin/pQVARIFcLOoohpuMSGBsgNwakiiWmODMzAuTKwH6QKYYYRRdYFXLeNYCvxRCjyIJmzpKf3Dy+Gq2K0cmeFk7YBqoC5GrAA9sZo2zsEU76kCX85CrBOc6wFbFtPHET+C6QewfqA+SSoFUiJlmS9NMQLcZrhZVFe0BlQW2IDltrZTbv7xtgMXgqqOGosjjp0w4YYkussOZ/BpaAq4LPbgXnwYQoyp6Ez7bPXFkcKsioXywAd/LaCyrqxzdqfuzgeuubYew0cAXUgx+SyUstPNCcBu/5fKoOGVcFLvDYHPfCInvg1XGXL4rHgnK71iRlU4ziJculXGgRFEYarAN7DQ3B2MX0w0sz32DTLonpoD7aSvDGNTGK+3wfe+SaGEUnWM4ZdEqMogdsArsEba1YxXRl0cK9j26JmKnZlrQsSCXRUvAqpNf2e0nq4vTmfBbvcsE6+C9BK8RCbi/Myju8+l823i8BBgAb0AQfHTBwWAAAAABJRU5ErkJggg=="
alt="" />
</div>
Basically I want background to be seen between rects. Right now I'm trying to leave a distance which is dependable on rect size between them, can I make that size to be exact number of pixels?
Because right now these empty spaces merge, sometimes are not seen at all, etc.
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
var canvas = document.getElementById("posHourCanvas");
var context = canvas.getContext('2d');
var boxes = [];
function init() {
context.clearRect(0, 0, canvas.width, canvas.height);
boxes.length = 0;
const strokeWidth = 0.2;
canvas.width = $('#two')[0].clientWidth;
var cellSize = canvas.width / 27;
canvas.height = 7 / 27 * canvas.width;
var x = y = 0;
draw(x, y, canvas.width, canvas.height, cellSize, strokeWidth);
}
function Box(x, y, day, hour) {
this.x = x;
this.y = y;
this.day = day;
this.hour = hour;
}
function draw(x, y, w, h, cellSize, strokeWidth) {
let onePixel = cellSize * strokeWidth;
cellSize = cellSize * (1 - strokeWidth);
context.beginPath();
context.lineWidth = 0.01;
context.strokeStyle = 'rgba(255, 255, 255, 0)';
for (let i = 0; i < 7; i++) {
context.beginPath();
dayRect(context, cellSize, i, onePixel);
let startX = 3 * cellSize + onePixel;
for (let j = 0; j < 25; j++) {
context.rect(startX, i * cellSize + i * onePixel, cellSize, cellSize);
context.fillStyle = "white";
context.fill();
startX += cellSize + onePixel;
}
}
}
function dayRect(context, cellSize, day, onePixel) {
var offSet = day * onePixel;
context.rect(0, day * cellSize + offSet, 3 * cellSize, cellSize);
context.fillStyle = "white";
context.fill();
}
init();
window.addEventListener("resize", init, false);
body {
margin: auto;
color: white;
background-color: black;
}
div#two {
margin-left: 5%;
width: 10%;
height: 30%;
}
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<div id="parent">
<div>text above</div>
<div id="two">
<canvas id="posHourCanvas" width="600" height="300"></canvas>
</div>
<div>text under</div>
</div>
JSFIDDLE: http://jsfiddle.net/kgbh9352/
the html file does not seem to be importing the javascript function particle() to upload i have the script in another file and i am importing it to my html file but it does not work , it might be some basic error i just cant figure it out here !
if you could fix this code i would really appreciate it .
var canvas = document.createElement("canvas");
c = canvas.getContext("2d");
var particles = {};
var particleIndex = 0;
var particleNum = 15;
// set canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// add canvas to body
document.body.appendChild(canvas);
// style the canvas
c.fillStyle = "black";
c.fillRect(0, 0, canvas.width, canvas.height);
function Particle() {
this.x = canvas.width / 2;
this.y = canvas.height / 2;
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = 0.3;
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
this.life = 0;
this.maxLife = Math.random() * 30 + 60;
this.color = "hsla(" + parseInt(Math.random() * 360, 10) + ",90%,60%,0.5";
}
Particle.prototype.draw = function() {
this.x += this.vx;
this.y += this.vy;
if (Math.random() < 0.1) {
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
}
this.life++;
if (this.life >= this.maxLife) {
delete particles[this.id];
}
c.fillStyle = this.color;
//c.fillRect(this.x, this.y, 5, 10);
c.beginPath();
c.arc(this.x, this.y, 2.5, 0, 2 * Math.PI);
c.fill();
};
setInterval(function() {
//normal setting before drawing over canvas w/ black background
c.globalCompositeOperation = "source-over";
c.fillStyle = "rgba(0,0,0,0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < particleNum; i++) {
new Particle();
}
// c.globalCompositeOperation = "darken";
for (var i in particles) {
particles[i].draw();
}
}, 30);
<!DOCTYPE html5>
<html>
<head>
<title>disturbed</title>
<script src="toto.js" type="text/javascript"></script>
<script type="text/javascript">
window.onload = function() {
Particle();
};
</script>
</head>
<body>
</body>
</html>
function runParticles () {
var canvas = document.createElement("canvas");
c = canvas.getContext("2d");
var particles = {};
var particleIndex = 0;
var particleNum = 15;
// set canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// add canvas to body
document.body.appendChild(canvas);
// style the canvas
c.fillStyle = "black";
c.fillRect(0, 0, canvas.width, canvas.height);
function Particle() {
this.x = canvas.width / 2;
this.y = canvas.height / 2;
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = 0.3;
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
this.life = 0;
this.maxLife = Math.random() * 30 + 60;
this.color = "hsla(" + parseInt(Math.random() * 360, 10) + ",90%,60%,0.5";
}
Particle.prototype.draw = function() {
this.x += this.vx;
this.y += this.vy;
if (Math.random() < 0.1) {
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
}
this.life++;
if (this.life >= this.maxLife) {
delete particles[this.id];
}
c.fillStyle = this.color;
//c.fillRect(this.x, this.y, 5, 10);
c.beginPath();
c.arc(this.x, this.y, 2.5, 0, 2 * Math.PI);
c.fill();
};
setInterval(function() {
//normal setting before drawing over canvas w/ black background
c.globalCompositeOperation = "source-over";
c.fillStyle = "rgba(0,0,0,0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < particleNum; i++) {
new Particle();
}
// c.globalCompositeOperation = "darken";
for (var i in particles) {
particles[i].draw();
}
}, 30);
}
<!DOCTYPE html5>
<html>
<head>
<title>disturbed</title>
<script src="toto.js" type="text/javascript"></script>
<script>
window.onload = () => runParticles();
</script>
</head>
<body>
</body>
</html>
Remove this:
<script type="text/javascript">
window.onload = function() {
Particle();
};
i have made a an animations in canvas html but now i want to make the origin from where the balls originate move around the canvas according to my mouse position. i want to add mouse event function but i can't seem to get the logic straightand add added to the code , any help would be appreciated !
function runParticles () {
var canvas = document.createElement("canvas");
c = canvas.getContext("2d");
var particles = {};
var particleIndex = 0;
var particleNum = 15;
// set canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// add canvas to body
document.body.appendChild(canvas);
// style the canvas
c.fillStyle = "black";
c.fillRect(0, 0, canvas.width, canvas.height);
function Particle() {
this.x = canvas.width / 2;
this.y = canvas.height / 2;
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = 0.3;
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
this.life = 0;
this.maxLife = Math.random() * 30 + 60;
this.color = "hsla(" + parseInt(Math.random() * 360, 10) + ",90%,60%,0.5";
}
Particle.prototype.draw = function() {
this.x += this.vx;
this.y += this.vy;
if (Math.random() < 0.1) {
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
}
this.life++;
if (this.life >= this.maxLife) {
delete particles[this.id];
}
c.fillStyle = this.color;
//c.fillRect(this.x, this.y, 5, 10);
c.beginPath();
c.arc(this.x, this.y, 2.5, degToRad(0), degToRad(360));
c.fill();
};
setInterval(function() {
//normal setting before drawing over canvas w/ black background
c.globalCompositeOperation = "source-over";
c.fillStyle = "rgba(0,0,0,0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < particleNum; i++) {
new Particle();
}
// c.globalCompositeOperation = "darken";
for (var i in particles) {
particles[i].draw();
}
}, 30);
}
function degToRad(deg) {
var radians = (deg * Math.PI / 180) - Math.PI / 2;
return radians;
}
<!DOCTYPE html5>
<html>
<head>
<title>disturbed</title>
<script src="toto.js" type="text/javascript"></script>
<script>
window.onload = () => runParticles();
</script>
</head>
<body>
</body>
</html>
I've added a function to detect the mouse position:
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}
I've declared a variable m (the mouse).
var m = {x:canvas.width/2,y:canvas.height/2};
and I've changed the origin of the particles from this.x = canvas.width / 2;
this.y = canvas.height / 2;to this.x = m.x; this.y = m.y;
This is the position when the mouse do not move over the canvas
I've added an event "mousemove". When the mouse move over the canvas it's position change.
canvas.addEventListener("mousemove", (evt)=>{
m = oMousePos(canvas, evt);
})
I've also added an event "mouseleave". When the mouse leaves the canvas, the mouse goes back in the center.
canvas.addEventListener("mouseleave", (evt)=>{
m = {x:canvas.width/2,y:canvas.height/2};
})
Also I've changed the setInterval for requestAnimationFrame ( much more efficient ). The code inside is your code.
function runParticles () {
var canvas = document.createElement("canvas");
c = canvas.getContext("2d");
var particles = {};
var particleIndex = 0;
var particleNum = 8;
// set canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var m = {x:canvas.width/2,y:canvas.height/2};///////
// add canvas to body
document.body.appendChild(canvas);
// style the canvas
c.fillStyle = "black";
c.fillRect(0, 0, canvas.width, canvas.height);
function Particle() {
this.x = m.x;//////////
this.y = m.y;//////////
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
this.gravity = 0.3;
particleIndex++;
particles[particleIndex] = this;
this.id = particleIndex;
this.life = 0;
this.maxLife = Math.random() * 30 + 60;
this.color = "hsla(" + parseInt(Math.random() * 360, 10) + ",90%,60%,0.5";
}
Particle.prototype.draw = function() {
this.x += this.vx;
this.y += this.vy;
if (Math.random() < 0.1) {
this.vx = Math.random() * 10 - 5;
this.vy = Math.random() * 10 - 5;
}
this.life++;
if (this.life >= this.maxLife) {
delete particles[this.id];
}
c.fillStyle = this.color;
//c.fillRect(this.x, this.y, 5, 10);
c.beginPath();
c.arc(this.x, this.y, 2.5, degToRad(0), degToRad(360));
c.fill();
};
function Draw() {
window.requestAnimationFrame(Draw);
c.globalCompositeOperation = "source-over";
c.fillStyle = "rgba(0,0,0,0.5)";
c.fillRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < particleNum; i++) {
new Particle();
}
// c.globalCompositeOperation = "darken";
for (var i in particles) {
particles[i].draw();
}
}
Draw();
///////////////////
canvas.addEventListener("mousemove", (evt)=>{
m = oMousePos(canvas, evt);
})
canvas.addEventListener("mouseleave", (evt)=>{
m = {x:canvas.width/2,y:canvas.height/2};
})
///////////////////
}
function degToRad(deg) {
var radians = (deg * Math.PI / 180) - Math.PI / 2;
return radians;
}
runParticles();
function oMousePos(canvas, evt) {
var ClientRect = canvas.getBoundingClientRect();
return { //objeto
x: Math.round(evt.clientX - ClientRect.left),
y: Math.round(evt.clientY - ClientRect.top)
}
}
body,canvas{margin:0;padding:0;}
I hope this helps.
I'm using line chart with Canvas. I drew with data I got. The yValue displayed data and xValue increased one step with updateInterval times like Dynamic line chart. I want to clear the data drew on line chart and redraw new data when xValue >= 200. How can I sovle this ?
Thank a lot.
<html>
<head>
</head>
<body>
<canvas id="myCanvas" width="1200" height="600" style="border:1px solid black;"></canvas>
<script type="text/javascript">
function LineChart(config){
// user defined properties
this.canvas = document.getElementById(config.canvasId);
this.minX = config.minX;
this.minY = config.minY;
this.maxX = config.maxX;
this.maxY = config.maxY;
this.unitsPerTickX = config.unitsPerTickX;
this.unitsPerTickY = config.unitsPerTickY;
// constants
this.padding = 10;
this.tickSize = 10;
this.axisColor = "#555";
this.pointRadius = 2;
this.font = "12pt Calibri";
/*
* measureText does not provide a text height
* metric, so we'll have to hardcode a text height
* value
*/
this.fontHeight = 12;
// relationships
this.context = this.canvas.getContext("2d");
this.rangeX = this.maxX - this.minY;
this.rangeY = this.maxY - this.minY;
this.numXTicks = Math.round(this.rangeX / this.unitsPerTickX);
this.numYTicks = Math.round(this.rangeY / this.unitsPerTickY);
this.x = this.getLongestValueWidth() + this.padding * 2;
this.y = this.padding * 2;
this.width = this.canvas.width - this.x - this.padding * 2;
this.height = this.canvas.height - this.y - this.padding -
this.fontHeight;
this.scaleX = this.width / this.rangeX;
this.scaleY = this.height / this.rangeY;
// draw x y axis and tick marks
this.drawXAxis();
this.drawYAxis();
}
LineChart.prototype.getLongestValueWidth = function(){
this.context.font = this.font;
var longestValueWidth = 0;
for (var n = 0; n <= this.numYTicks; n++) {
var value = this.maxY - (n * this.unitsPerTickY);
longestValueWidth = Math.max(longestValueWidth, this.
context.measureText(value).width);
}
return longestValueWidth;
};
LineChart.prototype.drawXAxis = function(){
var context = this.context;
context.save();
context.beginPath();
context.moveTo(this.x, this.y + this.height);
context.lineTo(this.x + this.width, this.y + this.height);
context.strokeStyle = this.axisColor;
context.lineWidth = 2;
context.stroke();
// draw tick marks
for (var n = 0; n < this.numXTicks; n++) {
context.beginPath();
context.moveTo((n + 1) * this.width / this.numXTicks +
this.x, this.y + this.height);
context.lineTo((n + 1) * this.width / this.numXTicks +
this.x, this.y + this.height - this.tickSize);
context.stroke();
}
// draw labels
context.font = this.font;
context.fillStyle = "black";
context.textAlign = "center";
context.textBaseline = "middle";
for (var n = 0; n < this.numXTicks; n++) {
var label = Math.round((n + 1) * this.maxX / this.
numXTicks);
context.save();
context.translate((n + 1) * this.width / this.numXTicks +
this.x, this.y + this.height + this.padding);
context.fillText(label, 0, 0);
context.restore();
}
context.restore();
};
LineChart.prototype.drawYAxis = function(){
var context = this.context;
context.save();
context.save();
context.beginPath();
context.moveTo(this.x, this.y);
context.lineTo(this.x, this.y + this.height);
context.strokeStyle = this.axisColor;
context.lineWidth = 2;
context.stroke();
context.restore();
// draw tick marks
for (var n = 0; n < this.numYTicks; n++) {
context.beginPath();
context.moveTo(this.x, n * this.height / this.numYTicks +
this.y);
context.lineTo(this.x + this.tickSize, n * this.height /
this.numYTicks + this.y);
context.stroke();
}
// draw values
context.font = this.font;
context.fillStyle = "black";
context.textAlign = "right";
context.textBaseline = "middle";
for (var n = 0; n < this.numYTicks; n++) {
var value = Math.round(this.maxY - n * this.maxY / this.numYTicks);
context.save();
context.translate(this.x - this.padding, n * this.height /
this.numYTicks + this.y);
context.fillText(value, 0, 0);
context.restore();
}
context.restore();
};
LineChart.prototype.drawLine = function(data, color, width){
var context = this.context;
context.save();
this.transformContext();
context.lineWidth = width;
context.strokeStyle = color;
context.fillStyle = color;
context.beginPath();
context.moveTo(data[0].x * this.scaleX, data[0].y * this.
scaleY);
for (var n = 0; n < data.length; n++) {
var point = data[n];
// draw segment
context.lineTo(point.x * this.scaleX, point.y * this.
scaleY);
context.stroke();
context.closePath();
context.beginPath();
context.arc(point.x * this.scaleX, point.y * this.scaleY,
this.pointRadius, 0, 2 * Math.PI, false);
context.fill();
context.closePath();
// position for next segment
context.beginPath();
context.moveTo(point.x * this.scaleX, point.y * this.scaleY);
}
context.restore();
};
LineChart.prototype.transformContext = function(){
var context = this.context;
// move context to center of canvas
this.context.translate(this.x, this.y + this.height);
// invert the y scale so that that increments
// as you move upwards
context.scale(1, -1);
};
window.onload = function(){
var myLineChart = new LineChart({
canvasId: "myCanvas",
minX: 0,
minY: 0,
maxX: 200,
maxY: 260,
unitsPerTickX: 20,
unitsPerTickY: 50
});
var dps = [];
var xVal = dps.length + 1;
var yVal ;
var updateInterval = 100;
function updatedata(){
yVal = xVal;
dps.push({x: xVal,y: yVal});
xVal++;
myLineChart.drawLine(dps, "blue", 3);
};
setInterval(function(){updatedata()}, updateInterval);
};
</script>
</body>
</html>
To re-animate the same line just clear dps and reset xVal
In your updatedata function, test if xVal>200. If yes:
clear the canvas
redraw the X & Y axes
reset the dps array to zero length
reset xVal to dps.length+1
Here's example code and a Demo:
function LineChart(config){
// user defined properties
this.canvas = document.getElementById(config.canvasId);
this.minX = config.minX;
this.minY = config.minY;
this.maxX = config.maxX;
this.maxY = config.maxY;
this.unitsPerTickX = config.unitsPerTickX;
this.unitsPerTickY = config.unitsPerTickY;
// constants
this.padding = 10;
this.tickSize = 10;
this.axisColor = "#555";
this.pointRadius = 2;
this.font = "12pt Calibri";
/*
* measureText does not provide a text height
* metric, so we'll have to hardcode a text height
* value
*/
this.fontHeight = 12;
// relationships
this.context = this.canvas.getContext("2d");
this.rangeX = this.maxX - this.minY;
this.rangeY = this.maxY - this.minY;
this.numXTicks = Math.round(this.rangeX / this.unitsPerTickX);
this.numYTicks = Math.round(this.rangeY / this.unitsPerTickY);
this.x = this.getLongestValueWidth() + this.padding * 2;
this.y = this.padding * 2;
this.width = this.canvas.width - this.x - this.padding * 2;
this.height = this.canvas.height - this.y - this.padding -
this.fontHeight;
this.scaleX = this.width / this.rangeX;
this.scaleY = this.height / this.rangeY;
// draw x y axis and tick marks
this.drawXAxis();
this.drawYAxis();
}
LineChart.prototype.getLongestValueWidth = function(){
this.context.font = this.font;
var longestValueWidth = 0;
for (var n = 0; n <= this.numYTicks; n++) {
var value = this.maxY - (n * this.unitsPerTickY);
longestValueWidth = Math.max(longestValueWidth, this.
context.measureText(value).width);
}
return longestValueWidth;
};
//
LineChart.prototype.drawXAxis = function(){
var context = this.context;
context.save();
context.beginPath();
context.moveTo(this.x, this.y + this.height);
context.lineTo(this.x + this.width, this.y + this.height);
context.strokeStyle = this.axisColor;
context.lineWidth = 2;
context.stroke();
// draw tick marks
for (var n = 0; n < this.numXTicks; n++) {
context.beginPath();
context.moveTo((n + 1) * this.width / this.numXTicks +
this.x, this.y + this.height);
context.lineTo((n + 1) * this.width / this.numXTicks +
this.x, this.y + this.height - this.tickSize);
context.stroke();
}
// draw labels
context.font = this.font;
context.fillStyle = "black";
context.textAlign = "center";
context.textBaseline = "middle";
for (var n = 0; n < this.numXTicks; n++) {
var label = Math.round((n + 1) * this.maxX / this.
numXTicks);
context.save();
context.translate((n + 1) * this.width / this.numXTicks +
this.x, this.y + this.height + this.padding);
context.fillText(label, 0, 0);
context.restore();
}
context.restore();
};
//
LineChart.prototype.drawYAxis = function(){
var context = this.context;
context.save();
context.save();
context.beginPath();
context.moveTo(this.x, this.y);
context.lineTo(this.x, this.y + this.height);
context.strokeStyle = this.axisColor;
context.lineWidth = 2;
context.stroke();
context.restore();
// draw tick marks
for (var n = 0; n < this.numYTicks; n++) {
context.beginPath();
context.moveTo(this.x, n * this.height / this.numYTicks +
this.y);
context.lineTo(this.x + this.tickSize, n * this.height /
this.numYTicks + this.y);
context.stroke();
}
// draw values
context.font = this.font;
context.fillStyle = "black";
context.textAlign = "right";
context.textBaseline = "middle";
for (var n = 0; n < this.numYTicks; n++) {
var value = Math.round(this.maxY - n * this.maxY / this.numYTicks);
context.save();
context.translate(this.x - this.padding, n * this.height /
this.numYTicks + this.y);
context.fillText(value, 0, 0);
context.restore();
}
context.restore();
};
//
LineChart.prototype.drawLine = function(data, color, width){
var context = this.context;
context.save();
this.transformContext();
context.lineWidth = width;
context.strokeStyle = color;
context.fillStyle = color;
context.beginPath();
context.moveTo(data[0].x * this.scaleX, data[0].y * this.
scaleY);
for (var n = 0; n < data.length; n++) {
var point = data[n];
// draw segment
context.lineTo(point.x * this.scaleX, point.y * this.
scaleY);
context.stroke();
context.closePath();
context.beginPath();
context.arc(point.x * this.scaleX, point.y * this.scaleY,
this.pointRadius, 0, 2 * Math.PI, false);
context.fill();
context.closePath();
// position for next segment
context.beginPath();
context.moveTo(point.x * this.scaleX, point.y * this.scaleY);
}
context.restore();
};
//
LineChart.prototype.transformContext = function(){
var context = this.context;
// move context to center of canvas
this.context.translate(this.x, this.y + this.height);
// invert the y scale so that that increments
// as you move upwards
context.scale(1, -1);
};
//
//
window.onload = function(){
var myLineChart = new LineChart({
canvasId: "myCanvas",
minX: 0,
minY: 0,
maxX: 200,
maxY: 260,
unitsPerTickX: 20,
unitsPerTickY: 50
});
//
var dps = [];
var xVal = dps.length + 1;
var yVal ;
var updateInterval = 100;
var color='blue';
function updatedata(){
if(xVal>200){
myLineChart.context.clearRect(0,0,myLineChart.canvas.width,myLineChart.canvas.height);
myLineChart.drawXAxis();
myLineChart.drawYAxis();
dps.length=0;
xVal=dps.length+1;
color=(color=='blue')?'red':'blue';
}
//
yVal = xVal;
dps.push({x: xVal,y: yVal});
xVal++;
myLineChart.drawLine(dps, color, 3);
};
setInterval(function(){updatedata()}, updateInterval);
};
<canvas id="myCanvas" width="1200" height="600" style="border:1px solid black;"></canvas>