基本介绍

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

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

其中函数中是x是指“弧度”而非角度。

弧度定义:两条射线从圆心向圆周射出,形成一个夹角和夹角正对的一段弧。当这段弧长正好等于圆的半径时,两条射线的夹角大小为1弧度(单位:rad)。

角度定义:两条射线从圆心向圆周射出,形成一个夹角和夹角正对的一段弧。当弧长正好等于圆周长的360分之一时,两条射线的夹角的大小为1度。(单位: º)

如图所示:

角度转弧度(弧度计算公式):2π / 360  = π / 180 ≈ 0.0174rad, 即: 度数 * (π / 180) = 弧度

弧度转角度(角度计算公式): 360 / 2π  = 180 / π ≈ 57.3º,  即:   弧度 * (180 / π) = 度数

// 将30º转为弧度rad
30º * (π / 180)= 0.523320 rad // 将0.523320rad转为度º
0.523320rad * (180 / π) = 29.9992352688º

可参考:

特殊值:

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

正弦函数和余弦函数的图像如图所示:

实例

实例1:如何得到圆上每个点的坐标?

解决思路:根据三角形的正玄、余弦来得值;

假设一个圆的圆心坐标是(a,b),半径为r,

则圆上每个点的X坐标=a + Math.sin(2*Math.PI / 360) * r ;Y坐标=b + Math.cos(2*Math.PI / 360) * r ;

实例2:如何求时钟的秒针转动一圈的轨迹?

假设秒针的初始值(起点)为12点钟方向,圆心的坐标为(a,b)。

解决思路:一分钟为60秒,一个圆为360°,所以平均每秒的转动角度为 360°/60 = 6°;

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) window.addEventListener('mousedown', this.handleMouseDown.bind(this))
window.addEventListener('pagehide', this.handlePageHide.bind(this))
} 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; window.addEventListener('mousedown', this.handleMouseDown.bind(this));
window.addEventListener('resize',this.changeWindow.bind(this));
} 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();

JS之Math.sin与Math.cos介绍及应用-实现鼠标点击后的烟花效果的更多相关文章

  1. JS Math.sin() 与 Math.cos() 用法

    Math.sin(x)      x 的正玄值.返回值在 -1.0 到 1.0 之间: Math.cos(x)    x 的余弦值.返回的是 -1.0 到 1.0 之间的数: 这两个函数中的X 都是指 ...

  2. JS Math.sin() 与 Math.cos() 用法 (含圆上每个点的坐标)

    Math.sin(x)      x 的正玄值.返回值在 -1.0 到 1.0 之间: Math.cos(x)    x 的余弦值.返回的是 -1.0 到 1.0 之间的数: 这两个函数中的X 都是指 ...

  3. javascript: Math.sin() cos() 用法

    Math.sin(x)      x 的正玄值.返回值在 -1.0 到 1.0 之间: Math.cos(x)    x 的余弦值.返回的是 -1.0 到 1.0 之间的数: 这两个函数中的X 都是指 ...

  4. 从零开始学习前端JAVASCRIPT — 4、JavaScript基础Math和Date对象的介绍

    Math对象的介绍 1:Math对象 Math 对象用于执行数学任务.并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math().您无需创建它,通过把 Math 作为对象使用就 ...

  5. js中Number对象与MATH方法整理总结

    W3C的文档: Number 对象属性 属性 描述 constructor 返回对创建此对象的 Number 函数的引用. MAX_VALUE 可表示的最大的数. MIN_VALUE 可表示的最小的数 ...

  6. js入门之内置对象Math

    一. 复习数据类型 简单数据类型, 基本数据类型/值类型 Number String Boolean Null Undefined 复杂数据类型 引用类型 Object 数组 数据在内存中是如何存储的 ...

  7. js中Math.round、parseInt、Math.floor和Math.ceil小数取整总结(转)

    js中Math.round.parseInt.Math.floor和Math.ceil小数取整总结 Math.round.parseInt.Math.floor和Math.ceil 都可以返回一个整数 ...

  8. js 数值精确运算使用math.js

    javaScript 浮点数运算的精度问题 问题:编程中你可能会遇到0.1*7=0.7000000000000001; 原因:几乎所有的编程语言都采用了 IEEE-745 浮点数表示法,任何使用二进制 ...

  9. js中Math.round、parseInt、Math.floor和Math.ceil小数取整总结

    Math.round.parseInt.Math.floor和Math.ceil 都可以返回一个整数,具体的区别请看下面的总结. 一.Math.round 作用:四舍五入,返回参数+0.5后,向下取整 ...

  10. js中Math.round、parseInt、Math.floor和Math.ceil小数取整小结

    以前经常在代码中看到Math.round.parseInt.Math.floor和Math.ceil这四个函数,虽然知道结果都可以返回一个整数,但是对他们四者的区别还是不太清楚,今天就做一个小结. 一 ...

