How do convert this mouse hover effect in reactjs - javascript

I don't know if this makes me lazy or what I just to use this kind method but it doesn't work well in react.
Here is the link of the code
HOVER
So basically my error here is the part of ctx = canvas.getContext('2d') I try to copy all the codes and do this something in my react
useEffect(() => {
const rippleSettings = {
maxSize: 100,
animationSpeed: 5,
strokeColor: [148, 217, 255],
};
const canvasSettings = {
blur: 8,
ratio: 1,
};
function Coords(x, y) {
this.x = x || null;
this.y = y || null;
}
const Ripple = function Ripple(x, y, circleSize, ctx) {
this.position = new Coords(x, y);
this.circleSize = circleSize;
this.maxSize = rippleSettings.maxSize;
this.opacity = 1;
this.ctx = ctx;
this.strokeColor = `rgba(${Math.floor(rippleSettings.strokeColor[0])},
${Math.floor(rippleSettings.strokeColor[1])},
${Math.floor(rippleSettings.strokeColor[2])},
${this.opacity})`;
this.animationSpeed = rippleSettings.animationSpeed;
this.opacityStep = (this.animationSpeed / (this.maxSize - circleSize)) / 2;
};
Ripple.prototype = {
update: function update() {
this.circleSize = this.circleSize + this.animationSpeed;
this.opacity = this.opacity - this.opacityStep;
this.strokeColor = `rgba(${Math.floor(rippleSettings.strokeColor[0])},
${Math.floor(rippleSettings.strokeColor[1])},
${Math.floor(rippleSettings.strokeColor[2])},
${this.opacity})`;
},
draw: function draw() {
this.ctx.beginPath();
this.ctx.strokeStyle = this.strokeColor;
this.ctx.arc(this.position.x, this.position.y, this.circleSize, 0,
2 * Math.PI);
this.ctx.stroke();
},
setStatus: function setStatus(status) {
this.status = status;
},
};
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');
console.log(ctx)
const ripples = [];
const rippleStartStatus = 'start';
const isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
canvas.style.filter = `blur(${canvasSettings.blur}px)`;
canvas.width = width * canvasSettings.ratio;
canvas.height = height * canvasSettings.ratio;
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
let animationFrame;
// Function which is executed on mouse hover on canvas
const canvasMouseOver = (e) => {
const x = e.clientX * canvasSettings.ratio;
const y = e.clientY * canvasSettings.ratio;
ripples.unshift(new Ripple(x, y, 2, ctx));
};
const animation = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
const length = ripples.length;
for (let i = length - 1; i >= 0; i -= 1) {
const r = ripples[i];
r.update();
r.draw();
if (r.opacity <= 0) {
ripples[i] = null;
delete ripples[i];
ripples.pop();
}
}
animationFrame = window.requestAnimationFrame(animation);
};
animation();
canvas.addEventListener('mousemove', canvasMouseOver);
})
I removed the part of GUI based on the link because I don't need the settings. So what I want here is the getContext('2d') I don't understand why it is wrong. Can anyone figure out it for me? Should I be asking this question? I feel so unlucky right now hahha badly need help.

Related

Draw line after zoom and pan in canvas on cursor point correcting-coordinates

