diff --git a/demo/css/main.css b/demo/css/main.css index db56b84..95f68f5 100644 --- a/demo/css/main.css +++ b/demo/css/main.css @@ -58,10 +58,20 @@ textarea { .w1-pixel-stage { width: 100%; - height: 100vh; + height: 25vh; background-image: url(https://unsplash.it/640/360); background-position: center center; background-size: cover; + margin-bottom: 50px; +} + +.w1-pixel-stage canvas { + opacity: 0; + transition: opacity .5s ease; +} + +.w1-pixel-stage-loaded canvas { + opacity: 1; } diff --git a/demo/index.html b/demo/index.html index 38edf70..09efa16 100644 --- a/demo/index.html +++ b/demo/index.html @@ -18,6 +18,7 @@
+ diff --git a/package-lock.json b/package-lock.json index 9fb8934..2f3ac74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,17 @@ "license": "SEE LICENSE IN LICENSE", "dependencies": { "@pixi/app": "^6.0.2", + "@pixi/constants": "^6.0.2", + "@pixi/core": "^6.0.2", "@pixi/display": "^6.0.2", - "@pixi/graphics": "^6.0.2" + "@pixi/graphics": "^6.0.2", + "@pixi/interaction": "^6.0.2", + "@pixi/math": "^6.0.2", + "@pixi/runner": "^6.0.2", + "@pixi/settings": "^6.0.2", + "@pixi/ticker": "^6.0.2", + "@pixi/utils": "^6.0.2", + "@tweenjs/tween.js": "^18.6.4" }, "devDependencies": { "@wordpress/scripts": "^14.1.0", @@ -2046,6 +2055,18 @@ "@pixi/utils": "6.0.2" } }, + "node_modules/@pixi/interaction": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@pixi/interaction/-/interaction-6.0.2.tgz", + "integrity": "sha512-YRT1reJXISgAf1+lRECpchR7+MUcGA/vdC612oG0fbrONCI0r1jMwMjdEcTnuMzZrzfSGL6yz0pkhIjWMjuY0g==", + "dependencies": { + "@pixi/core": "6.0.2", + "@pixi/display": "6.0.2", + "@pixi/math": "6.0.2", + "@pixi/ticker": "6.0.2", + "@pixi/utils": "6.0.2" + } + }, "node_modules/@pixi/math": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.0.2.tgz", @@ -2375,6 +2396,11 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@tweenjs/tween.js": { + "version": "18.6.4", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", + "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==" + }, "node_modules/@types/anymatch": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", @@ -24311,6 +24337,18 @@ "@pixi/utils": "6.0.2" } }, + "@pixi/interaction": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@pixi/interaction/-/interaction-6.0.2.tgz", + "integrity": "sha512-YRT1reJXISgAf1+lRECpchR7+MUcGA/vdC612oG0fbrONCI0r1jMwMjdEcTnuMzZrzfSGL6yz0pkhIjWMjuY0g==", + "requires": { + "@pixi/core": "6.0.2", + "@pixi/display": "6.0.2", + "@pixi/math": "6.0.2", + "@pixi/ticker": "6.0.2", + "@pixi/utils": "6.0.2" + } + }, "@pixi/math": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.0.2.tgz", @@ -24536,6 +24574,11 @@ "loader-utils": "^2.0.0" } }, + "@tweenjs/tween.js": { + "version": "18.6.4", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz", + "integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==" + }, "@types/anymatch": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", diff --git a/package.json b/package.json index 797b2aa..36a30e4 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,16 @@ }, "dependencies": { "@pixi/app": "^6.0.2", + "@pixi/constants": "^6.0.2", + "@pixi/core": "^6.0.2", "@pixi/display": "^6.0.2", - "@pixi/graphics": "^6.0.2" + "@pixi/graphics": "^6.0.2", + "@pixi/interaction": "^6.0.2", + "@pixi/math": "^6.0.2", + "@pixi/runner": "^6.0.2", + "@pixi/settings": "^6.0.2", + "@pixi/ticker": "^6.0.2", + "@pixi/utils": "^6.0.2", + "@tweenjs/tween.js": "^18.6.4" } } diff --git a/src/inc/pixel.js b/src/inc/pixel.js index da418f4..488a427 100644 --- a/src/inc/pixel.js +++ b/src/inc/pixel.js @@ -1,4 +1,5 @@ import * as PIXI from './../pixi.js'; +import TWEEN from '@tweenjs/tween.js'; /** * An object with some default parameters. @@ -9,6 +10,17 @@ const pixelDefaults = { color: 0xFFFFFF, } +/** + * Get a random integer bewtween min and max. + * + * @type {Function} + */ +const getRandomIntInclusive = (min, max) => { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min +1)) + min; +} + export default class W1Pixel extends PIXI.Graphics { /** @@ -26,13 +38,71 @@ export default class W1Pixel extends PIXI.Graphics { // Define the parameters and its defaults. this.params = Object.assign({}, pixelDefaults, params); - this.drawPixel( size ); + // Define the pixel size + this.pixelSize = size; + this.interactive = true; + + // Draw the pixel + this.drawPixel(); + + // Position the pixel this.x = x; this.y = y; + this.alpha = Math.random(); + this.duration = 5000 * ( getRandomIntInclusive(50, 100) / 100 ); + this.delay = this.duration * ( getRandomIntInclusive(0, 100) / 50 ); + + // Define the main tween + this.mainTween = new TWEEN.Tween(this); + this.mainTween.to({alpha: 0}, this.duration); + this.mainTween.repeat(Infinity); + this.mainTween.yoyo(true); + this.mainTween.delay(this.delay); + this.mainTween.repeatDelay(0); + this.mainTween.easing(TWEEN.Easing.Cubic.InOut) + this.mainTween.onUpdate((object) => { + this.updateTween(object); + }); + this.mainTween.onStart(() => { + this.currentTween = this.mainTween; + }); + + // Define the hover tween + this.hoverTween = new TWEEN.Tween(this); + this.hoverTween.to({alpha: 0}, this.duration * 2); + this.hoverTween.easing(TWEEN.Easing.Cubic.InOut) + this.hoverTween.onUpdate((object) => { + this.updateTween(object); + }); + this.hoverTween.onStart((tween) => { + this.currentTween = this.hoverTween; + }); + this.hoverTween.onComplete(() => { + this.mainTween.start(); + }); + + this.fade(); + + // Hover events + this.on( 'pointerover', function() { + this.currentTween.stop(); + this.alpha = 1; + this.hoverTween.start(); + }); + } + + drawPixel() { + this.clear(); + this.beginFill(this.params.color); + this.drawRect(0, 0, this.pixelSize, this.pixelSize); + } + + updateTween( object ) { + this.alpha = object.alpha; } - drawPixel( size ) { - this.beginFill(this.params.color, Math.random()); - this.drawRect(0, 0, size, size); + fade() { + this.mainTween.start(); + this.currentTween = this.mainTween; } } diff --git a/src/index.js b/src/index.js index 43250be..3b8e89c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ // Import external dependencies. import * as PIXI from './pixi.js'; +import TWEEN from '@tweenjs/tween.js'; // Import internal dependencies. import W1Pixel from './inc/pixel'; @@ -8,7 +9,7 @@ import W1Pixel from './inc/pixel'; // This should ideally be externalised and be modified by a window object. const options = { selectorClassName: 'w1-pixel-stage', - pixelSize: 20, // The default size of one pixel. + pixelSize: 200, // The default size of one pixel. overflow: false, // If we want to draw pixel over the edge of the stage. vAlign: 'center', // top, center, bottom hAlign: 'center', // left, center, right @@ -18,6 +19,8 @@ const options = { window.addEventListener( 'load', function( event ) { const elements = document.getElementsByClassName( options.selectorClassName ); Array.from( elements ).forEach( ( element ) => { + element.classList.add( options.selectorClassName + '-loading' ); + // Generate the PIXI app and add it to the DOMElement. const app = new PIXI.Application( { resizeTo: element, @@ -63,5 +66,13 @@ window.addEventListener( 'load', function( event ) { } else if ( options.hAlign === 'right' ) { container.x = (app.renderer.view.width - container.width); } + + element.classList.remove( options.selectorClassName + '-loading' ); + element.classList.add( options.selectorClassName + '-loaded' ); + } ); + + const ticker = PIXI.Ticker.shared; + ticker.add( () => { + TWEEN.update(); } ); }); diff --git a/src/pixi.js b/src/pixi.js index a398e92..5a2434f 100644 --- a/src/pixi.js +++ b/src/pixi.js @@ -1,3 +1,9 @@ +/** + * Define the pixi dependencies. + * + * @see https://pixijs.io/customize/ + */ + export * from '@pixi/constants'; export * from '@pixi/math'; export * from '@pixi/runner'; @@ -9,11 +15,14 @@ export * from '@pixi/display'; export * from '@pixi/core'; export * from '@pixi/app'; export * from '@pixi/graphics'; +export * from '@pixi/interaction'; // Renderer plugins import { Renderer } from '@pixi/core'; import { BatchRenderer } from '@pixi/core'; Renderer.registerPlugin('batch', BatchRenderer); +import { InteractionManager } from '@pixi/interaction'; +Renderer.registerPlugin('interaction', InteractionManager); // Application plugins import { Application } from '@pixi/app';