随机推荐

  1. oeasy教您玩转vim - 76 - # 组合键映射map

    ​ 会话session 回忆组合键映射的细节 上次我们定义了一系列的复合键 主要是和ctrl键一起 快速跳转window窗口 map <c-j> <c-w>j map < ...

  2. TIER 2: Oopsie

    TIER 2: Oopsie Web 渗透 此次靶机结合前面知识,非常简单: nmap 扫描,发现 22 和 80 端口开放 服务 80 的 HTTP 服务 之后使用继续 Web 渗透: 使用 Wap ...

  3. 文件系统(十):一文看懂 UBI 文件系统

    liwen01 2024.07.21 前言 UBI (Unsorted Block Images)文件系统是一种用于裸 flash 的文件系统管理层.它是专为管理原始闪存设备而设计,特别适用于嵌入式系 ...

  4. WordPress基础之基本SEO设置

    基础内容,不会涉及过深,在谷歌SEO教程中会做详细的介绍,我这里只简单讲下. 1. SEO介绍 SEO,又名搜索引擎优化(Search Engine Optimization,缩写为SEO)是透过了解 ...

  5. Python 在PDF中添加、替换、或删除图片

    PDF文件中的图片可以丰富文档内容,提升用户的阅读体验.除了在PDF中添加图片外,有时也需要替换或删除其中的图片,以改进视觉效果或更新信息.本文将提供以下三个示例,介绍如何使用Python 操作PDF ...

  6. android 点击退出按钮 结束所有的activity 回到手机主页面

    android 点击退出按钮 结束所有的activity 回到手机主页面我 实现了回到主页面 但是在点击这个程序 他还是回到**退出的界面 ** 我要实现点击按钮回到手机主页面 在点击这个程序后就重新 ...

  7. 对比python学julia(第四章:人工智能)--(第二节)人脸识别

    2.1.  项目简介 人脸识别是基于人的脸部特征信息进行身份识别的一种图像识别技术.使用0PenCV 进行人脸识别的过程如下. (1)  针对每个识别对象收集大量的人脸图傣作为样本. (2)  将样本 ...

  8. 【AI模型】PPT生成

    一.天工AI https://www.tiangong.cn/ 先对话进行提纲生成,然后可以编辑提纲,再进行PPT生成 生成完毕后,可以直接点击导出下载 二.星火讯飞 讯飞智文 生成的PPT相比天工的 ...

  9. 【Vue】Re01 理论概念和入门上手

    一.Vue概述 什么是渐进式?1.把Vue作应用的一部分嵌套项目中2.如果完全抛弃其他组件和框架,Vue又具有丰富的生态和库莱支持3.Core + Router + VueX 满足项目绝大多数的需求- ...

  10. blender建模渲染Tips

    blender渲染 灯光的三种方式 1,常规灯光:shift+A选择灯光. 2,世界环境光:右侧地球图标调整. 3,物体自发光:把渲染物体变成一个发光体来进行调节灯光. 渲染视窗的调节 ctrl+b裁 ...