I am creating a canvas with multiple image which have zoom and pan action in Svelte application. And now want to draw line on it after disable zoom and pan. Zoom and pan working well but I cannot draw line on the canvas after zoom and pan disabled as expected. Unable to draw line on cursor point or correcting-coordinates. It's drawing far from cursor and moving the line too far on mouse move.
I am giving full code here so that any one can run it in Svelte application to see it
I tried so many ways but can't solve it.
<script>
import { onMount } from "svelte";
import { f7ready } from "framework7-svelte";
let canvasWidth = 500;
let canvasHeight = 500;
let ctx;
let canvas;
let isDrawing = false;
let start;
var scaleFactor = 1.1;
var factor = 1.1;
let canDragAndZoom = true;
let t, l;
$: ctx;
$: canvas;
$: isDrawing;
$: start;
$: t;
$: l;
$: scaleFactor;
$: factor;
$: canDragAndZoom;
let lastX = canvasWidth;
let lastY = canvasHeight;
$: lastX;
$: lastY;
onMount(() => {
f7ready(async () => {
canvas = document.getElementById("myCanvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
var gkhead1 = new Image();
var gkhead2 = new Image();
var gkhead3 = new Image();
var gkhead4 = new Image();
var gkhead5 = new Image();
gkhead1.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg1.jpeg";
gkhead2.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg2.jpeg";
gkhead3.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg3.jpeg";
gkhead4.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg4.jpeg";
gkhead5.src =
"http://localhost/asset_ims/assets/uploads/files/canvasImg5.jpeg";
ctx = canvas.getContext("2d");
ctx.lineWidth = 1;
trackTransforms(ctx);
function redraw() {
// Clear the entire canvas
var p1 = ctx.transformedPoint(0, 0);
var p2 = ctx.transformedPoint(canvas.width, canvas.height);
ctx.clearRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
ctx.drawImage(gkhead1, 50, 150, 100, 129);
ctx.drawImage(gkhead2, 135, 150, 100, 194);
ctx.drawImage(gkhead3, 240, 150, 100, 141);
ctx.drawImage(gkhead4, 345, 150, 100, 125);
ctx.drawImage(gkhead5, 50, 300, 100, 75);
}
redraw();
var dragStart, dragged;
canvas.addEventListener(
"mousedown",
function (evt) {
document.body.style.mozUserSelect =
document.body.style.WebkitUserSelect =
document.body.style.userSelect =
document.body.style.msUserSelect =
"auto";
// drag code
lastX = evt.offsetX || evt.pageX - canvas.offsetLeft;
lastY = evt.offsetY || evt.pageY - canvas.offsetTop;
dragStart = ctx.transformedPoint(lastX, lastY);
// drag code
dragged = false;
},
false
);
canvas.addEventListener(
"mousemove",
function (evt) {
lastX = evt.offsetX || evt.pageX - canvas.offsetLeft;
lastY = evt.offsetY || evt.pageY - canvas.offsetTop;
dragged = true;
dragStart = canDragAndZoom ? dragStart : null;
if (dragStart) {
var pt = ctx.transformedPoint(lastX, lastY);
ctx.translate(pt.x - dragStart.x, pt.y - dragStart.y);
redraw();
}
},
false
);
canvas.addEventListener(
"mouseup",
function (evt) {
dragStart = null;
if (!dragged) zoom(evt.shiftKey ? -1 : 1);
},
false
);
// var scaleFactor = 1.1;
var zoom = function (clicks) {
if (!canDragAndZoom) {
return false;
}
var pt = ctx.transformedPoint(lastX, lastY);
ctx.translate(pt.x, pt.y);
factor = Math.pow(scaleFactor, clicks);
ctx.scale(factor, factor);
ctx.translate(-pt.x, -pt.y);
redraw();
};
var handleScroll = function (evt) {
var delta = evt.wheelDelta
? evt.wheelDelta / 40
: evt.detail
? -evt.detail
: 0;
if (delta) zoom(delta);
return evt.preventDefault() && false;
};
canvas.addEventListener("DOMMouseScroll", handleScroll, false);
canvas.addEventListener("mousewheel", handleScroll, false);
// };
});
});
$: if (ctx) {
ctx.strokeStyle = "red";
}
const handleStart = ({ offsetX: x, offsetY: y }) => {
isDrawing = true;
start = { x, y };
};
const handleEnd = () => {
isDrawing = false;
};
const dragEnable = () => {
canDragAndZoom = canDragAndZoom ? false : true;
};
const handleMove = (event) => {
if (!isDrawing) return;
let canvas = document.getElementById("myCanvas");
let context = canvas.getContext("2d");
let rect = canvas.getBoundingClientRect();
let currentX = event.clientX - rect.left;
let currentY = event.clientY - rect.top;
const { x, y } = start;
context.beginPath();
context.moveTo(x, y);
context.lineTo(currentX, currentY);
context.stroke();
start = { x: currentX, y: currentY };
};
function trackTransforms(ctx) {
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var xform = svg.createSVGMatrix();
ctx.getTransform = function () {
return xform;
};
var savedTransforms = [];
var save = ctx.save;
ctx.save = function () {
savedTransforms.push(xform.translate(0, 0));
return save.call(ctx);
};
var restore = ctx.restore;
ctx.restore = function () {
xform = savedTransforms.pop();
return restore.call(ctx);
};
var scale = ctx.scale;
ctx.scale = function (sx, sy) {
xform = xform.scaleNonUniform(sx, sy);
return scale.call(ctx, sx, sy);
};
var rotate = ctx.rotate;
ctx.rotate = function (radians) {
xform = xform.rotate((radians * 180) / Math.PI);
return rotate.call(ctx, radians);
};
var translate = ctx.translate;
ctx.translate = function (dx, dy) {
xform = xform.translate(dx, dy);
return translate.call(ctx, dx, dy);
};
var transform = ctx.transform;
ctx.transform = function (a, b, c, d, e, f) {
var m2 = svg.createSVGMatrix();
m2.a = a;
m2.b = b;
m2.c = c;
m2.d = d;
m2.e = e;
m2.f = f;
xform = xform.multiply(m2);
return transform.call(ctx, a, b, c, d, e, f);
};
var setTransform = ctx.setTransform;
ctx.setTransform = function (a, b, c, d, e, f) {
xform.a = a;
xform.b = b;
xform.c = c;
xform.d = d;
xform.e = e;
xform.f = f;
return setTransform.call(ctx, a, b, c, d, e, f);
};
var pt = svg.createSVGPoint();
ctx.transformedPoint = function (x, y) {
pt.x = x;
pt.y = y;
return pt.matrixTransform(xform.inverse());
};
}
</script>
<canvas
id="myCanvas"
bind:this={canvas}
on:mousedown={handleStart}
on:mouseup={handleEnd}
on:mouseleave={handleEnd}
on:mousemove={handleMove}
/>
<a href="#" on:click={dragEnable}>
<i class="f7-icons presc_icon">pencil_outline</i>
</a>
After so many try and lots of effort i was able to solve the issue and now it is working as expected .
just had to add some line in handleMove function .
I am posting the solution as answer here so that any one next time can learn it and use the whole code with answer .
const handleMove = (event) => {
if (!isDrawing) return;
let currentX = event.offsetX;
let currentY = event.offsetY;
const { x, y } = start;
let startx = ctx.transformedPoint(x, y);
let endy = ctx.transformedPoint(currentX, currentY);
ctx.beginPath();
ctx.moveTo(startx.x, startx.y);
ctx.lineTo(endy.x, endy.y);
ctx.stroke();
start = { x: currentX, y: currentY };
};

Change size of drawing marker relative to the speed of the cursor - Javascript

I have made a marker that draws when the mouse click is held down. I now want to change the size of this marker relative to the speed of the cursor. My code is as follows:
class App {
constructor(event, x) {
this.container = this.createContainer();
this.canvas = this.createCanvas();
this.ctx = this.canvas.getContext("2d");
this.addEventListeners();
this.isDrawing = this.letDrawing();
}
createContainer = () => {
const container = document.createElement("div");
container.className = "app-container";
document.body.appendChild(container);
return container;
};
createCanvas = () => {
const canvas = document.createElement("canvas");
canvas.className = "app-canvas";
this.container.appendChild(canvas);
canvas.width = this.container.getBoundingClientRect().width;
canvas.height = this.container.getBoundingClientRect().height;
return canvas;
};
addEventListeners = () => {
this.canvas.addEventListener("mousemove", this.onMouseMove);
this.canvas.addEventListener("mousedown", this.onMouseDown);
document.addEventListener("mouseup", this.onMouseUp);
};
letDrawing = () => {
this.isDrawing = false;
};
onMouseDown = () => {
this.isDrawing = true;
};
onMouseMove = (event) => {
if (this.isDrawing === true) {
this.drawBall(event.x, event.y);
}
};
onMouseUp = () => {
this.isDrawing = false;
};
drawBall = (x, y) => {
this.ctx.beginPath();
this.ctx.arc(x, y, 0, Math.PI * 2);
this.ctx.fillStyle = "#6f0ecf";
this.ctx.fill();
this.ctx.closePath();
};
}
export { App };
I was thinking of using previous position of X and Y, and doing something like below... Can I use deltaX in this scenario?
Any help on how to do this would be much appreciated!!
onMouseMove = (event) => {
if (this.isDrawing === true) {
this.drawBall(event.x, event.y);
this.previousX = this.currentX;
this.currentX = event.x;
distance = this.currentX - this.previousX;
}
};
onMouseMoveSpeed = () => {
const size = speed * 10 + 10;
};
onMouseUp = () => {
this.isDrawing = false;
};
drawBall = (x, y, size) => {
this.ctx.beginPath();
this.ctx.arc(x, y, size, 0, Math.PI * 2);
this.ctx.fillStyle = "#6f0ecf";
this.ctx.fill();
this.ctx.closePath();
};
yes, you'll need to save the last position and the last time the event occured and them compute the speed as the distance from the last position divided by the time difference.
let last = {
x: 0,
y: 0,
time: 0
}
window.onmousemove = function(evt) {
let
x = evt.clientX,
y = evt.clientY,
time = new Date;
let dist = Math.sqrt((last.x - x) ** 2 + (last.y - y) ** 2)
let speed = dist / (time - last.time) * 1000
last = {x, y, time}
console.log('speed=', speed.toFixed(0))
}

Bullets follows mouse position

Im making simple arena shooter in JS and HTML.
right now I wanted to add shooting mechanic,I thought i would use code from my enemy class with bits of tweaking
here:
//differences between objects
let dirx = mouse.x - player.x,
diry = mouse.y - player.y;
//normalizing
let dist = Math.sqrt(dirx * dirx + diry * diry);
dirx = dirx / dist;
diry = diry / dist;
this.x += dirx * 5;
this.y += diry * 5;
Since my player is moving the player.x& player.y coords in dirX & dirY will change, meaning bullet wont go to original coords.
So I would be pleased for some help.
You could use vectors to determine the trajectory of the bullets.
In the example below, when I fire a bullet:
Initialize the position at the source of the bullet
The speed is determined by:
Subtracting the mouse position from the source
Normalizing the distance
Applying a speed constant
class Bullet {
constructor(source, target, created) {
this.position = source.clone();
this.speed = this.position.clone()
.subtract(Victor.fromObject(target))
.normalize()
.multiply(new Victor(-2, -2));
this.size = 3;
this.timeLeft = created + 500;
}
update() {
this.position = this.position.add(this.speed);
}
draw(ctx) {
ctx.fillStyle = 'yellow';
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.size / 2, 0, 2 * Math.PI);
ctx.fill();
}
}
Note: I also added a timeLeft variable to remove the bullet from the game after a set period of time e.g. 500ms.
Demo
Here is an example using the vector logic explained above.
Controls
W (Up) - Move up
A (Left) - Move left
S (Down) - Move down
D (Right) - Move right
Mouse 1 - Hold to fire
const VK_W = 87;
const VK_A = 65;
const VK_S = 83;
const VK_D = 68;
const VK_UP = 38;
const VK_DOWN = 40;
const VK_LEFT = 37;
const VK_RIGHT = 39;
const canvas = document.querySelector('.game'),
stateBtn = document.querySelector('.state-btn');
let game;
const main = () => {
stateBtn.addEventListener('click', changeState);
const ctx = canvas.getContext('2d');
game = new Game(ctx, { width: 400, height: 300 });
game.run();
};
const changeState = (e) => {
const btn = e.currentTarget, running = btn.dataset.running === 'true';
if (running) {
game.pause();
} else {
game.run();
}
btn.textContent = running ? 'Pause' : 'Resume';
btn.dataset.running = !running;
};
class Game {
constructor(ctx, options) {
const { width, height } = options;
this.lastRender = 0;
this.ctx = ctx;
this.state = { keySet: new Set() };
this.bullets = [];
Object.assign(ctx.canvas, { width, height });
const origin = new Victor(width / 2, height / 2);
this.player = new Player({
name: 'Bob',
position: origin
});
ctx.canvas.addEventListener('mousemove', (e) => this.followMouse(e));
ctx.canvas.addEventListener('mousedown', (e) => this.mouseDown(e));
ctx.canvas.addEventListener('mouseup', (e) => this.mouseUp(e));
document.addEventListener('keydown', (e) => this.addKey(e), false);
document.addEventListener('keyup', (e) => this.removeKey(e), false);
}
followMouse(e) {
this.state.mousePos = getMousePos(e.currentTarget, e);
}
mouseDown(e) {
this.state.mouseDown = true;
}
mouseUp(e) {
this.state.mouseDown = false;
}
addKey(e) {
const key = e.which || e.keyCode || 0;
this.state.keySet.add(key);
}
removeKey(e) {
const key = e.which || e.keyCode || 0;
this.state.keySet.delete(key);
}
update(progress) {
const ks = this.state.keySet;
const x = (ks.has(VK_D) || ks.has(VK_RIGHT))
? 1 : (ks.has(VK_A) || ks.has(VK_LEFT)) ? -1 : 0;
const y = (ks.has(VK_S) || ks.has(VK_DOWN))
? 1 : (ks.has(VK_W) || ks.has(VK_UP)) ? -1 : 0;
this.player.position.add(new Victor(x, y));
this.bullets.forEach((bullet, index) => {
if (this.lastRender > bullet.timeLeft) {
this.bullets.splice(index, 1);
}
bullet.update(this.lastRender);
});
if (this.state.mousePos && this.state.mouseDown) {
this.bullets.push(new Bullet(this.player.position,
this.state.mousePos, this.lastRender));
}
}
draw() {
this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
this.player.draw(this.ctx);
this.bullets.forEach(bullet => bullet.draw(this.ctx));
}
run(timestamp) {
const progress = timestamp - this.lastRender;
this.update(progress);
this.draw();
this.lastRender = timestamp;
this.req = window.requestAnimationFrame((t) => this.run(t));
}
pause() {
const { width, height } = this.ctx.canvas;
this.ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
this.ctx.fillRect(0, 0, width, height);
this.ctx.font = '32px Arial';
this.ctx.fillStyle = '#FFF';
this.ctx.textAlign = 'center';
this.ctx.textBaseline = 'middle';
this.ctx.fillText('Paused', width / 2, height / 2);
cancelAnimationFrame(this.req);
this.req = null;
}
isRunning() {
return this.req !== null;
}
}
class Player {
constructor(options) {
const opts = { ...Player.defaultOptions, ...options };
this.name = opts.name;
this.position = opts.position;
this.size = opts.size;
}
draw(ctx) {
ctx.fillStyle = '#00FF00';
ctx.fillRect(this.position.x - this.size / 2,
this.position.y - this.size / 2, this.size, this.size);
}
};
Player.defaultOptions = {
size: 10,
position: new Victor(0, 0)
};
class Bullet {
constructor(source, target, created) {
this.position = source.clone();
this.speed = this.position.clone()
.subtract(Victor.fromObject(target))
.normalize()
.multiply(new Victor(-2, -2));
this.size = 3;
this.timeLeft = created + 500;
}
update() {
this.position = this.position.add(this.speed);
}
draw(ctx) {
ctx.fillStyle = 'yellow';
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.size / 2, 0, 2 * Math.PI);
ctx.fill();
}
}
const getMousePos = (canvas, event) =>
(({ top, left }) => ({
x: event.clientX - left,
y: event.clientY - top
}))(canvas.getBoundingClientRect());
main();
.game {
background: #111;
}
.as-console-wrapper { max-height: 4em !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/victor/1.1.0/victor.min.js"></script>
<canvas class="game"></canvas>
<div class="controls">
<button class="state-btn" data-running="true">Pause</button>
</div>

How do I get this canvas animation script to work in Firefox?

I wrote this canvas animation script in hopes to use it on my portfolio website, but it is basically non-functional in Firefox, and I am not sure why. The script draws stars on the canvas that slowly rotate, and if you hold down the mouse button they spin faster creating trails. It works awesome in chrome, but is extremely slow and choppy in Firefox.
let canvas = document.querySelector('canvas');
let c = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let mouse = {
x: window.innerWidth / 2,
y: window.innerHeight / 2
}
let stars = [];
const starCount = 800;
class Star {
constructor(x, y, radius, color){
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.draw = () => {
c.save();
c.beginPath();
c.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
c.fillStyle = this.color;
c.shadowColor = this.color;
c.shadowBlur = 15;
c.fill();
c.closePath();
c.restore();
};
this.update = () => {
this.draw();
};
}
}
let colors = [
"#A751CC",
"#DE9AF9",
"#F9E0F9",
"#B5ECFB",
"#5F86F7"
];
(initializeStars = () =>{
for(let i = 0; i < starCount; i++){
let randomColorIndex = Math.floor(Math.random() * 5);
let randomRadius = Math.random() * 2;
let x = (Math.random() * (canvas.width + 400)) - (canvas.width + 400) / 2;
let y = (Math.random() * (canvas.width + 400)) - (canvas.width + 400) / 2;
stars.push(new Star(x, y, randomRadius, colors[randomColorIndex]));
}
})();
let opacity = 1;
let speed = 0.0005;
let time = 0;
let spinSpeed = desiredSpeed => {
speed += (desiredSpeed - speed) * 0.01;
time += speed;
return time;
}
let starOpacity = (desiredOpacity, ease) => {
opacity += (desiredOpacity - opacity) * ease;
return c.fillStyle = `rgba(18, 18, 18, ${opacity})`;
}
let animate = () => {
window.requestAnimationFrame(animate);
c.save();
if(mouseDown){
starOpacity(0.01, 0.03);
spinSpeed(0.012);
}else{
starOpacity(1, 0.01);
spinSpeed(0.001);
}
c.fillRect(0,0, canvas.width, canvas.height);
c.translate(canvas.width / 2, canvas.height / 2);
c.rotate(time);
for(let i = 0; i < stars.length; i++){
stars[i].update();
}
c.restore();
}
window.addEventListener('mousemove', e => {
mouse.x = e.clientX - canvas.width / 2;
mouse.y = e.clientY - canvas.height / 2;
});
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
stars = [];
initializeStars();
});
let mouseDown = false;
window.addEventListener("mousedown", () =>{
mouseDown = true;
});
window.addEventListener("mouseup", () => {
mouseDown = false;
});
animate();
Here is the link to the demo on Code Pen; any help is appreciated.
You can use rect instead of arc to draw your stars:
c.rect(this.x, this.y, 2*this.radius, 2*this.radius);
remove the blur It's extremely expensive:
//c.shadowBlur = 15;
You can use a radial gradient going from opaque in the center to transparent in his stead.

