canvas 绘制的网页背景效果
This commit is contained in:
commit
552a4a05fe
28
.babelrc
Normal file
28
.babelrc
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"env": {
|
||||
"rollup": {
|
||||
"presets": [
|
||||
[
|
||||
"env",
|
||||
{
|
||||
"modules": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": [
|
||||
"transform-class-properties",
|
||||
"transform-object-rest-spread",
|
||||
"version"
|
||||
]
|
||||
},
|
||||
"babel": {
|
||||
"presets": ["env"],
|
||||
"plugins": [
|
||||
"transform-class-properties",
|
||||
"add-module-exports",
|
||||
"transform-object-rest-spread",
|
||||
"version"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
.project
|
||||
.settings
|
||||
.idea
|
||||
node_modules/*
|
||||
*.lock
|
||||
*.log
|
22
LICENSE
Normal file
22
LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Hust.cc
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
124
README-zh.md
Normal file
124
README-zh.md
Normal file
@ -0,0 +1,124 @@
|
||||
# canvas-nest.js
|
||||
|
||||
> 一个基于 html5 canvas 绘制的网页背景效果。
|
||||
|
||||
[![npm](https://img.shields.io/badge/demo-online-brightgreen.svg)](https://git.hust.cc/canvas-nest.js)
|
||||
[![npm](https://img.shields.io/npm/v/canvas-nest.js.svg)](https://www.npmjs.com/package/canvas-nest.js)
|
||||
[![npm](https://img.shields.io/npm/dm/canvas-nest.js.svg)](https://www.npmjs.com/package/canvas-nest.js)
|
||||
[![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)
|
||||
|
||||
![screenshot](/screenshot.png)
|
||||
|
||||
## 安装
|
||||
```sh
|
||||
# 使用 npm
|
||||
npm install --save canvas-nest.js
|
||||
|
||||
# 或者使用 yarn
|
||||
yarn add canvas-nest.js
|
||||
```
|
||||
|
||||
## 特性
|
||||
|
||||
- 不依赖 jQuery,使用原生的 javascript。
|
||||
- 非常小,只有 2 Kb。
|
||||
- 非常容易实现,配置简单,即使你不是 web 开发者,也能简单搞定。
|
||||
- 模块化 & 区域渲染。
|
||||
|
||||
|
||||
## 使用
|
||||
|
||||
- 快捷使用
|
||||
|
||||
将下面的代码插入到 `<body> 和 </body> 之间`.
|
||||
|
||||
```html
|
||||
<script type="text/javascript" src="dist/canvas-nest.js"></script>
|
||||
```
|
||||
|
||||
强烈建议在 `</body>`标签上方. 例如下面的代码结构:
|
||||
|
||||
```html
|
||||
<html>
|
||||
<head>
|
||||
...
|
||||
</head>
|
||||
<body>
|
||||
...
|
||||
...
|
||||
<script type="text/javascript" src="dist/canvas-nest.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
然后就完成了,打开网页即可看到效果!`请注意不要将代码置于 <head> </head>里面`.
|
||||
|
||||
|
||||
- 模块化区域绘制(定制开发)
|
||||
|
||||
完成安装好,可以使用模块化方式 import。
|
||||
|
||||
并且只有一个 API,使用如下:
|
||||
|
||||
```js
|
||||
import CanvasNest from 'canvas-nest.js';
|
||||
|
||||
const config = {
|
||||
color: '255,0,0',
|
||||
count: 88,
|
||||
};
|
||||
|
||||
// 在 element 地方使用 config 渲染效果
|
||||
const cn = new CanvasNest(element, config);
|
||||
|
||||
// destroy
|
||||
cn.destroy();
|
||||
```
|
||||
|
||||
|
||||
## 配置
|
||||
|
||||
- **`color`**: 线条颜色, 默认: `'0,0,0'` ;三个数字分别为(R,G,B),注意用,分割
|
||||
- **`pointColor`**: 交点颜色, 默认: `'0,0,0'` ;三个数字分别为(R,G,B),注意用,分割
|
||||
- **`opacity`**: 线条透明度(0~1), 默认: `0.5`
|
||||
- **`count`**: 线条的总数量, 默认: `150`
|
||||
- **`zIndex`**: 背景的z-index属性,css属性用于控制所在层的位置, 默认: `-1`
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
- 快捷使用
|
||||
|
||||
```html
|
||||
<script type="text/javascript" color="0,0,255" opacity='0.7' zIndex="-2" count="99" src="dist/canvas-nest.js"></script>
|
||||
```
|
||||
|
||||
- 模块化区域绘制(定制开发)
|
||||
|
||||
```js
|
||||
{
|
||||
color: '0,0,255',
|
||||
opacity: 0.7,
|
||||
zIndex: -2,
|
||||
count: 99,
|
||||
};
|
||||
```
|
||||
|
||||
**注意: 所有的配置项都有默认值,如果你不知道怎么设置,可以先不设置这些配置项,就使用默认值看看效果也可以的。**
|
||||
|
||||
|
||||
## 相关项目
|
||||
|
||||
- [canvas-nest-for-wp](https://github.com/aTool-org/canvas-nest-for-wp): WP 插件,在插件市场搜索 `canvas-nest` 即可安装。
|
||||
- [vue-canvas-nest](https://github.com/ZYSzys/vue-canvas-nest): VUE 组件包装。
|
||||
- [react-canvas-nest](https://github.com/flyerH/react-canvas-nest): React 组件包装。
|
||||
- [canvas-nest-for-vscode](https://github.com/AShujiao/vscode-nest): vscode 扩展, 在vscode扩展市场中搜索`nest` 即可安装。
|
||||
|
||||
## 使用项目
|
||||
|
||||
- [A Tool](https://atool.vip): 一个好用的工具集合.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT@[hustcc](https://github.com/hustcc).
|
126
README.md
Normal file
126
README.md
Normal file
@ -0,0 +1,126 @@
|
||||
# canvas-nest.js
|
||||
|
||||
> A nest background of website draw on canvas. [中文 Readme 帮助文档](README-zh.md).
|
||||
|
||||
[![npm](https://img.shields.io/badge/demo-online-brightgreen.svg)](https://git.hust.cc/canvas-nest.js)
|
||||
[![npm](https://img.shields.io/npm/v/canvas-nest.js.svg)](https://www.npmjs.com/package/canvas-nest.js)
|
||||
[![npm](https://img.shields.io/npm/dm/canvas-nest.js.svg)](https://www.npmjs.com/package/canvas-nest.js)
|
||||
[![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)
|
||||
|
||||
![screenshot](/screenshot.png)
|
||||
|
||||
## Feature
|
||||
|
||||
- It does not depend on jQuery and original javascrpit is used.
|
||||
- Small size, only 2 Kb.
|
||||
- Easy to implement, simple configuration.
|
||||
- You do not have to be a web developer to use it.
|
||||
- Modularized with area rendering.
|
||||
|
||||
|
||||
## Install
|
||||
```sh
|
||||
# use npm
|
||||
npm install --save canvas-nest.js
|
||||
|
||||
# or use yarn
|
||||
yarn add canvas-nest.js
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
- Script tag
|
||||
|
||||
Insert the code below `between <body> and </body>`.
|
||||
|
||||
```html
|
||||
<script src="dist/canvas-nest.js"></script>
|
||||
```
|
||||
|
||||
Strongly suggest to insert before the tag `</body>`, as the following:
|
||||
|
||||
```html
|
||||
<html>
|
||||
<head>
|
||||
...
|
||||
</head>
|
||||
<body>
|
||||
...
|
||||
...
|
||||
<script src="dist/canvas-nest.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Then ok! `Please do not add the code in the <head> </head>`.
|
||||
|
||||
|
||||
- Modular usage (Area render)
|
||||
|
||||
After installation, you can import this as module.
|
||||
|
||||
There is only one API, use it as below:
|
||||
|
||||
```js
|
||||
import CanvasNest from 'canvas-nest.js';
|
||||
|
||||
const config = {
|
||||
color: '255,0,0',
|
||||
count: 88,
|
||||
};
|
||||
|
||||
// Using config rendering effect at 'element'.
|
||||
const cn = new CanvasNest(element, config);
|
||||
|
||||
// destroy
|
||||
cn.destroy();
|
||||
```
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
- **`color`**: color of lines, default: `'0,0,0'`; RGB values: (R,G,B).(note: use ',' to separate.)
|
||||
- **`pointColor`**: color of points, default: `'0,0,0'`; RGB values: (R,G,B).(note: use ',' to separate.)
|
||||
- **`opacity`**: the opacity of line (0~1), default: `0.5`.
|
||||
- **`count`**: the number of lines, default: `99`.
|
||||
- **`zIndex`**: z-index property of the background, default: `-1`.
|
||||
|
||||
Example:
|
||||
|
||||
- Script tag
|
||||
|
||||
```html
|
||||
<script type="text/javascript" color="0,0,255" opacity='0.7' zIndex="-2" count="99" src="dist/canvas-nest.js"></script>
|
||||
```
|
||||
|
||||
- Modular usage (Area render)
|
||||
|
||||
```js
|
||||
{
|
||||
color: '0,0,255',
|
||||
opacity: 0.7,
|
||||
zIndex: -2,
|
||||
count: 99,
|
||||
};
|
||||
```
|
||||
|
||||
**Note: If the Configuration isn't customized, default values are available as well.**
|
||||
|
||||
|
||||
## Related projects
|
||||
|
||||
- [canvas-nest-for-wp](https://github.com/aTool-org/canvas-nest-for-wp): a wordpress plugin, search `canvas-nest` in wordpress store.
|
||||
- [vue-canvas-nest](https://github.com/ZYSzys/vue-canvas-nest): vue component wrapper.
|
||||
- [react-canvas-nest](https://github.com/flyerH/react-canvas-nest): react component wrapper.
|
||||
- [canvas-nest-for-vscode](https://github.com/AShujiao/vscode-nest): a vscode extensions, search `nest` in vscode extensions.
|
||||
|
||||
## Used by
|
||||
|
||||
- [A Tool](https://atool.vip): a convenient tool box.
|
||||
|
||||
|
||||
|
||||
## License
|
||||
|
||||
MIT@[hustcc](https://github.com/hustcc).
|
1
dist/canvas-nest.js
vendored
Normal file
1
dist/canvas-nest.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/canvas-nest.umd.js
vendored
Normal file
1
dist/canvas-nest.umd.js
vendored
Normal file
File diff suppressed because one or more lines are too long
30
index.d.ts
vendored
Normal file
30
index.d.ts
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
declare module 'canvas-nest.js' {
|
||||
interface configType {
|
||||
/**
|
||||
* 线条颜色, 默认: '0,0,0' ;三个数字分别为(R,G,B),注意用,分割
|
||||
*/
|
||||
color?: string;
|
||||
|
||||
/**
|
||||
* 线条的总数量, 默认: 150
|
||||
*/
|
||||
count?: number;
|
||||
|
||||
/**
|
||||
* 背景的z-index属性,css属性用于控制所在层的位置, 默认: -1
|
||||
*/
|
||||
zIndex?: number;
|
||||
|
||||
/**
|
||||
* 线条透明度(0~1), 默认: 0.5
|
||||
*/
|
||||
opacity?: number;
|
||||
}
|
||||
|
||||
class CanvasNest {
|
||||
constructor(element: Element, config?: configType)
|
||||
destroy(): void;
|
||||
}
|
||||
|
||||
export default CanvasNest;
|
||||
}
|
69
index.html
Normal file
69
index.html
Normal file
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>canvas-nest.js</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#github-iframe {
|
||||
position: fixed;
|
||||
left: 32px;
|
||||
top: 32px;
|
||||
}
|
||||
|
||||
#area-render {
|
||||
position: fixed;
|
||||
width: 320px;
|
||||
height: 160px;
|
||||
right: 4px;
|
||||
bottom: 4px;
|
||||
border: dashed 1px #ccc;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="github-iframe"></div>
|
||||
|
||||
<div id="area-render"></div>
|
||||
|
||||
<script type="text/javascript" color="255,0,0" pointColor="255,0,0" opacity='0.7' zIndex="-2" count="100" src="dist/canvas-nest.js"></script>
|
||||
<script type="text/javascript" src="dist/canvas-nest.umd.js"></script>
|
||||
<script type="text/javascript">
|
||||
var cn = new CanvasNest(document.getElementById('area-render'), {
|
||||
color: '255,0,255',
|
||||
count: 50,
|
||||
});
|
||||
|
||||
// 下面为其他 js,无需关注
|
||||
function asyncLoad() {
|
||||
//async load github
|
||||
var i = document.createElement("iframe");
|
||||
i.src = "https://ghbtns.com/github-btn.html?user=hustcc&repo=canvas-nest.js&type=star&count=true";
|
||||
i.scrolling = "no";
|
||||
i.frameborder = "0";
|
||||
i.border = "0";
|
||||
i.setAttribute("frameborder", "0", 0);
|
||||
i.width = "100px";
|
||||
i.height = "20px";
|
||||
document.getElementById("github-iframe").appendChild(i);
|
||||
}
|
||||
function loadGitHubBtn() {
|
||||
if (window.addEventListener) {window.addEventListener("load", asyncLoad, false);}
|
||||
else if (window.attachEvent) {window.attachEvent("onload", asyncLoad);}
|
||||
else {window.onload = asyncLoad;}
|
||||
}
|
||||
|
||||
loadGitHubBtn();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
178
lib/CanvasNest.js
Normal file
178
lib/CanvasNest.js
Normal file
@ -0,0 +1,178 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
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; };
|
||||
|
||||
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; }; }(); /**
|
||||
* Created by hustcc on 18/6/23.
|
||||
* Contract: i@hust.cc
|
||||
*/
|
||||
|
||||
var _sizeSensor = require('size-sensor');
|
||||
|
||||
var _utils = require('./utils');
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var CanvasNest = function () {
|
||||
function CanvasNest(el, config) {
|
||||
var _this = this;
|
||||
|
||||
_classCallCheck(this, CanvasNest);
|
||||
|
||||
this.randomPoints = function () {
|
||||
return (0, _utils.range)(_this.c.count).map(function () {
|
||||
return {
|
||||
x: Math.random() * _this.canvas.width,
|
||||
y: Math.random() * _this.canvas.height,
|
||||
xa: 2 * Math.random() - 1, // 随机运动返现
|
||||
ya: 2 * Math.random() - 1,
|
||||
max: 6000 // 沾附距离
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
this.el = el;
|
||||
|
||||
this.c = _extends({
|
||||
zIndex: -1, // z-index
|
||||
opacity: 0.5, // opacity
|
||||
color: '0,0,0', // color of lines
|
||||
pointColor: '0,0,0', // color of points
|
||||
count: 99 }, config);
|
||||
|
||||
this.canvas = this.newCanvas();
|
||||
this.context = this.canvas.getContext('2d');
|
||||
|
||||
this.points = this.randomPoints();
|
||||
this.current = {
|
||||
x: null, // 当前鼠标x
|
||||
y: null, // 当前鼠标y
|
||||
max: 20000 // 圈半径的平方
|
||||
};
|
||||
this.all = this.points.concat([this.current]);
|
||||
|
||||
this.bindEvent();
|
||||
|
||||
this.requestFrame(this.drawCanvas);
|
||||
}
|
||||
|
||||
_createClass(CanvasNest, [{
|
||||
key: 'bindEvent',
|
||||
value: function bindEvent() {
|
||||
var _this2 = this;
|
||||
|
||||
(0, _sizeSensor.bind)(this.el, function () {
|
||||
_this2.canvas.width = _this2.el.clientWidth;
|
||||
_this2.canvas.height = _this2.el.clientHeight;
|
||||
});
|
||||
|
||||
this.onmousemove = window.onmousemove;
|
||||
window.onmousemove = function (e) {
|
||||
_this2.current.x = e.clientX - _this2.el.offsetLeft + document.scrollingElement.scrollLeft; // 当存在横向滚动条时,x坐标再往右移动滚动条拉动的距离
|
||||
_this2.current.y = e.clientY - _this2.el.offsetTop + document.scrollingElement.scrollTop; // 当存在纵向滚动条时,y坐标再往下移动滚动条拉动的距离
|
||||
_this2.onmousemove && _this2.onmousemove(e);
|
||||
};
|
||||
|
||||
this.onmouseout = window.onmouseout;
|
||||
window.onmouseout = function () {
|
||||
_this2.current.x = null;
|
||||
_this2.current.y = null;
|
||||
_this2.onmouseout && _this2.onmouseout();
|
||||
};
|
||||
}
|
||||
}, {
|
||||
key: 'newCanvas',
|
||||
value: function newCanvas() {
|
||||
if (getComputedStyle(this.el).position === 'static') {
|
||||
this.el.style.position = 'relative';
|
||||
}
|
||||
var canvas = document.createElement('canvas'); // 画布
|
||||
canvas.style.cssText = (0, _utils.canvasStyle)(this.c);
|
||||
|
||||
canvas.width = this.el.clientWidth;
|
||||
canvas.height = this.el.clientHeight;
|
||||
|
||||
this.el.appendChild(canvas);
|
||||
return canvas;
|
||||
}
|
||||
}, {
|
||||
key: 'requestFrame',
|
||||
value: function requestFrame(func) {
|
||||
var _this3 = this;
|
||||
|
||||
this.tid = (0, _utils.requestAnimationFrame)(function () {
|
||||
return func.call(_this3);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'drawCanvas',
|
||||
value: function drawCanvas() {
|
||||
var _this4 = this;
|
||||
|
||||
var context = this.context;
|
||||
var width = this.canvas.width;
|
||||
var height = this.canvas.height;
|
||||
var current = this.current;
|
||||
var points = this.points;
|
||||
var all = this.all;
|
||||
|
||||
context.clearRect(0, 0, width, height);
|
||||
// 随机的线条和当前位置联合数组
|
||||
var e = void 0,
|
||||
i = void 0,
|
||||
d = void 0,
|
||||
x_dist = void 0,
|
||||
y_dist = void 0,
|
||||
dist = void 0; // 临时节点
|
||||
// 遍历处理每一个点
|
||||
points.forEach(function (r, idx) {
|
||||
r.x += r.xa;
|
||||
r.y += r.ya; // 移动
|
||||
r.xa *= r.x > width || r.x < 0 ? -1 : 1;
|
||||
r.ya *= r.y > height || r.y < 0 ? -1 : 1; // 碰到边界,反向反弹
|
||||
context.fillStyle = 'rgba(' + _this4.c.pointColor + ')';
|
||||
context.fillRect(r.x - 0.5, r.y - 0.5, 1, 1); // 绘制一个宽高为1的点
|
||||
// 从下一个点开始
|
||||
for (i = idx + 1; i < all.length; i++) {
|
||||
e = all[i];
|
||||
// 当前点存在
|
||||
if (null !== e.x && null !== e.y) {
|
||||
x_dist = r.x - e.x; // x轴距离 l
|
||||
y_dist = r.y - e.y; // y轴距离 n
|
||||
dist = x_dist * x_dist + y_dist * y_dist; // 总距离, m
|
||||
|
||||
dist < e.max && (e === current && dist >= e.max / 2 && (r.x -= 0.03 * x_dist, r.y -= 0.03 * y_dist), // 靠近的时候加速
|
||||
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());
|
||||
}
|
||||
}
|
||||
});
|
||||
this.requestFrame(this.drawCanvas);
|
||||
}
|
||||
}, {
|
||||
key: 'destroy',
|
||||
value: function destroy() {
|
||||
// 清除事件
|
||||
(0, _sizeSensor.clear)(this.el);
|
||||
|
||||
// mouse 事件清除
|
||||
window.onmousemove = this.onmousemove; // 回滚方法
|
||||
window.onmouseout = this.onmouseout;
|
||||
|
||||
// 删除轮询
|
||||
(0, _utils.cancelAnimationFrame)(this.tid);
|
||||
|
||||
// 删除 dom
|
||||
this.canvas.parentNode.removeChild(this.canvas);
|
||||
}
|
||||
}]);
|
||||
|
||||
return CanvasNest;
|
||||
}();
|
||||
|
||||
CanvasNest.version = '2.0.4';
|
||||
exports.default = CanvasNest;
|
||||
module.exports = exports['default'];
|
25
lib/iife.js
Normal file
25
lib/iife.js
Normal file
@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
var _CanvasNest = require('./CanvasNest');
|
||||
|
||||
var _CanvasNest2 = _interopRequireDefault(_CanvasNest);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var getScriptConfig = function getScriptConfig() {
|
||||
var scripts = document.getElementsByTagName('script');
|
||||
var len = scripts.length;
|
||||
var script = scripts[len - 1]; // 当前加载的script
|
||||
return {
|
||||
zIndex: script.getAttribute('zIndex'),
|
||||
opacity: script.getAttribute('opacity'),
|
||||
color: script.getAttribute('color'),
|
||||
pointColor: script.getAttribute('pointColor'),
|
||||
count: Number(script.getAttribute('count')) || 99
|
||||
};
|
||||
}; /**
|
||||
* Created by hustcc on 18/6/23.
|
||||
* Contract: i@hust.cc
|
||||
*/
|
||||
|
||||
new _CanvasNest2.default(document.body, getScriptConfig());
|
18
lib/index.js
Normal file
18
lib/index.js
Normal file
@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _CanvasNest = require('./CanvasNest');
|
||||
|
||||
var _CanvasNest2 = _interopRequireDefault(_CanvasNest);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
exports.default = _CanvasNest2.default; /**
|
||||
* Created by hustcc on 18/6/23.
|
||||
* Contract: i@hust.cc
|
||||
*/
|
||||
|
||||
module.exports = exports['default'];
|
25
lib/utils.js
Normal file
25
lib/utils.js
Normal file
@ -0,0 +1,25 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
/**
|
||||
* Created by hustcc on 18/6/23.
|
||||
* Contract: i@hust.cc
|
||||
*/
|
||||
|
||||
var requestAnimationFrame = exports.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || function (func) {
|
||||
return window.setTimeout(func, 1000 / 60);
|
||||
};
|
||||
|
||||
var cancelAnimationFrame = exports.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame || window.oCancelAnimationFrame || window.clearTimeout;
|
||||
|
||||
var range = exports.range = function range(n) {
|
||||
return new Array(n).fill(0).map(function (e, idx) {
|
||||
return idx;
|
||||
});
|
||||
};
|
||||
|
||||
var canvasStyle = exports.canvasStyle = function canvasStyle(config) {
|
||||
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;
|
||||
};
|
17402
package-lock.json
generated
Normal file
17402
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
66
package.json
Normal file
66
package.json
Normal file
@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "canvas-nest.js",
|
||||
"officialName": "canvas-nest.js",
|
||||
"version": "2.0.4",
|
||||
"main": "lib/index.js",
|
||||
"summary": "A nest backgroud of website draw on canvas use javascript, do not depends on jQuery.",
|
||||
"description": "A nest backgroud of website draw on canvas use javascript, do not depends on jQuery.",
|
||||
"scripts": {
|
||||
"test": "npm run size",
|
||||
"size": "size-limit",
|
||||
"build:lib": "rimraf ./lib && cross-env NODE_ENV=babel babel src -d lib",
|
||||
"build:umd": "cross-env NODE_ENV=rollup rollup -c rollup.config.umd.js",
|
||||
"build:iife": "cross-env NODE_ENV=rollup rollup -c rollup.config.iife.js",
|
||||
"build": "npm run build:umd && npm run build:iife && npm run build:lib && npm run test"
|
||||
},
|
||||
"dependencies": {
|
||||
"canvas-nest.js": "^2.0.4",
|
||||
"size-sensor": "^0.2.0"
|
||||
},
|
||||
"size-limit": [
|
||||
{
|
||||
"limit": "2.5 KB",
|
||||
"path": "dist/canvas-nest.umd.js"
|
||||
},
|
||||
{
|
||||
"limit": "2.5 KB",
|
||||
"path": "dist/canvas-nest.js"
|
||||
}
|
||||
],
|
||||
"author": {
|
||||
"name": "hustcc",
|
||||
"url": "https://github.com/hustcc"
|
||||
},
|
||||
"homepage": "https://atool.vip",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"canvas",
|
||||
"html5",
|
||||
"nest"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hustcc/canvas-nest.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/hustcc/canvas-nest.js/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-plugin-add-module-exports": "^0.2.1",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||
"babel-plugin-version": "^0.2.1",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"cross-env": "^5.1.3",
|
||||
"jest": "^24.9.0",
|
||||
"jest-electron": "^0.1.6",
|
||||
"rimraf": "^2.6.2",
|
||||
"rollup": "^0.58.1",
|
||||
"rollup-plugin-babel": "^3.0.4",
|
||||
"rollup-plugin-commonjs": "^9.1.3",
|
||||
"rollup-plugin-node-resolve": "^3.3.0",
|
||||
"rollup-plugin-uglify": "^3.0.0",
|
||||
"size-limit": "^0.18.0"
|
||||
}
|
||||
}
|
29
rollup.config.iife.js
Normal file
29
rollup.config.iife.js
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Created by hustcc on 18/6/23.
|
||||
* Contract: i@hust.cc
|
||||
*/
|
||||
|
||||
import uglify from 'rollup-plugin-uglify';
|
||||
import babel from 'rollup-plugin-babel';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
|
||||
export default {
|
||||
input: 'src/iife.js',
|
||||
output: {
|
||||
file: 'dist/canvas-nest.js',
|
||||
format: 'iife',
|
||||
},
|
||||
plugins: [
|
||||
resolve(),
|
||||
babel({
|
||||
exclude: 'node_modules/**',
|
||||
}),
|
||||
commonjs(),
|
||||
uglify({
|
||||
output: { comments: false },
|
||||
compress: { warnings: false }
|
||||
}),
|
||||
],
|
||||
external: [],
|
||||
};
|
30
rollup.config.umd.js
Normal file
30
rollup.config.umd.js
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Created by hustcc on 18/6/23.
|
||||
* Contract: i@hust.cc
|
||||
*/
|
||||
|
||||
import uglify from 'rollup-plugin-uglify';
|
||||
import babel from 'rollup-plugin-babel';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from 'rollup-plugin-commonjs';
|
||||
|
||||
export default {
|
||||
input: 'src/index.js',
|
||||
output: {
|
||||
file: 'dist/canvas-nest.umd.js',
|
||||
name: 'CanvasNest',
|
||||
format: 'umd',
|
||||
},
|
||||
plugins: [
|
||||
resolve(),
|
||||
babel({
|
||||
exclude: 'node_modules/**',
|
||||
}),
|
||||
commonjs(),
|
||||
uglify({
|
||||
output: { comments: false },
|
||||
compress: { warnings: false }
|
||||
}),
|
||||
],
|
||||
external: [],
|
||||
};
|
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 129 KiB |
146
src/CanvasNest.js
Normal file
146
src/CanvasNest.js
Normal file
@ -0,0 +1,146 @@
|
||||
/**
|
||||
* Created by hustcc on 18/6/23.
|
||||
* Contract: i@hust.cc
|
||||
*/
|
||||
|
||||
import { bind, clear } from 'size-sensor';
|
||||
import { requestAnimationFrame, cancelAnimationFrame, range, canvasStyle } from './utils';
|
||||
|
||||
export default class CanvasNest {
|
||||
|
||||
static version = __VERSION__;
|
||||
|
||||
constructor(el, config) {
|
||||
this.el = el;
|
||||
|
||||
this.c = {
|
||||
zIndex: -1, // z-index
|
||||
opacity: 0.5, // opacity
|
||||
color: '0,0,0', // color of lines
|
||||
pointColor: '0,0,0', // color of points
|
||||
count: 99, // count
|
||||
...config,
|
||||
};
|
||||
|
||||
this.canvas = this.newCanvas();
|
||||
this.context = this.canvas.getContext('2d');
|
||||
|
||||
this.points = this.randomPoints();
|
||||
this.current = {
|
||||
x: null, // 当前鼠标x
|
||||
y: null, // 当前鼠标y
|
||||
max: 20000 // 圈半径的平方
|
||||
};
|
||||
this.all = this.points.concat([this.current]);
|
||||
|
||||
this.bindEvent();
|
||||
|
||||
this.requestFrame(this.drawCanvas);
|
||||
}
|
||||
|
||||
bindEvent() {
|
||||
bind(this.el, () => {
|
||||
this.canvas.width = this.el.clientWidth;
|
||||
this.canvas.height = this.el.clientHeight;
|
||||
});
|
||||
|
||||
this.onmousemove = window.onmousemove;
|
||||
window.onmousemove = e => {
|
||||
this.current.x = e.clientX - this.el.offsetLeft + document.scrollingElement.scrollLeft; // 当存在横向滚动条时,x坐标再往右移动滚动条拉动的距离
|
||||
this.current.y = e.clientY - this.el.offsetTop + document.scrollingElement.scrollTop; // 当存在纵向滚动条时,y坐标再往下移动滚动条拉动的距离
|
||||
this.onmousemove && this.onmousemove(e);
|
||||
};
|
||||
|
||||
this.onmouseout = window.onmouseout;
|
||||
window.onmouseout = () => {
|
||||
this.current.x = null;
|
||||
this.current.y = null;
|
||||
this.onmouseout && this.onmouseout();
|
||||
};
|
||||
}
|
||||
|
||||
randomPoints = () => {
|
||||
return range(this.c.count).map(() => ({
|
||||
x: Math.random() * this.canvas.width,
|
||||
y: Math.random() * this.canvas.height,
|
||||
xa: 2 * Math.random() - 1, // 随机运动返现
|
||||
ya: 2 * Math.random() - 1,
|
||||
max: 6000 // 沾附距离
|
||||
}));
|
||||
};
|
||||
|
||||
newCanvas() {
|
||||
if (getComputedStyle(this.el).position === 'static') {
|
||||
this.el.style.position = 'relative'
|
||||
}
|
||||
const canvas = document.createElement('canvas'); // 画布
|
||||
canvas.style.cssText = canvasStyle(this.c);
|
||||
|
||||
canvas.width = this.el.clientWidth;
|
||||
canvas.height = this.el.clientHeight;
|
||||
|
||||
this.el.appendChild(canvas);
|
||||
return canvas;
|
||||
}
|
||||
|
||||
requestFrame(func) {
|
||||
this.tid = requestAnimationFrame(() => func.call(this));
|
||||
}
|
||||
|
||||
drawCanvas() {
|
||||
const context = this.context;
|
||||
const width = this.canvas.width;
|
||||
const height = this.canvas.height;
|
||||
const current = this.current;
|
||||
const points = this.points;
|
||||
const all = this.all;
|
||||
|
||||
context.clearRect(0, 0, width, height);
|
||||
// 随机的线条和当前位置联合数组
|
||||
let e, i, d, x_dist, y_dist, dist; // 临时节点
|
||||
// 遍历处理每一个点
|
||||
points.forEach((r, idx) => {
|
||||
r.x += r.xa;
|
||||
r.y += r.ya; // 移动
|
||||
r.xa *= r.x > width || r.x < 0 ? -1 : 1;
|
||||
r.ya *= r.y > height || r.y < 0 ? -1 : 1; // 碰到边界,反向反弹
|
||||
context.fillStyle = `rgba(${this.c.pointColor})`;
|
||||
context.fillRect(r.x - 0.5, r.y - 0.5, 1, 1); // 绘制一个宽高为1的点
|
||||
// 从下一个点开始
|
||||
for (i = idx + 1; i < all.length; i ++) {
|
||||
e = all[i];
|
||||
// 当前点存在
|
||||
if (null !== e.x && null !== e.y) {
|
||||
x_dist = r.x - e.x; // x轴距离 l
|
||||
y_dist = r.y - e.y; // y轴距离 n
|
||||
dist = x_dist * x_dist + y_dist * y_dist; // 总距离, m
|
||||
|
||||
dist < e.max && (e === current && dist >= e.max / 2 && (r.x -= 0.03 * x_dist, r.y -= 0.03 * y_dist), // 靠近的时候加速
|
||||
d = (e.max - dist) / e.max,
|
||||
context.beginPath(),
|
||||
context.lineWidth = d / 2,
|
||||
context.strokeStyle = `rgba(${this.c.color},${d + 0.2})`,
|
||||
context.moveTo(r.x, r.y),
|
||||
context.lineTo(e.x, e.y),
|
||||
context.stroke());
|
||||
}
|
||||
}
|
||||
});
|
||||
this.requestFrame(this.drawCanvas);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
// 清除事件
|
||||
clear(this.el);
|
||||
|
||||
// mouse 事件清除
|
||||
window.onmousemove = this.onmousemove; // 回滚方法
|
||||
window.onmouseout = this.onmouseout;
|
||||
|
||||
// 删除轮询
|
||||
cancelAnimationFrame(this.tid);
|
||||
|
||||
// 删除 dom
|
||||
this.canvas.parentNode.removeChild(this.canvas);
|
||||
}
|
||||
}
|
21
src/iife.js
Normal file
21
src/iife.js
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Created by hustcc on 18/6/23.
|
||||
* Contract: i@hust.cc
|
||||
*/
|
||||
|
||||
import CanvasNest from './CanvasNest';
|
||||
|
||||
const getScriptConfig = () => {
|
||||
const scripts = document.getElementsByTagName('script');
|
||||
const len = scripts.length;
|
||||
const script = scripts[len - 1]; // 当前加载的script
|
||||
return {
|
||||
zIndex: script.getAttribute('zIndex'),
|
||||
opacity: script.getAttribute('opacity'),
|
||||
color: script.getAttribute('color'),
|
||||
pointColor: script.getAttribute('pointColor'),
|
||||
count: Number(script.getAttribute('count')) || 99,
|
||||
};
|
||||
};
|
||||
|
||||
new CanvasNest(document.body, getScriptConfig());
|
8
src/index.js
Normal file
8
src/index.js
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Created by hustcc on 18/6/23.
|
||||
* Contract: i@hust.cc
|
||||
*/
|
||||
|
||||
import CanvasNest from './CanvasNest';
|
||||
|
||||
export default CanvasNest;
|
26
src/utils.js
Normal file
26
src/utils.js
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Created by hustcc on 18/6/23.
|
||||
* Contract: i@hust.cc
|
||||
*/
|
||||
|
||||
export const requestAnimationFrame = window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
window.oRequestAnimationFrame ||
|
||||
function(func) {
|
||||
return window.setTimeout(func, 1000 / 60);
|
||||
};
|
||||
|
||||
export const cancelAnimationFrame = window.cancelAnimationFrame ||
|
||||
window.webkitCancelAnimationFrame ||
|
||||
window.mozCancelAnimationFrame ||
|
||||
window.msCancelAnimationFrame ||
|
||||
window.oCancelAnimationFrame ||
|
||||
window.clearTimeout;
|
||||
|
||||
export const range = n =>
|
||||
new Array(n).fill(0).map((e, idx) => idx);
|
||||
|
||||
export const canvasStyle = config =>
|
||||
`display:block;position:absolute;top:0;left:0;height:100%;width:100%;overflow:hidden;pointer-events:none;z-index:${config.zIndex};opacity:${config.opacity}`;
|
Loading…
Reference in New Issue
Block a user