From 2fdc9effc2d9e63fc884bfa689dfe6764dd346a5 Mon Sep 17 00:00:00 2001 From: hustcc Date: Sat, 23 Jun 2018 11:32:46 +0800 Subject: [PATCH] module & area render --- .babelrc | 26 +++++++ .gitignore | 2 +- .jshintrc | 13 ---- .travis.yml | 3 - README-zh.md | 60 +++++++++++---- README.md | 79 ++++++++++++++------ dist/canvas-nest.js | 119 +----------------------------- dist/canvas-nest.min.js | 7 -- dist/canvas-nest.umd.js | 1 + gulpfile.js | 16 ---- index.html | 76 ++++++++++++++----- lib/CanvasNest.js | 159 ++++++++++++++++++++++++++++++++++++++++ lib/iife.js | 24 ++++++ lib/index.js | 18 +++++ lib/utils.js | 23 ++++++ package.json | 61 +++++++++++---- rollup.config.iife.js | 29 ++++++++ rollup.config.umd.js | 30 ++++++++ src/CanvasNest.js | 126 +++++++++++++++++++++++++++++++ src/canvas-nest.js | 118 ----------------------------- src/iife.js | 20 +++++ src/index.js | 8 ++ src/utils.js | 19 +++++ 23 files changed, 691 insertions(+), 346 deletions(-) create mode 100644 .babelrc delete mode 100644 .jshintrc delete mode 100644 .travis.yml delete mode 100644 dist/canvas-nest.min.js create mode 100644 dist/canvas-nest.umd.js delete mode 100644 gulpfile.js create mode 100644 lib/CanvasNest.js create mode 100644 lib/iife.js create mode 100644 lib/index.js create mode 100644 lib/utils.js create mode 100644 rollup.config.iife.js create mode 100644 rollup.config.umd.js create mode 100644 src/CanvasNest.js delete mode 100644 src/canvas-nest.js create mode 100644 src/iife.js create mode 100644 src/index.js create mode 100644 src/utils.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..9b21973 --- /dev/null +++ b/.babelrc @@ -0,0 +1,26 @@ +{ + "env": { + "rollup": { + "presets": [ + [ + "env", + { + "modules": false + } + ] + ], + "plugins": [ + "transform-class-properties", + "transform-object-rest-spread" + ] + }, + "babel": { + "presets": ["env"], + "plugins": [ + "transform-class-properties", + "add-module-exports", + "transform-object-rest-spread" + ] + } + } +} diff --git a/.gitignore b/.gitignore index 3f875d7..dd93304 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .project .settings - +.idea node_modules/* diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index f2772a8..0000000 --- a/.jshintrc +++ /dev/null @@ -1,13 +0,0 @@ -{ - "quotmark": true, - "boss": true, - "eqnull": true, - "expr": true, - "funcscope": true, - "loopfunc": true, - "smarttabs": true, - "node": true, - "browser": true, - "undef": true, - "unused": true -} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index aacd2fb..0000000 --- a/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: node_js -node_js: - - "4.4.4" \ No newline at end of file diff --git a/README-zh.md b/README-zh.md index ab83bc3..403c9a2 100644 --- a/README-zh.md +++ b/README-zh.md @@ -1,25 +1,27 @@ # canvas-nest.js -> 一个基于html5 canvas绘制的网页背景效果,非常赞!如果需要 `wordpress插件`,在插件库搜索 `canvas-nest` 或者看看项目 [canvas-nest-for-wp](https://github.com/aTool-org/canvas-nest-for-wp)。 +> 一个基于 html5 canvas 绘制的网页背景效果,非常赞!如果需要 `wordpress插件`,在插件库搜索 `canvas-nest` 或者看看项目 [canvas-nest-for-wp](https://github.com/aTool-org/canvas-nest-for-wp)。 -![travis-ci](https://travis-ci.org/hustcc/canvas-nest.js.svg?branch=master) ![npm](https://img.shields.io/npm/v/canvas-nest.js.svg?style=flat-square) ![npm](https://img.shields.io/npm/l/canvas-nest.js.svg?style=flat-square) +[![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) +![npm](https://img.shields.io/npm/dm/canvas-nest.js.svg) ## 特性 - - 不依赖任何框架或者类库,比如不依赖 jQuery,使用原生的 javascript。 - - 非常小,只有1.6 kb,如果开启 gzip,可以更小。 - - 非常容易实现,配置简单,即使你不是web开发者,也能简单搞定。 + - 不依赖 jQuery,使用原生的 javascript。 + - 非常小,只有 2 Kb。 + - 非常容易实现,配置简单,即使你不是 web 开发者,也能简单搞定。 ## 使用 -使用非常简单,感觉都没有必要写这一节内容。 + - 快捷使用 将下面的代码插入到 ` 和 之间`. ```html - + ``` 强烈建议在 ``标签上方. 例如下面的代码结构: @@ -32,15 +34,31 @@ ... ... - ... - + ``` -`请注意不要将代码置于 里面`. +然后就完成了,打开网页即可看到效果!`请注意不要将代码置于 里面`. + + + - 模块化区域绘制(定制开发) + +> npm i --save canvas-nest.js + +然后可以使用 script 方式引入 umd 包,当然也可使用模块化方式 import。并且只有一个 API,使用如下: + +``` +import CanvasNest from 'canvas-nest.js'; + +const config = { + color: '255,0,0', + count: 88, +}; -然后就完成了,打开网页即可看到效果! +// 在 element 地方使用 config 渲染效果 +new CanvasNest(element, config); +``` ## 配置和配置项 @@ -54,11 +72,22 @@ Example: ``` - + ``` 这些属性配置在引用js的script标签中,作为它的一个属性值。所有的配置项都有默认值,如果你不知道怎么设置,可以先不设置这些配置项,就使用默认值看看效果也可以的。 +或者模块化调用的时候,写成: + +```js +{ + color: '0,0,255', + opacity: 0.7, + zIndex: -2, + count: 99, +}; +``` + ## 示例 @@ -71,6 +100,9 @@ Example: ## 其他 -本项目的Javascript文件已经存储在CDN上,可以直接使用,地址为: [http://www.bootcdn.cn/canvas-nest.js/](http://www.bootcdn.cn/canvas-nest.js/),如果你不需要 CDN 或者有自己的 CDN,可以直接下载源码 dist 目录中的 `canvas-nest.min.js`,然后相应的修改使用地址即可。 +本项目的 Javascript 文件已经存储在 CDN 上,可以直接使用,地址为: [http://www.bootcdn.cn/canvas-nest.js/](http://www.bootcdn.cn/canvas-nest.js/),如果你不需要 CDN 或者有自己的 CDN,可以直接下载源码 dist 目录中的 `canvas-nest.js`,然后相应的修改使用地址即可。 + + +## License -有任何的bug或者建议,非常鼓励 issue 和 pr,来者不拒。 +MIT@[hustcc](https://github.com/hustcc). diff --git a/README.md b/README.md index 33486c7..f456cad 100644 --- a/README.md +++ b/README.md @@ -2,28 +2,29 @@ > A nest backgroud of website draw on canvas. [中文Readme帮助文档](https://github.com/hustcc/canvas-nest.js/blob/master/README-zh.md). For `wordpress plugin`, search `canvas-nest` or see [canvas-nest-for-wp](https://github.com/aTool-org/canvas-nest-for-wp). -![travis-ci](https://travis-ci.org/hustcc/canvas-nest.js.svg?branch=master) ![npm](https://img.shields.io/npm/v/canvas-nest.js.svg?style=flat-square) ![npm](https://img.shields.io/npm/l/canvas-nest.js.svg?style=flat-square) +[![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) +![npm](https://img.shields.io/npm/dm/canvas-nest.js.svg) +## Feature -## feature + - No need jQuery. + - Light, only 2 Kb. + - Easy to use, even you are not a web developer. - - do not depend on jQuery or other javascript framework. - - very light, only 1.6 kb. can be smaller after gzip. - - so easy to use, even you are not a web developer. +## Usage -## usage + - Script tag -so eazy that I do not want write the chapter. - -insert the code below `between and `. +Insert the code below `between and `. ```html - + ``` -suggest before the tag ``. like below: +Suggest before the tag ``, like below: ```html @@ -33,19 +34,36 @@ suggest before the tag ``. like below: ... ... - ... - + ``` +Then ok! `Please do not add the code in the `. + + + - Module usage (Area render) + +> npm i --save canvas-nest.js + +Or import the `umd` package use `script` tag. + +There is only one API, use it like: + +``` +import CanvasNest from 'canvas-nest.js'; -`please do not add the code in the `. +const config = { + color: '255,0,0', + count: 88, +}; -then ok! +// render nest on element with config. +new CanvasNest(element, config); +``` -## config +## Config - **`color`**: the canvas line color, default: `'0,0,0'` ; the color is (R,G,B) - **`opacity`**: the opacity of line (0~1), default: `0.5` @@ -55,23 +73,40 @@ then ok! Example: ```html - + +``` + +Or + +```js +{ + color: '0,0,255', + opacity: 0.7, + zIndex: -2, + count: 99, +}; ``` set the config on the script node `as a attribute`. all the config has the default value, you can choose to set any of them. -## preview +## Preview 1. [Online Tools: https://atool.vip/](https://atool.vip/) -if you has used this project, pls let me know, I can add your website on. + +If you has used this project, you can send pr and write it here. + ![screenshot](https://raw.githubusercontent.com/hustcc/canvas-nest.js/master/screenshot.png) -## other +## Other + +Library cdn url: [http://www.bootcdn.cn/canvas-nest.js/](http://www.bootcdn.cn/canvas-nest.js/). + + -Project library cdn url: [http://www.bootcdn.cn/canvas-nest.js/](http://www.bootcdn.cn/canvas-nest.js/). +## License -any bug or question, welcome to push request and issue. +MIT@[hustcc](https://github.com/hustcc). diff --git a/dist/canvas-nest.js b/dist/canvas-nest.js index e7bff1b..e1021cd 100644 --- a/dist/canvas-nest.js +++ b/dist/canvas-nest.js @@ -1,118 +1 @@ -/** - * Copyright (c) 2016 hustcc - * License: MIT - * Version: v1.0.1 - * GitHub: https://github.com/hustcc/canvas-nest.js -**/ -! function() { - //封装方法,压缩之后减少文件大小 - function get_attribute(node, attr, default_value) { - return node.getAttribute(attr) || default_value; - } - //封装方法,压缩之后减少文件大小 - function get_by_tagname(name) { - return document.getElementsByTagName(name); - } - //获取配置参数 - function get_config_option() { - var scripts = get_by_tagname("script"), - script_len = scripts.length, - script = scripts[script_len - 1]; //当前加载的script - return { - l: script_len, //长度,用于生成id用 - z: get_attribute(script, "zIndex", -1), //z-index - o: get_attribute(script, "opacity", 0.5), //opacity - c: get_attribute(script, "color", "0,0,0"), //color - n: get_attribute(script, "count", 99) //count - }; - } - //设置canvas的高宽 - function set_canvas_size() { - canvas_width = the_canvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, - canvas_height = the_canvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; - } - - //绘制过程 - function draw_canvas() { - context.clearRect(0, 0, canvas_width, canvas_height); - //随机的线条和当前位置联合数组 - var e, i, d, x_dist, y_dist, dist; //临时节点 - //遍历处理每一个点 - random_points.forEach(function(r, idx) { - r.x += r.xa, - r.y += r.ya, //移动 - r.xa *= r.x > canvas_width || r.x < 0 ? -1 : 1, - r.ya *= r.y > canvas_height || r.y < 0 ? -1 : 1, //碰到边界,反向反弹 - context.fillRect(r.x - 0.5, r.y - 0.5, 1, 1); //绘制一个宽高为1的点 - //从下一个点开始 - for (i = idx + 1; i < all_array.length; i++) { - e = all_array[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_point && 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(" + config.c + "," + (d + 0.2) + ")", - context.moveTo(r.x, r.y), - context.lineTo(e.x, e.y), - context.stroke()); - } - } - }), frame_func(draw_canvas); - } - //创建画布,并添加到body中 - var the_canvas = document.createElement("canvas"), //画布 - config = get_config_option(), //配置 - canvas_id = "c_n" + config.l, //canvas id - context = the_canvas.getContext("2d"), canvas_width, canvas_height, - frame_func = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(func) { - window.setTimeout(func, 1000 / 45); - }, random = Math.random, - current_point = { - x: null, //当前鼠标x - y: null, //当前鼠标y - max: 20000 // 圈半径的平方 - }, - all_array; - the_canvas.id = canvas_id; - the_canvas.style.cssText = "position:fixed;top:0;left:0;z-index:" + config.z + ";opacity:" + config.o; - get_by_tagname("body")[0].appendChild(the_canvas); - - //初始化画布大小 - set_canvas_size(); - window.onresize = set_canvas_size; - //当时鼠标位置存储,离开的时候,释放当前位置信息 - window.onmousemove = function(e) { - e = e || window.event; - current_point.x = e.clientX; - current_point.y = e.clientY; - }, window.onmouseout = function() { - current_point.x = null; - current_point.y = null; - }; - //随机生成config.n条线位置信息 - for (var random_points = [], i = 0; config.n > i; i++) { - var x = random() * canvas_width, //随机位置 - y = random() * canvas_height, - xa = 2 * random() - 1, //随机运动方向 - ya = 2 * random() - 1; - // 随机点 - random_points.push({ - x: x, - y: y, - xa: xa, - ya: ya, - max: 6000 //沾附距离 - }); - } - all_array = random_points.concat([current_point]); - //0.1秒后绘制 - setTimeout(function() { - draw_canvas(); - }, 100); -}(); +!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 i=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 i=this,o=arguments.length,r=Array(o),s=0;sn||r.x<0?-1:1,r.ya*=r.y>i||r.y<0?-1:1,t.fillRect(r.x-.5,r.y-.5,1,1),u=v+1;u=a.max/2&&(r.x-=.03*c,r.y-=.03*d),l=(a.max-h)/a.max,t.beginPath(),t.lineWidth=l/2,t.strokeStyle="rgba("+e.c.color+","+(l+.2)+")",t.moveTo(r.x,r.y),t.lineTo(a.x,a.y),t.stroke()))}),this.requestFrame(this.drawCanvas)}}]),e}())(document.body,(v=document.getElementsByTagName("script"),{zIndex:(f=v[v.length-1]).getAttribute("zIndex"),opacity:f.getAttribute("opacity"),color:f.getAttribute("color"),count:Number(f.getAttribute("count"))||99}))}(); diff --git a/dist/canvas-nest.min.js b/dist/canvas-nest.min.js deleted file mode 100644 index 006aada..0000000 --- a/dist/canvas-nest.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Copyright (c) 2016 hustcc - * License: MIT - * Version: v1.0.1 - * GitHub: https://github.com/hustcc/canvas-nest.js -**/ -!function(){function n(n,e,t){return n.getAttribute(e)||t}function e(n){return document.getElementsByTagName(n)}function t(){var t=e("script"),o=t.length,i=t[o-1];return{l:o,z:n(i,"zIndex",-1),o:n(i,"opacity",.5),c:n(i,"color","0,0,0"),n:n(i,"count",99)}}function o(){a=m.width=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth,c=m.height=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight}function i(){r.clearRect(0,0,a,c);var n,e,t,o,m,l;s.forEach(function(i,x){for(i.x+=i.xa,i.y+=i.ya,i.xa*=i.x>a||i.x<0?-1:1,i.ya*=i.y>c||i.y<0?-1:1,r.fillRect(i.x-.5,i.y-.5,1,1),e=x+1;e=n.max/2&&(i.x-=.03*o,i.y-=.03*m),t=(n.max-l)/n.max,r.beginPath(),r.lineWidth=t/2,r.strokeStyle="rgba("+d.c+","+(t+.2)+")",r.moveTo(i.x,i.y),r.lineTo(n.x,n.y),r.stroke()))}),x(i)}var a,c,u,m=document.createElement("canvas"),d=t(),l="c_n"+d.l,r=m.getContext("2d"),x=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(n){window.setTimeout(n,1e3/45)},w=Math.random,y={x:null,y:null,max:2e4};m.id=l,m.style.cssText="position:fixed;top:0;left:0;z-index:"+d.z+";opacity:"+d.o,e("body")[0].appendChild(m),o(),window.onresize=o,window.onmousemove=function(n){n=n||window.event,y.x=n.clientX,y.y=n.clientY},window.onmouseout=function(){y.x=null,y.y=null};for(var s=[],f=0;d.n>f;f++){var h=w()*a,g=w()*c,v=2*w()-1,p=2*w()-1;s.push({x:h,y:g,xa:v,ya:p,max:6e3})}u=s.concat([y]),setTimeout(function(){i()},100)}(); \ No newline at end of file diff --git a/dist/canvas-nest.umd.js b/dist/canvas-nest.umd.js new file mode 100644 index 0000000..3a7f67f --- /dev/null +++ b/dist/canvas-nest.umd.js @@ -0,0 +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 i=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 i=this,o=arguments.length,r=Array(o),s=0;sn||r.x<0?-1:1,r.ya*=r.y>i||r.y<0?-1:1,t.fillRect(r.x-.5,r.y-.5,1,1),u=h+1;u=a.max/2&&(r.x-=.03*c,r.y-=.03*d),l=(a.max-f)/a.max,t.beginPath(),t.lineWidth=l/2,t.strokeStyle="rgba("+e.c.color+","+(l+.2)+")",t.moveTo(r.x,r.y),t.lineTo(a.x,a.y),t.stroke()))}),this.requestFrame(this.drawCanvas)}}]),e}()}); diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index f106eaa..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,16 +0,0 @@ -const fs = require('fs'); -const gulp = require('gulp'); -const uglify = require('gulp-uglify'); -const rename = require("gulp-rename"); -const injectVersion = require('gulp-inject-version'); - -gulp.task('mini', () => ( - gulp.src('src/canvas-nest.js') - .pipe(injectVersion()) - .pipe(gulp.dest('dist/')) - .pipe(uglify({ - preserveComments: 'license' - })) //uglify - .pipe(rename("canvas-nest.min.js")) - .pipe(gulp.dest('dist/')) -)); \ No newline at end of file diff --git a/index.html b/index.html index ffab0eb..eae6a20 100644 --- a/index.html +++ b/index.html @@ -4,28 +4,68 @@ canvas-nest.js - + + -
+
+ +
- + + diff --git a/lib/CanvasNest.js b/lib/CanvasNest.js new file mode 100644 index 0000000..57dce83 --- /dev/null +++ b/lib/CanvasNest.js @@ -0,0 +1,159 @@ +'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 + 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; + }); + + var onmousemove = window.onmousemove; + window.onmousemove = function (e) { + _this2.current.x = e.clientX; + _this2.current.y = e.clientY; + onmousemove && onmousemove(e); + }; + + var onmouseout = window.onmouseout; + window.onmouseout = function () { + _this2.current.x = null; + _this2.current.y = null; + onmouseout && 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; + + return (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.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); + } + }]); + + return CanvasNest; +}(); + +exports.default = CanvasNest; +module.exports = exports['default']; \ No newline at end of file diff --git a/lib/iife.js b/lib/iife.js new file mode 100644 index 0000000..c2cc9a1 --- /dev/null +++ b/lib/iife.js @@ -0,0 +1,24 @@ +'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'), + count: Number(script.getAttribute('count')) || 99 + }; +}; /** + * Created by hustcc on 18/6/23. + * Contract: i@hust.cc + */ + +new _CanvasNest2.default(document.body, getScriptConfig()); \ No newline at end of file diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..fbcaf1b --- /dev/null +++ b/lib/index.js @@ -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']; \ No newline at end of file diff --git a/lib/utils.js b/lib/utils.js new file mode 100644 index 0000000..cc9afca --- /dev/null +++ b/lib/utils.js @@ -0,0 +1,23 @@ +"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.oRequestAnimationFrame || window.msRequestAnimationFrame || function (func) { + return window.setTimeout(func, 1000 / 60); +}; + +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; +}; \ No newline at end of file diff --git a/package.json b/package.json index 4849913..c297d8f 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,42 @@ { "name": "canvas-nest.js", "officialName": "canvas-nest.js", - "version": "1.0.1", + "version": "2.0.0", + "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": { + "size-sensor": "^0.0.4" + }, + "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": "http://www.atool.org", + "homepage": "https://atool.vip", "license": "MIT", "keywords": [ "canvas", "html5", "nest" ], - "main": "dist/canvas-nest.min.js", "repository": { "type": "git", "url": "https://github.com/hustcc/canvas-nest.js" @@ -24,17 +45,25 @@ "url": "https://github.com/hustcc/canvas-nest.js/issues" }, "devDependencies": { - "gulp": "^3.9.0", - "gulp-uglify": "^1.5.3", - "jshint": "^2.9.2", - "gulp-rename": "^1.2.2", - "gulp-inject-version": "^1.0.1" - }, - "scripts": { - "lint": "jshint src/canvas-nest.js", - "test": "npm run lint", - "build": "gulp mini && npm run test" - }, - "dependencies": { + "babel-cli": "^6.26.0", + "babel-jest": "^22.4.1", + "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-preset-env": "^1.6.1", + "coveralls": "^3.0.0", + "cross-env": "^5.1.3", + "jest": "^22.4.2", + "jest-date-mock": "^1.0.0", + "jest-expect": "^0.0.1", + "jsdom": "^11.5.1", + "mitt": "^1.1.3", + "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" } -} \ No newline at end of file +} diff --git a/rollup.config.iife.js b/rollup.config.iife.js new file mode 100644 index 0000000..699fce1 --- /dev/null +++ b/rollup.config.iife.js @@ -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: [], +}; diff --git a/rollup.config.umd.js b/rollup.config.umd.js new file mode 100644 index 0000000..ad79cfe --- /dev/null +++ b/rollup.config.umd.js @@ -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: [], +}; diff --git a/src/CanvasNest.js b/src/CanvasNest.js new file mode 100644 index 0000000..2490785 --- /dev/null +++ b/src/CanvasNest.js @@ -0,0 +1,126 @@ +/** + * Created by hustcc on 18/6/23. + * Contract: i@hust.cc + */ + +import { bind } from 'size-sensor'; +import { requestAnimationFrame, range, canvasStyle } from './utils'; + +export default class CanvasNest { + constructor(el, config) { + this.el = el; + + this.c = { + zIndex: -1, // z-index + opacity: 0.5, // opacity + color: '0,0,0', // color + 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; + }); + + const onmousemove = window.onmousemove; + window.onmousemove = e => { + this.current.x = e.clientX; + this.current.y = e.clientY; + onmousemove && onmousemove(e); + }; + + const onmouseout = window.onmouseout; + window.onmouseout = () => { + this.current.x = null; + this.current.y = null; + onmouseout && 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) { + return 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.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); + } +} diff --git a/src/canvas-nest.js b/src/canvas-nest.js deleted file mode 100644 index 88f859a..0000000 --- a/src/canvas-nest.js +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Copyright (c) 2016 hustcc - * License: MIT - * Version: %%GULP_INJECT_VERSION%% - * GitHub: https://github.com/hustcc/canvas-nest.js -**/ -! function() { - //封装方法,压缩之后减少文件大小 - function get_attribute(node, attr, default_value) { - return node.getAttribute(attr) || default_value; - } - //封装方法,压缩之后减少文件大小 - function get_by_tagname(name) { - return document.getElementsByTagName(name); - } - //获取配置参数 - function get_config_option() { - var scripts = get_by_tagname("script"), - script_len = scripts.length, - script = scripts[script_len - 1]; //当前加载的script - return { - l: script_len, //长度,用于生成id用 - z: get_attribute(script, "zIndex", -1), //z-index - o: get_attribute(script, "opacity", 0.5), //opacity - c: get_attribute(script, "color", "0,0,0"), //color - n: get_attribute(script, "count", 99) //count - }; - } - //设置canvas的高宽 - function set_canvas_size() { - canvas_width = the_canvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, - canvas_height = the_canvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; - } - - //绘制过程 - function draw_canvas() { - context.clearRect(0, 0, canvas_width, canvas_height); - //随机的线条和当前位置联合数组 - var e, i, d, x_dist, y_dist, dist; //临时节点 - //遍历处理每一个点 - random_points.forEach(function(r, idx) { - r.x += r.xa, - r.y += r.ya, //移动 - r.xa *= r.x > canvas_width || r.x < 0 ? -1 : 1, - r.ya *= r.y > canvas_height || r.y < 0 ? -1 : 1, //碰到边界,反向反弹 - context.fillRect(r.x - 0.5, r.y - 0.5, 1, 1); //绘制一个宽高为1的点 - //从下一个点开始 - for (i = idx + 1; i < all_array.length; i++) { - e = all_array[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_point && 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(" + config.c + "," + (d + 0.2) + ")", - context.moveTo(r.x, r.y), - context.lineTo(e.x, e.y), - context.stroke()); - } - } - }), frame_func(draw_canvas); - } - //创建画布,并添加到body中 - var the_canvas = document.createElement("canvas"), //画布 - config = get_config_option(), //配置 - canvas_id = "c_n" + config.l, //canvas id - context = the_canvas.getContext("2d"), canvas_width, canvas_height, - frame_func = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(func) { - window.setTimeout(func, 1000 / 60); - }, random = Math.random, - current_point = { - x: null, //当前鼠标x - y: null, //当前鼠标y - max: 20000 // 圈半径的平方 - }, - all_array; - the_canvas.id = canvas_id; - the_canvas.style.cssText = "position:fixed;top:0;left:0;z-index:" + config.z + ";opacity:" + config.o; - get_by_tagname("body")[0].appendChild(the_canvas); - - //初始化画布大小 - set_canvas_size(); - window.onresize = set_canvas_size; - //当时鼠标位置存储,离开的时候,释放当前位置信息 - window.onmousemove = function(e) { - e = e || window.event; - current_point.x = e.clientX; - current_point.y = e.clientY; - }, window.onmouseout = function() { - current_point.x = null; - current_point.y = null; - }; - //随机生成config.n条线位置信息 - for (var random_points = [], i = 0; config.n > i; i++) { - var x = random() * canvas_width, //随机位置 - y = random() * canvas_height, - xa = 2 * random() - 1, //随机运动方向 - ya = 2 * random() - 1; - // 随机点 - random_points.push({ - x: x, - y: y, - xa: xa, - ya: ya, - max: 6000 //沾附距离 - }); - } - all_array = random_points.concat([current_point]); - //0.1秒后绘制 - setTimeout(function() { - frame_func(draw_canvas); - }, 100); -}(); diff --git a/src/iife.js b/src/iife.js new file mode 100644 index 0000000..5e5cf86 --- /dev/null +++ b/src/iife.js @@ -0,0 +1,20 @@ +/** + * 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'), + count: Number(script.getAttribute('count')) || 99, + }; +}; + +new CanvasNest(document.body, getScriptConfig()); diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..c604ed1 --- /dev/null +++ b/src/index.js @@ -0,0 +1,8 @@ +/** + * Created by hustcc on 18/6/23. + * Contract: i@hust.cc + */ + +import CanvasNest from './CanvasNest'; + +export default CanvasNest; diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..ff77c22 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,19 @@ +/** + * Created by hustcc on 18/6/23. + * Contract: i@hust.cc + */ + +export const requestAnimationFrame = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(func) { + return window.setTimeout(func, 1000 / 60); + }; + +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}`;