stop the Rain from falling

I am trying to toggle a particle emitter to on or off.
I have some Reactjs code that creates rain/snow particles with the canvas element.
Every notion i have came up with to properly kill the animation still results in memory leaks (in this case i think it is just projecting a new canvas over the old and still running the original animation in memory).
Here is the Codepen.
Here is the page code:
class CanvasComponent extends React.Component {
componentDidMount() {
this.BtnOnOff();
}
constructor() {
super();
this.toggleState = this.toggleState.bind(this);
this.state = {
isActive : false
}
}
toggleState() {
this.setState({isActive:!this.state.isActive});
this.BtnOnOff();
//console.log(this.state.isActive);
}
snowMaker() {
// Ref canvas & get context
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// Weather Types/////////////
var liteSnow = 13; //code 13 for snow light fluries.
var snow = 16; //code 13 for snow fluries.
var hevySnow = 41; //code 41 for Heavy snow.
var hevySnow2 = 43; //code 43 for Heavy snow.
var DRain = 9; //code 9 for drizzel
var HRain = 3; //code 3/4 for Thunderstorms/severe thunderstorms
var Code = 43; // Code will take in the current weather code.
// Resize canvas
let width = canvas.width = window.innerWidth;
let height = canvas.height = window.innerHeight;
// Variables
if (Code === 13) { /// Make it snow (light fluries)
var drops = [];
var dropColour = "rgba(255,255,255,1)";
var dropLengths = [3, 3, 3, 3, 3, 3, 3];
var dropSkews = [-2, -1, 0, 1, 2];
var maxDrops = 100;
var velocity = 8;
var flutter = 5;
}
else if (Code === 16){ /// Make it snow (fluries)
var drops = [];
var dropColour = "rgba(255,255,255,1)";
var dropLengths = [3, 3, 3, 3, 3, 3, 3];
var dropSkews = [-2, -1, 0, 1, 2];
var maxDrops = 500;
var velocity = 7;
var flutter = 5;
}
else if (Code === 41||Code === 43){ /// Make it Heavy snow
var drops = [];
var dropColour = "rgba(255,255,255,1)";
var dropLengths = [3, 2, 3, 2, 3, 2, 3];
var dropSkews = [-3, -1, 0, 1, 3];
var maxDrops = 800;
var velocity = .5;
var flutter = 8;
}
else if (Code === 9){ /// Make it rain
var drops = [];
var dropColour = "rgba(255,255,255,0.41)";
var dropLengths = [4, 5, 3, 6, 2, 3, 3];
var dropSkews = [0, 0.2, 0, 0, 0.1];
var maxDrops = 100;
var velocity =1;
var flutter = 1;
}
else if (Code === 3||Code === 4){ /// Make it ThunderStorms
var drops = [];
var dropColour = "rgba(255,255,255,0.5)";
var dropLengths = [10, 8, 8, 8, 7, 15, 9];
var dropSkews = [-0.2, -0.3, -0.2, -0.2, 0.1];
var maxDrops = 1000;
var velocity = .8;
var flutter = .1;
}
// Raindrop class
class Droplet {
constructor(x, y, length, skew) {
this.x = x;
this.y = y;
this.length = length;
this.skew = skew;
}
// Move method
move() {
// Increment x & y
this.y += this.length / velocity;
this.x += this.skew / flutter;
// Set limits
if (this.y > height) {
this.y = 0;
}
if (this.x > width || this.x < 0) {
this.y = 0;
this.x = Math.floor(Math.random() * width);
}
}
// Draw method
draw(ctx) {
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(this.x + this.skew, this.y + this.length);
ctx.strokeStyle = dropColour;
ctx.stroke();
}
}
// Create drops and push to array
for (let i = 0; i < maxDrops; i++) {
let instance = new Droplet(
Math.floor(Math.random() * width),
Math.floor(Math.random() * height),
randVal(dropLengths),
randVal(dropSkews)
);
drops.push(instance);
}
// Animation loop
function loop() {
// Clear Canvas
ctx.clearRect(0, 0, width, height);
// Draw / Move drops
for (let drop of drops) {
drop.move();
drop.draw(ctx);
}
// Animation Frame
requestAnimationFrame(loop)
}
// Begin animation
loop();
// Resize canvas - responsive
window.addEventListener('resize', resize);
function resize() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
}
// Function for random array values
function randVal(array) {
return array[Math.floor(Math.random() * array.length)];
}
}////////End of update canvas
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
snowKiller() {
// Ref canvas & get context
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
var Code = 13;
// Resize canvas
let width = canvas.width = window.innerWidth;
let height = canvas.height = window.innerHeight;
// Variables
if (Code === 13) { /// Make it snow (light fluries)
var drops = [];
var dropColour = "";
var dropLengths = [0];
var dropSkews = [0];
var maxDrops = 0;
var velocity = 0;
var flutter = 0;
}
// Raindrop class
class Droplet {
constructor(x, y, length, skew) {
this.x = x;
this.y = y;
this.length = length;
this.skew = skew;
}
// Move method
move() {
// Increment x & y
this.y += this.length / velocity;
this.x += this.skew / flutter;
// Set limits
if (this.y > height) {
this.y = 0;
}
if (this.x > width || this.x < 0) {
this.y = 0;
this.x = Math.floor(Math.random() * width);
}
}
// Draw method
draw(ctx) {
ctx.beginPath();
ctx.moveTo(this.x, this.y);
ctx.lineTo(this.x + this.skew, this.y + this.length);
ctx.strokeStyle = dropColour;
ctx.stroke();
}
}
// Create drops and push to array
for (let i = 0; i < maxDrops; i++) {
let instance = new Droplet(
Math.floor(Math.random() * width),
Math.floor(Math.random() * height),
randVal(dropLengths),
randVal(dropSkews)
);
drops.push(instance);
}
// Animation loop
function loop() {
// Clear Canvas
ctx.clearRect(0, 0, width, height);
// Draw / Move drops
for (let drop of drops) {
drop.move();
drop.draw(ctx);
}
// Animation Frame
requestAnimationFrame(loop)
}
// Begin animation
loop();
// Resize canvas - responsive
window.addEventListener('resize', resize);
function resize() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
}
// Function for random array values
function randVal(array) {
return array[Math.floor(Math.random() * array.length)];
}
}////////End of update canvas
BtnOnOff(){
const OnOff =$('#Button').attr('class');
if(OnOff=== "active"){
// alert('this is on!')
this.snowMaker();
}else {
this.snowKiller();
// alert('this is off!');
}
console.log(OnOff);
}
render() {
return (
<div>
<button id="Button" className={this.state.isActive ? 'inactive' : 'active'} onClick ={this.toggleState}>{this.state.isActive ? 'STOP' : 'START'}</button>
<canvas id="canvas"/>
</div>
);
}
}
ReactDOM.render(<CanvasComponent/>, document.getElementById('app'));
Idealy the solution would be something like clearing the requestAnimationFrame but i can't seem to figure it out.
Help would be very much apreciated.
Thanks
(Code tl;dr) you can always use the request-ID returned by requestAnimationFrame(), like this:
var reqID;
function loop() {
// rain
reqID = requestAnimationFrame(loop);
}
// start loop same way
reqID = requestAnimationFrame(loop);
Then when you want to stop it:
cancelAnimationFrame(reqID);
Calling it with an empty "reqID" is safe.

Categories