├── .gitignore ├── screenshot.png ├── src ├── index.js ├── iife.js ├── utils.js └── CanvasNest.js ├── .babelrc ├── lib ├── index.js ├── iife.js ├── utils.js └── CanvasNest.js ├── index.d.ts ├── rollup.config.iife.js ├── rollup.config.umd.js ├── LICENSE ├── index.html ├── package.json ├── README-zh.md ├── README.md └── dist ├── canvas-nest.umd.js └── canvas-nest.js /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | .settings 3 | .idea 4 | node_modules/* 5 | *.lock 6 | *.log 7 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itning/canvas-nest.js/master/screenshot.png -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by hustcc on 18/6/23. 3 | * Contract: i@hust.cc 4 | */ 5 | 6 | import CanvasNest from './CanvasNest'; 7 | 8 | export default CanvasNest; 9 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "rollup": { 4 | "presets": [ 5 | [ 6 | "env", 7 | { 8 | "modules": false 9 | } 10 | ] 11 | ], 12 | "plugins": [ 13 | "transform-class-properties", 14 | "transform-object-rest-spread", 15 | "version" 16 | ] 17 | }, 18 | "babel": { 19 | "presets": ["env"], 20 | "plugins": [ 21 | "transform-class-properties", 22 | "add-module-exports", 23 | "transform-object-rest-spread", 24 | "version" 25 | ] 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _CanvasNest = require('./CanvasNest'); 8 | 9 | var _CanvasNest2 = _interopRequireDefault(_CanvasNest); 10 | 11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 12 | 13 | exports.default = _CanvasNest2.default; /** 14 | * Created by hustcc on 18/6/23. 15 | * Contract: i@hust.cc 16 | */ 17 | 18 | module.exports = exports['default']; -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'canvas-nest.js' { 2 | interface configType { 3 | /** 4 | * 线条颜色, 默认: '0,0,0' ;三个数字分别为(R,G,B),注意用,分割 5 | */ 6 | color?: string; 7 | 8 | /** 9 | * 线条的总数量, 默认: 150 10 | */ 11 | count?: number; 12 | 13 | /** 14 | * 背景的z-index属性,css属性用于控制所在层的位置, 默认: -1 15 | */ 16 | zIndex?: number; 17 | 18 | /** 19 | * 线条透明度(0~1), 默认: 0.5 20 | */ 21 | opacity?: number; 22 | } 23 | 24 | class CanvasNest { 25 | constructor(element: Element, config?: configType) 26 | destroy(): void; 27 | } 28 | 29 | export default CanvasNest; 30 | } -------------------------------------------------------------------------------- /src/iife.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by hustcc on 18/6/23. 3 | * Contract: i@hust.cc 4 | */ 5 | 6 | import CanvasNest from './CanvasNest'; 7 | 8 | const getScriptConfig = () => { 9 | const scripts = document.getElementsByTagName('script'); 10 | const len = scripts.length; 11 | const script = scripts[len - 1]; // 当前加载的script 12 | return { 13 | zIndex: script.getAttribute('zIndex'), 14 | opacity: script.getAttribute('opacity'), 15 | color: script.getAttribute('color'), 16 | pointColor: script.getAttribute('pointColor'), 17 | count: Number(script.getAttribute('count')) || 99, 18 | }; 19 | }; 20 | 21 | new CanvasNest(document.body, getScriptConfig()); 22 | -------------------------------------------------------------------------------- /rollup.config.iife.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by hustcc on 18/6/23. 3 | * Contract: i@hust.cc 4 | */ 5 | 6 | import uglify from 'rollup-plugin-uglify'; 7 | import babel from 'rollup-plugin-babel'; 8 | import resolve from 'rollup-plugin-node-resolve'; 9 | import commonjs from 'rollup-plugin-commonjs'; 10 | 11 | export default { 12 | input: 'src/iife.js', 13 | output: { 14 | file: 'dist/canvas-nest.js', 15 | format: 'iife', 16 | }, 17 | plugins: [ 18 | resolve(), 19 | babel({ 20 | exclude: 'node_modules/**', 21 | }), 22 | commonjs(), 23 | uglify({ 24 | output: { comments: false }, 25 | compress: { warnings: false } 26 | }), 27 | ], 28 | external: [], 29 | }; 30 | -------------------------------------------------------------------------------- /rollup.config.umd.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by hustcc on 18/6/23. 3 | * Contract: i@hust.cc 4 | */ 5 | 6 | import uglify from 'rollup-plugin-uglify'; 7 | import babel from 'rollup-plugin-babel'; 8 | import resolve from 'rollup-plugin-node-resolve'; 9 | import commonjs from 'rollup-plugin-commonjs'; 10 | 11 | export default { 12 | input: 'src/index.js', 13 | output: { 14 | file: 'dist/canvas-nest.umd.js', 15 | name: 'CanvasNest', 16 | format: 'umd', 17 | }, 18 | plugins: [ 19 | resolve(), 20 | babel({ 21 | exclude: 'node_modules/**', 22 | }), 23 | commonjs(), 24 | uglify({ 25 | output: { comments: false }, 26 | compress: { warnings: false } 27 | }), 28 | ], 29 | external: [], 30 | }; 31 | -------------------------------------------------------------------------------- /lib/iife.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _CanvasNest = require('./CanvasNest'); 4 | 5 | var _CanvasNest2 = _interopRequireDefault(_CanvasNest); 6 | 7 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 8 | 9 | var getScriptConfig = function getScriptConfig() { 10 | var scripts = document.getElementsByTagName('script'); 11 | var len = scripts.length; 12 | var script = scripts[len - 1]; // 当前加载的script 13 | return { 14 | zIndex: script.getAttribute('zIndex'), 15 | opacity: script.getAttribute('opacity'), 16 | color: script.getAttribute('color'), 17 | pointColor: script.getAttribute('pointColor'), 18 | count: Number(script.getAttribute('count')) || 99 19 | }; 20 | }; /** 21 | * Created by hustcc on 18/6/23. 22 | * Contract: i@hust.cc 23 | */ 24 | 25 | new _CanvasNest2.default(document.body, getScriptConfig()); -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by hustcc on 18/6/23. 3 | * Contract: i@hust.cc 4 | */ 5 | 6 | export const requestAnimationFrame = window.requestAnimationFrame || 7 | window.webkitRequestAnimationFrame || 8 | window.mozRequestAnimationFrame || 9 | window.msRequestAnimationFrame || 10 | window.oRequestAnimationFrame || 11 | function(func) { 12 | return window.setTimeout(func, 1000 / 60); 13 | }; 14 | 15 | export const cancelAnimationFrame = window.cancelAnimationFrame || 16 | window.webkitCancelAnimationFrame || 17 | window.mozCancelAnimationFrame || 18 | window.msCancelAnimationFrame || 19 | window.oCancelAnimationFrame || 20 | window.clearTimeout; 21 | 22 | export const range = n => 23 | new Array(n).fill(0).map((e, idx) => idx); 24 | 25 | export const canvasStyle = config => 26 | `display:block;position:absolute;top:0;left:0;height:100%;width:100%;overflow:hidden;pointer-events:none;z-index:${config.zIndex};opacity:${config.opacity}`; 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Hust.cc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | /** 7 | * Created by hustcc on 18/6/23. 8 | * Contract: i@hust.cc 9 | */ 10 | 11 | var requestAnimationFrame = exports.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || function (func) { 12 | return window.setTimeout(func, 1000 / 60); 13 | }; 14 | 15 | var cancelAnimationFrame = exports.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame || window.oCancelAnimationFrame || window.clearTimeout; 16 | 17 | var range = exports.range = function range(n) { 18 | return new Array(n).fill(0).map(function (e, idx) { 19 | return idx; 20 | }); 21 | }; 22 | 23 | var canvasStyle = exports.canvasStyle = function canvasStyle(config) { 24 | return "display:block;position:absolute;top:0;left:0;height:100%;width:100%;overflow:hidden;pointer-events:none;z-index:" + config.zIndex + ";opacity:" + config.opacity; 25 | }; -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | canvas-nest.js 7 | 33 | 34 | 35 |
36 | 37 |
38 | 39 | 40 | 41 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "canvas-nest.js", 3 | "officialName": "canvas-nest.js", 4 | "version": "2.0.4", 5 | "main": "lib/index.js", 6 | "summary": "A nest backgroud of website draw on canvas use javascript, do not depends on jQuery.", 7 | "description": "A nest backgroud of website draw on canvas use javascript, do not depends on jQuery.", 8 | "scripts": { 9 | "test": "npm run size", 10 | "size": "size-limit", 11 | "build:lib": "rimraf ./lib && cross-env NODE_ENV=babel babel src -d lib", 12 | "build:umd": "cross-env NODE_ENV=rollup rollup -c rollup.config.umd.js", 13 | "build:iife": "cross-env NODE_ENV=rollup rollup -c rollup.config.iife.js", 14 | "build": "npm run build:umd && npm run build:iife && npm run build:lib && npm run test" 15 | }, 16 | "dependencies": { 17 | "size-sensor": "^0.2.0" 18 | }, 19 | "size-limit": [ 20 | { 21 | "limit": "2.5 KB", 22 | "path": "dist/canvas-nest.umd.js" 23 | }, 24 | { 25 | "limit": "2.5 KB", 26 | "path": "dist/canvas-nest.js" 27 | } 28 | ], 29 | "author": { 30 | "name": "hustcc", 31 | "url": "https://github.com/hustcc" 32 | }, 33 | "homepage": "https://atool.vip", 34 | "license": "MIT", 35 | "keywords": [ 36 | "canvas", 37 | "html5", 38 | "nest" 39 | ], 40 | "repository": { 41 | "type": "git", 42 | "url": "https://github.com/hustcc/canvas-nest.js" 43 | }, 44 | "bugs": { 45 | "url": "https://github.com/hustcc/canvas-nest.js/issues" 46 | }, 47 | "devDependencies": { 48 | "babel-cli": "^6.26.0", 49 | "babel-plugin-add-module-exports": "^0.2.1", 50 | "babel-plugin-transform-class-properties": "^6.24.1", 51 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 52 | "babel-plugin-version": "^0.2.1", 53 | "babel-preset-env": "^1.6.1", 54 | "cross-env": "^5.1.3", 55 | "rimraf": "^2.6.2", 56 | "rollup": "^0.58.1", 57 | "rollup-plugin-babel": "^3.0.4", 58 | "rollup-plugin-commonjs": "^9.1.3", 59 | "rollup-plugin-node-resolve": "^3.3.0", 60 | "rollup-plugin-uglify": "^3.0.0", 61 | "size-limit": "^0.18.0" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /README-zh.md: -------------------------------------------------------------------------------- 1 | # canvas-nest.js 2 | 3 | > 一个基于 html5 canvas 绘制的网页背景效果。 4 | 5 | [![npm](https://img.shields.io/badge/demo-online-brightgreen.svg)](https://git.hust.cc/canvas-nest.js) 6 | [![npm](https://img.shields.io/npm/v/canvas-nest.js.svg)](https://www.npmjs.com/package/canvas-nest.js) 7 | [![npm](https://img.shields.io/npm/dm/canvas-nest.js.svg)](https://www.npmjs.com/package/canvas-nest.js) 8 | [![gzip](http://img.badgesize.io/https://unpkg.com/canvas-nest.js/dist/canvas-nest.js?compression=gzip)](https://unpkg.com/canvas-nest.js/dist/canvas-nest.js) 9 | 10 | ![screenshot](/screenshot.png) 11 | 12 | ## 安装 13 | ```sh 14 | # 使用 npm 15 | npm install --save canvas-nest.js 16 | 17 | # 或者使用 yarn 18 | yarn add canvas-nest.js 19 | ``` 20 | 21 | ## 特性 22 | 23 | - 不依赖 jQuery,使用原生的 javascript。 24 | - 非常小,只有 2 Kb。 25 | - 非常容易实现,配置简单,即使你不是 web 开发者,也能简单搞定。 26 | - 模块化 & 区域渲染。 27 | 28 | 29 | ## 使用 30 | 31 | - 快捷使用 32 | 33 | 将下面的代码插入到 ` 和 之间`. 34 | 35 | ```html 36 | 37 | ``` 38 | 39 | 强烈建议在 ``标签上方. 例如下面的代码结构: 40 | 41 | ```html 42 | 43 | 44 | ... 45 | 46 | 47 | ... 48 | ... 49 | 50 | 51 | 52 | ``` 53 | 54 | 然后就完成了,打开网页即可看到效果!`请注意不要将代码置于 里面`. 55 | 56 | 57 | - 模块化区域绘制(定制开发) 58 | 59 | 完成安装好,可以使用模块化方式 import。 60 | 61 | 并且只有一个 API,使用如下: 62 | 63 | ```js 64 | import CanvasNest from 'canvas-nest.js'; 65 | 66 | const config = { 67 | color: '255,0,0', 68 | count: 88, 69 | }; 70 | 71 | // 在 element 地方使用 config 渲染效果 72 | const cn = new CanvasNest(element, config); 73 | 74 | // destroy 75 | cn.destroy(); 76 | ``` 77 | 78 | 79 | ## 配置 80 | 81 | - **`color`**: 线条颜色, 默认: `'0,0,0'` ;三个数字分别为(R,G,B),注意用,分割 82 | - **`pointColor`**: 交点颜色, 默认: `'0,0,0'` ;三个数字分别为(R,G,B),注意用,分割 83 | - **`opacity`**: 线条透明度(0~1), 默认: `0.5` 84 | - **`count`**: 线条的总数量, 默认: `150` 85 | - **`zIndex`**: 背景的z-index属性,css属性用于控制所在层的位置, 默认: `-1` 86 | 87 | 88 | Example: 89 | 90 | - 快捷使用 91 | 92 | ```html 93 | 94 | ``` 95 | 96 | - 模块化区域绘制(定制开发) 97 | 98 | ```js 99 | { 100 | color: '0,0,255', 101 | opacity: 0.7, 102 | zIndex: -2, 103 | count: 99, 104 | }; 105 | ``` 106 | 107 | **注意: 所有的配置项都有默认值,如果你不知道怎么设置,可以先不设置这些配置项,就使用默认值看看效果也可以的。** 108 | 109 | 110 | ## 相关项目 111 | 112 | - [canvas-nest-for-wp](https://github.com/aTool-org/canvas-nest-for-wp): WP 插件,在插件市场搜索 `canvas-nest` 即可安装。 113 | - [vue-canvas-nest](https://github.com/ZYSzys/vue-canvas-nest): VUE 组件包装。 114 | - [react-canvas-nest](https://github.com/flyerH/react-canvas-nest): React 组件包装。 115 | - [canvas-nest-for-vscode](https://github.com/AShujiao/vscode-nest): vscode 扩展, 在vscode扩展市场中搜索`nest` 即可安装。 116 | 117 | ## 使用项目 118 | 119 | - [A Tool](https://atool.vip): 一个好用的工具集合. 120 | 121 | 122 | ## License 123 | 124 | MIT@[hustcc](https://github.com/hustcc). 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # canvas-nest.js 2 | 3 | > A nest background of website draw on canvas. [中文 Readme 帮助文档](README-zh.md). 4 | 5 | [![npm](https://img.shields.io/badge/demo-online-brightgreen.svg)](https://git.hust.cc/canvas-nest.js) 6 | [![npm](https://img.shields.io/npm/v/canvas-nest.js.svg)](https://www.npmjs.com/package/canvas-nest.js) 7 | [![npm](https://img.shields.io/npm/dm/canvas-nest.js.svg)](https://www.npmjs.com/package/canvas-nest.js) 8 | [![gzip](http://img.badgesize.io/https://unpkg.com/canvas-nest.js/dist/canvas-nest.js?compression=gzip)](https://unpkg.com/canvas-nest.js/dist/canvas-nest.js) 9 | 10 | ![screenshot](/screenshot.png) 11 | 12 | ## Feature 13 | 14 | - It does not depend on jQuery and original javascrpit is used. 15 | - Small size, only 2 Kb. 16 | - Easy to implement, simple configuration. 17 | - You do not have to be a web developer to use it. 18 | - Modularized with area rendering. 19 | 20 | 21 | ## Install 22 | ```sh 23 | # use npm 24 | npm install --save canvas-nest.js 25 | 26 | # or use yarn 27 | yarn add canvas-nest.js 28 | ``` 29 | 30 | 31 | ## Usage 32 | 33 | - Script tag 34 | 35 | Insert the code below `between and `. 36 | 37 | ```html 38 | 39 | ``` 40 | 41 | Strongly suggest to insert before the tag ``, as the following: 42 | 43 | ```html 44 | 45 | 46 | ... 47 | 48 | 49 | ... 50 | ... 51 | 52 | 53 | 54 | ``` 55 | 56 | Then ok! `Please do not add the code in the `. 57 | 58 | 59 | - Modular usage (Area render) 60 | 61 | After installation, you can import this as module. 62 | 63 | There is only one API, use it as below: 64 | 65 | ```js 66 | import CanvasNest from 'canvas-nest.js'; 67 | 68 | const config = { 69 | color: '255,0,0', 70 | count: 88, 71 | }; 72 | 73 | // Using config rendering effect at 'element'. 74 | const cn = new CanvasNest(element, config); 75 | 76 | // destroy 77 | cn.destroy(); 78 | ``` 79 | 80 | 81 | ## Configuration 82 | 83 | - **`color`**: color of lines, default: `'0,0,0'`; RGB values: (R,G,B).(note: use ',' to separate.) 84 | - **`pointColor`**: color of points, default: `'0,0,0'`; RGB values: (R,G,B).(note: use ',' to separate.) 85 | - **`opacity`**: the opacity of line (0~1), default: `0.5`. 86 | - **`count`**: the number of lines, default: `99`. 87 | - **`zIndex`**: z-index property of the background, default: `-1`. 88 | 89 | Example: 90 | 91 | - Script tag 92 | 93 | ```html 94 | 95 | ``` 96 | 97 | - Modular usage (Area render) 98 | 99 | ```js 100 | { 101 | color: '0,0,255', 102 | opacity: 0.7, 103 | zIndex: -2, 104 | count: 99, 105 | }; 106 | ``` 107 | 108 | **Note: If the Configuration isn't customized, default values are available as well.** 109 | 110 | 111 | ## Related projects 112 | 113 | - [canvas-nest-for-wp](https://github.com/aTool-org/canvas-nest-for-wp): a wordpress plugin, search `canvas-nest` in wordpress store. 114 | - [vue-canvas-nest](https://github.com/ZYSzys/vue-canvas-nest): vue component wrapper. 115 | - [react-canvas-nest](https://github.com/flyerH/react-canvas-nest): react component wrapper. 116 | - [canvas-nest-for-vscode](https://github.com/AShujiao/vscode-nest): a vscode extensions, search `nest` in vscode extensions. 117 | 118 | ## Used by 119 | 120 | - [A Tool](https://atool.vip): a convenient tool box. 121 | 122 | 123 | 124 | ## License 125 | 126 | MIT@[hustcc](https://github.com/hustcc). 127 | -------------------------------------------------------------------------------- /src/CanvasNest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by hustcc on 18/6/23. 3 | * Contract: i@hust.cc 4 | */ 5 | 6 | import { bind, clear } from 'size-sensor'; 7 | import { requestAnimationFrame, cancelAnimationFrame, range, canvasStyle } from './utils'; 8 | 9 | export default class CanvasNest { 10 | 11 | static version = __VERSION__; 12 | 13 | constructor(el, config) { 14 | this.el = el; 15 | 16 | this.c = { 17 | zIndex: -1, // z-index 18 | opacity: 0.5, // opacity 19 | color: '0,0,0', // color of lines 20 | pointColor: '0,0,0', // color of points 21 | count: 99, // count 22 | ...config, 23 | }; 24 | 25 | this.canvas = this.newCanvas(); 26 | this.context = this.canvas.getContext('2d'); 27 | 28 | this.points = this.randomPoints(); 29 | this.current = { 30 | x: null, // 当前鼠标x 31 | y: null, // 当前鼠标y 32 | max: 20000 // 圈半径的平方 33 | }; 34 | this.all = this.points.concat([this.current]); 35 | 36 | this.bindEvent(); 37 | 38 | this.requestFrame(this.drawCanvas); 39 | } 40 | 41 | bindEvent() { 42 | bind(this.el, () => { 43 | this.canvas.width = this.el.clientWidth; 44 | this.canvas.height = this.el.clientHeight; 45 | }); 46 | 47 | this.onmousemove = window.onmousemove; 48 | window.onmousemove = e => { 49 | this.current.x = e.clientX - this.el.offsetLeft + document.scrollingElement.scrollLeft; // 当存在横向滚动条时,x坐标再往右移动滚动条拉动的距离 50 | this.current.y = e.clientY - this.el.offsetTop + document.scrollingElement.scrollTop; // 当存在纵向滚动条时,y坐标再往下移动滚动条拉动的距离 51 | this.onmousemove && this.onmousemove(e); 52 | }; 53 | 54 | this.onmouseout = window.onmouseout; 55 | window.onmouseout = () => { 56 | this.current.x = null; 57 | this.current.y = null; 58 | this.onmouseout && this.onmouseout(); 59 | }; 60 | } 61 | 62 | randomPoints = () => { 63 | return range(this.c.count).map(() => ({ 64 | x: Math.random() * this.canvas.width, 65 | y: Math.random() * this.canvas.height, 66 | xa: 2 * Math.random() - 1, // 随机运动返现 67 | ya: 2 * Math.random() - 1, 68 | max: 6000 // 沾附距离 69 | })); 70 | }; 71 | 72 | newCanvas() { 73 | if (getComputedStyle(this.el).position === 'static') { 74 | this.el.style.position = 'relative' 75 | } 76 | const canvas = document.createElement('canvas'); // 画布 77 | canvas.style.cssText = canvasStyle(this.c); 78 | 79 | canvas.width = this.el.clientWidth; 80 | canvas.height = this.el.clientHeight; 81 | 82 | this.el.appendChild(canvas); 83 | return canvas; 84 | } 85 | 86 | requestFrame(func) { 87 | this.tid = requestAnimationFrame(() => func.call(this)); 88 | } 89 | 90 | drawCanvas() { 91 | const context = this.context; 92 | const width = this.canvas.width; 93 | const height = this.canvas.height; 94 | const current = this.current; 95 | const points = this.points; 96 | const all = this.all; 97 | 98 | context.clearRect(0, 0, width, height); 99 | // 随机的线条和当前位置联合数组 100 | let e, i, d, x_dist, y_dist, dist; // 临时节点 101 | // 遍历处理每一个点 102 | points.forEach((r, idx) => { 103 | r.x += r.xa; 104 | r.y += r.ya; // 移动 105 | r.xa *= r.x > width || r.x < 0 ? -1 : 1; 106 | r.ya *= r.y > height || r.y < 0 ? -1 : 1; // 碰到边界,反向反弹 107 | context.fillStyle = `rgba(${this.c.pointColor})`; 108 | context.fillRect(r.x - 0.5, r.y - 0.5, 1, 1); // 绘制一个宽高为1的点 109 | // 从下一个点开始 110 | for (i = idx + 1; i < all.length; i ++) { 111 | e = all[i]; 112 | // 当前点存在 113 | if (null !== e.x && null !== e.y) { 114 | x_dist = r.x - e.x; // x轴距离 l 115 | y_dist = r.y - e.y; // y轴距离 n 116 | dist = x_dist * x_dist + y_dist * y_dist; // 总距离, m 117 | 118 | dist < e.max && (e === current && dist >= e.max / 2 && (r.x -= 0.03 * x_dist, r.y -= 0.03 * y_dist), // 靠近的时候加速 119 | d = (e.max - dist) / e.max, 120 | context.beginPath(), 121 | context.lineWidth = d / 2, 122 | context.strokeStyle = `rgba(${this.c.color},${d + 0.2})`, 123 | context.moveTo(r.x, r.y), 124 | context.lineTo(e.x, e.y), 125 | context.stroke()); 126 | } 127 | } 128 | }); 129 | this.requestFrame(this.drawCanvas); 130 | } 131 | 132 | destroy() { 133 | // 清除事件 134 | clear(this.el); 135 | 136 | // mouse 事件清除 137 | window.onmousemove = this.onmousemove; // 回滚方法 138 | window.onmouseout = this.onmouseout; 139 | 140 | // 删除轮询 141 | cancelAnimationFrame(this.tid); 142 | 143 | // 删除 dom 144 | this.canvas.parentNode.removeChild(this.canvas); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /dist/canvas-nest.umd.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.CanvasNest=t()}(this,function(){"use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function t(e,t){return e(t={exports:{}},t.exports),t.exports}var n=t(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=1;t.default=function(){return""+n++},e.exports=t.default});e(n);var o=t(function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:30,n=null;return function(){for(var o=this,i=arguments.length,r=Array(i),a=0;an||r.x<0?-1:1,r.ya*=r.y>o||r.y<0?-1:1,t.fillStyle="rgba("+e.c.pointColor+")",t.fillRect(r.x-.5,r.y-.5,1,1),u=v+1;u=s.max/2&&(r.x-=.03*l,r.y-=.03*d),c=(s.max-f)/s.max,t.beginPath(),t.lineWidth=c/2,t.strokeStyle="rgba("+e.c.color+","+(c+.2)+")",t.moveTo(r.x,r.y),t.lineTo(s.x,s.y),t.stroke()))}),this.requestFrame(this.drawCanvas)}},{key:"destroy",value:function(){l(this.el),window.onmousemove=this.onmousemove,window.onmouseout=this.onmouseout,v(this.tid),this.canvas.parentNode.removeChild(this.canvas)}}]),e}();return y.version="2.0.4",y}); 2 | -------------------------------------------------------------------------------- /dist/canvas-nest.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function t(e,t){return e(t={exports:{}},t.exports),t.exports}var n=t(function(e,t){Object.defineProperty(t,"__esModule",{value:!0});var n=1;t.default=function(){return""+n++},e.exports=t.default});e(n);var o=t(function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:30,n=null;return function(){for(var o=this,i=arguments.length,r=Array(i),a=0;an||r.x<0?-1:1,r.ya*=r.y>o||r.y<0?-1:1,t.fillStyle="rgba("+e.c.pointColor+")",t.fillRect(r.x-.5,r.y-.5,1,1),u=f+1;u=s.max/2&&(r.x-=.03*l,r.y-=.03*d),c=(s.max-v)/s.max,t.beginPath(),t.lineWidth=c/2,t.strokeStyle="rgba("+e.c.color+","+(c+.2)+")",t.moveTo(r.x,r.y),t.lineTo(s.x,s.y),t.stroke()))}),this.requestFrame(this.drawCanvas)}},{key:"destroy",value:function(){l(this.el),window.onmousemove=this.onmousemove,window.onmouseout=this.onmouseout,f(this.tid),this.canvas.parentNode.removeChild(this.canvas)}}]),e}();y.version="2.0.4";var w,b;new y(document.body,(w=document.getElementsByTagName("script"),{zIndex:(b=w[w.length-1]).getAttribute("zIndex"),opacity:b.getAttribute("opacity"),color:b.getAttribute("color"),pointColor:b.getAttribute("pointColor"),count:Number(b.getAttribute("count"))||99}))}(); 2 | -------------------------------------------------------------------------------- /lib/CanvasNest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 8 | 9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** 10 | * Created by hustcc on 18/6/23. 11 | * Contract: i@hust.cc 12 | */ 13 | 14 | var _sizeSensor = require('size-sensor'); 15 | 16 | var _utils = require('./utils'); 17 | 18 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 19 | 20 | var CanvasNest = function () { 21 | function CanvasNest(el, config) { 22 | var _this = this; 23 | 24 | _classCallCheck(this, CanvasNest); 25 | 26 | this.randomPoints = function () { 27 | return (0, _utils.range)(_this.c.count).map(function () { 28 | return { 29 | x: Math.random() * _this.canvas.width, 30 | y: Math.random() * _this.canvas.height, 31 | xa: 2 * Math.random() - 1, // 随机运动返现 32 | ya: 2 * Math.random() - 1, 33 | max: 6000 // 沾附距离 34 | }; 35 | }); 36 | }; 37 | 38 | this.el = el; 39 | 40 | this.c = _extends({ 41 | zIndex: -1, // z-index 42 | opacity: 0.5, // opacity 43 | color: '0,0,0', // color of lines 44 | pointColor: '0,0,0', // color of points 45 | count: 99 }, config); 46 | 47 | this.canvas = this.newCanvas(); 48 | this.context = this.canvas.getContext('2d'); 49 | 50 | this.points = this.randomPoints(); 51 | this.current = { 52 | x: null, // 当前鼠标x 53 | y: null, // 当前鼠标y 54 | max: 20000 // 圈半径的平方 55 | }; 56 | this.all = this.points.concat([this.current]); 57 | 58 | this.bindEvent(); 59 | 60 | this.requestFrame(this.drawCanvas); 61 | } 62 | 63 | _createClass(CanvasNest, [{ 64 | key: 'bindEvent', 65 | value: function bindEvent() { 66 | var _this2 = this; 67 | 68 | (0, _sizeSensor.bind)(this.el, function () { 69 | _this2.canvas.width = _this2.el.clientWidth; 70 | _this2.canvas.height = _this2.el.clientHeight; 71 | }); 72 | 73 | this.onmousemove = window.onmousemove; 74 | window.onmousemove = function (e) { 75 | _this2.current.x = e.clientX - _this2.el.offsetLeft + document.scrollingElement.scrollLeft; // 当存在横向滚动条时,x坐标再往右移动滚动条拉动的距离 76 | _this2.current.y = e.clientY - _this2.el.offsetTop + document.scrollingElement.scrollTop; // 当存在纵向滚动条时,y坐标再往下移动滚动条拉动的距离 77 | _this2.onmousemove && _this2.onmousemove(e); 78 | }; 79 | 80 | this.onmouseout = window.onmouseout; 81 | window.onmouseout = function () { 82 | _this2.current.x = null; 83 | _this2.current.y = null; 84 | _this2.onmouseout && _this2.onmouseout(); 85 | }; 86 | } 87 | }, { 88 | key: 'newCanvas', 89 | value: function newCanvas() { 90 | if (getComputedStyle(this.el).position === 'static') { 91 | this.el.style.position = 'relative'; 92 | } 93 | var canvas = document.createElement('canvas'); // 画布 94 | canvas.style.cssText = (0, _utils.canvasStyle)(this.c); 95 | 96 | canvas.width = this.el.clientWidth; 97 | canvas.height = this.el.clientHeight; 98 | 99 | this.el.appendChild(canvas); 100 | return canvas; 101 | } 102 | }, { 103 | key: 'requestFrame', 104 | value: function requestFrame(func) { 105 | var _this3 = this; 106 | 107 | this.tid = (0, _utils.requestAnimationFrame)(function () { 108 | return func.call(_this3); 109 | }); 110 | } 111 | }, { 112 | key: 'drawCanvas', 113 | value: function drawCanvas() { 114 | var _this4 = this; 115 | 116 | var context = this.context; 117 | var width = this.canvas.width; 118 | var height = this.canvas.height; 119 | var current = this.current; 120 | var points = this.points; 121 | var all = this.all; 122 | 123 | context.clearRect(0, 0, width, height); 124 | // 随机的线条和当前位置联合数组 125 | var e = void 0, 126 | i = void 0, 127 | d = void 0, 128 | x_dist = void 0, 129 | y_dist = void 0, 130 | dist = void 0; // 临时节点 131 | // 遍历处理每一个点 132 | points.forEach(function (r, idx) { 133 | r.x += r.xa; 134 | r.y += r.ya; // 移动 135 | r.xa *= r.x > width || r.x < 0 ? -1 : 1; 136 | r.ya *= r.y > height || r.y < 0 ? -1 : 1; // 碰到边界,反向反弹 137 | context.fillStyle = 'rgba(' + _this4.c.pointColor + ')'; 138 | context.fillRect(r.x - 0.5, r.y - 0.5, 1, 1); // 绘制一个宽高为1的点 139 | // 从下一个点开始 140 | for (i = idx + 1; i < all.length; i++) { 141 | e = all[i]; 142 | // 当前点存在 143 | if (null !== e.x && null !== e.y) { 144 | x_dist = r.x - e.x; // x轴距离 l 145 | y_dist = r.y - e.y; // y轴距离 n 146 | dist = x_dist * x_dist + y_dist * y_dist; // 总距离, m 147 | 148 | dist < e.max && (e === current && dist >= e.max / 2 && (r.x -= 0.03 * x_dist, r.y -= 0.03 * y_dist), // 靠近的时候加速 149 | d = (e.max - dist) / e.max, context.beginPath(), context.lineWidth = d / 2, context.strokeStyle = 'rgba(' + _this4.c.color + ',' + (d + 0.2) + ')', context.moveTo(r.x, r.y), context.lineTo(e.x, e.y), context.stroke()); 150 | } 151 | } 152 | }); 153 | this.requestFrame(this.drawCanvas); 154 | } 155 | }, { 156 | key: 'destroy', 157 | value: function destroy() { 158 | // 清除事件 159 | (0, _sizeSensor.clear)(this.el); 160 | 161 | // mouse 事件清除 162 | window.onmousemove = this.onmousemove; // 回滚方法 163 | window.onmouseout = this.onmouseout; 164 | 165 | // 删除轮询 166 | (0, _utils.cancelAnimationFrame)(this.tid); 167 | 168 | // 删除 dom 169 | this.canvas.parentNode.removeChild(this.canvas); 170 | } 171 | }]); 172 | 173 | return CanvasNest; 174 | }(); 175 | 176 | CanvasNest.version = '2.0.4'; 177 | exports.default = CanvasNest; 178 | module.exports = exports['default']; --------------------------------------------------------------------------------