bubble-hearts
Advanced tools
Comparing version 0.0.3 to 0.0.4
@@ -126,3 +126,2 @@ import random from './random.js'; | ||
return this; | ||
} | ||
@@ -129,0 +128,0 @@ } |
/** | ||
* @ProjectName bubble-hearts | ||
* @Version 0.0.3 | ||
* @Version 0.0.4 | ||
* @Author lixinliang(https://github.com/lixinliang) | ||
* @Update 2017-01-11 3:25:32 pm | ||
* @Update 2017-01-11 4:16:39 pm | ||
*/ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.BubbleHearts=e()}(this,function(){"use strict";function t(t,n,r){var i=e.uniformDiscrete(89,91)/100,o=1-i,u=(e.uniformDiscrete(45,60)+e.uniformDiscrete(45,60))/100,a=function(t){return t>i?Math.max(((1-t)/o).toFixed(2),.1)*u:u},c=e.uniformDiscrete(-30,30),f=function(t){return c},h=10,s=n.width/2+e.uniformDiscrete(-h,h),l=(n.width-Math.sqrt(Math.pow(t.width,2)+Math.pow(t.height,2)))/2-h,d=e.uniformDiscrete(.8*l,l)*(e.uniformDiscrete(0,1)?1:-1),m=e.uniformDiscrete(250,400),w=function(t){return t>i?s:s+d*Math.sin(m*(i-t)*Math.PI/180)},p=function(e){return t.height/2+(n.height-t.height/2)*e},v=e.uniformDiscrete(14,18)/100,g=function(t){return t>v?1:1-((v-t)/v).toFixed(2)};return function(e){if(!(e>=0))return!0;var n=a(e),i=f(e),o=w(e),u=p(e);r.translate(o,u),r.scale(n,n),r.rotate(i*Math.PI/180),r.globalAlpha=g(e),r.drawImage(t,-t.width/2,-t.height/2,t.width,t.height),r.rotate(-i*Math.PI/180),r.scale(1/n,1/n),r.translate(-o,-u),r.globalAlpha=1}}var e=function(t){var e=t,n=Math.floor,r=Math.random;return t.uniform=function(t,e){return t+(e-t)*r()},t.uniformDiscrete=function(t,r){return t+n((r-t+1)*e.uniform(0,1))},t}({}),n=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},r=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),i=window.requestAnimationFrame||window.webkitRequestAnimationFrame||function(t){return setTimeout(t,16)},o=function(){function o(){n(this,o);var t=this.canvas=document.createElement("canvas"),e=this.context=t.getContext("2d"),r=this._children=[],u=function n(){i(n),e.clearRect(0,0,t.width,t.height);for(var o=0,u=r.length;o<u;){var a=r[o];a.render.call(null,(a.timestamp+a.duration-new Date)/a.duration)?(r.splice(o,1),u--):o++}};i(u)}return r(o,[{key:"bubble",value:function(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:e.uniformDiscrete(2400,3600),i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:t(n,this.canvas,this.context);return this._children.push({render:i,duration:r,timestamp:+new Date}),this}}]),o}();return o}); |
{ | ||
"name": "bubble-hearts", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "(<3kb) 💖Bubble hearts animation.", | ||
@@ -5,0 +5,0 @@ "main": "./bubble-hearts.min.js", |
162
README.md
[![npm](https://img.shields.io/npm/l/bubble-hearts.svg?style=flat-square)](https://www.npmjs.org/package/bubble-hearts) | ||
[![npm](https://img.shields.io/npm/v/bubble-hearts.svg?style=flat-square)](https://www.npmjs.org/package/bubble-hearts) | ||
[![npm](https://img.shields.io/npm/dm/bubble-hearts.svg?style=flat-square)](https://www.npmjs.org/package/bubble-hearts) | ||
[![bitHound Code](https://www.bithound.io/github/lixinliang/bubble-hearts/badges/code.svg)](https://www.bithound.io/github/lixinliang/bubble-hearts) | ||
@@ -25,6 +24,165 @@ # bubble-hearts | ||
* coming soon. | ||
#### #Init | ||
```js | ||
let stage = new BubbleHearts(); | ||
``` | ||
#### #Config | ||
```js | ||
let canvas = stage.canvas; | ||
let context = stage.context; | ||
canvas.width = 200; | ||
canvas.height = 400; | ||
canvas.style['width'] = '200px'; | ||
canvas.style['height'] = '400px'; | ||
``` | ||
#### #Display | ||
```js | ||
document.body.appendChild(canvas); | ||
``` | ||
### #Animate | ||
```js | ||
let image = new Image; | ||
image.onload = () => { | ||
stage.bubble(image); | ||
}; | ||
image.src = src; | ||
``` | ||
## Doc | ||
#### #bubble | ||
> stage.bubble( image : Image/Canvas, duration : Number, handler : Function ) | ||
| Param | Type | Required | Default | Description | | ||
|---|---|---|---|---| | ||
| image | Image/Canvas | * | - | Let this image bubbles in canvas. | | ||
| duration | Number | - | 3000 | The duration of animation. | | ||
| handler | Function | - | [@see handler](#handler) | The handler of animation. | | ||
#### #handler | ||
> handler( lifespan : Number ) | ||
| Param | Type | Description | | ||
|---|---|---| | ||
| lifespan | Number | From `1` to `0`; `1` means full live; `0` means over. | | ||
* default handler | ||
```js | ||
/** | ||
* Create a default Render | ||
* @param {Canvas} canvas canvas | ||
* @param {Context} context context | ||
* @return {Function} handler | ||
*/ | ||
function createRender ( image, canvas, context ) { | ||
const zoomInStage = random.uniformDiscrete(89, 91) / 100; | ||
const zoomInRest = 1 - zoomInStage; | ||
const basicScale = (random.uniformDiscrete(45, 60) + random.uniformDiscrete(45, 60)) / 100; | ||
let getScale = ( lifespan ) => { | ||
if (lifespan > zoomInStage) { | ||
return Math.max(((1 - lifespan) / zoomInRest).toFixed(2), 0.1) * basicScale; | ||
} else { | ||
return basicScale; | ||
} | ||
}; | ||
const basicRotate = random.uniformDiscrete(-30, 30); | ||
let getRotate = ( lifespan ) => { | ||
return basicRotate; | ||
}; | ||
const offset = 10; | ||
const basicTranslateX = canvas.width / 2 + random.uniformDiscrete(-offset, offset); | ||
const amplitude = (canvas.width - Math.sqrt(Math.pow(image.width, 2) + Math.pow(image.height, 2))) / 2 - offset; | ||
const wave = random.uniformDiscrete(amplitude * 0.8, amplitude) * (random.uniformDiscrete(0, 1) ? 1 : -1); | ||
const frequency = random.uniformDiscrete(250, 400); | ||
let getTranslateX = ( lifespan ) => { | ||
if (lifespan > zoomInStage) { | ||
return basicTranslateX; | ||
} else { | ||
return basicTranslateX + wave * Math.sin(frequency * (zoomInStage - lifespan) * Math.PI / 180); | ||
} | ||
}; | ||
let getTranslateY = ( lifespan ) => { | ||
return image.height / 2 + (canvas.height - image.height / 2) * lifespan; | ||
}; | ||
const fadeOutStage = random.uniformDiscrete(14, 18) / 100; | ||
let getAlpha = ( lifespan ) => { | ||
if (lifespan > fadeOutStage) { | ||
return 1; | ||
} else { | ||
return 1 - ((fadeOutStage - lifespan) / fadeOutStage).toFixed(2); | ||
} | ||
}; | ||
return ( lifespan ) => { | ||
if (lifespan >= 0) { | ||
let scale = getScale(lifespan); | ||
let rotate = getRotate(lifespan); | ||
let translateX = getTranslateX(lifespan); | ||
let translateY = getTranslateY(lifespan); | ||
context.translate(translateX, translateY); | ||
context.scale(scale, scale); | ||
context.rotate(rotate * Math.PI / 180); | ||
context.globalAlpha = getAlpha(lifespan); | ||
context.drawImage( | ||
image, | ||
-image.width / 2, | ||
-image.height / 2, | ||
image.width, | ||
image.height | ||
); | ||
context.rotate(-rotate * Math.PI / 180); | ||
context.scale(1 / scale, 1 / scale); | ||
context.translate(-translateX, -translateY); | ||
context.globalAlpha = 1; | ||
} else { | ||
return true; | ||
} | ||
}; | ||
} | ||
``` | ||
* simple custom example | ||
```js | ||
stage.bubble(image, 3000, function ( lifespan ) { | ||
// You got its lifespan, and from 1 to 0 | ||
if (lifespan >= 0) { | ||
stage.context.drawImage( | ||
image, | ||
(canvas.width - image.width) / 2, | ||
// lifespan control its positionY, so that it will look like fly up | ||
(canvas.height - image.height) * lifespan, | ||
image.width, | ||
image.height | ||
); | ||
} else { | ||
// Return true to free the memory | ||
return true; | ||
} | ||
}); | ||
``` | ||
#### #why `return true` ? | ||
* lifespan from `1` to `0`, and go on to be negative. | ||
* handler function repeats again and again to `drawImage`. | ||
* `return true` is a flag to tell iterator to remove this handler, and stop repeating this handler again. | ||
## License | ||
MIT |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
130937
188