# JS之Math.sin与Math.cos介绍及应用-实现鼠标点击后的烟花效果

## 基本介绍

Math.sin(x) ：x 的正玄值。返回值在 -1.0 到 1.0 之间；

Math.cos(x) ：x 的余弦值。返回的是 -1.0 到 1.0 之间的数；

30º * (π / 180）= 0.523320 rad

0.523320rad * (180 / π) = 29.9992352688º

 度 0° 30° 45° 60° 90° 120° 135° 150° 180° 270° 360° 弧度 0 π/6 π/4 π/3 π/2 2π/3 3π/4 5π/6 π 3π/2 2π

## 实例

### 实例2：如何求时钟的秒针转动一圈的轨迹？

for(var times=0; times<60; times++) {
var hudu = (2*Math.PI / 360) * 6 * times;
var X = a + Math.sin(hudu) * r;
var Y = b - Math.cos(hudu) * r    //  注意此处是“-”号，因为我们要得到的Y是相对于（0,0）而言的。
}

1、本例是以“12点为起点, 角度增大时为顺时针方向“，求X坐标和Y坐标的方法是：
X坐标=a + Math.sin(角度 * (Math.PI / 180)) * r ；
Y坐标=b - Math.cos(角数 * (Math.PI / 180)) * r ；

2、一般“3点为起点, 角度增大时为逆时针方向“，求X坐标和Y坐标的方法是：
X坐标 = a + Math.cos(角度 * (Math.PI / 180)) * r;
Y坐标 = b - Math.sin(角度 * (Math.PI / 180)) * r;

### 实例3：使用Math.sin与Math.cos实现鼠标点击后的烟花效果

cursor-effects.js网上代码：

class Circle {
constructor({ origin, speed, color, angle, context }) {
this.origin = origin
this.position = { ...this.origin }
this.color = color
this.speed = speed
this.angle = angle
this.context = context
this.renderCount = 0
}

draw() {
this.context.fillStyle = this.color
this.context.beginPath()
this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2)
this.context.fill()
}

move() {
this.position.x = (Math.sin(this.angle) * this.speed) + this.position.x
this.position.y = (Math.cos(this.angle) * this.speed) + this.position.y + (this.renderCount * 0.3)
this.renderCount++
}
}

class Boom {
constructor ({ origin, context, circleCount = 10, area }) {
this.origin = origin
this.context = context
this.circleCount = circleCount
this.area = area
this.stop = false
this.circles = []
}

randomArray(range) {
const length = range.length
const randomIndex = Math.floor(length * Math.random())
return range[randomIndex]
}

randomColor() {
const range = ['8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
return '#' + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range)
}

randomRange(start, end) {
return (end - start) * Math.random() + start
}

init() {
for(let i = 0; i < this.circleCount; i++) {
const circle = new Circle({
context: this.context,
origin: this.origin,
color: this.randomColor(),
angle: this.randomRange(Math.PI - 1, Math.PI + 1),
speed: this.randomRange(1, 6)
})
this.circles.push(circle)
}
}

move() {
this.circles.forEach((circle, index) => {
if (circle.position.x > this.area.width || circle.position.y > this.area.height) {
return this.circles.splice(index, 1)
}
circle.move()
})
if (this.circles.length == 0) {
this.stop = true
}
}

draw() {
this.circles.forEach(circle => circle.draw())
}
}

class CursorSpecialEffects {
constructor() {
this.computerCanvas = document.createElement('canvas')
this.renderCanvas = document.createElement('canvas')

this.computerContext = this.computerCanvas.getContext('2d')
this.renderContext = this.renderCanvas.getContext('2d')

this.globalWidth = window.innerWidth
this.globalHeight = window.innerHeight

this.booms = []
this.running = false
}

handleMouseDown(e) {
const boom = new Boom({
origin: { x: e.clientX, y: e.clientY },
context: this.computerContext,
area: {
width: this.globalWidth,
height: this.globalHeight
}
})
boom.init()
this.booms.push(boom)
this.running || this.run()
}

handlePageHide() {
this.booms = []
this.running = false
}

init() {
const style = this.renderCanvas.style
style.position = 'fixed'
style.top = style.left = 0
style.zIndex = '999999999999999999999999999999999999999999'
style.pointerEvents = 'none'

style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth
style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight

document.body.append(this.renderCanvas)

}

run() {
this.running = true
if (this.booms.length == 0) {
return this.running = false
}
requestAnimationFrame(this.run.bind(this))
this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight)

this.booms.forEach((boom, index) => {
if (boom.stop) {
return this.booms.splice(index, 1)
}
boom.move()
boom.draw()
})
this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight)
}
}

