Я пытаюсь создать виртуальную гитару с помощью React. js и эту ручку: https://codepen.io/wentin/pen/VYegqq
Я изменил код, чтобы анимация запускалась onClick, не на MouseMove.
Сейчас мой объект Canvas выглядит так:
import React, { Component } from "react";
class Canvas extends React.Component {
componentDidUpdate() {}
componentDidMount() {
const canvas = this.refs.canvas;
//GSTRING main function =====================================================================
function GString(ref, startPoint, endPoint) {
//ctor
this.canvas = ref;
this.ctx = canvas.getContext("2d");
this.canvas.width = this.canvas.clientWidth;
this.canvas.height = this.canvas.clientHeight;
this.startPoint = startPoint;
this.endPoint = endPoint;
this.controlPoint = new Point(0, 0);
this.lastMouseX = this.controlPoint.x;
this.lastMouseY = this.controlPoint.y;
this.count = 0;
this.damping = 0.98;
this.finishWave = false;
//add event listener
var self = this;
this.canvas.addEventListener(
"click",
function (pos) {
console.dir(pos);
self.click(self, pos);
},
false
);
}
//drawArc function =======================================================================
GString.prototype.drawArc = function (
startPoint,
thirdPoint,
endPoint,
ctx
) {
var dy1 = thirdPoint.y - startPoint.y;
var dx1 = thirdPoint.x - startPoint.x;
var dy2 = endPoint.y - thirdPoint.y;
var dx2 = endPoint.x - thirdPoint.x;
var aSlope = dy1 / dx1;
var bSlope = dy2 / dx2;
var centerX =
(aSlope * bSlope * (startPoint.y - endPoint.y) +
bSlope * (startPoint.x + thirdPoint.x) -
aSlope * (thirdPoint.x + endPoint.x)) /
(2 * (bSlope - aSlope));
var centerY =
(-1 * (centerX - (startPoint.x + thirdPoint.x) / 2)) / aSlope +
(startPoint.y + thirdPoint.y) / 2;
var r = dist(centerX, centerY, startPoint.x, startPoint.y);
var angle = Math.atan2(centerX - startPoint.x, centerY - startPoint.y);
if (!angle || this.finishWave) {
ctx.beginPath();
ctx.moveTo(startPoint.x, startPoint.y); //change startPoint.x to this.controlPoint.x to start the line where it was pressed
ctx.lineTo(endPoint.x, endPoint.y);
//updown ANIMATION -----------------------------------------
} else if (!this.finishWave) {
if (angle > Math.PI / 2) {
ctx.beginPath();
ctx.arc(
centerX,
centerY,
r,
Math.PI * 1.5 - angle,
Math.PI * 1.5 + angle,
true
);
} else {
ctx.beginPath();
ctx.arc(
centerX,
centerY,
r,
Math.PI * 1.5 - angle,
Math.PI * 1.5 + angle,
false
);
}
}
//updown ANIMATION --end ---------------------------------
var gradient = ctx.createLinearGradient(100, 100, 500, 200);
gradient.addColorStop("0", "magenta");
gradient.addColorStop("0.5", "blue");
gradient.addColorStop("1.0", "#23CE6B");
ctx.strokeStyle = gradient;
ctx.stroke();
};
//drawArc function --end ==================================================================
//draw function ==========================================================================
GString.prototype.draw = function () {
// draw stuff
var r = circleCenter(
new Point(this.startPoint.x, this.startPoint.y),
new Point(this.controlPoint.x, this.controlPoint.y),
new Point(this.endPoint.x, this.endPoint.y)
).r;
if (
r > 2400 &&
this.controlPoint.x > this.startPoint.x &&
this.controlPoint.x < this.endPoint.x
) {
this.drawArc(
this.startPoint,
this.controlPoint,
this.endPoint,
this.ctx
);
this.lastMouseX = this.controlPoint.x;
this.lastMouseY = this.controlPoint.y;
this.count = 0;
this.finishWave = false;
this.controlPoint.x = -1;
} else {
var x = this.lastMouseX;
var y =
this.startPoint.y +
(this.lastMouseY - this.startPoint.y) *
Math.cos((this.count / 5) * Math.PI) *
Math.pow(this.damping, this.count);
if (Math.pow(this.damping, this.count) < 0.1) {
this.finishWave = true;
}
var wavePoint = new Point(x, y);
this.drawArc(this.startPoint, wavePoint, this.endPoint, this.ctx);
this.count++;
}
};
//draw function --end =====================================================================
GString.prototype.clear = function () {
// clear
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
};
GString.prototype.update = function () {
// update
};
//---------------------------------------------------------------------ACTION LISTENER
GString.prototype.click = function (self, pos) {
// self.controlPoint.x = pos.layerX;
// self.controlPoint.y = pos.layerY;
self.controlPoint.x = 1074; //CHANGED
self.controlPoint.y = 32; //CHANGED
};
//---------------------------------------------------------------------ACTION LISTENER
var dist = function (x, y, x0, y0) {
return Math.sqrt((x -= x0) * x + (y -= y0) * y);
};
var circleCenter = function (startPoint, thirdPoint, endPoint) {
var dy1 = thirdPoint.y - startPoint.y;
var dx1 = thirdPoint.x - startPoint.x;
var dy2 = endPoint.y - thirdPoint.y;
var dx2 = endPoint.x - thirdPoint.x;
var aSlope = dy1 / dx1;
var bSlope = dy2 / dx2;
var centerX =
(aSlope * bSlope * (startPoint.y - endPoint.y) +
bSlope * (startPoint.x + thirdPoint.x) -
aSlope * (thirdPoint.x + endPoint.x)) /
(2 * (bSlope - aSlope));
var centerY =
(-1 * (centerX - (startPoint.x + thirdPoint.x) / 2)) / aSlope +
(startPoint.y + thirdPoint.y) / 2;
var r = dist(centerX, centerY, startPoint.x, startPoint.y);
return {
x: centerX,
y: centerY,
r: r,
};
};
var Point = function (x, y) {
this.x = x;
this.y = y;
};
var myString = new GString(
this.refs.canvas,
new Point(0, 20),
new Point(2400, 20)
);
(function animate() {
// update
myString.update();
// clear
myString.clear();
// draw stuff
myString.draw();
// request new frame
requestAnimationFrame(function () {
animate();
});
})();
window.onload = () => {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
}
);
};
}
render() {
return (
<div>
<canvas ref="canvas" width={1100} height={32}></canvas>
</div>
);
}
}
export default Canvas;
Мой вопрос: как заменить функцию addEventListener чем-то, что будет реагировать на изменение свойств компонента Canvas?