JavaScript實(shí)現(xiàn)環(huán)繞鼠標(biāo)旋轉(zhuǎn)效果
本文實(shí)例為大家分享了JavaScript實(shí)現(xiàn)環(huán)繞鼠標(biāo)旋轉(zhuǎn)效果的具體代碼,供大家參考,具體內(nèi)容如下
<!DOCTYPE html> <html lang="en"> ? <head> ? ? <meta charset="UTF-8"> ? ? <meta name="viewport" content="width=device-width, initial-scale=1.0"> ? ? <meta http-equiv="X-UA-Compatible" content="ie=edge"> ? ? <title>Canvas Resize</title> ? ? <style type="text/css"> ? ? ? ? /* 清除默認(rèn)邊距 */ ? ? ? ? *{ ? ? ? ? ? ? margin: 0; ? ? ? ? ? ? padding:0 ? ? ? ? } ? ? ? ? html,body{ ? ? ? ? ? ? /* 設(shè)置瀏覽器寬高為100% */ ? ? ? ? ? ? width: 100%; ? ? ? ? ? ? height: 100%; ? ? ? ? } ? ? </style> </head> ? <body> ? ? <!-- canvas可以書寫內(nèi)容 但是只會在瀏覽器不顯示canvas時(shí)才會顯示書寫的內(nèi)容 --> ? ? <canvas></canvas> ? ? <script src="js/javascript.js"></script> </body> ? </html>
js:
//以前封裝的函數(shù) 直接從工具庫中復(fù)制過來的 /** ?* 獲取隨機(jī)數(shù)的函數(shù) 獲取到的隨機(jī)數(shù)取整 ?*/ ?function getRandom(a, b){ ? ? return Math.floor(Math.random() * Math.abs(a - b)) + Math.min(a, b) } /** ?* 獲取16進(jìn)制的隨機(jī)顏色值 ?*/ function getColor(){ ? ? var color = '#' ? ? for(var i=0;i<3;i++){ ? ? ? ? var hex = getRandom(0, 256).toString(16) ? ? ? ? color += hex.length === 1 ? '0' + hex : hex; ? ? } ? ? return color } //獲取隨機(jī)數(shù) 但是不取整 function randomDoubleFromRange(a,b) { ? ? return Math.random() * (Math.abs(a - b)) + Math.min(a, b); } ? //設(shè)置鼠標(biāo)的位置 先設(shè)置為window的中心 var mouse = { ? ? x: window.innerWidth / 2, ? ? y: window.innerHeight / 2 } ? //創(chuàng)建鼠標(biāo)移動的事件監(jiān)聽事件 ?監(jiān)聽鼠標(biāo)所在window中的實(shí)時(shí)位置 window.addEventListener('mousemove', function (window) { ? ? //給數(shù)組中的x和y修改值 ? ? mouse.x = window.clientX; ? ? mouse.y = window.clientY; }); ? //當(dāng)窗口大小發(fā)生改變時(shí) 重新獲取畫布寬高并且重置代碼 resize事件在窗口大小變化時(shí)觸發(fā) window.addEventListener('resize', function () { ? ? //window的可用窗口大小 包含了滾動條的區(qū)域大小 ? ? canvas.width = window.innerWidth; ? ? canvas.height = window.innerHeight; ? ? init(); }); ? //獲取頁面上的canvas var canvas = document.querySelector('canvas'); ? //設(shè)置canvas的大小為window大小 如果不設(shè)置 就使用默認(rèn)寬高300*150 canvas.width = window.innerWidth; canvas.height = window.innerHeight; ? //設(shè)置canvas繪畫的環(huán)境 語法Canvas.getContext(contextID) 現(xiàn)在版本只能寫參數(shù)2d 以后可能會支持3d var ctx = canvas.getContext('2d'); ? //封裝一個(gè)制造環(huán)繞鼠標(biāo)的小球的函數(shù) 參數(shù)是小球圓心在x軸的位置 在y軸的位置 小球半徑 小球填充顏色 function Particle(x, y, radius, color) { ? ? //小球中心點(diǎn)的x軸位置 ? ? this.x = x; ? ? //小球中心點(diǎn)的y軸位置 ? ? this.y = y; ? ? //小球半徑 ? ? this.radius = radius; ? ? //小球顏色 ? ? this.color = color; ? ? //小球轉(zhuǎn)動的弧度值 不取整 如果取整 就少了很多數(shù)字 很多小球都會重疊 ? ? this.theta = randomDoubleFromRange(0, 2 * Math.PI); ? ? //小球繞中心點(diǎn)轉(zhuǎn)動的速度 ? ? this.speed = 0.05; ? ? //小球距離中心點(diǎn)的距離 ? ? this.distance = getRandom(70, 90); ? ? //小球跟隨鼠標(biāo)移動的速度 ? ? this.dragSpeed = 0.05; ? ? //記錄鼠標(biāo)移動前鼠標(biāo)的位置 ? ? this.lastMouse = { ? ? ? ? x: x, ? ? ? ? y: y ? ? }; ? ? //繪制函數(shù) ? ? this.draw = function (lastPosition) { ? ? ? ? //重置當(dāng)前路徑 因?yàn)閯?chuàng)建的每一個(gè)路徑都會以上一個(gè)beginPath之后的所有路徑作為基礎(chǔ)繪制 會把之前所有線條的顏色全部繪制成和最后一個(gè)線條相同的一個(gè)顏色 ? ? ? ? ctx.beginPath(); ? ? ? ? //將小球顏色作為填充顏色 ? ? ? ? ctx.strokeStyle = this.color; ? ? ? ? //將小球半徑作為路徑寬度 ? ? ? ? ctx.lineWidth = this.radius; ? ? ? ? //路徑起始位置 ? ? ? ? ctx.moveTo(lastPosition.x, lastPosition.y); ? ? ? ? //路徑結(jié)束位置 ? ? ? ? ctx.lineTo(this.x, this.y); ? ? ? ? //繪制確切路徑 ? ? ? ? ctx.stroke(); ? ? ? ? //關(guān)閉路徑 不是結(jié)束路徑 而是從結(jié)束點(diǎn)創(chuàng)建一條線連接到起始點(diǎn) 使路徑閉合 ? ? ? ? ctx.closePath(); ? ? } ? ? ? //更新數(shù)據(jù)的函數(shù) ? ? this.update = function () { ? ? ? ? //創(chuàng)建lastPosition對象接收上一次鼠標(biāo)的x和y的值 ? ? ? ? var lastPosition = { ? ? ? ? ? ? x: this.x, ? ? ? ? ? ? y: this.y ? ? ? ? } ? ? ? ? ? //每次調(diào)用函數(shù)移動鼠標(biāo)當(dāng)前位置和上一次位置之間的dragSpeed = 0.05的距離 產(chǎn)生拖拽感覺 ? ? ? ? this.lastMouse.x += (mouse.x - this.lastMouse.x) * this.dragSpeed; ? ? ? ? this.lastMouse.y += (mouse.y - this.lastMouse.y) * this.dragSpeed; ? ? ? ? ? //更新小球當(dāng)前位置 因?yàn)槊恳淮握{(diào)用小球的旋轉(zhuǎn)角度不同導(dǎo)致其位置不同 ? ? ? ? this.x = this.lastMouse.x + Math.cos(this.theta) * this.distance; ? ? ? ? this.y = this.lastMouse.y + Math.sin(this.theta) * this.distance; ? ? ? ? ? //更新小球的角度值 ? ? ? ? this.theta += this.speed; ? ? ? ? //將參數(shù)傳遞給繪制函數(shù)繪制路徑 ? ? ? ? this.draw(lastPosition); ? ? } } ? //定義particles變量 var particles; ? //初始化函數(shù) function init() { ? ? // 每次調(diào)用這個(gè)函數(shù)都要先把數(shù)組內(nèi)容清空 因?yàn)槭褂眠@個(gè)函數(shù)除了打開網(wǎng)頁后第一次代表調(diào)用之外 別的調(diào)用都表示窗口大小發(fā)生了改變 參數(shù)發(fā)生了變化 為了修改窗口大小之后又因?yàn)檎{(diào)用該函數(shù)導(dǎo)致小球重復(fù)創(chuàng)建 所以要調(diào)用后先清空再創(chuàng)建 ? ? particles = []; ? ? // 繪制50個(gè)小球 ? ? for (var i = 0; i < 50; i++) { ? ? ? ? //獲取隨機(jī)的顏色 ? ? ? ? let color = getColor() ? ? ? ? //將構(gòu)造函數(shù)創(chuàng)造的小球添加到數(shù)組中 ? ? ? ? particles.push(new Particle(canvas.width / 2, canvas.height / 2, 3, color)); ? ? } } ? function animate() { ? ? //定時(shí)的調(diào)用這個(gè)函數(shù) 類似于setInterval 但是setInterval時(shí)間間隔不是很準(zhǔn)確 requestAnimationFrame固定為以每秒60次的頻率調(diào)用一次括號內(nèi)的函數(shù) ? ? requestAnimationFrame(animate); ? ? ? // 每一幀都給之前的幀蒙上一層白色透明的矩形 用以清除上一幀繪制的路徑 ? ? //填充矩形顏色 矩形背景顏色 透明度設(shè)置為0.1 可以使之前幾幀的路徑因?yàn)槎啻胃采w慢慢邊淡 只是會在背景上留下很淡的痕跡 如果直接使用rgb白色覆蓋 雖然沒有痕跡殘留 但是之前路徑直接被白色覆蓋 沒有拖尾效果 ? ? // ctx.fillStyle = 'rgb(255, 255, 255)'; ? ? ctx.fillStyle = 'rgba(255, 255, 255, 0.1)'; ? ? //繪制矩形 給window繪制一個(gè)等高等寬的矩形 以此制造一個(gè)漸變的效果 ? ? ctx.fillRect(0, 0, canvas.width, canvas.height); ? ? ? //對鍵名遍歷數(shù)組 獲取canvas.width / 2, canvas.height / 2, 3, color參數(shù) 每遍歷一次就調(diào)用一次update函數(shù) 將獲取到的參數(shù)作為實(shí)參傳遞給update函數(shù) ? ? for (var p of particles) { ? ? ? ? p.update(); ? ? } } ? //初始化 創(chuàng)建小球 init(); //開始動畫 animate();
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript中的JSON轉(zhuǎn)為Python可讀取
本文主要介紹了JavaScript中的JSON轉(zhuǎn)為Python可讀取,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01echarts實(shí)現(xiàn)橫向和縱向滾動條(使用dataZoom)
這篇文章主要給大家介紹了關(guān)于echarts使用dataZoom實(shí)現(xiàn)橫向和縱向滾動條的相關(guān)資料,最近項(xiàng)目中使用到echarts圖表,當(dāng)數(shù)據(jù)過多時(shí)需要添加橫向滾動條,需要的朋友可以參考下2023-08-08javascript簡單鏈?zhǔn)秸{(diào)用案例分析
這篇文章主要介紹了javascript簡單鏈?zhǔn)秸{(diào)用,結(jié)合具體實(shí)例形式模擬jQuery分析了鏈?zhǔn)秸{(diào)用的原理與具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-05-05使用JavaScript實(shí)現(xiàn)一個(gè)拖拽縮放效果
這篇文章主要介紹了如何使用JS實(shí)現(xiàn)一個(gè)這樣的拖拽縮放效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05深入理解JavaScript 中的執(zhí)行上下文和執(zhí)行棧
這篇文章主要介紹了JavaScript 中的執(zhí)行上下文和執(zhí)行棧的相關(guān)知識,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-10-10webpack 3.X學(xué)習(xí)之多頁面打包的方法
這篇文章主要介紹了webpack 3.X學(xué)習(xí)之多頁面打包的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09