const cursorSpecialEffects = new CursorSpecialEffects()
cursorSpecialEffects.init()

class Circle {
constructor({origin,context,color,angle,speed}) {
this.position = {...origin};
this.context = context;
this.color = color;
this.angle = angle;
this.speed = speed;
this.renderCount = 0;
}
draw() {
this.context.fillStyle = this.color;
this.context.beginPath();
this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2, false);
this.context.fill();
}
move() {
this.position.x += Math.sin(this.angle) * this.speed;
this.position.y += Math.cos(this.angle) * this.speed + this.renderCount * 0.3;
this.renderCount ++;
}
}

class Boom {
constructor({origin,context,area,circleNum = 10}) {
this.origin = origin;
this.context = context;
this.area = area;
this.circleNum = circleNum;
this.circles = [];
this.stop = false;
}

randomColor() {
const rang = '89ABCDEF';
const num = 6;
let resultStr = '';
for(let i = 0, num = 6; i < num; i++) {
resultStr += rang.charAt(Math.floor(rang.length * Math.random()));
}
return '#' + resultStr;
}

randomRange(start,end) {
return start + Math.random() * (end - start)
}

init() {
for(let i = 0; i < this.circleNum; i++) {
const circle = new Circle({
origin: this.origin,
context: this.context,
color: this.randomColor(),
angle: this.randomRange(Math.PI / 2, Math.PI * 3 / 2),
speed: this.randomRange(1,6)
})
this.circles.push(circle);
}
}

move() {
for(let i = 0; i < this.circles.length; i++) {
const curCircle = this.circles[i];
if(curCircle.x >= this.area.width || curCircle.y >= this.area.height) {
this.circles.splice(i,1);
i--;
continue;
}
curCircle.move();
}
if(this.circles.length === 0) {
this.stop = true;
}
}

draw() {
this.circles.forEach((circle) => circle.draw());
}
}

class MouseClickEffect {
constructor() {
this.drawCanvas = document.createElement('canvas');
this.drawContext = this.drawCanvas.getContext('2d');
const style = this.drawCanvas.style;
style.left = style.top = 0;
style.position = 'fixed';
style.zIndex = '999999999';
style.pointerEvents = 'none';
this.drawCanvas.width = this.globalWidth = window.innerWidth;
this.drawCanvas.height = this.globalHeight = window.innerHeight;
document.body.appendChild(this.drawCanvas);
this.booms = [];
this.running = false;

}

handleMouseDown(e) {
const boom = new Boom({
origin: {x: e.clientX, y: e.clientY},
area: {width: this.globalWidth, height: this.globalHeight},
context: this.drawContext
});
boom.init();
this.booms.push(boom);
this.running || this.run();
}

changeWindow() {
this.booms = [];
this.running = false;
this.drawCanvas.width = this.globalWidth = window.innerWidth;
this.drawCanvas.height = this.globalHeight = window.innerHeight;
this.drawContext.clearRect(0, 0, this.globalWidth, this.globalHeight);
}

run() {
this.running = true;
if(this.booms.length === 0) {
return this.running = false;
}
requestAnimationFrame(this.run.bind(this));
this.drawContext.clearRect(0, 0, this.globalWidth, this.globalHeight);
for(let i = 0; i < this.booms.length; i++) {
const boom = this.booms[i];
if(boom.stop) {
this.booms.splice(i, 1);
i--;
continue;
}
boom.move();
boom.draw();
}
}
}

new MouseClickEffect();

posted @ 2020-10-09 22:08  风雨后见彩虹  阅读(234)  评论(0编辑  收藏