├── .babelrc ├── .gitignore ├── LICENSE ├── README.md ├── build ├── tiny.base.js ├── tiny.js └── tiny.mini.js ├── examples ├── index.html ├── js │ ├── App2D.js │ ├── App3D.js │ ├── objects │ │ └── MiniMap.js │ └── particles │ │ ├── Confetti.js │ │ ├── Explode.js │ │ ├── Firework.js │ │ ├── Ribbon.js │ │ └── Smoke.js ├── jsm │ └── particles │ │ ├── Confetti.js │ │ ├── Explode.js │ │ ├── ExplodingConfetti.js │ │ ├── Firework.js │ │ ├── MoneyFalling.js │ │ ├── Ribbon.js │ │ └── Smoke.js ├── libs │ ├── GLTFLoader.js │ ├── ace │ │ ├── ace.js │ │ ├── ext-keybinding_menu.js │ │ ├── ext-language_tools.js │ │ ├── ext-options.js │ │ ├── ext-prompt.js │ │ ├── ext-searchbox.js │ │ ├── ext-settings_menu.js │ │ ├── ext-spellcheck.js │ │ ├── keybinding-sublime.js │ │ ├── mode-javascript.js │ │ ├── snippets │ │ │ └── javascript.js │ │ ├── theme-monokai.js │ │ └── worker-javascript.js │ ├── howler.js │ ├── three.min.js │ └── tiny │ │ ├── plugins │ │ ├── anim.js │ │ ├── create.js │ │ ├── extra.js │ │ ├── particles.js │ │ ├── sound.js │ │ ├── three.js │ │ └── three.js.LICENSE.txt │ │ ├── tiny.js │ │ ├── tiny.js.LICENSE.txt │ │ ├── tiny.mini.js │ │ └── tiny.mini.js.LICENSE.txt ├── res │ ├── image.png │ ├── image2.png │ ├── resources.js │ ├── script.js │ └── style.css └── tests │ ├── AnimKeyframes.js │ ├── AnimSpritesheet.js │ ├── Basic.js │ ├── BlendMode.js │ ├── CreateSpritesheet.js │ ├── DemoInfinityWorm.js │ ├── Extended.js │ ├── Graphics.js │ ├── Graphics2.js │ ├── Input.js │ ├── Particles1.js │ ├── Particles2.js │ ├── ProgressBar.js │ ├── RenderLayer.js │ ├── RendererTexture.js │ ├── Sound.js │ ├── ThreeBasic.js │ ├── ThreeCanvas.js │ ├── ThreeScreen2D.js │ ├── TilingSprite.js │ └── Tweens.js ├── package.json ├── plugins ├── anim │ ├── Anim.js │ ├── AnimationManager.js │ ├── KeyframesAnim.js │ ├── Loader.js │ ├── SpritesheetAnim.js │ └── index.js ├── create │ ├── index.js │ └── spritesheet.js ├── extra │ ├── index.js │ ├── math │ │ └── Ellipse.js │ ├── objects │ │ ├── Button.js │ │ ├── Object2D.js │ │ ├── Opaque.js │ │ ├── ProgressBar.js │ │ ├── RenderLayer.js │ │ └── TilingSprite.js │ ├── systems │ │ ├── Loader.js │ │ └── Tween.js │ └── textures │ │ └── Texture.js ├── particles │ ├── Emitter.js │ ├── Particle.js │ └── index.js ├── sound │ └── index.js └── three │ ├── index.js │ ├── objects │ ├── Canvas2D.js │ ├── Canvas3D.js │ ├── Screen2D.js │ └── Text3D.js │ └── systems │ ├── Input.js │ └── Loader.js ├── src ├── App.js ├── base.js ├── global.js ├── index.js ├── math │ ├── Circle.js │ ├── Math.js │ ├── Matrix.js │ ├── Point.js │ ├── Polygon.js │ ├── Rectangle.js │ └── RoundedRectangle.js ├── mini.js ├── objects │ ├── BaseObject2D.js │ ├── Graphics.js │ ├── Object2D.js │ ├── Scene.js │ ├── Sprite.js │ └── Text.js ├── renderers │ ├── CanvasMaskManager.js │ ├── CanvasRenderer.js │ ├── CanvasTinter.js │ └── GraphicsRenderer.js ├── systems │ ├── Input.js │ ├── Loader.js │ ├── RAF.js │ ├── Timer.js │ └── Tween.js ├── textures │ ├── RenderTexture.js │ └── Texture.js └── utils │ ├── CanvasBuffer.js │ ├── EventEmitter.js │ └── polyfill.js ├── webpack.build.js └── webpack.dev.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | npm-debug.log 4 | .idea 5 | package-lock.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2018 GREEN PANDA GAMES. ALL RIGHTS RESERVED. -------------------------------------------------------------------------------- /examples/js/App2D.js: -------------------------------------------------------------------------------- 1 | class App2D extends Tiny.App { 2 | constructor(width, height, parentNode, states) { 3 | super(states); 4 | 5 | this.width = width; 6 | this.height = height; 7 | 8 | this.renderer = new Tiny.CanvasRenderer(this.width, this.height, { 9 | resolution: 1.25, 10 | autoResize: true 11 | }); 12 | 13 | this.renderer.setClearColor("#f4f4f4"); 14 | 15 | var view = (this.inputView = this.renderer.domElement); 16 | 17 | parentNode = parentNode ? document.getElementById(parentNode) : document.body; 18 | parentNode.appendChild(view); 19 | // view.style.position = 'absolute'; 20 | 21 | // view.style.top = "0px"; 22 | // view.style.left = "0px"; 23 | 24 | // view.style.transformOrigin = '0% 0%'; 25 | view.style.perspective = "1000px"; 26 | 27 | this.scene = new Tiny.Scene(); 28 | } 29 | 30 | setPixelRatio(dpr) { 31 | this.renderer.setPixelRatio(dpr); 32 | } 33 | 34 | render() { 35 | this.renderer.render(this.scene); 36 | } 37 | 38 | resize(width, height) { 39 | super.resize(width, height); 40 | 41 | this.renderer.resize(width, height); 42 | } 43 | 44 | destroy(clearCache) { 45 | super.destroy(clearCache); 46 | 47 | this.scene.destroy(); 48 | this.renderer.destroy(true); 49 | } 50 | } 51 | 52 | Tiny.App2D = App2D; 53 | -------------------------------------------------------------------------------- /examples/js/App3D.js: -------------------------------------------------------------------------------- 1 | class App3D extends Tiny.App { 2 | constructor(width, height, parentNode, states) { 3 | super(states); 4 | 5 | this.width = width; 6 | this.height = height; 7 | 8 | this.renderer = new THREE.WebGLRenderer({ 9 | antialias: true 10 | }); 11 | 12 | this.renderer.outputEncoding = THREE.sRGBEncoding; 13 | 14 | this.renderer.setSize(this.width, this.height); 15 | this.renderer.setClearColor("#232323"); 16 | 17 | var view = (this.canvas = this.inputView = this.renderer.domElement); 18 | 19 | parentNode = parentNode ? document.getElementById(parentNode) : document.body; 20 | parentNode.appendChild(view); 21 | // view.style.position = 'absolute'; 22 | 23 | // view.style.top = "0px"; 24 | // view.style.left = "0px"; 25 | 26 | // view.style.transformOrigin = '0% 0%'; 27 | view.style.perspective = "1000px"; 28 | 29 | this.scene = new THREE.Scene(); 30 | this.camera = new THREE.OrthographicCamera(1, 1, 1, 1, 0.3, 500); 31 | // this.camera = new PerspectiveCamera(50, window.innerWidth/window.innerHeight, 0.1, 1000); 32 | 33 | this.camera.position.set(40, 50, 40); 34 | this.camera.lookAt(0, 0, 0); 35 | this.camera.distance = 4; 36 | 37 | this.screen2d = new Tiny.Screen2D(this.width, this.height); 38 | 39 | this.setupCamera(); 40 | } 41 | 42 | setupCamera() { 43 | if (this.camera) { 44 | var aspect = this.width / this.height; 45 | var distance = this.camera.distance; 46 | 47 | if (this.camera.isOrthographicCamera) { 48 | this.camera.left = -distance * aspect; 49 | this.camera.right = distance * aspect; 50 | this.camera.top = distance; 51 | this.camera.bottom = -distance; 52 | } else { 53 | this.camera.fov = distance * 1.2; 54 | this.camera.aspect = aspect; 55 | } 56 | 57 | this.camera.updateProjectionMatrix(); 58 | } 59 | } 60 | 61 | setPixelRatio(dpr) { 62 | this.renderer.setPixelRatio(dpr); 63 | this.screen2d.renderer.setPixelRatio(dpr); 64 | } 65 | 66 | render() { 67 | this.renderer.autoClear = true; 68 | this.renderer.render(this.scene, this.camera); 69 | this.renderer.autoClear = false; 70 | this.renderer.render(this.screen2d.scene, this.screen2d.camera); 71 | } 72 | 73 | resize(width, height) { 74 | super.resize(width, height); 75 | 76 | this.screen2d.setSize(width, height); 77 | this.renderer.setSize(width, height); 78 | this.setupCamera(); 79 | } 80 | 81 | destroy(clearCache) { 82 | super.destroy(clearCache); 83 | 84 | // console.log("dasdasd") 85 | 86 | this.screen2d.scene.dispose(); 87 | this.scene.dispose(); 88 | // this.ui_scene = null; 89 | // this.ui_camera = null; 90 | // this.ui_sprite = this.ui_texture = null; 91 | 92 | if (this.renderer.domElement.parentNode) { 93 | this.renderer.domElement.parentNode.removeChild(this.renderer.domElement); 94 | } 95 | 96 | this.renderer.dispose(); 97 | this.renderer = undefined; 98 | } 99 | } 100 | 101 | Tiny.App3D = App3D; 102 | -------------------------------------------------------------------------------- /examples/js/objects/MiniMap.js: -------------------------------------------------------------------------------- 1 | class MiniMap extends Tiny.Sprite { 2 | constructor(game, resolution) { 3 | var texture = new Tiny.RenderTexture(game.width, game.height, null, resolution || 1); 4 | 5 | super(texture); 6 | this.game = game; 7 | this.scene = game.scene; 8 | this.texture = texture; 9 | this.delay = 100; 10 | this._timer = this.delay; 11 | 12 | this.frames = new Tiny.Graphics(); 13 | this.updateFrames(); 14 | 15 | this.anchor.y = 1; 16 | this.scale.set(0.3); 17 | this.alpha = 0.7; 18 | // this.width = 150; 19 | // this.height = 100; 20 | this.y = game.height; 21 | this.x = 0; 22 | 23 | this._update(); 24 | } 25 | 26 | updateFrames() { 27 | this.frames.clear(); 28 | this.frames.beginFill("#000000", 0.2); 29 | this.frames.drawRect(0, 0, this.game.width, this.game.height); 30 | this.frames.endFill(); 31 | this.frames.lineStyle(15, "#000000", 0.7); 32 | this.frames.drawRect(0, 0, this.game.width, this.game.height); 33 | } 34 | 35 | resize(width, height) { 36 | this.texture.resize(width, height); 37 | this.y = height; 38 | 39 | this.updateFrames(); 40 | 41 | this._update(); 42 | } 43 | 44 | _update() { 45 | this.visible = false; 46 | this.texture.render(this.scene, null, true); 47 | this.texture.render(this.frames); 48 | this.visible = true; 49 | } 50 | 51 | update(delta) { 52 | this._timer -= delta; 53 | if (this._timer < 0) { 54 | this._timer = this.delay; 55 | this._update(); 56 | } 57 | } 58 | } 59 | 60 | Tiny.MiniMap = MiniMap; 61 | 62 | class RecursiveSprite extends Tiny.Sprite { 63 | constructor(game, resolution) { 64 | var texture = new Tiny.RenderTexture(game.width, game.height, null, resolution || 1); 65 | 66 | super(texture); 67 | this.game = game; 68 | this.scene = game.scene; 69 | this.texture = texture; 70 | this.delay = 1; 71 | this._timer = this.delay; 72 | this.clearAlpha = 0.1; 73 | 74 | this.frames = new Tiny.Graphics(); 75 | this.updateFrames(); 76 | 77 | this.scale.set(0.98); 78 | this.alpha = 0.9; 79 | 80 | this.setCenter(0, 0); 81 | 82 | this._update(); 83 | } 84 | 85 | setCenter(x, y) { 86 | this.anchor.set(x, y); 87 | this.x = this.game.width * x; 88 | this.y = this.game.height * y; 89 | } 90 | 91 | updateFrames() { 92 | this.frames.clear(); 93 | this.frames.beginFill(this.game.renderer.clearColor, this.clearAlpha); 94 | this.frames.drawRect(0, 0, this.game.width, this.game.height); 95 | this.frames.endFill(); 96 | // this.frames.lineStyle(15, "#000000", 0.2); 97 | // this.frames.drawRect(0, 0, this.game.width, this.game.height); 98 | } 99 | 100 | resize(width, height) { 101 | this.texture.resize(width, height); 102 | this.x = width * this.anchor.x; 103 | this.y = height * this.anchor.y; 104 | 105 | this.updateFrames(); 106 | 107 | this._update(); 108 | } 109 | 110 | _update() { 111 | // this.visible = false; 112 | this.texture.render(this.scene); 113 | this.frames && this.texture.render(this.frames); 114 | // this.visible = true; 115 | } 116 | 117 | update(delta) { 118 | this._timer -= delta; 119 | if (this._timer < 0) { 120 | this._timer = this.delay; 121 | this._update(); 122 | } 123 | } 124 | } 125 | 126 | Tiny.RecursiveSprite = RecursiveSprite; 127 | -------------------------------------------------------------------------------- /examples/js/particles/Confetti.js: -------------------------------------------------------------------------------- 1 | var PI = Math.PI, 2 | random = Math.random, 3 | cos = Math.cos, 4 | sin = Math.sin; 5 | 6 | var DEG_TO_RAD = PI / 180, 7 | colors = [ 8 | ["#df0049", "#660671"], 9 | ["#00e857", "#005291"], 10 | ["#2bebbc", "#05798a"], 11 | ["#ffd200", "#b06c00"] 12 | ]; 13 | 14 | Tiny.ConfettiParticle = function (emitter) { 15 | Tiny.Particle.call(this, emitter); 16 | 17 | this.rotationSpeed = random() * 600 + 800; 18 | var angle = DEG_TO_RAD * random() * 360; 19 | this.rotationpart = DEG_TO_RAD * random() * 360; 20 | this.cosA = 1.0; 21 | this.size = 10.0; 22 | this.oscillationSpeed = random() * 1.5 + 0.5; 23 | this.xSpeed = 80.0; 24 | this.ySpeed = random() * 60 + 50.0; 25 | this.corners = new Array(); 26 | this.time = random(); 27 | var ci = Math.round(random() * (colors.length - 1)); 28 | this.frontColor = colors[ci][0]; 29 | this.backColor = colors[ci][1]; 30 | for (var i = 0; i < 4; i++) { 31 | var dx = cos(angle + DEG_TO_RAD * (i * 90 + 45)); 32 | var dy = sin(angle + DEG_TO_RAD * (i * 90 + 45)); 33 | this.corners[i] = { x: dx, y: dy }; 34 | } 35 | }; 36 | 37 | Tiny.ConfettiParticle.prototype = Object.create(Tiny.Particle.prototype); 38 | Tiny.ConfettiParticle.prototype.constructor = Tiny.ConfettiParticle; 39 | 40 | Tiny.ConfettiParticle.prototype._update = function (delta) { 41 | if (this.visible === false) return false; 42 | 43 | this.lifespan -= delta; 44 | 45 | if (this.lifespan <= 0) { 46 | this.visible = false; 47 | return false; 48 | } 49 | 50 | delta = delta * 0.001; 51 | 52 | this.time += delta; 53 | this.rotationpart += this.rotationSpeed * delta; 54 | this.cosA = cos(DEG_TO_RAD * this.rotationpart); 55 | this.x += cos(this.time * this.oscillationSpeed) * this.xSpeed * delta; 56 | this.y += this.ySpeed * delta; 57 | }; 58 | 59 | var _g, _res; 60 | 61 | Tiny.ConfettiParticle.prototype.render = function (renderSession) { 62 | if (this.visible === false || this.alpha === 0) return; 63 | 64 | _g = renderSession.context; 65 | _res = renderSession.resolution; 66 | 67 | if (this.cosA > 0) { 68 | _g.fillStyle = this.frontColor; 69 | } else { 70 | _g.fillStyle = this.backColor; 71 | } 72 | _g.beginPath(); 73 | _g.moveTo( 74 | (this.x + this.corners[0].x * this.size) * _res, 75 | (this.y + this.corners[0].y * this.size * this.cosA) * _res 76 | ); 77 | for (var i = 1; i < 4; i++) { 78 | _g.lineTo( 79 | (this.x + this.corners[i].x * this.size) * _res, 80 | (this.y + this.corners[i].y * this.size * this.cosA) * _res 81 | ); 82 | } 83 | _g.closePath(); 84 | _g.fill(); 85 | }; 86 | -------------------------------------------------------------------------------- /examples/js/particles/Explode.js: -------------------------------------------------------------------------------- 1 | Tiny.ExplodeParticle = function (emitter) { 2 | Tiny.Particle.call(this, emitter); 3 | }; 4 | 5 | Tiny.ExplodeParticle.prototype = Object.create(Tiny.Particle.prototype); 6 | Tiny.ExplodeParticle.prototype.constructor = Tiny.ExplodeParticle; 7 | 8 | Tiny.ExplodeParticle.prototype.update = function (time, delta) { 9 | var scale = Math.min(time / 200, 1); 10 | this.scale.set(scale * scale * scale * scale); 11 | this.alpha = Math.min(time / 250, 1); 12 | 13 | var speed = scale * scale * scale * scale * 5; 14 | 15 | this.x += this.xspeed * speed; 16 | this.y += this.yspeed * speed; 17 | }; 18 | 19 | Tiny.ExplodeParticle.prototype.onEmit = function () { 20 | var randAgle = Math.random() * Math.PI * 2; 21 | 22 | var rand_speed = Math.random() * 3; 23 | 24 | this.xspeed = Math.sin(randAgle) * rand_speed; 25 | this.yspeed = Math.cos(randAgle) * rand_speed; 26 | 27 | this.x = this.xspeed * Math.random() * 3; 28 | this.y = this.yspeed * Math.random() * 3; 29 | }; 30 | 31 | Tiny.ExplodeParticle.prototype.draw = function (context, resolution) { 32 | context.beginPath(); 33 | context.arc(0, 0, 20 * resolution, 0, 2 * Math.PI, false); 34 | context.fill(); 35 | }; 36 | -------------------------------------------------------------------------------- /examples/js/particles/Firework.js: -------------------------------------------------------------------------------- 1 | Tiny.FireworkParticle = function (emitter) { 2 | Tiny.Particle.call(this, emitter); 3 | }; 4 | 5 | Tiny.FireworkParticle.prototype = Object.create(Tiny.Particle.prototype); 6 | Tiny.FireworkParticle.prototype.constructor = Tiny.FireworkParticle; 7 | 8 | var normTime, speed; 9 | 10 | Tiny.FireworkParticle.prototype.update = function (time, delta) { 11 | normTime = time / this.maxlifespan; 12 | 13 | this.scale.set(Math.tan(normTime * normTime)); 14 | 15 | this.alpha = Math.min(Math.tan(normTime), 1); 16 | 17 | speed = normTime * normTime * normTime * 10; 18 | 19 | this.x += this.xspeed * speed * delta * normTime; 20 | this.y += this.yspeed * speed * delta + normTime * 0.8 * delta; 21 | }; 22 | 23 | Tiny.FireworkParticle.prototype.onEmit = function () { 24 | var randAgle = Math.random() * Math.PI * 2; 25 | 26 | var rand_speed = Math.random() * 3; 27 | 28 | this.maxlifespan = this.lifespan; 29 | 30 | this.xspeed = Math.sin(randAgle) * rand_speed * 0.05; 31 | this.yspeed = Math.cos(randAgle) * rand_speed * 0.05; 32 | }; 33 | 34 | Tiny.FireworkParticle.prototype.draw = function (context, resolution) { 35 | context.beginPath(); 36 | context.arc(0, 0, 20 * resolution, 0, 2 * Math.PI, false); 37 | context.fill(); 38 | }; 39 | -------------------------------------------------------------------------------- /examples/js/particles/Smoke.js: -------------------------------------------------------------------------------- 1 | Tiny.SmokeParticle = function (emitter) { 2 | Tiny.Particle.call(this, emitter); 3 | }; 4 | 5 | Tiny.SmokeParticle.prototype = Object.create(Tiny.Particle.prototype); 6 | Tiny.SmokeParticle.prototype.constructor = Tiny.SmokeParticle; 7 | 8 | Tiny.SmokeParticle.prototype.update = function (time, delta) { 9 | this.scale.set(Math.min(time / 1000, 0.7)); 10 | this.alpha = Math.min(time / 1000, 1); 11 | 12 | this.y -= this.yspeed * delta; 13 | this.x += this.xspeed * delta; 14 | this.rotation += this.rotationsp; 15 | }; 16 | 17 | Tiny.SmokeParticle.prototype.onEmit = function () { 18 | this.xspeed = Tiny.rnd(-4, 4) * 0.05; 19 | this.yspeed = Tiny.rnd(2, 10) * 0.05; 20 | this.rotationsp = Math.random() * 0.02 - 0.01; 21 | }; 22 | 23 | Tiny.SmokeParticle.prototype.draw = function (context, resolution) { 24 | //context.fillRect(0, 0, 100, 100) 25 | 26 | context.beginPath(); 27 | context.arc(0, 0, 100 * resolution, 0, 2 * Math.PI, false); 28 | context.fill(); 29 | }; 30 | -------------------------------------------------------------------------------- /examples/jsm/particles/Confetti.js: -------------------------------------------------------------------------------- 1 | var PI = Math.PI, 2 | random = Math.random, 3 | cos = Math.cos, 4 | sin = Math.sin; 5 | 6 | var DEG_TO_RAD = PI / 180, 7 | colors = [ 8 | ["#df0049", "#660671"], 9 | ["#00e857", "#005291"], 10 | ["#2bebbc", "#05798a"], 11 | ["#ffd200", "#b06c00"] 12 | ]; 13 | 14 | var _g, _res; 15 | 16 | export default class ConfettiParticle extends Tiny.Particle { 17 | constructor(emitter) { 18 | super(emitter); 19 | 20 | this.rotationSpeed = random() * 600 + 800; 21 | var angle = DEG_TO_RAD * random() * 360; 22 | this.rotationpart = DEG_TO_RAD * random() * 360; 23 | this.cosA = 1.0; 24 | this.size = 10.0; 25 | this.oscillationSpeed = random() * 1.5 + 0.5; 26 | this.xSpeed = 80.0; 27 | this.ySpeed = random() * 60 + 50.0; 28 | this.corners = new Array(); 29 | this.time = random(); 30 | var ci = Math.round(random() * (colors.length - 1)); 31 | this.frontColor = colors[ci][0]; 32 | this.backColor = colors[ci][1]; 33 | for (var i = 0; i < 4; i++) { 34 | var dx = cos(angle + DEG_TO_RAD * (i * 90 + 45)); 35 | var dy = sin(angle + DEG_TO_RAD * (i * 90 + 45)); 36 | this.corners[i] = { x: dx, y: dy }; 37 | } 38 | } 39 | 40 | _update(delta) { 41 | if (this.visible === false) return false; 42 | 43 | this.lifespan -= delta; 44 | 45 | if (this.lifespan <= 0) { 46 | this.visible = false; 47 | return false; 48 | } 49 | 50 | delta = delta * 0.001; 51 | 52 | this.time += delta; 53 | this.rotationpart += this.rotationSpeed * delta; 54 | this.cosA = cos(DEG_TO_RAD * this.rotationpart); 55 | this.x += cos(this.time * this.oscillationSpeed) * this.xSpeed * delta; 56 | this.y += this.ySpeed * delta; 57 | } 58 | 59 | render(renderSession) { 60 | if (this.visible === false || this.alpha === 0) return; 61 | 62 | _g = renderSession.context; 63 | _res = renderSession.resolution; 64 | 65 | if (this.cosA > 0) { 66 | _g.fillStyle = this.frontColor; 67 | } else { 68 | _g.fillStyle = this.backColor; 69 | } 70 | _g.beginPath(); 71 | _g.moveTo( 72 | (this.x + this.corners[0].x * this.size) * _res, 73 | (this.y + this.corners[0].y * this.size * this.cosA) * _res 74 | ); 75 | for (var i = 1; i < 4; i++) { 76 | _g.lineTo( 77 | (this.x + this.corners[i].x * this.size) * _res, 78 | (this.y + this.corners[i].y * this.size * this.cosA) * _res 79 | ); 80 | } 81 | _g.closePath(); 82 | _g.fill(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /examples/jsm/particles/Explode.js: -------------------------------------------------------------------------------- 1 | export default class ExplodeParticle extends Tiny.Particle { 2 | constructor(emitter) { 3 | super(emitter); 4 | } 5 | 6 | update(time, delta) { 7 | var scale = Math.min(time / 200, 1); 8 | this.scale.set(scale * scale * scale * scale); 9 | this.alpha = Math.min(time / 250, 1); 10 | 11 | var speed = scale * scale * scale * scale * 5; 12 | 13 | this.x += this.xspeed * speed; 14 | this.y += this.yspeed * speed; 15 | } 16 | 17 | onEmit() { 18 | var randAgle = Math.random() * Math.PI * 2; 19 | 20 | var rand_speed = Math.random() * 3; 21 | 22 | this.xspeed = Math.sin(randAgle) * rand_speed; 23 | this.yspeed = Math.cos(randAgle) * rand_speed; 24 | 25 | this.x = this.xspeed * Math.random() * 3; 26 | this.y = this.yspeed * Math.random() * 3; 27 | } 28 | 29 | draw(context, resolution) { 30 | context.beginPath(); 31 | context.arc(0, 0, 20 * resolution, 0, 2 * Math.PI, false); 32 | context.fill(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /examples/jsm/particles/ExplodingConfetti.js: -------------------------------------------------------------------------------- 1 | const HALF_PI = Math.PI * 0.5; 2 | var timeStep = 1 / 60; 3 | var _g, _res, f, p, dx, dy; 4 | 5 | var Point = function (x, y) { 6 | this.x = x || 0; 7 | this.y = y || 0; 8 | }; 9 | 10 | Point.prototype.set = function (x, y) { 11 | this.x = x || 0; 12 | this.y = y || 0; 13 | }; 14 | 15 | var Ease = { 16 | inCubic: function (t, b, c, d) { 17 | t /= d; 18 | return c * t * t * t + b; 19 | }, 20 | outCubic: function (t, b, c, d) { 21 | t /= d; 22 | t--; 23 | return c * (t * t * t + 1) + b; 24 | }, 25 | inOutCubic: function (t, b, c, d) { 26 | t /= d / 2; 27 | if (t < 1) return (c / 2) * t * t * t + b; 28 | t -= 2; 29 | return (c / 2) * (t * t * t + 2) + b; 30 | }, 31 | inBack: function (t, b, c, d, s) { 32 | s = s || 1.70158; 33 | return c * (t /= d) * t * ((s + 1) * t - s) + b; 34 | } 35 | }; 36 | 37 | function cubeBezier(p0, c0, c1, p1, t) { 38 | var p = new Point(); 39 | var nt = 1 - t; 40 | 41 | p.x = nt * nt * nt * p0.x + 3 * nt * nt * t * c0.x + 3 * nt * t * t * c1.x + t * t * t * p1.x; 42 | p.y = nt * nt * nt * p0.y + 3 * nt * nt * t * c0.y + 3 * nt * t * t * c1.y + t * t * t * p1.y; 43 | 44 | return p; 45 | } 46 | 47 | export default class ExplodingConfettiParticle extends Tiny.Particle { 48 | constructor(emitter) { 49 | super(emitter); 50 | 51 | this.duration = 3 + Math.random() * 2; 52 | this.color = "#" + Math.floor(Math.random() * 0xffffff).toString(16); 53 | 54 | this.p_w = 18; 55 | this.p_h = 16; 56 | 57 | this.p0 = new Point(0, 0); // Start point 58 | 59 | this.p1 = new Point(); 60 | this.p2 = new Point(); 61 | this.p3 = new Point(); 62 | } 63 | 64 | onEmit() { 65 | this.position.set(0); 66 | 67 | this.time = 0; 68 | 69 | this.p1.set( 70 | this.p0.x - this.parent.width + this.parent.width * 2 * Math.random(), 71 | this.p0.y - this.parent.height / 2 + this.parent.height * Math.random() 72 | ); 73 | this.p2.set( 74 | this.p0.x - this.parent.width + this.parent.width * 2 * Math.random(), 75 | this.p0.y - this.parent.height / 2 + this.parent.height * Math.random() 76 | ); 77 | this.p3.set( 78 | this.p0.x - this.parent.width + this.parent.width * 2 * Math.random(), 79 | this.p0.y - this.parent.height / 2 + this.parent.height * 2 80 | ); 81 | } 82 | 83 | _update(delta) { 84 | if (this.visible === false) return false; 85 | 86 | this.lifespan -= delta; 87 | 88 | if (this.lifespan <= 0) { 89 | this.visible = false; 90 | return false; 91 | } 92 | 93 | this.time = Math.min(this.duration, this.time + timeStep); 94 | 95 | f = Ease.outCubic(this.time, 0, 1, this.duration); 96 | p = cubeBezier(this.p0, this.p1, this.p2, this.p3, f); 97 | 98 | dx = p.x - this.x; 99 | dy = p.y - this.y; 100 | 101 | this.rotation = Math.atan2(dy, dx) + HALF_PI; 102 | this.scale.y = Math.sin(Math.PI * f * 10); 103 | this.position.x = p.x; 104 | this.position.y = p.y; 105 | } 106 | 107 | render(renderSession) { 108 | if (this.visible === false || this.alpha === 0) return; 109 | 110 | _g = renderSession.context; 111 | _res = renderSession.resolution; 112 | 113 | _g.save(); 114 | _g.translate(this.position.x, this.position.y); 115 | _g.rotate(this.rotation); 116 | _g.scale(_res, this.scale.y * _res); 117 | 118 | _g.fillStyle = this.color; 119 | _g.fillRect(-this.p_w * 0.5, -this.p_h * 0.5, this.p_w * _res, this.p_h * _res); 120 | 121 | _g.restore(); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /examples/jsm/particles/Firework.js: -------------------------------------------------------------------------------- 1 | var normTime, speed; 2 | 3 | export default class FireworkParticle extends Tiny.Particle { 4 | constructor(emitter) { 5 | super(emitter); 6 | } 7 | 8 | update(time, delta) { 9 | normTime = time / this.maxlifespan; 10 | 11 | this.scale.set(Math.tan(normTime * normTime)); 12 | 13 | this.alpha = Math.min(Math.tan(normTime), 1); 14 | 15 | speed = normTime * normTime * normTime * 10; 16 | 17 | this.x += this.xspeed * speed * delta * normTime; 18 | this.y += this.yspeed * speed * delta + normTime * 10 * delta; 19 | } 20 | 21 | onEmit() { 22 | var randAgle = Math.random() * Math.PI * 2; 23 | 24 | var rand_speed = Math.random() * 3; 25 | 26 | this.maxlifespan = this.lifespan; 27 | 28 | this.xspeed = Math.sin(randAgle) * rand_speed * 0.05; 29 | this.yspeed = Math.cos(randAgle) * rand_speed * 0.05; 30 | } 31 | 32 | draw(context, resolution) { 33 | context.beginPath(); 34 | context.arc(0, 0, 20 * resolution, 0, 2 * Math.PI, false); 35 | context.fill(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/jsm/particles/MoneyFalling.js: -------------------------------------------------------------------------------- 1 | var random = Math.random, 2 | cos = Math.cos, 3 | sin = Math.sin; 4 | 5 | export default class MoneyFallingParticle extends Tiny.Particle { 6 | constructor(emitter) { 7 | super(emitter); 8 | } 9 | 10 | onEmit() { 11 | this.tilt = Math.floor(random() * 10) - 10; 12 | this.tiltAngleIncremental = random() * 0.25 + 0.15 - 0.2; 13 | this.tiltAngle = 0; 14 | this.scale.set((random() * 0.4 + 0.6) / 2); 15 | this.angle = random() * 6.28; 16 | 17 | this.speed = random() * 1 + 0.5; 18 | } 19 | 20 | update(time, delta) { 21 | delta = delta * 0.001; 22 | this.angle += delta; 23 | this.tiltAngle += this.tiltAngleIncremental; 24 | this.y += ((cos(this.angle + 3) + 3 + 2 / 2) / 2) * delta * 100 * this.speed; 25 | this.x += sin(this.angle) * delta * 100 * this.speed; 26 | this.rotation = sin(this.tiltAngle) * 0.5 * this.speed; 27 | } 28 | 29 | render(renderSession) { 30 | if (this.visible === false || this.alpha === 0) return; 31 | 32 | renderSession.context.setTransform( 33 | this.worldTransform.a * cos(this.tiltAngle), 34 | this.worldTransform.b, 35 | this.worldTransform.c, 36 | this.worldTransform.d, 37 | this.worldTransform.tx * renderSession.resolution, 38 | this.worldTransform.ty * renderSession.resolution 39 | ); 40 | 41 | this.drawTexture(renderSession); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /examples/jsm/particles/Smoke.js: -------------------------------------------------------------------------------- 1 | export default class SmokeParticle extends Tiny.Particle { 2 | constructor(emitter) { 3 | super(emitter); 4 | } 5 | 6 | update(time, delta) { 7 | this.scale.set(Math.min(time / 1000, 0.7)); 8 | this.alpha = Math.min(time / 1000, 1); 9 | 10 | this.y -= this.yspeed * delta; 11 | this.x += this.xspeed * delta; 12 | this.rotation += this.rotationsp; 13 | } 14 | 15 | onEmit() { 16 | this.xspeed = Tiny.rnd(-4, 4) * 0.05; 17 | this.yspeed = Tiny.rnd(2, 10) * 0.05; 18 | this.rotationsp = Math.random() * 0.02 - 0.01; 19 | } 20 | 21 | draw(context, resolution) { 22 | context.fillRect(0, 0, 100 * resolution, 100 * resolution); 23 | 24 | // context.beginPath(); 25 | // context.arc(0, 0, 100, 0, 2 * Math.PI, false); 26 | // context.fill(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/libs/ace/ext-keybinding_menu.js: -------------------------------------------------------------------------------- 1 | define("ace/ext/menu_tools/settings_menu.css",["require","exports","module"],function(e,t,n){n.exports="#ace_settingsmenu, #kbshortcutmenu {\n background-color: #F7F7F7;\n color: black;\n box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55);\n padding: 1em 0.5em 2em 1em;\n overflow: auto;\n position: absolute;\n margin: 0;\n bottom: 0;\n right: 0;\n top: 0;\n z-index: 9991;\n cursor: default;\n}\n\n.ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu {\n box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25);\n background-color: rgba(255, 255, 255, 0.6);\n color: black;\n}\n\n.ace_optionsMenuEntry:hover {\n background-color: rgba(100, 100, 100, 0.1);\n transition: all 0.3s\n}\n\n.ace_closeButton {\n background: rgba(245, 146, 146, 0.5);\n border: 1px solid #F48A8A;\n border-radius: 50%;\n padding: 7px;\n position: absolute;\n right: -8px;\n top: -8px;\n z-index: 100000;\n}\n.ace_closeButton{\n background: rgba(245, 146, 146, 0.9);\n}\n.ace_optionsMenuKey {\n color: darkslateblue;\n font-weight: bold;\n}\n.ace_optionsMenuCommand {\n color: darkcyan;\n font-weight: normal;\n}\n.ace_optionsMenuEntry input, .ace_optionsMenuEntry button {\n vertical-align: middle;\n}\n\n.ace_optionsMenuEntry button[ace_selected_button=true] {\n background: #e7e7e7;\n box-shadow: 1px 0px 2px 0px #adadad inset;\n border-color: #adadad;\n}\n.ace_optionsMenuEntry button {\n background: white;\n border: 1px solid lightgray;\n margin: 0px;\n}\n.ace_optionsMenuEntry button:hover{\n background: #f0f0f0;\n}"}),define("ace/ext/menu_tools/overlay_page",["require","exports","module","ace/lib/dom","ace/ext/menu_tools/settings_menu.css"],function(e,t,n){"use strict";var r=e("../../lib/dom"),i=e("./settings_menu.css");r.importCssString(i,"settings_menu.css",!1),n.exports.overlayPage=function(t,n,r){function o(e){e.keyCode===27&&u()}function u(){if(!i)return;document.removeEventListener("keydown",o),i.parentNode.removeChild(i),t&&t.focus(),i=null,r&&r()}function a(e){s=e,e&&(i.style.pointerEvents="none",n.style.pointerEvents="auto")}var i=document.createElement("div"),s=!1;return i.style.cssText="margin: 0; padding: 0; position: fixed; top:0; bottom:0; left:0; right:0;z-index: 9990; "+(t?"background-color: rgba(0, 0, 0, 0.3);":""),i.addEventListener("click",function(e){s||u()}),document.addEventListener("keydown",o),n.addEventListener("click",function(e){e.stopPropagation()}),i.appendChild(n),document.body.appendChild(i),t&&t.blur(),{close:u,setIgnoreFocusOut:a}}}),define("ace/ext/menu_tools/get_editor_keyboard_shortcuts",["require","exports","module","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../../lib/keys");n.exports.getEditorKeybordShortcuts=function(e){var t=r.KEY_MODS,n=[],i={};return e.keyBinding.$handlers.forEach(function(e){var t=e.commandKeyBinding;for(var r in t){var s=r.replace(/(^|-)\w/g,function(e){return e.toUpperCase()}),o=t[r];Array.isArray(o)||(o=[o]),o.forEach(function(e){typeof e!="string"&&(e=e.name),i[e]?i[e].key+="|"+s:(i[e]={key:s,command:e},n.push(i[e]))})}}),n}}),define("ace/ext/keybinding_menu",["require","exports","module","ace/editor","ace/ext/menu_tools/overlay_page","ace/ext/menu_tools/get_editor_keyboard_shortcuts"],function(e,t,n){"use strict";function i(t){if(!document.getElementById("kbshortcutmenu")){var n=e("./menu_tools/overlay_page").overlayPage,r=e("./menu_tools/get_editor_keyboard_shortcuts").getEditorKeybordShortcuts,i=r(t),s=document.createElement("div"),o=i.reduce(function(e,t){return e+'
'+t.command+" : "+''+t.key+"
"},"");s.id="kbshortcutmenu",s.innerHTML="

Keyboard Shortcuts

"+o+"",n(t,s)}}var r=e("../editor").Editor;n.exports.init=function(e){r.prototype.showKeyboardShortcuts=function(){i(this)},e.commands.addCommands([{name:"showKeyboardShortcuts",bindKey:{win:"Ctrl-Alt-h",mac:"Command-Alt-h"},exec:function(e,t){e.showKeyboardShortcuts()}}])}}); (function() { 2 | window.require(["ace/ext/keybinding_menu"], function(m) { 3 | if (typeof module == "object" && typeof exports == "object" && module) { 4 | module.exports = m; 5 | } 6 | }); 7 | })(); 8 | -------------------------------------------------------------------------------- /examples/libs/ace/ext-spellcheck.js: -------------------------------------------------------------------------------- 1 | define("ace/ext/spellcheck",["require","exports","module","ace/lib/event","ace/editor","ace/config"],function(e,t,n){"use strict";var r=e("../lib/event");t.contextMenuHandler=function(e){var t=e.target,n=t.textInput.getElement();if(!t.selection.isEmpty())return;var i=t.getCursorPosition(),s=t.session.getWordRange(i.row,i.column),o=t.session.getTextRange(s);t.session.tokenRe.lastIndex=0;if(!t.session.tokenRe.test(o))return;var u="\x01\x01",a=o+" "+u;n.value=a,n.setSelectionRange(o.length,o.length+1),n.setSelectionRange(0,0),n.setSelectionRange(0,o.length);var f=!1;r.addListener(n,"keydown",function l(){r.removeListener(n,"keydown",l),f=!0}),t.textInput.setInputHandler(function(e){if(e==a)return"";if(e.lastIndexOf(a,0)===0)return e.slice(a.length);if(e.substr(n.selectionEnd)==a)return e.slice(0,-a.length);if(e.slice(-2)==u){var r=e.slice(0,-2);if(r.slice(-1)==" ")return f?r.substring(0,n.selectionEnd):(r=r.slice(0,-1),t.session.replace(s,r),"")}return e})};var i=e("../editor").Editor;e("../config").defineOptions(i.prototype,"editor",{spellcheck:{set:function(e){var n=this.textInput.getElement();n.spellcheck=!!e,e?this.on("nativecontextmenu",t.contextMenuHandler):this.removeListener("nativecontextmenu",t.contextMenuHandler)},value:!0}})}); (function() { 2 | window.require(["ace/ext/spellcheck"], function(m) { 3 | if (typeof module == "object" && typeof exports == "object" && module) { 4 | module.exports = m; 5 | } 6 | }); 7 | })(); 8 | -------------------------------------------------------------------------------- /examples/libs/ace/snippets/javascript.js: -------------------------------------------------------------------------------- 1 | define("ace/snippets/javascript.snippets",["require","exports","module"],function(e,t,n){n.exports='# Prototype\nsnippet proto\n ${1:class_name}.prototype.${2:method_name} = function(${3:first_argument}) {\n ${4:// body...}\n };\n# Function\nsnippet fun\n function ${1?:function_name}(${2:argument}) {\n ${3:// body...}\n }\n# Anonymous Function\nregex /((=)\\s*|(:)\\s*|(\\()|\\b)/f/(\\))?/\nsnippet f\n function${M1?: ${1:functionName}}($2) {\n ${0:$TM_SELECTED_TEXT}\n }${M2?;}${M3?,}${M4?)}\n# Immediate function\ntrigger \\(?f\\(\nendTrigger \\)?\nsnippet f(\n (function(${1}) {\n ${0:${TM_SELECTED_TEXT:/* code */}}\n }(${1}));\n# if\nsnippet if\n if (${1:true}) {\n ${0}\n }\n# if ... else\nsnippet ife\n if (${1:true}) {\n ${2}\n } else {\n ${0}\n }\n# tertiary conditional\nsnippet ter\n ${1:/* condition */} ? ${2:a} : ${3:b}\n# switch\nsnippet switch\n switch (${1:expression}) {\n case \'${3:case}\':\n ${4:// code}\n break;\n ${5}\n default:\n ${2:// code}\n }\n# case\nsnippet case\n case \'${1:case}\':\n ${2:// code}\n break;\n ${3}\n\n# while (...) {...}\nsnippet wh\n while (${1:/* condition */}) {\n ${0:/* code */}\n }\n# try\nsnippet try\n try {\n ${0:/* code */}\n } catch (e) {}\n# do...while\nsnippet do\n do {\n ${2:/* code */}\n } while (${1:/* condition */});\n# Object Method\nsnippet :f\nregex /([,{[])|^\\s*/:f/\n ${1:method_name}: function(${2:attribute}) {\n ${0}\n }${3:,}\n# setTimeout function\nsnippet setTimeout\nregex /\\b/st|timeout|setTimeo?u?t?/\n setTimeout(function() {${3:$TM_SELECTED_TEXT}}, ${1:10});\n# Get Elements\nsnippet gett\n getElementsBy${1:TagName}(\'${2}\')${3}\n# Get Element\nsnippet get\n getElementBy${1:Id}(\'${2}\')${3}\n# console.log (Firebug)\nsnippet cl\n console.log(${1});\n# return\nsnippet ret\n return ${1:result}\n# for (property in object ) { ... }\nsnippet fori\n for (var ${1:prop} in ${2:Things}) {\n ${0:$2[$1]}\n }\n# hasOwnProperty\nsnippet has\n hasOwnProperty(${1})\n# docstring\nsnippet /**\n /**\n * ${1:description}\n *\n */\nsnippet @par\nregex /^\\s*\\*\\s*/@(para?m?)?/\n @param {${1:type}} ${2:name} ${3:description}\nsnippet @ret\n @return {${1:type}} ${2:description}\n# JSON.parse\nsnippet jsonp\n JSON.parse(${1:jstr});\n# JSON.stringify\nsnippet jsons\n JSON.stringify(${1:object});\n# self-defining function\nsnippet sdf\n var ${1:function_name} = function(${2:argument}) {\n ${3:// initial code ...}\n\n $1 = function($2) {\n ${4:// main code}\n };\n }\n# singleton\nsnippet sing\n function ${1:Singleton} (${2:argument}) {\n // the cached instance\n var instance;\n\n // rewrite the constructor\n $1 = function $1($2) {\n return instance;\n };\n \n // carry over the prototype properties\n $1.prototype = this;\n\n // the instance\n instance = new $1();\n\n // reset the constructor pointer\n instance.constructor = $1;\n\n ${3:// code ...}\n\n return instance;\n }\n# class\nsnippet class\nregex /^\\s*/clas{0,2}/\n var ${1:class} = function(${20}) {\n $40$0\n };\n \n (function() {\n ${60:this.prop = ""}\n }).call(${1:class}.prototype);\n \n exports.${1:class} = ${1:class};\n# \nsnippet for-\n for (var ${1:i} = ${2:Things}.length; ${1:i}--; ) {\n ${0:${2:Things}[${1:i}];}\n }\n# for (...) {...}\nsnippet for\n for (var ${1:i} = 0; $1 < ${2:Things}.length; $1++) {\n ${3:$2[$1]}$0\n }\n# for (...) {...} (Improved Native For-Loop)\nsnippet forr\n for (var ${1:i} = ${2:Things}.length - 1; $1 >= 0; $1--) {\n ${3:$2[$1]}$0\n }\n\n\n#modules\nsnippet def\n define(function(require, exports, module) {\n "use strict";\n var ${1/.*\\///} = require("${1}");\n \n $TM_SELECTED_TEXT\n });\nsnippet req\nguard ^\\s*\n var ${1/.*\\///} = require("${1}");\n $0\nsnippet requ\nguard ^\\s*\n var ${1/.*\\/(.)/\\u$1/} = require("${1}").${1/.*\\/(.)/\\u$1/};\n $0\n'}),define("ace/snippets/javascript",["require","exports","module","ace/snippets/javascript.snippets"],function(e,t,n){"use strict";t.snippetText=e("./javascript.snippets"),t.scope="javascript"}); (function() { 2 | window.require(["ace/snippets/javascript"], function(m) { 3 | if (typeof module == "object" && typeof exports == "object" && module) { 4 | module.exports = m; 5 | } 6 | }); 7 | })(); 8 | -------------------------------------------------------------------------------- /examples/libs/ace/theme-monokai.js: -------------------------------------------------------------------------------- 1 | define("ace/theme/monokai.css",["require","exports","module"],function(e,t,n){n.exports=".ace-monokai .ace_gutter {\n background: #2F3129;\n color: #8F908A\n}\n\n.ace-monokai .ace_print-margin {\n width: 1px;\n background: #555651\n}\n\n.ace-monokai {\n background-color: #272822;\n color: #F8F8F2\n}\n\n.ace-monokai .ace_cursor {\n color: #F8F8F0\n}\n\n.ace-monokai .ace_marker-layer .ace_selection {\n background: #49483E\n}\n\n.ace-monokai.ace_multiselect .ace_selection.ace_start {\n box-shadow: 0 0 3px 0px #272822;\n}\n\n.ace-monokai .ace_marker-layer .ace_step {\n background: rgb(102, 82, 0)\n}\n\n.ace-monokai .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid #49483E\n}\n\n.ace-monokai .ace_marker-layer .ace_active-line {\n background: #202020\n}\n\n.ace-monokai .ace_gutter-active-line {\n background-color: #272727\n}\n\n.ace-monokai .ace_marker-layer .ace_selected-word {\n border: 1px solid #49483E\n}\n\n.ace-monokai .ace_invisible {\n color: #52524d\n}\n\n.ace-monokai .ace_entity.ace_name.ace_tag,\n.ace-monokai .ace_keyword,\n.ace-monokai .ace_meta.ace_tag,\n.ace-monokai .ace_storage {\n color: #F92672\n}\n\n.ace-monokai .ace_punctuation,\n.ace-monokai .ace_punctuation.ace_tag {\n color: #fff\n}\n\n.ace-monokai .ace_constant.ace_character,\n.ace-monokai .ace_constant.ace_language,\n.ace-monokai .ace_constant.ace_numeric,\n.ace-monokai .ace_constant.ace_other {\n color: #AE81FF\n}\n\n.ace-monokai .ace_invalid {\n color: #F8F8F0;\n background-color: #F92672\n}\n\n.ace-monokai .ace_invalid.ace_deprecated {\n color: #F8F8F0;\n background-color: #AE81FF\n}\n\n.ace-monokai .ace_support.ace_constant,\n.ace-monokai .ace_support.ace_function {\n color: #66D9EF\n}\n\n.ace-monokai .ace_fold {\n background-color: #A6E22E;\n border-color: #F8F8F2\n}\n\n.ace-monokai .ace_storage.ace_type,\n.ace-monokai .ace_support.ace_class,\n.ace-monokai .ace_support.ace_type {\n font-style: italic;\n color: #66D9EF\n}\n\n.ace-monokai .ace_entity.ace_name.ace_function,\n.ace-monokai .ace_entity.ace_other,\n.ace-monokai .ace_entity.ace_other.ace_attribute-name,\n.ace-monokai .ace_variable {\n color: #A6E22E\n}\n\n.ace-monokai .ace_variable.ace_parameter {\n font-style: italic;\n color: #FD971F\n}\n\n.ace-monokai .ace_string {\n color: #E6DB74\n}\n\n.ace-monokai .ace_comment {\n color: #75715E\n}\n\n.ace-monokai .ace_indent-guide {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y\n}\n\n.ace-monokai .ace_indent-guide-active {\n background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQIW2PQ1dX9zzBz5sz/ABCcBFFentLlAAAAAElFTkSuQmCC) right repeat-y;\n}\n"}),define("ace/theme/monokai",["require","exports","module","ace/theme/monokai.css","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-monokai",t.cssText=e("./monokai.css");var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass,!1)}); (function() { 2 | window.require(["ace/theme/monokai"], function(m) { 3 | if (typeof module == "object" && typeof exports == "object" && module) { 4 | module.exports = m; 5 | } 6 | }); 7 | })(); 8 | -------------------------------------------------------------------------------- /examples/libs/tiny/plugins/three.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | //!\ DECLARE ALIAS AFTER assign prototype ! 2 | -------------------------------------------------------------------------------- /examples/libs/tiny/tiny.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! ./App.js */ 2 | 3 | /*! ./base.js */ 4 | 5 | /*! ./global.js */ 6 | 7 | /*! ./math/Circle.js */ 8 | 9 | /*! ./math/Math.js */ 10 | 11 | /*! ./math/Matrix.js */ 12 | 13 | /*! ./math/Point.js */ 14 | 15 | /*! ./math/Polygon.js */ 16 | 17 | /*! ./math/Rectangle.js */ 18 | 19 | /*! ./math/RoundedRectangle.js */ 20 | 21 | /*! ./mini.js */ 22 | 23 | /*! ./objects/BaseObject2D.js */ 24 | 25 | /*! ./objects/Graphics.js */ 26 | 27 | /*! ./objects/Object2D.js */ 28 | 29 | /*! ./objects/Scene.js */ 30 | 31 | /*! ./objects/Sprite.js */ 32 | 33 | /*! ./objects/Text.js */ 34 | 35 | /*! ./renderers/CanvasMaskManager.js */ 36 | 37 | /*! ./renderers/CanvasRenderer.js */ 38 | 39 | /*! ./renderers/CanvasTinter.js */ 40 | 41 | /*! ./renderers/GraphicsRenderer.js */ 42 | 43 | /*! ./systems/Input.js */ 44 | 45 | /*! ./systems/Loader.js */ 46 | 47 | /*! ./systems/RAF.js */ 48 | 49 | /*! ./systems/Timer.js */ 50 | 51 | /*! ./systems/Tween.js */ 52 | 53 | /*! ./textures/RenderTexture.js */ 54 | 55 | /*! ./textures/Texture.js */ 56 | 57 | /*! ./utils/CanvasBuffer.js */ 58 | 59 | /*! ./utils/EventEmitter.js */ 60 | 61 | /*! ./utils/polyfill.js */ 62 | 63 | /*!********************!*\ 64 | !*** ./src/App.js ***! 65 | \********************/ 66 | 67 | /*!*********************!*\ 68 | !*** ./src/base.js ***! 69 | \*********************/ 70 | 71 | /*!*********************!*\ 72 | !*** ./src/mini.js ***! 73 | \*********************/ 74 | 75 | /*!**********************!*\ 76 | !*** ./src/index.js ***! 77 | \**********************/ 78 | 79 | /*!***********************!*\ 80 | !*** ./src/global.js ***! 81 | \***********************/ 82 | 83 | /*!**************************!*\ 84 | !*** ./src/math/Math.js ***! 85 | \**************************/ 86 | 87 | /*!***************************!*\ 88 | !*** ./src/math/Point.js ***! 89 | \***************************/ 90 | 91 | /*!****************************!*\ 92 | !*** ./src/math/Circle.js ***! 93 | \****************************/ 94 | 95 | /*!****************************!*\ 96 | !*** ./src/math/Matrix.js ***! 97 | \****************************/ 98 | 99 | /*!****************************!*\ 100 | !*** ./src/systems/RAF.js ***! 101 | \****************************/ 102 | 103 | /*!*****************************!*\ 104 | !*** ./src/math/Polygon.js ***! 105 | \*****************************/ 106 | 107 | /*!*****************************!*\ 108 | !*** ./src/objects/Text.js ***! 109 | \*****************************/ 110 | 111 | /*!******************************!*\ 112 | !*** ./src/objects/Scene.js ***! 113 | \******************************/ 114 | 115 | /*!******************************!*\ 116 | !*** ./src/systems/Input.js ***! 117 | \******************************/ 118 | 119 | /*!******************************!*\ 120 | !*** ./src/systems/Timer.js ***! 121 | \******************************/ 122 | 123 | /*!******************************!*\ 124 | !*** ./src/systems/Tween.js ***! 125 | \******************************/ 126 | 127 | /*!*******************************!*\ 128 | !*** ./src/math/Rectangle.js ***! 129 | \*******************************/ 130 | 131 | /*!*******************************!*\ 132 | !*** ./src/objects/Sprite.js ***! 133 | \*******************************/ 134 | 135 | /*!*******************************!*\ 136 | !*** ./src/systems/Loader.js ***! 137 | \*******************************/ 138 | 139 | /*!*******************************!*\ 140 | !*** ./src/utils/polyfill.js ***! 141 | \*******************************/ 142 | 143 | /*!*********************************!*\ 144 | !*** ./src/objects/Graphics.js ***! 145 | \*********************************/ 146 | 147 | /*!*********************************!*\ 148 | !*** ./src/objects/Object2D.js ***! 149 | \*********************************/ 150 | 151 | /*!*********************************!*\ 152 | !*** ./src/textures/Texture.js ***! 153 | \*********************************/ 154 | 155 | /*!***********************************!*\ 156 | !*** ./src/utils/CanvasBuffer.js ***! 157 | \***********************************/ 158 | 159 | /*!***********************************!*\ 160 | !*** ./src/utils/EventEmitter.js ***! 161 | \***********************************/ 162 | 163 | /*!*************************************!*\ 164 | !*** ./src/objects/BaseObject2D.js ***! 165 | \*************************************/ 166 | 167 | /*!**************************************!*\ 168 | !*** ./src/math/RoundedRectangle.js ***! 169 | \**************************************/ 170 | 171 | /*!***************************************!*\ 172 | !*** ./src/renderers/CanvasTinter.js ***! 173 | \***************************************/ 174 | 175 | /*!***************************************!*\ 176 | !*** ./src/textures/RenderTexture.js ***! 177 | \***************************************/ 178 | 179 | /*!*****************************************!*\ 180 | !*** ./src/renderers/CanvasRenderer.js ***! 181 | \*****************************************/ 182 | 183 | /*!*******************************************!*\ 184 | !*** ./src/renderers/GraphicsRenderer.js ***! 185 | \*******************************************/ 186 | 187 | /*!********************************************!*\ 188 | !*** ./src/renderers/CanvasMaskManager.js ***! 189 | \********************************************/ 190 | -------------------------------------------------------------------------------- /examples/libs/tiny/tiny.mini.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /*! ./App.js */ 2 | 3 | /*! ./base.js */ 4 | 5 | /*! ./global.js */ 6 | 7 | /*! ./math/Math.js */ 8 | 9 | /*! ./math/Matrix.js */ 10 | 11 | /*! ./math/Point.js */ 12 | 13 | /*! ./math/Rectangle.js */ 14 | 15 | /*! ./objects/BaseObject2D.js */ 16 | 17 | /*! ./objects/Object2D.js */ 18 | 19 | /*! ./objects/Scene.js */ 20 | 21 | /*! ./objects/Sprite.js */ 22 | 23 | /*! ./objects/Text.js */ 24 | 25 | /*! ./renderers/CanvasRenderer.js */ 26 | 27 | /*! ./systems/Input.js */ 28 | 29 | /*! ./systems/Loader.js */ 30 | 31 | /*! ./systems/RAF.js */ 32 | 33 | /*! ./systems/Timer.js */ 34 | 35 | /*! ./textures/Texture.js */ 36 | 37 | /*! ./utils/EventEmitter.js */ 38 | 39 | /*! ./utils/polyfill.js */ 40 | 41 | /*!********************!*\ 42 | !*** ./src/App.js ***! 43 | \********************/ 44 | 45 | /*!*********************!*\ 46 | !*** ./src/base.js ***! 47 | \*********************/ 48 | 49 | /*!*********************!*\ 50 | !*** ./src/mini.js ***! 51 | \*********************/ 52 | 53 | /*!***********************!*\ 54 | !*** ./src/global.js ***! 55 | \***********************/ 56 | 57 | /*!**************************!*\ 58 | !*** ./src/math/Math.js ***! 59 | \**************************/ 60 | 61 | /*!***************************!*\ 62 | !*** ./src/math/Point.js ***! 63 | \***************************/ 64 | 65 | /*!****************************!*\ 66 | !*** ./src/math/Matrix.js ***! 67 | \****************************/ 68 | 69 | /*!****************************!*\ 70 | !*** ./src/systems/RAF.js ***! 71 | \****************************/ 72 | 73 | /*!*****************************!*\ 74 | !*** ./src/objects/Text.js ***! 75 | \*****************************/ 76 | 77 | /*!******************************!*\ 78 | !*** ./src/objects/Scene.js ***! 79 | \******************************/ 80 | 81 | /*!******************************!*\ 82 | !*** ./src/systems/Input.js ***! 83 | \******************************/ 84 | 85 | /*!******************************!*\ 86 | !*** ./src/systems/Timer.js ***! 87 | \******************************/ 88 | 89 | /*!*******************************!*\ 90 | !*** ./src/math/Rectangle.js ***! 91 | \*******************************/ 92 | 93 | /*!*******************************!*\ 94 | !*** ./src/objects/Sprite.js ***! 95 | \*******************************/ 96 | 97 | /*!*******************************!*\ 98 | !*** ./src/systems/Loader.js ***! 99 | \*******************************/ 100 | 101 | /*!*******************************!*\ 102 | !*** ./src/utils/polyfill.js ***! 103 | \*******************************/ 104 | 105 | /*!*********************************!*\ 106 | !*** ./src/objects/Object2D.js ***! 107 | \*********************************/ 108 | 109 | /*!*********************************!*\ 110 | !*** ./src/textures/Texture.js ***! 111 | \*********************************/ 112 | 113 | /*!***********************************!*\ 114 | !*** ./src/utils/EventEmitter.js ***! 115 | \***********************************/ 116 | 117 | /*!*************************************!*\ 118 | !*** ./src/objects/BaseObject2D.js ***! 119 | \*************************************/ 120 | 121 | /*!*****************************************!*\ 122 | !*** ./src/renderers/CanvasRenderer.js ***! 123 | \*****************************************/ 124 | -------------------------------------------------------------------------------- /examples/res/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smoudjs/tiny/2fce883dc7bee738ffb883a681d32156c8a2cdec/examples/res/image.png -------------------------------------------------------------------------------- /examples/res/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smoudjs/tiny/2fce883dc7bee738ffb883a681d32156c8a2cdec/examples/res/image2.png -------------------------------------------------------------------------------- /examples/res/script.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var script = document.createElement('script'); 3 | 4 | script.onload = function () { 5 | var stats = new Stats(); 6 | document.body.appendChild(stats.dom); 7 | requestAnimationFrame(function loop() { 8 | stats.update(); 9 | requestAnimationFrame(loop); 10 | }); 11 | }; 12 | 13 | script.src = 'https://mrdoob.github.io/stats.js/build/stats.min.js'; 14 | document.head.appendChild(script); 15 | })(); 16 | 17 | document.addEventListener('scroll', function () { 18 | window.game && window.game.input.updateBounds(); 19 | }); 20 | 21 | window.addEventListener('resize', function () { 22 | window.game && window.game.input.updateBounds(); 23 | }); 24 | 25 | window.config = { 26 | width: 640, 27 | height: 400 28 | }; 29 | 30 | window.GLTFLoader = THREE.GLTFLoader; 31 | 32 | window.initTest = function (states) { 33 | destroyGame(); 34 | 35 | const container = document.getElementById('game-container'); 36 | container.innerHTML = ''; 37 | 38 | // var game; 39 | 40 | // if (!is3D) { 41 | // game = window.game = new Tiny.App2D(config.width, config.height, 'test-container', states); 42 | // } else { 43 | // game = window.game = new Tiny.App3D(config.width, config.height, 'test-container', states); 44 | // } 45 | 46 | var game = (window.game = new MyGame(config.width, config.height)); 47 | 48 | game.once('postrender', () => { 49 | resizeCanvas(config.width, config.height); 50 | }); 51 | }; 52 | 53 | window.destroyGame = function () { 54 | if (window.game) { 55 | window.game.destroy(); 56 | window.game = null; 57 | } 58 | const container = document.getElementById('game-container'); 59 | container.style.minWidth = '640px'; 60 | container.style.minHeight = '400px'; 61 | }; 62 | 63 | window.resizeCanvas = function (width, height) { 64 | if (window.game) { 65 | const container = document.getElementById('game-container'); 66 | config.width = width || Math.floor(Math.random() * 400) + 400; 67 | config.height = height || Math.floor(Math.random() * 300) + 300; 68 | 69 | container.style.minWidth = ''; 70 | container.style.minHeight = ''; 71 | 72 | window.game.resize(config.width, config.height); 73 | } 74 | }; 75 | 76 | window.addEventListener('load', function (argument) { 77 | ace.require('ace/ext/language_tools'); 78 | 79 | var editor = ace.edit('editor'); 80 | 81 | editor.setOptions({ 82 | enableBasicAutocompletion: true, 83 | enableSnippets: true, 84 | enableLiveAutocompletion: true, 85 | copyWithEmptySelection: true 86 | }); 87 | 88 | editor.setHighlightActiveLine(true); 89 | 90 | editor.session.on('changeMode', function (e, session) { 91 | if ('ace/mode/javascript' === session.getMode().$id) { 92 | if (!!session.$worker) { 93 | session.$worker.send('setOptions', [ 94 | { 95 | esversion: 9, 96 | esnext: true 97 | } 98 | ]); 99 | } 100 | } 101 | }); 102 | 103 | editor.setTheme('ace/theme/monokai'); 104 | editor.session.setMode('ace/mode/javascript'); 105 | 106 | window.editor = editor; 107 | 108 | 109 | window.initCode = function (name) { 110 | 111 | var urlEl = document.getElementById('url-el'); 112 | 113 | var url = 'https://github.com/smoudjs/tiny/blob/master/examples/tests/' + name + '.js'; 114 | 115 | urlEl.innerHTML = url; 116 | urlEl.href = url; 117 | 118 | fetch('tests/' + name + '.js') 119 | .then((res) => { 120 | res.text().then((e) => { 121 | // var js = ace.createEditSession(e); 122 | // var css = ace.createEditSession(["some", "css", "code here"]); 123 | // // and then to load document into editor, just call 124 | // editor.setSession(js); 125 | editor.session.setValue(e); 126 | runCode(); 127 | // editor.setValue(e); 128 | 129 | // editor.session.replace(editor.selection.getRange(), e); 130 | }); 131 | }) 132 | .catch((err) => { 133 | alert(err.message); 134 | }); 135 | }; 136 | 137 | window.runCode = function () { 138 | var code = editor.getValue(); 139 | 140 | code = '(function () {' + code + ';window.MyGame = MyGame;})()'; 141 | 142 | var script = document.createElement('script'); 143 | script.text = code; 144 | document.body.appendChild(script); 145 | 146 | initTest(); 147 | }; 148 | 149 | window.saveCode = function () { 150 | 151 | var link = document.createElement('a'); 152 | var file = new Blob([editor.getValue()], { type: 'application/javascript' }); 153 | link.href = URL.createObjectURL(file); 154 | link.download = 'MyGame.js'; 155 | link.click(); 156 | URL.revokeObjectURL(link.href); 157 | }; 158 | 159 | document.addEventListener('keydown', (e) => { 160 | if (e.ctrlKey && e.key === 's') { 161 | // Prevent the Save dialog to open 162 | e.preventDefault(); 163 | // Place your code here 164 | runCode(); 165 | } 166 | }); 167 | 168 | document.getElementById('resources-list').innerHTML = Object.keys(resources).join(", "); 169 | }); 170 | -------------------------------------------------------------------------------- /examples/res/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: monospace; 3 | background-color: #fff; 4 | color: #454545; 5 | font-family: Nunito, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, 6 | sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji; 7 | font-size: 1rem; 8 | font-weight: 400; 9 | line-height: 1.5; 10 | margin: 0; 11 | text-align: left; 12 | } 13 | 14 | hr { 15 | width: 100%; 16 | } 17 | 18 | h3 { 19 | font-family: monospace; 20 | margin-top: 10px; 21 | margin-bottom: 5px; 22 | color: #0249ff; 23 | } 24 | 25 | .btn { 26 | font-family: monospace; 27 | border: 0px; 28 | border-bottom: 2px solid #8ec6ff; 29 | display: inline-block; 30 | font-size: 1rem; 31 | font-weight: 400; 32 | padding: 0.375rem 0.75rem; 33 | text-align: center; 34 | transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; 35 | -webkit-user-select: none; 36 | -ms-user-select: none; 37 | user-select: none; 38 | vertical-align: middle; 39 | background-color: #396fa7; 40 | color: #ffffff; 41 | cursor: pointer; 42 | margin: 0px 3px 0px 3px; 43 | } 44 | 45 | .left-panel { 46 | width: 25%; 47 | text-align: center; 48 | display: flex; 49 | flex-direction: column; 50 | padding: 15px; 51 | background-color: #f9f9f9; 52 | } 53 | 54 | .right-panel { 55 | width: 75%; 56 | display: flex; 57 | align-items: center; 58 | flex-direction: column; 59 | padding: 15px; 60 | border-left: 1px solid #c4c4c4; 61 | background-color: #f2f6ff; 62 | } 63 | 64 | .canvas-container { 65 | border: 3px solid rgb(17, 114, 169); 66 | line-height: 0; 67 | border-radius: 5px; 68 | } 69 | 70 | .controll { 71 | display: flex; 72 | background-color: #396fa7; 73 | padding: 8px 10px 5px 10px; 74 | border-radius: 10px 10px 0px 0px; 75 | } 76 | 77 | .source-container { 78 | margin-top: 20px; 79 | width: 100%; 80 | } 81 | 82 | #code-el { 83 | position: relative; 84 | width: 100%; 85 | min-height: 600px; 86 | } 87 | 88 | #editor { 89 | position: absolute; 90 | top: 0; 91 | right: 0; 92 | bottom: 0; 93 | left: 0; 94 | font-size: 16px; 95 | } 96 | 97 | #url-el { 98 | font-family: monospace; 99 | } 100 | 101 | 102 | .ace_scrollbar::-webkit-scrollbar { 103 | height: 12px; 104 | width: 12px; 105 | } 106 | 107 | .ace_scrollbar::-webkit-scrollbar-track 108 | { 109 | box-shadow: inset 0 0 6px rgba(0,0,0,0.3); 110 | background-color: #272822; /* Matches ace monokai */ 111 | border-radius: 10px; 112 | } 113 | 114 | .ace_scrollbar::-webkit-scrollbar-thumb { 115 | background-color: darkgrey; 116 | outline: 1px solid slategrey; 117 | border-radius: 10px; 118 | } -------------------------------------------------------------------------------- /examples/tests/AnimSpritesheet.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | * import "h5tiny/plugins/anim" 5 | * import "h5tiny/plugins/create" 6 | * 7 | * or 8 | * 9 | * import "h5tiny/plugins/create/spritesheet" 10 | * 11 | * To ignore unnecessary extra components 12 | * 13 | */ 14 | 15 | class MyGame extends Tiny.App2D { 16 | constructor(width, height) { 17 | super(width, height, 'game-container'); 18 | } 19 | 20 | preload() { 21 | this.load.image('base', resources.baseImage); 22 | this.load.spritesheet('gifspritesheet', resources.spritesheet, 222, 222); 23 | this.load.atlas('atlas', resources.atlas, resources.atlas_data); 24 | } 25 | 26 | create() { 27 | const head = new Tiny.Sprite('base'); 28 | head.y = -40; 29 | head.scale.set(1.3, 0.5); 30 | head.anchor.set(0, 1); 31 | 32 | const body = new Tiny.Sprite('base'); 33 | body.anchor.set(0.5); 34 | 35 | const lleg = new Tiny.Sprite('atlas', 'IH'); 36 | lleg.scale.x = 0.3; 37 | 38 | const rleg = new Tiny.Sprite('atlas', 'IH'); 39 | rleg.scale.x = 0.3; 40 | 41 | lleg.anchor.set(0.5, 0); 42 | rleg.anchor.set(0.5, 0); 43 | 44 | var group = new Tiny.Object2D(); 45 | group.add(lleg); 46 | group.add(body); 47 | group.add(rleg); 48 | body.add(head); 49 | 50 | Tiny.Create.spritesheet({ 51 | width: 400, 52 | height: 400, 53 | frames: 30, 54 | resolution: 0.2, 55 | key: 'spritesheetRunAnimation', 56 | draw(progress, ctx, frame) { 57 | body.y = Math.sin(progress * Math.PI * 4) * 30; 58 | lleg.rotation = Math.sin(progress * Math.PI * 2); 59 | rleg.rotation = -Math.sin(progress * Math.PI * 2); 60 | head.x = Math.sin(progress * Math.PI * 2) * 20; 61 | head.rotation = Math.sin(progress * Math.PI * 4) * 0.3; 62 | body.rotation = Math.sin(progress * Math.PI * 4) * 0.2; 63 | return group; 64 | } 65 | }); 66 | 67 | Tiny.Create.spritesheet({ 68 | width: 400, 69 | height: 400, 70 | frames: 20, 71 | resolution: 0.2, 72 | key: 'spritesheetIdleAnimation', 73 | draw(progress, ctx, frame) { 74 | body.y = Math.sin(progress * Math.PI * 2) * 30; 75 | head.x = Math.sin(progress * Math.PI * 4) * 10; 76 | head.rotation = Math.sin(progress * Math.PI * 4) * 0.1; 77 | return group; 78 | } 79 | }); 80 | 81 | this.anim.create({ 82 | key: "run", 83 | data: "spritesheetRunAnimation", 84 | fps: 50, 85 | repeat: -1 86 | }); 87 | 88 | this.anim.create({ 89 | key: "idle", 90 | data: { 91 | key: "spritesheetIdleAnimation" 92 | }, 93 | fps: 15, 94 | repeat: -1 95 | }); 96 | 97 | this.anim.create({ 98 | key: "movie", 99 | data: "gifspritesheet", 100 | fps: 15 101 | }); 102 | 103 | this.anim.create({ 104 | key: "cutAnim", 105 | data: { 106 | key: "spritesheetRunAnimation", 107 | from: 10, 108 | to: 15 109 | }, 110 | fps: 50, 111 | repeat: 5, 112 | yoyo: true, 113 | repeatDelay: 100 114 | }); 115 | 116 | var movie = new Tiny.Sprite('gifspritesheet', 0); 117 | movie.position.set(320, 50); 118 | this.anim.add(movie); 119 | this.input.add(movie); 120 | this.scene.add(movie); 121 | 122 | movie.input.on('down', function() { 123 | movie.play({ 124 | key: "movie", 125 | onComplete: function() { 126 | console.log("To be continued...") 127 | } 128 | }); 129 | }) 130 | 131 | var sprite1 = new Tiny.Sprite('spritesheetIdleAnimation', 0); 132 | sprite1.position.set(Tiny.rnd(40, 600), Tiny.rnd(40, 360)); 133 | sprite1.anchor.set(0.5); 134 | this.anim.add(sprite1); 135 | this.scene.add(sprite1); 136 | 137 | sprite1.play('idle'); 138 | 139 | var runTween = null; 140 | this.input.on('down', function(e) { 141 | if (runTween) { 142 | this.tweens.remove(runTween); 143 | runTween = null; 144 | } 145 | sprite1.play('run'); 146 | 147 | if (e.x > sprite1.x) sprite1.scale.x = 1; 148 | else sprite1.scale.x = -1; 149 | 150 | var a = e.x - sprite1.x; 151 | var b = e.y - sprite1.y; 152 | 153 | var distance = Math.sqrt( a*a + b*b ); 154 | 155 | runTween = this.tweens.add(sprite1).to({x: e.x, y: e.y}, distance * 4).onComplete(function(argument) { 156 | sprite1.play('idle'); 157 | }).start(); 158 | }, this); 159 | 160 | var sprite2 = new Tiny.Sprite('spritesheetIdleAnimation', 0); 161 | sprite2.position.set(100, 300); 162 | sprite2.anchor.set(0.5); 163 | this.anim.add(sprite2); 164 | this.input.add(sprite2); 165 | this.scene.add(sprite2); 166 | 167 | sprite2.play('cutAnim'); 168 | 169 | sprite2.input.on('down', function() { 170 | sprite2.play({ 171 | key: "run", 172 | repeat: 2, 173 | fps: 60, 174 | onComplete: function() { 175 | sprite2.play('cutAnim'); 176 | } 177 | }) 178 | }) 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /examples/tests/Basic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | */ 4 | 5 | class MyGame extends Tiny.App { 6 | constructor(width, height) { 7 | super(); 8 | 9 | this.width = width; 10 | this.height = height; 11 | 12 | this.renderer = new Tiny.CanvasRenderer(this.width, this.height, { 13 | resolution: 1.25, 14 | autoResize: true 15 | }); 16 | 17 | this.renderer.setClearColor('#f4f4f4'); 18 | 19 | var view = (this.inputView = this.renderer.domElement); 20 | 21 | document.getElementById('game-container').appendChild(view); 22 | 23 | this.scene = new Tiny.Scene(); 24 | } 25 | 26 | preload() { 27 | this.load.image('coin', resources.baseImage); 28 | } 29 | 30 | create() { 31 | var text = new Tiny.Text('Hello Tiny!'); 32 | text.anchor.set(0.5); 33 | text.x = 320; 34 | text.y = 200; 35 | this.text = text; 36 | 37 | var sprite = new Tiny.Sprite('coin'); 38 | 39 | this.scene.add(sprite); 40 | this.scene.add(text); 41 | } 42 | 43 | update(time, delta) { 44 | this.text.rotation += delta * 0.001; 45 | } 46 | 47 | setPixelRatio(dpr) { 48 | this.renderer.setPixelRatio(dpr); 49 | } 50 | 51 | render() { 52 | this.renderer.render(this.scene); 53 | } 54 | 55 | resize(width, height) { 56 | super.resize(width, height); 57 | 58 | this.renderer.resize(width, height); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /examples/tests/BlendMode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | */ 5 | 6 | class MyGame extends Tiny.App2D { 7 | constructor(width, height) { 8 | super(width, height, 'game-container'); 9 | } 10 | 11 | preload() { 12 | this.load.image('base', resources.baseImage); 13 | 14 | resizeCanvas(640, 600); 15 | 16 | this.addLabel = (_x, _y, text, color) => { 17 | var text = new Tiny.Text(text, { 18 | fill: color || '#ffffff', 19 | font: '300 9pt Courier', 20 | align: 'center' 21 | }); 22 | text.position.set(_x, _y); 23 | text.anchor.set(0.5, 3.2); 24 | this.scene.add(text); 25 | }; 26 | 27 | this.addSprite = (x, y, mode, anchorX, anchorY) => { 28 | var sprite = new Tiny.Sprite('base'); 29 | sprite.position.set(x, y); 30 | sprite.anchor.set(anchorX, anchorY); 31 | sprite.scale.set(0.4); 32 | sprite.blendMode = mode; 33 | this.scene.add(sprite); 34 | }; 35 | } 36 | 37 | create() { 38 | const blendModes = [ 39 | 'source-over', 40 | 'screen', 41 | 'lighter', 42 | 'xor', 43 | 'multiply', 44 | 'overlay', 45 | 'darken', 46 | 'lighten', 47 | 'color-dodge', 48 | 'color-burn', 49 | 'hard-light', 50 | 'soft-light', 51 | 'difference', 52 | 'exclusion', 53 | 'luminosity' 54 | ]; 55 | 56 | let x = 0; 57 | let y = 0; 58 | const offset = 110; 59 | const start = this.width / 12; 60 | 61 | const background = new Tiny.Graphics(); 62 | 63 | background.beginFill('#232323'); 64 | background.blendMode = 'source-over'; 65 | background.drawRect(0, 0, this.width / 2, this.height); 66 | this.scene.add(background); 67 | 68 | this.input.on('down', function () { 69 | background.clear(); 70 | background.beginFill(Tiny.hex2style(Math.floor(Math.random() * 16777215))); 71 | background.drawRect(0, 0, game.width / 2, game.height); 72 | }); 73 | 74 | for (let mode of blendModes) { 75 | const _x = x * (this.width / 6) + start; 76 | const _y = y * offset + 70; 77 | 78 | this.addLabel(_x, _y, mode, '#ffffff'); 79 | this.addSprite(_x, _y, mode, 0.2, 0.2); 80 | this.addSprite(_x, _y, mode, 0.7, 0.2); 81 | this.addSprite(_x, _y, mode, 0.5, 0.7); 82 | 83 | x++; 84 | if (x > 2) { 85 | x = 0; 86 | y++; 87 | } 88 | } 89 | 90 | x = 0; 91 | y = 0; 92 | 93 | for (let mode of blendModes) { 94 | const _x = this.width / 2 + x * (this.width / 6) + start; 95 | const _y = y * offset + 70; 96 | 97 | this.addLabel(_x, _y, mode, '#232323'); 98 | this.addSprite(_x, _y, mode, 0.2, 0.2); 99 | this.addSprite(_x, _y, mode, 0.7, 0.2); 100 | this.addSprite(_x, _y, mode, 0.5, 0.7); 101 | 102 | x++; 103 | if (x > 2) { 104 | x = 0; 105 | y++; 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /examples/tests/Extended.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | */ 5 | 6 | class MyGame extends Tiny.App2D { 7 | constructor(width, height) { 8 | super(width, height, 'game-container'); 9 | } 10 | 11 | preload() { 12 | this.load.image('base', resources.baseImage); 13 | this.load.atlas('atlas', resources.atlas, resources.atlas_data); 14 | // this.load.spritesheet("gifsprite", spritesheet, 222, 222); 15 | // this.load.spritesheet("gifsprite", spritesheet, spritesheet_data); 16 | 17 | this.load.all([ 18 | // { key: "base", src: resources.baseImage, type: "image" }, 19 | // { key: "atlas", src: resources.atlas, data: atlas_data, type: "atlas" }, 20 | // { key: "gifsprite", src: spritesheet, cols: 12, rows: 1, total: 15, duration: 40, type: "spritesheet" }, 21 | // { key: "gifsprite", src: spritesheet, width: 222, height: 222, duration: 40, type: "spritesheet" }, 22 | { key: 'gifsprite', src: resources.spritesheet, cols: 6, rows: 1, duration: 90, type: 'spritesheet' } 23 | // { key: "gifsprite", src: spritesheet, data: spritesheet_data, type: "spritesheet" } 24 | ]); 25 | } 26 | 27 | create() { 28 | 29 | this.anim.create({ 30 | key: "idle", 31 | type: "spritesheet", 32 | data: { 33 | key: "gifsprite", 34 | // from: 0, 35 | // to: 3 36 | }, 37 | repeat: -1, 38 | yoyo: true, 39 | fps: 16 40 | }); 41 | 42 | this.group = new Tiny.Object2D(); 43 | this.group.x = 200; 44 | this.group.y = 200; 45 | 46 | this.group.add(new Tiny.Text('Hello World')); 47 | this.group.add(new Tiny.Sprite('base')); 48 | this.group.add(new Tiny.Text('Hello World', { fill: '#ff0000' })); 49 | this.group.cacheAsBitmap = true; 50 | this.group.children[2].y = 70; 51 | this.group.updateCache(); 52 | 53 | var texture1 = (this.texture1 = this.group.generateTexture()); 54 | var spriteFromGenerated = new Tiny.Sprite(texture1); 55 | 56 | spriteFromGenerated.x = this.group.x; 57 | spriteFromGenerated.y = this.group.y; 58 | spriteFromGenerated.alpha = 0.3; 59 | spriteFromGenerated.scale.set(0.7); 60 | 61 | this.scene.add(spriteFromGenerated); 62 | this.scene.add(this.group); 63 | 64 | var spriteFromGenerated2 = new Tiny.Sprite(texture1); 65 | spriteFromGenerated2.x = 70; 66 | spriteFromGenerated2.y = 70; 67 | spriteFromGenerated2.rotation = 0.5; 68 | spriteFromGenerated2.alpha = 0.3; 69 | spriteFromGenerated2.scale.set(0.7); 70 | 71 | this.group.add(spriteFromGenerated2); 72 | this.group.updateCache(); 73 | 74 | this.input.add(this.group); 75 | this.group.input.on('click', function () { 76 | alert('Oup, you catched me !'); 77 | }); 78 | 79 | this.bottomRightSprite = new Tiny.Sprite('base'); 80 | this.bottomRightSprite.anchor.set(0.5); 81 | this.scene.add(this.bottomRightSprite); 82 | this.bottomRightSprite.position.set(this.width - 100, this.height - 100); 83 | 84 | this.testCoin = new Tiny.Sprite('base'); 85 | this.testCoin.x = 350; 86 | this.testCoin.y = 200; 87 | this.testCoin.scale.set(0.5); 88 | this.scene.add(this.testCoin); 89 | 90 | this.icon = new Tiny.Sprite('atlas', 'IH'); 91 | this.icon.tint = '#23f423'; 92 | this.icon.scale.set(0.5); 93 | this.scene.add(this.icon); 94 | 95 | const animatedSprite = new Tiny.Sprite('gifsprite', 0); 96 | animatedSprite.anchor.set(0.5); 97 | animatedSprite.position.set(450, 120); 98 | animatedSprite.scale.set(0.7); 99 | animatedSprite.game = this; 100 | // animatedSprite.animate(60, true); 101 | 102 | this.anim.add(animatedSprite); 103 | this.input.add(animatedSprite); 104 | 105 | 106 | animatedSprite.play('idle'); 107 | animatedSprite.input.once('down', function () { 108 | animatedSprite.play({key: 'idle', yoyo: false, fps: 30}); 109 | }); 110 | 111 | this.interval = setInterval(function () { 112 | // console.log('Rotate sprite!'); 113 | // animatedSprite.rotation = 1 - Math.random() * 2; 114 | }, 1000); 115 | 116 | this.scene.add(animatedSprite); 117 | 118 | /** 119 | * Creating scene mini-map 120 | */ 121 | this.miniMap = new Tiny.MiniMap(this); 122 | this.scene.add(this.miniMap); 123 | } 124 | 125 | update(time, delta) { 126 | this.testCoin.rotation += delta * 0.0001; 127 | this.testCoin.anchor.x = Math.sin(time * 0.001); 128 | 129 | this.group.scale.x = Math.sin(time / 500); 130 | this.group.scale.y = Math.cos(time / 500); 131 | 132 | this.group.x = Math.sin(time / 100) * 10 + 200; 133 | this.group.y = Math.cos(time / 100) * 10 + 200; 134 | 135 | this.miniMap.update(delta); 136 | } 137 | 138 | resize(width, height) { 139 | super.resize(width, height); 140 | this.bottomRightSprite.x = width - 100; 141 | this.bottomRightSprite.y = height - 100; 142 | 143 | this.miniMap.resize(width, height); 144 | } 145 | 146 | destroy(clearCache) { 147 | super.destroy(clearCache); 148 | clearInterval(this.interval); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /examples/tests/Graphics.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | */ 5 | 6 | class MyGame extends Tiny.App2D { 7 | constructor(width, height) { 8 | super(width, height, 'game-container'); 9 | } 10 | 11 | create() { 12 | const graphics = new Tiny.Graphics(); 13 | 14 | // Rectangle 15 | graphics.beginFill('#DE3249'); 16 | graphics.drawRect(20, 20, 100, 100); 17 | graphics.endFill(); 18 | 19 | // Rectangle + line style 1 20 | graphics.lineStyle(2, '#FEEB77', 1); 21 | graphics.beginFill('#650A5A'); 22 | graphics.drawRect(140, 20, 100, 100); 23 | graphics.endFill(); 24 | 25 | // Rectangle + line style 2 26 | graphics.lineStyle(10, '#FFBD01', 1); 27 | graphics.beginFill('#C34288'); 28 | graphics.drawRect(260, 20, 100, 100); 29 | graphics.endFill(); 30 | 31 | // Rectangle 2 32 | graphics.lineStyle(2, '#000000', 1); 33 | graphics.beginFill('#AA4F08'); 34 | graphics.drawRect(410, 20, 140, 100); 35 | graphics.endFill(); 36 | 37 | // Circle 38 | graphics.lineStyle(0); // draw a circle, set the lineStyle to zero so the circle doesn't have an outline 39 | graphics.beginFill('#DE3249', 1); 40 | graphics.drawCircle(70, 190, 100); 41 | graphics.endFill(); 42 | 43 | // Circle + line style 1 44 | graphics.lineStyle(2, '#FEEB77', 1); 45 | graphics.beginFill('#650A5A', 1); 46 | graphics.drawCircle(190, 190, 100); 47 | graphics.endFill(); 48 | 49 | // Circle + line style 2 50 | graphics.lineStyle(10, '#FFBD01', 1); 51 | graphics.beginFill('#C34288', 1); 52 | graphics.drawCircle(310, 190, 100); 53 | graphics.endFill(); 54 | 55 | // Ellipse + line style 2 56 | graphics.lineStyle(2, '#000000', 1); 57 | graphics.beginFill('#AA4F08', 1); 58 | graphics.drawEllipse(250, 350, 70, 40); 59 | graphics.endFill(); 60 | 61 | // draw a shape 62 | graphics.beginFill('#FF3300'); 63 | graphics.lineStyle(4, '#ffd900', 1); 64 | graphics.moveTo(50, 270); 65 | graphics.lineTo(250, 270); 66 | graphics.lineTo(100, 320); 67 | graphics.lineTo(50, 270); 68 | //graphics.closePath(); 69 | graphics.endFill(); 70 | 71 | // draw a rounded rectangle 72 | graphics.lineStyle(2, '#FF00FF', 1); 73 | graphics.beginFill('#f1f1f1', 0.25); 74 | graphics.drawRoundedRect(330, 270, 100, 100, 16); 75 | graphics.endFill(); 76 | 77 | // draw star 78 | // graphics.lineStyle(2, "#FFFFFF"); 79 | // graphics.beginFill("#35CC5A", 1); 80 | // graphics.drawStar(360, 370, 5, 50); 81 | // graphics.endFill(); 82 | 83 | // draw star 2 84 | // graphics.lineStyle(2, "#FFFFFF"); 85 | // graphics.beginFill("#FFCC5A", 1); 86 | // graphics.drawStar(280, 510, 7, 50); 87 | // graphics.endFill(); 88 | 89 | // draw star 3 90 | // graphics.lineStyle(4, "#FFFFFF"); 91 | // graphics.beginFill("#55335A", 1); 92 | // graphics.drawStar(470, 450, 4, 50); 93 | // graphics.endFill(); 94 | 95 | // draw polygon 96 | const path = [450, 170, 550, 260, 630, 220, 580, 370, 440, 320]; 97 | 98 | graphics.lineStyle(0); 99 | graphics.beginFill('#3500FA', 1); 100 | graphics.drawPolygon(path); 101 | graphics.endFill(); 102 | 103 | this.scene.add(graphics); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /examples/tests/Graphics2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | */ 5 | 6 | class MyGame extends Tiny.App2D { 7 | constructor(width, height) { 8 | super(width, height, 'game-container'); 9 | } 10 | 11 | create() { 12 | this.graphics = new Tiny.Graphics(); 13 | this.graphics.x = 100; 14 | this.graphics.y = 100; 15 | this.graphics.beginFill('#0a6dc1'); 16 | this.graphics.drawCircle(0, 0, 182); 17 | this.graphics.beginFill('#04589e'); 18 | this.graphics.drawCircle(0, 0, 170); 19 | 20 | for (var i = 0; i < 40; i++) { 21 | this.graphics.beginFill('#5500c5', 0.06); 22 | this.graphics.drawCircle(0, 0, i * 4); 23 | } 24 | 25 | // this.scene.add(this.graphics); 26 | 27 | const texture1 = this.graphics.generateTexture(); 28 | 29 | const sprite = new Tiny.Sprite(texture1); 30 | this.scene.add(sprite); 31 | 32 | this.graphics.destroy(); 33 | 34 | this.graphics = new Tiny.Graphics(); 35 | this.graphics.position.set(100, 100); 36 | this.graphics.beginFill('#45a187'); 37 | this.graphics.drawCircle(34, 100, 125); 38 | this.graphics.beginFill('#ff4545'); 39 | this.graphics.drawRect(120, 45, 50, 50); 40 | this.graphics.scale.set(2, 1); 41 | this.graphics.rotation = 0.3; 42 | 43 | var texture2 = this.graphics.generateTexture(0.5); 44 | 45 | const sprite2 = new Tiny.Sprite(texture2); 46 | this.scene.add(sprite2); 47 | 48 | this.scene.add(this.graphics); 49 | 50 | this.graphics.lineStyle(4, '#232323', 0.5); 51 | this.graphics.moveTo(23, 100); 52 | this.graphics.lineTo(150, 150); 53 | 54 | this.graphics.moveTo(200, 30); 55 | 56 | this.graphics.quadraticCurveTo(100, 134, 220, 145); 57 | this.graphics.bezierCurveTo(30, 5, 140, 10, 100, 50); 58 | this.graphics.arcTo(200, -0, 250, -120, 150); 59 | 60 | this.graphics.beginFill('#f4a187', 0.5); 61 | 62 | this.graphics.drawRoundedRect(120, 0, 100, 60, 15); 63 | // this.graphics.drawRoundedRect2(120, 70, 100, 60, 15); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /examples/tests/Input.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | * 5 | * import "h5tiny/examples/js/objects/MiniMap"; 6 | * to use RecursiveSprite 7 | */ 8 | 9 | class MyGame extends Tiny.App2D { 10 | 11 | constructor(width, height) { 12 | super(width, height, "game-container"); 13 | } 14 | 15 | preload () { 16 | this.load.image("base", resources.baseImage); 17 | this.load.atlas("atlas", resources.atlas, resources.atlas_data); 18 | } 19 | 20 | create () { 21 | const debugText = (this.debugText = new Tiny.Text("0:0", { fill: "#3434f3" })); 22 | this.scene.add(debugText); 23 | 24 | this.input.on("down", function (e) { 25 | console.log("Mouse down: " + e.x + ":" + e.y); 26 | }, this); 27 | 28 | this.input.on("up", function (e) { 29 | console.log("Mouse up: " + e.x + ":" + e.y); 30 | }, this); 31 | 32 | this.input.on("move", function (e) { 33 | console.log("Mouse move: ", this.input.isDown); 34 | debugText.setText(Math.floor(e.x) + " : " + Math.floor(e.y)); 35 | }, this); 36 | 37 | var coin = (this.coin = new Tiny.Sprite("base")); 38 | coin.x = 300; 39 | coin.y = 200; 40 | coin.anchor.set(0.5); 41 | coin.scale.set(0.9); 42 | this.scene.add(coin); 43 | 44 | this.input.add(coin); 45 | coin.input.on("click", function () { 46 | console.log("Coin 2 clicked"); 47 | coin.tint = Tiny.hex2style(Math.floor(Math.random() * 162000)); 48 | }, this); 49 | 50 | coin.input.on("down", function () { 51 | this.dragging = true; 52 | }, coin); 53 | 54 | var coin2 = (this.coin2 = new Tiny.Sprite("base")); 55 | coin2.x = 100; 56 | coin2.y = 300; 57 | coin2.anchor.set(0.5); 58 | coin2.scale.set(0.9); 59 | this.scene.add(coin2); 60 | this.input.add(coin2); 61 | 62 | this.graphics = new Tiny.Graphics(); 63 | this.graphics.x = 100; 64 | this.graphics.beginFill("#0a6dc1"); 65 | this.graphics.drawCircle(0, 0, 182); 66 | this.graphics.beginFill("#04589e"); 67 | this.graphics.drawCircle(0, 0, 170); 68 | for (var i = 0; i < 40; i++) { 69 | this.graphics.beginFill("#5500c5", 0.06); 70 | this.graphics.drawCircle(0, 0, i * 4); 71 | } 72 | var newTexture = this.graphics.generateTexture(); 73 | this.graphics.destroy(); 74 | 75 | var sprite = (this.sprite = new Tiny.Sprite(newTexture)); 76 | sprite.position.set(560, 120); 77 | sprite.anchor.set(0.5); 78 | 79 | var text = (this.text = new Tiny.Text("Drag me!", { fill: "#ffffff" })); 80 | text.anchor.set(0.5); 81 | 82 | this.tweens 83 | .add(text.scale) 84 | .to({ x: 1.1, y: 1.1 }, 500) 85 | .yoyo(true) 86 | .easing(Tiny.Easing.Sinusoidal.InOut) 87 | .repeat(Infinity) 88 | .start(); 89 | 90 | var pulseTween = this.tweens 91 | .add(sprite.scale) 92 | .to({ x: 1.1, y: 1.1 }, 100) 93 | .yoyo(true) 94 | .easing(Tiny.Easing.Sinusoidal.InOut) 95 | .repeat(Infinity) 96 | .start(); 97 | 98 | pulseTween.pause(); 99 | 100 | sprite.add(text); 101 | 102 | var dragging = false; 103 | 104 | var startOffsetX = 0; 105 | var startOffsetY = 0; 106 | 107 | this.input.on( 108 | "up", 109 | function (e) { 110 | dragging = false; 111 | this.coin2.dragging = false; 112 | this.coin.dragging = false; 113 | pulseTween.pause(); 114 | sprite.scale.set(1); 115 | }, 116 | this 117 | ); 118 | 119 | this.input.on( 120 | "move", 121 | function (e) { 122 | if (dragging) { 123 | sprite.position.set(e.x + startOffsetX, e.y + startOffsetY); 124 | } 125 | 126 | if (this.coin2.dragging) { 127 | this.coin2.position.set(e.x, e.y); 128 | this.recusrive.setCenter(this.coin2.x / game.width, this.coin2.y / game.height); 129 | } 130 | 131 | if (this.coin.dragging) { 132 | this.coin.position.set(e.x, e.y); 133 | this.recusrive.alpha = this.coin.x / game.width; 134 | this.recusrive.clearAlpha = this.coin.y / game.height; 135 | this.recusrive.clearAlpha *= this.recusrive.clearAlpha * this.recusrive.clearAlpha; 136 | this.recusrive.updateFrames(); 137 | } 138 | }, 139 | this 140 | ); 141 | 142 | this.input.add(sprite); 143 | 144 | sprite.input.on("down", function (e) { 145 | startOffsetX = sprite.x - e.x; 146 | startOffsetY = sprite.y - e.y; 147 | dragging = true; 148 | pulseTween.resume(); 149 | }); 150 | 151 | this.scene.add(sprite); 152 | 153 | /** 154 | * Creating scene recursive sprite 155 | */ 156 | this.recusrive = new Tiny.RecursiveSprite(this); 157 | this.scene.add(this.recusrive); 158 | 159 | coin2.input.on("down", function () { 160 | this.dragging = true; 161 | }, coin2); 162 | } 163 | 164 | resize (width, height) { 165 | super.resize(width, height); 166 | this.recusrive.resize(width, height); 167 | } 168 | 169 | update (time, delta) { 170 | this.recusrive.update(delta); 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /examples/tests/Particles1.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | * import "h5tiny/plugins/particles"; 5 | * 6 | * import "h5tiny/examples/js/particles/Smoke"; 7 | * to use SmokeParticle pattern 8 | * 9 | * import "h5tiny/examples/js/particles/Explode"; 10 | * to use ExplodeParticle pattern 11 | * 12 | * import "h5tiny/examples/js/objects/MiniMap"; 13 | * to use RecursiveSprite 14 | */ 15 | 16 | class MyGame extends Tiny.App2D { 17 | constructor(width, height) { 18 | super(width, height, 'game-container'); 19 | } 20 | 21 | preload() { 22 | this.load.image('base', resources.baseImage); 23 | } 24 | 25 | create() { 26 | var emitter = (this.emitter = new Tiny.Emitter(60)); 27 | emitter.x = 200; 28 | emitter.y = 300; 29 | emitter.width = 40; 30 | 31 | emitter.pattern = Tiny.SmokeParticle; 32 | emitter.fillStyle = '#666666'; 33 | 34 | emitter.makeParticles('base'); //Tiny.TextureCache["atlas_BR"]) 35 | emitter.scale.set(0.7); 36 | 37 | emitter.start(false, 500, 0); 38 | 39 | // emitter.flow(1000, 10, 3); 40 | 41 | this.timer.loop(5000, function () { 42 | if (Math.random() > 0.5) { 43 | emitter.width = 300; 44 | emitter.flow(500, 10, 5); 45 | } else { 46 | emitter.width = 40; 47 | emitter.flow(1000, 100, 8); 48 | } 49 | }); 50 | 51 | this.particles.add(emitter); 52 | this.scene.add(emitter); 53 | 54 | var bombEmitter = (this.bombEmitter = new Tiny.Emitter(30)); 55 | bombEmitter.pattern = Tiny.ExplodeParticle; 56 | bombEmitter.makeParticles(); 57 | 58 | var clickMe = new Tiny.Text('Click me !'); 59 | clickMe.anchor.set(0.5); 60 | clickMe.position.set(this.width / 2, this.height / 2); 61 | this.scene.add(clickMe); 62 | 63 | this.input.once('down', function (e) { 64 | clickMe.destroy(); 65 | }); 66 | 67 | this.input.on('down', function (e) { 68 | bombEmitter.fillStyle = '#' + Math.floor(Math.random() * 0xffffff).toString(16); 69 | bombEmitter.x = e.x; 70 | bombEmitter.y = e.y; 71 | console.log('Explode'); 72 | bombEmitter.explode(300, 80); 73 | }); 74 | 75 | this.particles.add(bombEmitter); 76 | this.scene.add(bombEmitter); 77 | 78 | this.recusrive = new Tiny.RecursiveSprite(this); 79 | this.recusrive.delay = 1; 80 | this.recusrive.setCenter(0.5, 0.7); 81 | this.scene.add(this.recusrive); 82 | } 83 | 84 | update(time, delta) { 85 | this.recusrive.update(delta); 86 | } 87 | 88 | resize(width, height) { 89 | super.resize(width, height); 90 | this.recusrive.resize(width, height); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /examples/tests/Particles2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | * import "h5tiny/plugins/particles"; 5 | * 6 | * import "h5tiny/examples/js/particles/Confetti"; 7 | * to use ConfettiParticle pattern 8 | * 9 | * import "h5tiny/examples/js/particles/Ribbon"; 10 | * to use RibbonParticle pattern 11 | * 12 | */ 13 | 14 | class MyGame extends Tiny.App2D { 15 | constructor(width, height) { 16 | super(width, height, 'game-container'); 17 | } 18 | 19 | create() { 20 | var confetti = (this.confetti = new Tiny.Emitter(150)); 21 | confetti.x = 350; 22 | confetti.width = 800; 23 | 24 | confetti.pattern = Tiny.ConfettiParticle; 25 | 26 | confetti.makeParticles(); 27 | confetti.scale.set(0.7); 28 | 29 | confetti.flow(10000, 300, 5); 30 | 31 | this.particles.add(confetti); 32 | this.scene.add(confetti); 33 | 34 | var ribbon = (this.ribbon = new Tiny.Emitter(18)); 35 | ribbon.x = 350; 36 | ribbon.width = 800; 37 | 38 | ribbon.pattern = Tiny.RibbonParticle; 39 | ribbon.makeParticles(); 40 | ribbon.scale.set(0.7); 41 | 42 | ribbon.start(false, 5000, 300); 43 | 44 | this.particles.add(ribbon); 45 | this.scene.add(ribbon); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/tests/ProgressBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | * import "h5tiny/plugins/extra" 5 | * 6 | * or 7 | * 8 | * import "h5tiny/plugins/extra/objects/ProgressBar" 9 | * 10 | * To ignore unnecessary extra components 11 | * 12 | */ 13 | 14 | class MyGame extends Tiny.App2D { 15 | constructor(width, height) { 16 | super(width, height, 'game-container'); 17 | } 18 | 19 | create() { 20 | const _self = this; 21 | 22 | function addProgressBar(x, y, options) { 23 | options = options || {}; 24 | options.game = _self; 25 | 26 | const progress = new Tiny.ProgressBar(options); 27 | 28 | progress.x = x; 29 | progress.y = y; 30 | 31 | _self.scene.add(progress); 32 | 33 | _self.timer.loop(1500, function () { 34 | progress.setValue(Math.random()); 35 | }); 36 | 37 | _self.input.on('down', function () { 38 | progress.setValue(1); 39 | }); 40 | 41 | return progress; 42 | } 43 | 44 | addProgressBar(150, 40); 45 | addProgressBar(150, 100, { colors: ['#ff0000', '#0000ff'] }); 46 | addProgressBar(150, 160, { 47 | radius: 0, 48 | height: 20, 49 | width: 250, 50 | duration: 1100, 51 | easing: Tiny.Easing.Elastic.Out, 52 | colors: ['#666666', '#69d6e1', '#5778e0', '#583fbe', '#e01b1b', '#ffd700'] 53 | }); 54 | 55 | addProgressBar(150, 220, { 56 | strokeWidth: 10 57 | // strokeColor: "#e1e1e1", 58 | // strokeAlpha: 1 59 | }); 60 | 61 | addProgressBar(150, 280, { 62 | strokeWidth: 3, 63 | bgColor: '#a1a1ff', 64 | bgAlpha: 0.5, 65 | strokeColor: '#0000a1', 66 | colors: ['#0000ff'] 67 | }); 68 | 69 | addProgressBar(150, 340, { 70 | animated: false, 71 | value: 0.5 72 | }); 73 | 74 | var circleProgress = addProgressBar(370, 300, { 75 | radius: 35, 76 | height: 70, 77 | width: 70 78 | }); 79 | 80 | circleProgress.rotation = Math.PI; 81 | 82 | var progress = addProgressBar(400, 130, { 83 | value: 0.2, 84 | strokeWidth: 10 85 | // strokeColor: "#e1e1e1", 86 | // strokeAlpha: 1 87 | }); 88 | 89 | progress.scale.set(0.5); 90 | progress.rotation = -Math.PI / 2; 91 | 92 | var progress2 = addProgressBar(460, 150, { 93 | radius: 0, 94 | height: 20, 95 | width: 250, 96 | colors: ['#666666', '#69d6e1', '#5778e0', '#583fbe', '#e01b1b', '#ffd700'] 97 | }); 98 | 99 | progress2.rotation = -Math.PI / 2; 100 | 101 | var progress3 = addProgressBar(560, 150, { 102 | height: 80, 103 | width: 120, 104 | strokeWidth: 5, 105 | strokeColor: '#aaa0aa', 106 | colors: ['#0000ff', '#fff000'] 107 | }); 108 | 109 | progress3.rotation = -Math.PI / 2; 110 | 111 | var graphics = new Tiny.Graphics(); 112 | 113 | graphics.drawCircle(0, -90, 120); 114 | graphics.drawPolygon([0, -56, 23, -11, 67, 23, -12, -64, 1, 354]); 115 | graphics.drawRect(-50, 20, 100, 100); 116 | 117 | graphics.x = progress3.x; 118 | graphics.y = progress3.y; 119 | this.scene.add(graphics); 120 | 121 | progress3.mask = graphics; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /examples/tests/RenderLayer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | * import "h5tiny/plugins/extra" 5 | * 6 | * or 7 | * 8 | * import "h5tiny/plugins/extra/objects/RenderLayer" 9 | * import "h5tiny/plugins/extra/objects/Opaque" 10 | * 11 | * To ignore unnecessary extra components 12 | * 13 | */ 14 | 15 | class MyGame extends Tiny.App2D { 16 | constructor(width, height) { 17 | super(width, height, 'game-container'); 18 | } 19 | 20 | preload() { 21 | this.load.image("base", resources.baseImage); 22 | this.load.atlas("atlas", resources.atlas, resources.atlas_data); 23 | } 24 | 25 | create() { 26 | const bottomLayer = new Tiny.Object2D(); 27 | bottomLayer.position.set(this.width / 2, this.height / 2); 28 | const topLayer = new Tiny.RenderLayer(); 29 | topLayer.position.set(this.width / 2, this.height / 2); 30 | const opaque = new Tiny.Opaque({game: this, alpha: 0.7}); 31 | 32 | this.scene.add(bottomLayer); 33 | this.scene.add(opaque); 34 | this.scene.add(topLayer); 35 | 36 | /** 37 | * Running tweens - to transform main bottom group 38 | * To see child behaviour after layer changes 39 | */ 40 | this.tweens 41 | .add(bottomLayer.pivot) 42 | .to({ x: [-50, 0, 50, 0] }, 6000) 43 | .repeat(Infinity) 44 | .start(); 45 | this.tweens 46 | .add(bottomLayer) 47 | .to({ rotation: [-0.5, 0, 0.5, 0] }, 5000) 48 | .repeat(Infinity) 49 | .start(); 50 | this.tweens.add(bottomLayer.scale).to({ x: 1.2, y: 1.2 }, 3000).yoyo(true).repeat(Infinity).start(); 51 | 52 | var _self = this; 53 | 54 | function addSprite(key, frame) { 55 | var sprite = new Tiny.Sprite(key, frame); 56 | sprite.x = Tiny.rnd(-_self.width / 2, _self.width / 2); 57 | sprite.y = Tiny.rnd(-_self.height / 2, _self.height / 2); 58 | sprite.scale.set(0.5); 59 | sprite.anchor.set(0.5); 60 | sprite.addedToTop = false; 61 | bottomLayer.add(sprite); 62 | 63 | _self.input.add(sprite); 64 | 65 | sprite.input.on( "down", function () { 66 | if (this.addedToTop) topLayer.remove(this); 67 | else topLayer.add(this); 68 | 69 | this.addedToTop = !this.addedToTop; 70 | }, sprite); 71 | } 72 | 73 | let spritesAmount = 10; 74 | while (spritesAmount--) { 75 | if (Math.random() > 0.3) addSprite("base"); 76 | else addSprite("atlas", "BR"); 77 | } 78 | 79 | const tip = new Tiny.Text("Click any object", { 80 | fill: "#ffffff" 81 | }); 82 | tip.anchor.set(0.5); 83 | tip.x = this.width / 2; 84 | tip.y = 30; 85 | this.scene.add(tip); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /examples/tests/RendererTexture.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | * 5 | * import "h5tiny/plugins/particles"; 6 | * to use particles 7 | * 8 | * import "h5tiny/examples/js/objects/MiniMap"; 9 | * to use RecursiveSprite and MiniMap 10 | */ 11 | 12 | class MyGame extends Tiny.App2D { 13 | constructor(width, height) { 14 | super(width, height, 'game-container'); 15 | } 16 | 17 | preload() { 18 | this.load.image('base', resources.baseImage); 19 | this.load.atlas('atlas', resources.atlas, resources.atlas_data); 20 | } 21 | 22 | create() { 23 | var emitter = (this.emitter = new Tiny.Emitter(300)); 24 | emitter.x = this.width / 2; 25 | emitter.y = 300; 26 | emitter.width = 400; 27 | 28 | emitter.pattern = Tiny.SmokeParticle; 29 | emitter.fillStyle = '#666666'; 30 | 31 | emitter.makeParticles(this.cache.texture['atlas.IH']); 32 | emitter.scale.set(0.7); 33 | 34 | emitter.flow(500, 10, 5); 35 | 36 | // emitter.flow(1000, 10, 3); 37 | 38 | this.particles.add(emitter); 39 | this.scene.add(emitter); 40 | 41 | var bombEmitter = (this.bombEmitter = new Tiny.Emitter(300)); 42 | bombEmitter.pattern = Tiny.ExplodeParticle; 43 | bombEmitter.makeParticles(); 44 | 45 | this.input.on('down', function (e) { 46 | bombEmitter.fillStyle = '#' + Math.floor(Math.random() * 0xffffff).toString(16); 47 | bombEmitter.x = e.x; 48 | bombEmitter.y = e.y; 49 | console.log('Explode'); 50 | bombEmitter.explode(300, 80); 51 | }); 52 | 53 | this.particles.add(bombEmitter); 54 | this.scene.add(bombEmitter); 55 | 56 | var text = (this.text = new Tiny.Text('Tiny', { 57 | font: 'bold 40pt Courier', 58 | fill: '#4e73df', 59 | wordWrap: true, 60 | wordWrapWidth: 150, 61 | align: 'center' 62 | })); 63 | 64 | this.timer.loop(100, function (argument) { 65 | text.rotation = Math.random() * Math.PI; 66 | game.text.pivot.x = Tiny.rnd(-100, 100); 67 | game.text.pivot.y = Tiny.rnd(-100, 100); 68 | }); 69 | 70 | text.anchor.set(0.5); 71 | 72 | text.x = this.width / 2; 73 | text.y = this.height * 0.3; 74 | 75 | this.scene.add(text); 76 | 77 | this.recusrive = new Tiny.RecursiveSprite(this); 78 | this.recusrive.setCenter(0.5, 0.7); 79 | this.recusrive.scale.set(0.5); 80 | this.recusrive.clearAlpha = 0.01; 81 | this.recusrive.alpha = 0.8; 82 | this.recusrive.updateFrames(); 83 | this.scene.add(this.recusrive); 84 | 85 | this.miniMap = new Tiny.MiniMap(this, 0.5); 86 | this.miniMap.delay = 1; 87 | this.scene.add(this.miniMap); 88 | } 89 | 90 | update(time, delta) { 91 | this.recusrive.update(delta); 92 | this.miniMap.update(delta); 93 | } 94 | 95 | resize(width, height) { 96 | super.resize(width, height); 97 | this.recusrive.resize(width, height); 98 | this.miniMap.resize(width, height); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /examples/tests/Sound.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | * import "h5tiny/plugins/sound"; 5 | */ 6 | 7 | class MyGame extends Tiny.App2D { 8 | constructor(width, height) { 9 | super(width, height, 'game-container'); 10 | } 11 | 12 | preload() { 13 | this.load.image("base", resources.baseImage); 14 | this.load.sound("theme", resources.theme); 15 | this.load.sound("click", resources.sound); 16 | } 17 | 18 | create() { 19 | this.sound.loop("theme"); 20 | 21 | var sprite = new Tiny.Sprite("base"); 22 | sprite.position.set(this.width / 2, this.height / 2); 23 | sprite.anchor.set(0.5); 24 | this.scene.add(sprite); 25 | 26 | this.input.add(sprite); 27 | sprite.input.on("click", function() { 28 | this.sound.play("click"); 29 | }, this); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/tests/ThreeBasic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App3D"; 4 | * import "h5tiny/plugins/three"; 5 | */ 6 | 7 | class MyGame extends Tiny.App3D { 8 | constructor(width, height) { 9 | super(width, height, 'game-container'); 10 | } 11 | 12 | preload() { 13 | this.load.image('base', resources.baseImage); 14 | this.load.atlas('atlas', resources.atlas, resources.atlas_data); 15 | 16 | // this.cache.image["key"] 17 | // this.cache.texture["key.1"]; 18 | // this.cache.texture["key.frameName"]; 19 | 20 | this.load.gltf('gltfTest', resources.gltf, true, function (gltf) { 21 | gltf.scene.traverse(function (obj) { 22 | if (obj.isMesh) obj.geometry.computeVertexNormals(); 23 | }); 24 | }); 25 | 26 | this.load.texture3d('base', resources.baseImage); 27 | 28 | // this.cache.gltf["key"]; 29 | // this.cache.texture3d["key"]; 30 | // this.cache.mesh3d["key.meshName"]; 31 | // this.cache.animation3d["key.animationName"]; 32 | } 33 | 34 | create() { 35 | /** 36 | * Adding directional light to scene 37 | */ 38 | var light = new THREE.DirectionalLight(0xffffff, 0.8); 39 | light.position.set(15, 59, 53); 40 | light.lookAt(0, 0, 0); 41 | this.scene.add(light); 42 | 43 | /** 44 | * Adding ambient light to scene 45 | */ 46 | var alight = new THREE.AmbientLight(0xffffff, 0.3); 47 | this.scene.add(alight); 48 | 49 | /** 50 | * Creating test mesh, with texture.map from cache atlas image, 51 | * Playing with texture frame data via offset property 52 | */ 53 | var mesh = (this.mesh = new THREE.Mesh( 54 | new THREE.BoxBufferGeometry(1, 1, 1), 55 | new THREE.MeshLambertMaterial({ 56 | // color: "#ff4534", 57 | map: new THREE.Texture(this.cache.image['atlas']) 58 | }) 59 | )); 60 | // mesh.scale.set(3,3,3); 61 | var map = (window.texture = mesh.material.map); 62 | map.repeat.set(0.5, 0.5); 63 | // map.offset.set(0, 0); // BR 64 | // map.offset.set(0.5, 0); // MM 65 | map.offset.set(0, 0.5); // SB 66 | // map.offset.set(0.5, 0.5); // IH 67 | map.encoding = THREE.sRGBEncoding; 68 | map.needsUpdate = true; 69 | this.scene.add(mesh); 70 | 71 | /** 72 | * Adding scene from cache 73 | */ 74 | var car = (this.car = this.cache.gltf['gltfTest'].scene); 75 | var material = new THREE.MeshLambertMaterial({ 76 | map: this.cache.texture3d['base'] 77 | }); 78 | car.traverse(function (obj) { 79 | if (obj.isMesh) obj.material = material; 80 | }); 81 | car.position.x = 3; 82 | car.position.z = 3; 83 | this.scene.add(car); 84 | 85 | /** 86 | * Creating new mesh with geometry from cached mesh 87 | */ 88 | var mesh2 = (this.mesh2 = new THREE.Mesh( 89 | this.cache.mesh3d['gltfTest.cabin'].geometry, 90 | mesh.material 91 | )); 92 | mesh2.rotation.z = -Math.PI / 2; 93 | mesh2.position.x = -3; 94 | mesh2.position.z = -3; 95 | this.scene.add(mesh2); 96 | 97 | /** 98 | * Getting ang clonning mesh from cache 99 | */ 100 | this.scene.add(game.cache.mesh3d['gltfTest.cabin'].clone()); 101 | 102 | /** 103 | * Creating new Tiny.Text3D object which is avaiable on three plugin 104 | */ 105 | var text = new Tiny.Text3D('Hello World', { 106 | font: 'bold 30pt Courier', 107 | fill: '#ffffff', 108 | wordWrap: true, 109 | wordWrapWidth: 100, 110 | align: 'center', 111 | size: 4 112 | }); 113 | this.scene.add(text); 114 | } 115 | 116 | update(time, delta) { 117 | this.mesh.rotation.x += delta * 0.001; 118 | this.mesh2.rotation.z += delta * 0.001; 119 | this.car.rotation.y += delta * 0.001; 120 | this.mesh.position.x = Math.sin(time * 0.0001); 121 | this.mesh.position.z = 1 + Math.sin(time * 0.0001); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /examples/tests/ThreeCanvas.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App3D"; 4 | * import "h5tiny/plugins/three"; 5 | */ 6 | 7 | class MyGame extends Tiny.App3D { 8 | constructor(width, height) { 9 | super(width, height, 'game-container'); 10 | } 11 | 12 | preload() { 13 | this.load.image('base', resources.baseImage); 14 | } 15 | 16 | create() { 17 | const light = new THREE.DirectionalLight(0xffffff, 1); 18 | light.position.set(15, 59, 53); 19 | light.lookAt(0, 0, 0); 20 | this.scene.add(light); 21 | 22 | const mesh = (this.mesh = new THREE.Mesh( 23 | new THREE.BoxBufferGeometry(1, 1, 1), 24 | new THREE.MeshLambertMaterial({ 25 | color: '#ff4534' 26 | }) 27 | )); 28 | 29 | mesh.material.color.convertSRGBToLinear(); 30 | 31 | this.scene.add(mesh); 32 | 33 | const text = new Tiny.Text3D('Hello World', { 34 | font: 'bold 30pt Arial', 35 | fill: '#ffffff', 36 | wordWrap: true, 37 | wordWrapWidth: 100, 38 | align: 'center', 39 | size: 4 40 | }); 41 | 42 | this.scene.add(text); 43 | 44 | const canvas2d = new Tiny.Canvas2D(300, 300); 45 | canvas2d.scale.set(4, 4, 1); 46 | canvas2d.position.z = 1.3; 47 | 48 | const sprite2d = new Tiny.Sprite('base'); 49 | canvas2d.add(sprite2d); 50 | 51 | const text2d = new Tiny.Text('Hello From Canvas 2D', { 52 | font: 'bold 30pt Arial', 53 | fill: '#ffffff', 54 | wordWrap: true, 55 | wordWrapWidth: 200, 56 | align: 'center' 57 | }); 58 | 59 | canvas2d.add(text2d); 60 | 61 | canvas2d.update(); 62 | this.mesh.add(canvas2d); 63 | 64 | const canvas3d = new Tiny.Canvas3D(300, 300); 65 | canvas3d.scale.set(4, 4, 1); 66 | canvas3d.position.z = 1.3; 67 | canvas3d.position.x = 3.3; 68 | canvas3d.material.side = 2; 69 | 70 | canvas3d.add(sprite2d); 71 | text2d.setText('Hello From Canvas 3D'); 72 | canvas3d.add(text2d); 73 | 74 | canvas3d.update(); 75 | this.mesh.add(canvas3d); 76 | } 77 | 78 | update(time, delta) { 79 | this.mesh.rotation.x += delta * 0.005; 80 | this.mesh.position.x = Math.sin(time * 0.001); 81 | this.mesh.position.z = 1 + Math.sin(time * 0.001); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /examples/tests/ThreeScreen2D.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App3D"; 4 | * import "h5tiny/plugins/three"; 5 | */ 6 | 7 | class MyGame extends Tiny.App3D { 8 | constructor(width, height) { 9 | super(width, height, 'game-container'); 10 | } 11 | 12 | preload() { 13 | this.load.image('base', resources.baseImage); 14 | this.load.atlas('atlas', resources.atlas, resources.atlas_data); 15 | } 16 | 17 | create() { 18 | var debugText = new Tiny.Text('', { 19 | font: 'bold 30pt Arial', 20 | fill: '#ffffff', 21 | wordWrap: true, 22 | wordWrapWidth: 200, 23 | align: 'center' 24 | }); 25 | 26 | debugText.x = 200; 27 | debugText.y = 20; 28 | this.screen2d.add(debugText); 29 | 30 | const button = (this.button = new Tiny.Sprite('base')); 31 | button.x = 200; 32 | button.y = 100; 33 | 34 | this.input.add(button); 35 | button.input.on('click', function () { 36 | debugText.setText('Clicked Button'); 37 | console.log('Clicked Button'); 38 | }); 39 | 40 | // this.input.attach(button); 41 | 42 | // button.input.on("click", function() { 43 | 44 | // }) 45 | 46 | // this.input.objects.push(button); 47 | 48 | this.screen2d.add(button); 49 | 50 | button.add(new Tiny.Text('Button')); 51 | 52 | // this.screen2d.canvas.autoUpdate = true; 53 | // this.screen2d.canvas.update(); 54 | 55 | this.screen2d.scene.add( 56 | new THREE.Mesh( 57 | new THREE.BoxBufferGeometry(1, 1, 1), 58 | new THREE.MeshLambertMaterial({ color: 0xffffff }) 59 | ) 60 | ); 61 | 62 | const light = new THREE.DirectionalLight(0xffffff, 1); 63 | light.position.set(15, 59, 53); 64 | light.lookAt(0, 0, 0); 65 | this.scene.add(light); 66 | 67 | const mesh = (this.mesh = new THREE.Mesh( 68 | new THREE.BoxBufferGeometry(1, 1, 1), 69 | new THREE.MeshLambertMaterial({ color: '#ff4534' }) 70 | )); 71 | 72 | var clickMeT = new Tiny.Text3D('Click Me'); 73 | clickMeT.position.z = 0.51; 74 | mesh.add(clickMeT); 75 | 76 | var clickMeF = new Tiny.Text3D('Click Me'); 77 | clickMeF.position.y = 0.51; 78 | clickMeF.rotation.x = -Math.PI / 2; 79 | mesh.add(clickMeF); 80 | 81 | var clickMeB = new Tiny.Text3D('Click Me'); 82 | clickMeB.position.y = -0.51; 83 | clickMeB.rotation.x = Math.PI / 2; 84 | mesh.add(clickMeB); 85 | // mesh.input = new Tiny.Input.Object3D(); 86 | 87 | // mesh.input.on("click", function() { 88 | // // body... 89 | // }) 90 | 91 | // sprite.position.x = 10; 92 | // sprite.position.y = 4; 93 | 94 | this.input.add3d(mesh, { 95 | hitBox: new THREE.Vector3(2, 2, 2), 96 | transparent: true 97 | }); 98 | 99 | mesh.input.on('click', function () { 100 | debugText.setText('Click from raycaster'); 101 | console.log('Click from raycaster'); 102 | }); 103 | 104 | this.scene.add(mesh); 105 | 106 | var confetti = (this.confetti = new Tiny.Emitter(150)); 107 | confetti.x = 350; 108 | confetti.width = 800; 109 | 110 | confetti.pattern = Tiny.ConfettiParticle; 111 | 112 | confetti.makeParticles(); 113 | confetti.scale.set(0.7); 114 | 115 | confetti.flow(10000, 300, 5); 116 | 117 | this.particles.add(confetti); 118 | this.screen2d.add(confetti); 119 | 120 | var ribbon = (this.ribbon = new Tiny.Emitter(18)); 121 | ribbon.x = 350; 122 | ribbon.width = 800; 123 | 124 | ribbon.pattern = Tiny.RibbonParticle; 125 | ribbon.makeParticles(); 126 | ribbon.scale.set(0.7); 127 | 128 | ribbon.start(false, 5000, 300); 129 | 130 | this.particles.add(ribbon); 131 | this.screen2d.add(ribbon); 132 | 133 | this.bottomRightSprite = new Tiny.Sprite('base'); 134 | this.bottomRightSprite.anchor.set(0.5); 135 | 136 | this.input.add(this.bottomRightSprite, { transparent: true }); 137 | this.bottomRightSprite.input.on('click', function () { 138 | mesh.scale.set(Math.random() * 2 + 1, Math.random() * 2 + 1, Math.random() * 2 + 1); 139 | }); 140 | 141 | this.screen2d.add(this.bottomRightSprite); 142 | 143 | this.bottomRightSprite.position.set(this.width - 100, this.height - 100); 144 | 145 | this.input.on( 146 | 'move', 147 | function (e) { 148 | debugText.setText(Math.floor(e.x) + ' : ' + Math.floor(e.y)); 149 | }, 150 | this 151 | ); 152 | 153 | // this.screen2d.scene.add(mesh); 154 | } 155 | 156 | update(time, delta) { 157 | this.button.scale.x = Math.sin(time * 0.001); 158 | this.mesh.rotation.x += delta * 0.005; 159 | this.mesh.position.x = Math.sin(time * 0.001); 160 | this.mesh.position.z = 1 + Math.sin(time * 0.001); 161 | } 162 | 163 | resize(width, height) { 164 | super.resize(width, height); 165 | this.bottomRightSprite.x = width - 100; 166 | this.bottomRightSprite.y = height - 100; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /examples/tests/TilingSprite.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | * import "h5tiny/plugins/extra" 5 | * 6 | * or 7 | * 8 | * import "h5tiny/plugins/extra/objects/TilingSprite" 9 | * 10 | * To ignore unnecessary extra components 11 | * 12 | */ 13 | 14 | class MyGame extends Tiny.App2D { 15 | constructor(width, height) { 16 | super(width, height, 'game-container'); 17 | } 18 | 19 | preload() { 20 | this.load.atlas('atlas', resources.atlas, resources.atlas_data); 21 | } 22 | 23 | create() { 24 | this.sprite = new Tiny.TilingSprite('atlas', 'MM', this.width - 10, this.height - 10); 25 | this.sprite.x = this.sprite.y = 5; 26 | // this.sprite.scale.set(0.6); 27 | 28 | this.scene.add(this.sprite); 29 | } 30 | 31 | update(time, delta) { 32 | this.sprite.tilePosition.x += 0.5 * delta; 33 | this.sprite.tilePosition.y += Math.sin(time * 0.01) * 10; 34 | 35 | this.sprite.tileScale.x = this.sprite.tileScale.y = Math.sin(time * 0.0007) * 1; 36 | } 37 | 38 | resize(width, height) { 39 | super.resize(width, height); 40 | this.sprite.width = width - 10; 41 | this.sprite.height = height - 10; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /examples/tests/Tweens.js: -------------------------------------------------------------------------------- 1 | /** 2 | * import "h5tiny"; 3 | * import "h5tiny/examples/js/App2D"; 4 | */ 5 | 6 | class MyGame extends Tiny.App2D { 7 | constructor(width, height) { 8 | super(width, height, 'game-container'); 9 | } 10 | 11 | preload() { 12 | this.load.image('base', resources.baseImage); 13 | } 14 | 15 | create() { 16 | var sprite1 = new Tiny.Sprite('base'); 17 | var sprite2 = new Tiny.Sprite('base'); 18 | var sprite3 = new Tiny.Sprite('base'); 19 | var sprite4 = new Tiny.Sprite('base'); 20 | 21 | sprite1.scale.set(0.5); 22 | sprite2.scale.set(0.5); 23 | sprite3.scale.set(0.5); 24 | sprite4.scale.set(0.5); 25 | sprite1.position.set(50, 40); 26 | sprite2.position.set(50, 40 + 70); 27 | sprite3.position.set(50, 40 + 70 + 70); 28 | sprite4.position.set(50, 40 + 70 + 70 + 70); 29 | 30 | this.scene.add(sprite1); 31 | this.scene.add(sprite2); 32 | this.scene.add(sprite3); 33 | this.scene.add(sprite4); 34 | 35 | this.tweens.add(sprite1).to({ x: 200 }, 1400).start(); 36 | this.tweens.add(sprite2).to({ x: 200 }, 1000).delay(1400).repeatDelay(100).repeat(5).start(); 37 | this.tweens 38 | .add(sprite3) 39 | .to({ x: 200 }, 500) 40 | .yoyo(true) 41 | .easing(Tiny.Easing.Sinusoidal.InOut) 42 | .repeat(Infinity) 43 | .start(); 44 | var tween = this.tweens 45 | .add(sprite4) 46 | .to({ x: 200 }, 500) 47 | .yoyo(true) 48 | .easing(Tiny.Easing.Sinusoidal.InOut) 49 | .repeat(Infinity) 50 | .start(); 51 | 52 | this.timer.loop(2000, function () { 53 | if (tween.isPaused()) tween.resume(); 54 | else tween.pause(); 55 | }); 56 | 57 | /** 58 | * Easing tests 59 | */ 60 | let y = 15; 61 | 62 | for (let easeName in Tiny.Easing) { 63 | for (let fun in Tiny.Easing[easeName]) { 64 | let name = easeName + '.' + fun; 65 | let ease = Tiny.Easing[easeName][fun]; 66 | 67 | let sprite = new Tiny.Sprite('base'); 68 | sprite.scale.set(0.1); 69 | sprite.x = 400; 70 | sprite.y = y; 71 | y += 12; 72 | this.scene.add(sprite); 73 | 74 | var nameText = new Tiny.Text(name, { font: '300 7pt Courier' }); 75 | nameText.x = sprite.x - 10; 76 | nameText.y = sprite.y; 77 | nameText.anchor.x = 1; 78 | 79 | this.scene.add(nameText); 80 | 81 | this.tweens 82 | .add(sprite) 83 | .to({ x: 570 }, 2000) 84 | .yoyo(true) 85 | .repeatDelay(500) 86 | .repeat(Infinity) 87 | .easing(ease) 88 | .start(); 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "h5tiny", 3 | "version": "2.2.3", 4 | "description": "Fast and tiny JavaScript library for HTML5 game and creatives developing.", 5 | "main": "./build/tiny.js", 6 | "files": [ 7 | "src", 8 | "build", 9 | "plugins", 10 | "examples/js", 11 | "examples/jsm", 12 | "README.md" 13 | ], 14 | "directories": { 15 | "examples": "examples" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/peter-hutsul/h5tiny" 20 | }, 21 | "scripts": { 22 | "serve": "webpack-dev-server --port 3000 --open --live-reload --mode development --watch-files examples --static-directory examples", 23 | "watch": "webpack --config webpack.dev.js --watch", 24 | "dev": "start npm run watch && npm run serve", 25 | "build": "webpack --config webpack.build.js" 26 | }, 27 | "keywords": [ 28 | "2d", 29 | "html5", 30 | "canvas", 31 | "game", 32 | "tiny", 33 | "javascript", 34 | "playable", 35 | "three" 36 | ], 37 | "author": "Peter Hutsul", 38 | "license": "ISC", 39 | "devDependencies": { 40 | "terser-webpack-plugin": "^5.3.6", 41 | "three": "^0.112.1", 42 | "webpack": "^5.75.0", 43 | "webpack-cli": "^5.0.1", 44 | "webpack-dev-server": "^4.13.3" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /plugins/anim/Anim.js: -------------------------------------------------------------------------------- 1 | var noop = function () {}; 2 | 3 | var _nextId = 0; 4 | 5 | class Anim { 6 | constructor(obj, options) { 7 | this.uuid = _nextId++; 8 | this.key = options.key; 9 | this.system = options.system; 10 | this.parent = obj; 11 | this.valid = false; 12 | this.duration = options.duration || 1000; 13 | this._time = 0; 14 | this.running = false; 15 | this.repeat = options.repeat || 0; 16 | this._reverse = options.reverse || false; 17 | this.yoyo = options.yoyo || false; 18 | this.repeatDelay = options.repeatDelay || 0; 19 | this._delay = 0; 20 | this.onStart = options.onStart || noop; 21 | this.onStop = options.onStop || noop; 22 | this.onComplete = options.onComplete || noop; 23 | this.onRepeat = options.onRepeat || noop; 24 | if (options.delay) this._delay = -options.delay; 25 | this._onStartFired = false; 26 | } 27 | setValue() {} 28 | reverse() { 29 | this._reverse = !this._reverse; 30 | } 31 | start() { 32 | if (!this.running) { 33 | this.running = true; 34 | if (this.system) this.system.addAnim(this); 35 | } 36 | } 37 | pause() { 38 | if (this.running) { 39 | this.running = false; 40 | if (this.system) this.system.removeAnim(this); 41 | } 42 | } 43 | stop() { 44 | this.running = false; 45 | this._time = 0; 46 | this.setValue(0); 47 | if (this.system) this.system.removeAnim(this); 48 | this.onStop(this.parent); 49 | } 50 | update(delta) { 51 | if (!this.parent.worldTransform || !this.valid) return false; 52 | 53 | if (this.running) { 54 | if (this._delay < 0) { 55 | this._delay += delta; 56 | return true; 57 | } 58 | 59 | if (!this._onStartFired) { 60 | this._onStartFired = true; 61 | this.onStart(this.parent); 62 | } 63 | 64 | this._time += delta; 65 | if (this._time > this.duration) { 66 | if (this.repeat > 0 || this.repeat == -1) { 67 | do { 68 | this._time -= this.duration; 69 | } while (this._time > this.duration); 70 | 71 | if (this.repeat > 0) this.repeat--; 72 | 73 | if (this.repeatDelay) { 74 | this._delay = -this.repeatDelay; 75 | } 76 | 77 | if (this.yoyo) this.reverse(); 78 | this.onRepeat(this.parent); 79 | } else { 80 | this.onComplete(this.parent); 81 | this._time = this.duration; 82 | this.running = false; 83 | return false; 84 | } 85 | } 86 | var progress = this._time / this.duration; 87 | if (this._reverse) progress = 1 - progress; 88 | this.setValue(progress); 89 | } 90 | 91 | return true; 92 | } 93 | } 94 | 95 | Tiny.Anim = Anim; 96 | -------------------------------------------------------------------------------- /plugins/anim/AnimationManager.js: -------------------------------------------------------------------------------- 1 | class AnimationManager { 2 | constructor(game) { 3 | this.game = game; 4 | this.anims = {}; 5 | // this._addedAnims = {}; 6 | this.cache = {}; 7 | } 8 | 9 | create(options) { 10 | options.system = this; 11 | options.type = options.type || 'spritesheet'; 12 | this.cache[options.key] = options; 13 | // this.list.push(options); 14 | } 15 | 16 | removeAnim(animation) { 17 | var uuid = animation.uuid; 18 | delete this.anims[uuid]; 19 | // delete this._addedAnims[uuid]; 20 | 21 | // var index = this.list.indexOf(animation); 22 | // if (index > -1) this.list.splice(index, 1); 23 | } 24 | 25 | addAnim(anim) { 26 | var uuid = anim.uuid; 27 | this.anims[uuid] = anim; 28 | // this._addedAnims[uuid] = anim; 29 | } 30 | 31 | add(obj, data) { 32 | let manager = this; 33 | 34 | obj.anim = { 35 | cache: {}, 36 | data: data || {}, 37 | current: null, 38 | system: this 39 | }; 40 | 41 | obj.play = function (options) { 42 | if (obj.anim.current) manager.removeAnim(obj.anim.current); 43 | 44 | if (typeof options === 'string') options = { key: options }; 45 | 46 | var source = manager.cache[options.key]; 47 | var __class__ = Tiny.Anim[source.type]; 48 | 49 | for (var key in source) { 50 | if (options[key] === undefined) options[key] = source[key]; 51 | } 52 | 53 | var animation = new __class__(obj, options); 54 | obj.anim.current = animation; 55 | 56 | // manager.list.push(animation); 57 | animation.start(); 58 | // manager.addAnim(animation); 59 | 60 | return animation; 61 | 62 | // body... 63 | }; 64 | 65 | obj.resume = function () { 66 | obj.anim.current && obj.anim.current.start(); 67 | }; 68 | 69 | obj.pause = function () { 70 | obj.anim.current && obj.anim.current.pause(); 71 | }; 72 | 73 | obj.stop = function () { 74 | obj.anim.current && obj.anim.current.stop(); 75 | }; 76 | } 77 | 78 | update(delta) { 79 | // for (var i = 0; i < this.list.length; i++) { 80 | // this.list[i].update(delta); 81 | // } 82 | 83 | var _ids = Object.keys(this.anims); 84 | 85 | if (_ids.length === 0) return; 86 | 87 | // do { 88 | // this._addedAnims = {}; 89 | 90 | for (var i = 0; i < _ids.length; i++) { 91 | var anim = this.anims[_ids[i]]; 92 | 93 | if (anim && anim.update(delta) === false) { 94 | // anim.running = false; 95 | 96 | // if (!preserve) { 97 | delete this.anims[_ids[i]]; 98 | // } 99 | } 100 | } 101 | 102 | // _ids = Object.keys(this._addedAnims); 103 | 104 | // } while (_ids.length > 0); 105 | 106 | // while (ids.length > 0) { 107 | // this._addedAnims = {}; 108 | 109 | // for (var i = 0; i < ids.length; i++) { 110 | // var anim = this.anims[ids[i]]; 111 | 112 | // if (anim && anim.update(delta) === false) { 113 | // // anim.running = false; 114 | 115 | // // if (!preserve) { 116 | // delete this.anims[ids[i]]; 117 | // // } 118 | // } 119 | // } 120 | 121 | // ids = Object.keys(this._addedAnims); 122 | // } 123 | 124 | return true; 125 | } 126 | 127 | destroy(clearCache) { 128 | // this.list.length = 0; 129 | this.cache = {}; 130 | this.anims = {}; 131 | // this._addedAnims = {}; 132 | } 133 | } 134 | 135 | Tiny.registerSystem('anim', AnimationManager); 136 | -------------------------------------------------------------------------------- /plugins/anim/Loader.js: -------------------------------------------------------------------------------- 1 | Tiny.Cache.keyframes = {}; 2 | 3 | Tiny.Loader.prototype.keyframes = function (key, src) { 4 | if (src) { 5 | this.list.push({ 6 | key: key, 7 | src: src, 8 | type: 'keyframes' 9 | }); 10 | } 11 | }; 12 | 13 | Tiny.Loader.keyframes = function (resource, cb) { 14 | Tiny.Cache.keyframes[resource.key] = resource.src; 15 | cb(); 16 | }; 17 | -------------------------------------------------------------------------------- /plugins/anim/SpritesheetAnim.js: -------------------------------------------------------------------------------- 1 | class SpritesheetAnim extends Tiny.Anim { 2 | constructor(obj, options) { 3 | super(obj, options); 4 | 5 | this.frames = []; 6 | this.currentIndex = 0; 7 | 8 | var data = options.data; 9 | 10 | if (typeof data === 'string') { 11 | data = { key: data }; 12 | } 13 | 14 | if (Array.isArray(data)) this.frames = data; 15 | else if (data.key) { 16 | var texture = Tiny.Cache.texture[data.key + '.0']; 17 | 18 | if (texture) { 19 | var from = data.from || 0; 20 | var to = data.to || texture.lastFrame; 21 | 22 | for (var frame = from; frame <= to; frame++) { 23 | this.frames.push(texture.key + '.' + frame); 24 | } 25 | } 26 | } 27 | 28 | if (this.frames.length > 0) { 29 | if (options.fps) this.duration = (1000 / options.fps) * this.frames.length; 30 | 31 | this.valid = true; 32 | } 33 | } 34 | 35 | reverse() { 36 | super.reverse(); 37 | if (!this.repeatDelay) this._time += this.duration / this.frames.length; 38 | } 39 | 40 | setValue(progress) { 41 | var index = (this.frames.length * progress) | 0; 42 | if (index > this.frames.length - 1) index = this.frames.length - 1; 43 | 44 | // console.log(index); 45 | 46 | if (index != this.currentIndex) { 47 | this.currentIndex = index; 48 | // if (this.reverse) index = this.frames.length - index - 1; 49 | var frame = this.frames[index]; 50 | 51 | // console.log(index); 52 | var texture = Tiny.Cache.texture[frame]; 53 | 54 | // texture && 55 | this.parent.setTexture(texture); 56 | // this.parent.setTexture(Tiny.Cache.texture[this.texture.key + "." +frame]); 57 | // console.log(progress); 58 | } 59 | } 60 | } 61 | 62 | Tiny.Anim.spritesheet = SpritesheetAnim; 63 | -------------------------------------------------------------------------------- /plugins/anim/index.js: -------------------------------------------------------------------------------- 1 | require('./Anim'); 2 | require('./SpritesheetAnim'); 3 | require('./KeyframesAnim'); 4 | require('./AnimationManager'); -------------------------------------------------------------------------------- /plugins/create/index.js: -------------------------------------------------------------------------------- 1 | Tiny.Create = {}; 2 | 3 | require('./spritesheet'); -------------------------------------------------------------------------------- /plugins/create/spritesheet.js: -------------------------------------------------------------------------------- 1 | Tiny.Create.spritesheet = function spritesheet(options) { 2 | var resolution = options.resolution || 1; 3 | var frameWidth = (resolution * options.width) | 0; 4 | var frameHeight = (resolution * options.height) | 0; 5 | var frames = options.frames; 6 | var key = options.key; 7 | var lastFrame = frames - 1; 8 | 9 | var totalWidth = frameWidth * options.frames; 10 | var renderer = Tiny.defaultRenderer; 11 | 12 | var textureBuffer = new Tiny.CanvasBuffer(totalWidth, frameHeight); 13 | 14 | var tmpMatrix = new Tiny.Matrix(); 15 | // var scale = 16 | // tmpMatrix.scale(0.5, 0.5); 17 | 18 | var uuid, texture, frame, displayObject, bounds, wt, context; 19 | 20 | for (var index = 0; index < frames; index++) { 21 | frame = new Tiny.Rectangle(frameWidth * index, 0, frameWidth, frameHeight); 22 | 23 | context = textureBuffer.context; 24 | 25 | displayObject = options.draw((index + 1) / frames, context, frame); 26 | 27 | if(displayObject) { 28 | 29 | bounds = displayObject.getBounds(); 30 | // console.log(bounds.x, bounds.y, bounds.width, bounds.height); 31 | 32 | // tmpMatrix.translate() 33 | tmpMatrix.tx = -bounds.x + frame.x; 34 | tmpMatrix.ty = -bounds.y; 35 | 36 | wt = displayObject.worldTransform; 37 | wt.tx = options.width * index + options.width / 2; 38 | wt.ty = options.height / 2; 39 | // wt.identity(); 40 | // wt.scale(0.5, 0.5); 41 | // wt.a = 0.5; 42 | // wt.d = 0.5; 43 | 44 | // console.log(wt.a, wt.d) 45 | 46 | // wt.append(tmpMatrix); 47 | // console.log(wt.a, wt.d) 48 | 49 | // displayObject.width = 50; 50 | // displayObject.height = 50; 51 | 52 | // setWorld Alpha to ensure that the object is renderer at full opacity 53 | displayObject.worldAlpha = 1; 54 | 55 | // Time to update all the children of the displayObject with the new matrix.. 56 | var children = displayObject.children; 57 | 58 | for (var i = 0, j = children.length; i < j; i++) { 59 | children[i].updateTransform(); 60 | } 61 | 62 | var realResolution = renderer.resolution; 63 | 64 | renderer.resolution = resolution; 65 | 66 | renderer.renderObject(displayObject, context); 67 | 68 | // if (__DEBUG__) { 69 | // context.resetTransform(); 70 | // context.rect(frame.x, frame.y, frame.width, frame.height); 71 | // context.stroke(); 72 | // } 73 | 74 | renderer.resolution = realResolution; 75 | } 76 | 77 | uuid = key + '.' + index; 78 | 79 | texture = new Tiny.Texture(textureBuffer.canvas, frame); 80 | 81 | texture.key = key; 82 | texture.lastFrame = lastFrame; 83 | 84 | Tiny.Cache.texture[uuid] = texture; 85 | } 86 | 87 | Tiny.Cache.texture[key] = new Tiny.Texture(textureBuffer.canvas); 88 | 89 | // return renderTexture; 90 | }; 91 | -------------------------------------------------------------------------------- /plugins/extra/index.js: -------------------------------------------------------------------------------- 1 | require('./systems/Tween'); 2 | require('./systems/Loader'); 3 | require('./math/Ellipse'); 4 | require('./objects/TilingSprite'); 5 | require('./objects/RenderLayer'); 6 | require('./objects/ProgressBar'); 7 | require('./objects/Opaque'); 8 | // require('./objects/Button'); 9 | require('./textures/Texture'); 10 | -------------------------------------------------------------------------------- /plugins/extra/math/Ellipse.js: -------------------------------------------------------------------------------- 1 | Tiny.Ellipse = function (x, y, width, height) { 2 | x = x || 0; 3 | y = y || 0; 4 | width = width || 0; 5 | height = height || 0; 6 | 7 | this.x = x || 0; 8 | this.y = y || 0; 9 | 10 | this.width = width || 0; 11 | this.height = height || 0; 12 | 13 | this.type = Tiny.Primitives.ELIP; 14 | }; 15 | 16 | Tiny.Ellipse.prototype.constructor = Tiny.Ellipse; 17 | 18 | Tiny.Graphics.prototype.drawEllipse = function (x, y, width, height) { 19 | this.drawShape(new Tiny.Ellipse(x, y, width, height)); 20 | 21 | return this; 22 | }; 23 | -------------------------------------------------------------------------------- /plugins/extra/objects/Button.js: -------------------------------------------------------------------------------- 1 | Tiny.Button = function(input, params) { 2 | 3 | var options; 4 | 5 | if (typeof params === "string") { 6 | options = { 7 | label: params, 8 | width: 160, 9 | height: 40 10 | } 11 | } 12 | else { 13 | options = params; 14 | options.width = options.width || 160; 15 | options.height = options.height || 40; 16 | } 17 | 18 | var bg = new Tiny.Graphics(); 19 | bg.beginFill("#4e63df"); 20 | bg.drawRoundedRect(0, 0, options.width, options.height, 10); 21 | bg.endFill(); 22 | bg.lineStyle(5, "#3e4fb2", 1); 23 | bg.drawRoundedRect(0, 0, options.width, options.height, 10); 24 | 25 | Tiny.Sprite.call(this, bg.generateTexture()); 26 | 27 | var label = this.label = new Tiny.Text(options.label, { 28 | fill: "#ffffff", 29 | font: "300 13pt Arial", 30 | align: "center" 31 | }); 32 | label.y = 2; 33 | label.anchor.set(0.5); 34 | this.add(label); 35 | 36 | this.anchor.set(0.5); 37 | 38 | input.add(this); 39 | 40 | input.on("move", function(e) { 41 | var bounds = this.getBounds(); 42 | if (bounds.contains(e.x, e.y)) this.tint = "#a1a1a1" 43 | else this.tint = "#ffffff" 44 | } , this) 45 | 46 | this.input.on("down", function(e) { 47 | this.scale.set(0.95); 48 | }, this) 49 | 50 | this.input.on("up", function(e) { 51 | this.scale.set(1.05); 52 | }, this) 53 | }; 54 | 55 | Tiny.Button.prototype = Object.create(Tiny.Sprite.prototype); 56 | Tiny.Button.prototype.constructor = Tiny.Button; -------------------------------------------------------------------------------- /plugins/extra/objects/Object2D.js: -------------------------------------------------------------------------------- 1 | Tiny.Object2D.prototype.removeChildren = function (beginIndex, endIndex) { 2 | var begin = beginIndex || 0; 3 | var end = typeof endIndex === "number" ? endIndex : this.children.length; 4 | var range = end - begin; 5 | 6 | if (range > 0 && range <= end) { 7 | var removed = this.children.splice(begin, range); 8 | for (var i = 0; i < removed.length; i++) { 9 | var child = removed[i]; 10 | child.parent = undefined; 11 | } 12 | return removed; 13 | } else if (range === 0 && this.children.length === 0) { 14 | return []; 15 | } else { 16 | throw new Error("removeChildren: Range Error, numeric values are outside the acceptable range"); 17 | } 18 | }; -------------------------------------------------------------------------------- /plugins/extra/objects/Opaque.js: -------------------------------------------------------------------------------- 1 | Tiny.Opaque = function (options) { 2 | // Tiny.BaseObject2D.call(this); 3 | 4 | var game = (this.game = options.game); 5 | this.visible = true; 6 | this._bounds = new Tiny.Rectangle(0, 0, 1, 1); 7 | this.color = options.color || '#000000'; 8 | this.alpha = options.alpha || 0.5; 9 | 10 | if (options.input !== false) { 11 | game.input.add(this, { transparent: options.transparent }); 12 | } 13 | }; 14 | 15 | // Tiny.Opaque.prototype = Object.create(Tiny.BaseObject2D.prototype); 16 | Tiny.Opaque.prototype.constructor = Tiny.Opaque; 17 | 18 | Tiny.Opaque.prototype.destroy = function () {}; 19 | Tiny.Opaque.prototype.updateTransform = function () {}; 20 | 21 | Object.defineProperty(Tiny.Opaque.prototype, "worldVisible", { 22 | get: function () { 23 | return this.visible; 24 | } 25 | }); 26 | 27 | Tiny.Opaque.prototype.getBounds = function () { 28 | this._bounds.setTo(0, 0, this.game.width, this.game.height); 29 | return this._bounds; 30 | }; 31 | 32 | Tiny.Opaque.prototype.render = function (renderSession) { 33 | if (this.visible === false || this.alpha === 0) return; 34 | 35 | renderSession.context.resetTransform(); 36 | 37 | renderSession.context.globalAlpha = this.alpha; 38 | renderSession.context.fillStyle = this.color; 39 | renderSession.context.fillRect( 40 | 0, 41 | 0, 42 | renderSession.context.canvas.width, 43 | renderSession.context.canvas.height 44 | ); 45 | }; 46 | -------------------------------------------------------------------------------- /plugins/extra/objects/ProgressBar.js: -------------------------------------------------------------------------------- 1 | var defaultOptions = { 2 | bgColor: "#ffffff", 3 | bgAlpha: 1, 4 | value: 1, 5 | width: 230, 6 | height: 30, 7 | radius: 15, 8 | colors: ["#ff0000", "#ffc322", "#08c013"], 9 | animated: true, 10 | duration: 1000, 11 | easing: Tiny.Easing.Cubic.InOut, 12 | strokeColor: "#e1e1e1", 13 | strokeWidth: 0, 14 | strokeAlpha: 1, 15 | resolution: 1 16 | }; 17 | 18 | Tiny.ProgressBar = function (options) { 19 | options = options || {}; 20 | 21 | for (var key in defaultOptions) { 22 | if (options[key] == undefined) options[key] = defaultOptions[key]; 23 | } 24 | 25 | var graphics = new Tiny.Graphics(); 26 | 27 | graphics.beginFill(options.bgColor, options.bgAlpha); 28 | graphics.drawRoundedRect( 29 | options.strokeWidth / 2, 30 | options.strokeWidth / 2, 31 | options.width, 32 | options.height, 33 | options.radius 34 | ); 35 | graphics.endFill(); 36 | 37 | if (options.strokeWidth) { 38 | graphics.lineStyle(options.strokeWidth, options.strokeColor, options.strokeAlpha); 39 | graphics.drawRoundedRect( 40 | 0, 41 | 0, 42 | options.width + options.strokeWidth, 43 | options.height + options.strokeWidth, 44 | options.radius + options.strokeWidth / 2 45 | ); 46 | } 47 | 48 | Tiny.Sprite.call(this, graphics.generateTexture(options.resolution)); 49 | 50 | this.anchor.set(0.5); 51 | 52 | this.game = options.game || this.game; 53 | this.animated = options.animated; 54 | this.duration = options.duration; 55 | this.easing = options.easing; 56 | this.value = options.value; 57 | this.originalWidth = options.width * options.resolution; 58 | this._tween = null; 59 | this._crop = new Tiny.Rectangle( 60 | 0, 61 | 0, 62 | options.width * options.resolution, 63 | options.height * options.resolution 64 | ); 65 | this._sprites = []; 66 | 67 | for (var i = 0; i < options.colors.length; i++) { 68 | graphics.clear(); 69 | graphics.beginFill(options.colors[i]); 70 | graphics.drawRoundedRect(0, 0, options.width, options.height, options.radius); 71 | graphics.endFill(); 72 | 73 | var colorSprite = new Tiny.Sprite(graphics.generateTexture(options.resolution)); 74 | colorSprite.anchor = this.anchor; 75 | // colorSprite.anchor.set(0.5); 76 | colorSprite.texture.crop = this._crop; 77 | this.add(colorSprite); 78 | this._sprites.push(colorSprite); 79 | } 80 | 81 | graphics.destroy(); 82 | 83 | this._setValue(this.value); 84 | }; 85 | 86 | Tiny.ProgressBar.prototype = Object.create(Tiny.Sprite.prototype); 87 | Tiny.ProgressBar.prototype.constructor = Tiny.ProgressBar; 88 | 89 | Tiny.ProgressBar.prototype._setValue = function (value) { 90 | 91 | value = Math.min(1, Math.max(0, value)); 92 | 93 | if (value == this._value) return; 94 | 95 | this._value = value; 96 | 97 | this._crop.width = this.originalWidth * value; 98 | 99 | if (value == 0 || this._sprites.length === 1) return; 100 | if (value == 1) { 101 | this._sprites[this._sprites.length - 1].alpha = 1; 102 | return; 103 | } 104 | 105 | var step; 106 | if (this._sprites.length == 2) { 107 | this._sprites[1].alpha = value; 108 | } else if (this._sprites.length == 3) { 109 | step = 0.5; 110 | var lerp; 111 | 112 | if (value >= step) { 113 | lerp = 1 - (1 - value) / step; 114 | this._sprites[1].alpha = 1; 115 | this._sprites[2].alpha = lerp * lerp; 116 | } else if (value < step) { 117 | lerp = (1 - value - step) / step; 118 | this._sprites[1].alpha = 1 - lerp * lerp; 119 | this._sprites[2].alpha = 0; 120 | } 121 | } else { 122 | var mixes = this._sprites.length - 1; 123 | step = 1 / mixes; 124 | 125 | var index = Math.floor(value * mixes) + 1; 126 | var alpha = (value - step * (index - 1)) / step; 127 | 128 | for (var i = 0; i < this._sprites.length; i++) { 129 | this._sprites[i].alpha = 0; 130 | } 131 | 132 | this._sprites[index - 1].alpha = 1; 133 | this._sprites[index].alpha = alpha; 134 | } 135 | }; 136 | 137 | Tiny.ProgressBar.prototype.setValue = function (value) { 138 | value = Math.min(1, Math.max(0, value)); 139 | this.value = value; 140 | 141 | if (this.animated) { 142 | if (this._tween) this._tween.stop(); 143 | 144 | var _self = this; 145 | 146 | var tmpObj = { value: _self._value }; 147 | 148 | this._tween = this.game.tweens 149 | .add(tmpObj) 150 | .to({ value: value }, this.duration) 151 | .easing(this.easing) 152 | .onUpdate(function () { 153 | _self._setValue(tmpObj.value); 154 | }) 155 | .start(); 156 | } else { 157 | this._setValue(value); 158 | } 159 | }; 160 | 161 | Tiny.ProgressBar.defaultOptions = defaultOptions; 162 | -------------------------------------------------------------------------------- /plugins/extra/objects/RenderLayer.js: -------------------------------------------------------------------------------- 1 | Tiny.RenderLayer = function () { 2 | Tiny.Object2D.call(this); 3 | }; 4 | 5 | Tiny.RenderLayer.prototype = Object.create(Tiny.Object2D.prototype); 6 | Tiny.RenderLayer.prototype.constructor = Tiny.RenderLayer; 7 | 8 | var noop = function () {}; 9 | 10 | Tiny.RenderLayer.prototype.addChildAt = function (child, index) { 11 | if (index >= 0 && index <= this.children.length) { 12 | 13 | child._RenderLayer_render = child.render; 14 | child.render = noop; 15 | 16 | this.children.splice(index, 0, child); 17 | 18 | return child; 19 | } else { 20 | throw new Error( 21 | child + "addChildAt: The index " + index + " supplied is out of bounds " + this.children.length 22 | ); 23 | } 24 | }; 25 | 26 | Tiny.RenderLayer.prototype.removeChildAt = function (index) { 27 | var child = this.getChildAt(index); 28 | this.children.splice(index, 1); 29 | 30 | child.render = child._RenderLayer_render; 31 | child._RenderLayer_render = null; 32 | 33 | return child; 34 | }; 35 | 36 | Tiny.RenderLayer.prototype.updateTransform = function () {} 37 | 38 | 39 | Tiny.RenderLayer.prototype.render = function (renderSession) { 40 | if (this.visible === false || this.alpha === 0) return; 41 | 42 | if (this._cacheAsBitmap) { 43 | this._renderCachedSprite(renderSession); 44 | return; 45 | } 46 | 47 | if (this._mask) { 48 | renderSession.maskManager.pushMask(this._mask, renderSession); 49 | } 50 | 51 | for (var i = 0; i < this.children.length; i++) { 52 | this.children[i]._RenderLayer_render(renderSession); 53 | } 54 | 55 | if (this._mask) { 56 | renderSession.maskManager.popMask(renderSession); 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /plugins/extra/systems/Loader.js: -------------------------------------------------------------------------------- 1 | Tiny.Cache.font = {}; 2 | 3 | Tiny.Loader.prototype.font = function (key, src, weight) { 4 | this.list.push({ 5 | key: key, 6 | src: src, 7 | weight: weight, 8 | type: "font" 9 | }); 10 | }; 11 | 12 | Tiny.Loader.font = function (resource, cb) { 13 | 14 | var weight = resource.weight || 'normal'; 15 | var key = resource.key + '-' + weight; 16 | 17 | if (Tiny.Cache.font[key]) return cb(); 18 | 19 | var font = new FontFace(resource.key, 'url(' + resource.src + ')', { weight: weight }); 20 | font.load().then( 21 | function () { 22 | document.fonts.add(font); 23 | Tiny.Cache.font[key] = font; 24 | cb(); 25 | }, 26 | function () { 27 | console.error(err); 28 | } 29 | ); 30 | }; -------------------------------------------------------------------------------- /plugins/extra/systems/Tween.js: -------------------------------------------------------------------------------- 1 | Tiny.TweenManager.prototype.removeByObject = function (obj) { 2 | var tweens = this.group._tweens; 3 | var tweenIds = Object.keys(tweens); 4 | 5 | for (var i = 0; i < tweenIds.length; i++) { 6 | var tween = tweens[tweenIds[i]]; 7 | 8 | if (tween._object === obj) this.remove(tween); 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /plugins/extra/textures/Texture.js: -------------------------------------------------------------------------------- 1 | Tiny.Texture.EMPTY = new Tiny.Texture({}, new Tiny.Rectangle(), new Tiny.Rectangle()); -------------------------------------------------------------------------------- /plugins/particles/Particle.js: -------------------------------------------------------------------------------- 1 | Tiny.Particle = function (emitter) { 2 | Tiny.BaseObject2D.call(this); 3 | 4 | this.parent = emitter; 5 | 6 | this.anchor = new Tiny.Point(); 7 | 8 | this.texture = { valid: false }; 9 | 10 | this._frame = 0; 11 | 12 | this.lifespan = 0; 13 | }; 14 | 15 | Tiny.Particle.prototype = Object.create(Tiny.BaseObject2D.prototype); 16 | Tiny.Particle.prototype.constructor = Tiny.Particle; 17 | 18 | Tiny.Particle.prototype.setTexture = function (texture, key) { 19 | if (typeof texture == "string") { 20 | var imagePath = texture; 21 | 22 | if (key != undefined) { 23 | imagePath = imagePath + "_" + key; 24 | } 25 | 26 | texture = Tiny.Cache.texture[imagePath]; 27 | 28 | if (!texture) texture = new Tiny.Texture(imagePath); 29 | } 30 | 31 | this.texture = texture; 32 | }; 33 | 34 | Object.defineProperty(Tiny.Particle.prototype, "frameName", { 35 | get: function () { 36 | return this.texture.frame.name; 37 | }, 38 | 39 | set: function (value) { 40 | if (this.texture.frame.name) { 41 | this.setTexture(Tiny.TextureCache[this.texture.key + "_" + value]); 42 | } 43 | } 44 | }); 45 | 46 | Object.defineProperty(Tiny.Particle.prototype, "frame", { 47 | get: function () { 48 | return this._frame; 49 | }, 50 | 51 | set: function (value) { 52 | if (this.texture.max_no_frame) { 53 | this._frame = value; 54 | if (this._frame > this.texture.max_no_frame) this._frame = 0; 55 | this.setTexture(Tiny.TextureCache[this.texture.key + "_" + this._frame]); 56 | } 57 | } 58 | }); 59 | 60 | Tiny.Particle.prototype.drawTexture = function (renderSession) { 61 | var dx = this.anchor.x * -this.texture.frame.width; 62 | var dy = this.anchor.y * -this.texture.frame.height; 63 | 64 | var resolution = this.texture.resolution / renderSession.resolution; 65 | 66 | renderSession.context.drawImage( 67 | this.texture.source, 68 | this.texture.crop.x, 69 | this.texture.crop.y, 70 | this.texture.crop.width, 71 | this.texture.crop.height, 72 | dx / resolution, 73 | dy / resolution, 74 | this.texture.crop.width / resolution, 75 | this.texture.crop.height / resolution 76 | ); 77 | }; 78 | 79 | Tiny.Particle.prototype.reset = function (x, y) { 80 | this.x = x || 0; 81 | this.y = y || 0; 82 | 83 | this.alpha = 1; 84 | this.scale.set(1); 85 | }; 86 | 87 | Tiny.Particle.prototype.update = function (time, delta) {}; 88 | 89 | Tiny.Particle.prototype.onEmit = function () {}; 90 | 91 | Tiny.Particle.prototype.draw = function (renderSession) {}; 92 | 93 | Tiny.Particle.prototype._update = function (delta) { 94 | if (this.visible === false) return false; 95 | 96 | this.lifespan -= delta; 97 | 98 | if (this.lifespan <= 0) { 99 | this.visible = false; 100 | return false; 101 | } 102 | 103 | this.update(this.lifespan, delta); 104 | }; 105 | 106 | Tiny.Particle.prototype.render = function (renderSession) { 107 | if (this.visible === false || this.alpha === 0) return; 108 | 109 | this.updateTransform(); 110 | 111 | renderSession.context.globalAlpha = this.worldAlpha; 112 | 113 | renderSession.context.setTransform( 114 | this.worldTransform.a, 115 | this.worldTransform.b, 116 | this.worldTransform.c, 117 | this.worldTransform.d, 118 | this.worldTransform.tx * renderSession.resolution, 119 | this.worldTransform.ty * renderSession.resolution 120 | ); 121 | 122 | if (this.texture.valid) this.drawTexture(renderSession); 123 | else this.draw(renderSession.context, renderSession.resolution); 124 | }; 125 | -------------------------------------------------------------------------------- /plugins/particles/index.js: -------------------------------------------------------------------------------- 1 | Tiny.Particles = function (game) { 2 | this.game = game; 3 | 4 | this.list = []; 5 | }; 6 | 7 | Tiny.Particles.prototype = { 8 | add: function (emitter) { 9 | emitter.system = this; 10 | 11 | this.list.push(emitter); 12 | 13 | return emitter; 14 | }, 15 | 16 | remove: function (emitter) { 17 | var indexOf = this.list.indexOf(emitter); 18 | 19 | if (indexOf > -1) { 20 | var emitter = this.list.splice(indexOf, 1); 21 | emitter.system = null; 22 | return emitter; 23 | } 24 | }, 25 | 26 | update: function (delta) { 27 | var i = this.list.length; 28 | 29 | while (i--) { 30 | this.list[i].update(delta); 31 | } 32 | }, 33 | 34 | destroy: function () { 35 | this.list.length = 0; 36 | } 37 | }; 38 | 39 | Tiny.Particles.prototype.constructor = Tiny.Particles; 40 | 41 | require("./Particle"); 42 | require("./Emitter"); 43 | 44 | Tiny.registerSystem("particles", Tiny.Particles); 45 | -------------------------------------------------------------------------------- /plugins/sound/index.js: -------------------------------------------------------------------------------- 1 | var context = window; 2 | 3 | class SoundManager { 4 | constructor(game) { 5 | this.game = game; 6 | } 7 | 8 | volume(vol) { 9 | if (context.Howler) { 10 | context.Howler.volume(vol); 11 | } 12 | } 13 | 14 | loop(audio, volume) { 15 | var sound = Tiny.Cache.sound[audio]; 16 | 17 | if (sound) { 18 | if (volume !== undefined) { 19 | sound.volume(volume); 20 | } 21 | 22 | sound.loop(true); 23 | sound.play(); 24 | } 25 | 26 | return sound; 27 | } 28 | 29 | play(audio, volume) { 30 | var sound = Tiny.Cache.sound[audio]; 31 | 32 | if (sound) { 33 | if (context.Howler.state === "running") { 34 | if (volume !== undefined) { 35 | sound.volume(volume); 36 | } 37 | 38 | sound.play(); 39 | } 40 | } 41 | 42 | return sound; 43 | } 44 | 45 | fade(audio, volume, duration) { 46 | var sound = Tiny.Cache.sound[audio]; 47 | 48 | if (volume == undefined) volume = 1; 49 | if (duration == undefined) duration = 600; 50 | 51 | if (sound) { 52 | if (context.Howler.state === "running") { 53 | sound.fade(volume, 0, duration); 54 | 55 | sound.play(); 56 | } 57 | } 58 | 59 | return sound; 60 | } 61 | 62 | destroy(clearCache) { 63 | for (var y in Tiny.Cache.sound) Tiny.Cache.sound[y].stop(); 64 | 65 | if (clearCache) { 66 | for (var y in Tiny.Cache.sound) Tiny.Cache.sound[y].unload(); 67 | } 68 | } 69 | } 70 | 71 | Tiny.Cache.sound = {}; 72 | 73 | Tiny.Loader.prototype.sound = function (key, src) { 74 | if (src) { 75 | this.list.push({ 76 | key: key, 77 | src: src, 78 | type: "sound" 79 | }); 80 | } 81 | }; 82 | 83 | Tiny.Loader.sound = function (resource, cb) { 84 | 85 | if (Tiny.Cache.sound[resource.key]) return cb(); 86 | 87 | var sound = new window.Howl({ 88 | src: [resource.src] 89 | }); 90 | 91 | sound.once("load", function () { 92 | Tiny.Cache.sound[resource.key] = sound; 93 | cb(); 94 | }); 95 | }; 96 | 97 | // Tiny.SoundManager = SoundManager; 98 | Tiny.registerSystem("sound", SoundManager); 99 | -------------------------------------------------------------------------------- /plugins/three/index.js: -------------------------------------------------------------------------------- 1 | require("./objects/Canvas2D"); 2 | require("./objects/Canvas3D"); 3 | require("./objects/Text3D"); 4 | require("./objects/Screen2D"); 5 | 6 | require("./systems/Loader"); 7 | require("./systems/Input"); 8 | -------------------------------------------------------------------------------- /plugins/three/objects/Canvas2D.js: -------------------------------------------------------------------------------- 1 | var THREE = require("three"), 2 | Sprite = THREE.Sprite, 3 | SpriteMaterial = THREE.SpriteMaterial, 4 | CanvasTexture = THREE.CanvasTexture, 5 | sRGBEncoding = THREE.sRGBEncoding, 6 | LinearFilter = THREE.LinearFilter; 7 | 8 | class Canvas2D extends Sprite { 9 | constructor(width, height) { 10 | const renderer = new Tiny.CanvasRenderer(width, height, { transparent: true }); 11 | // renderer.setClearColor("#ffffff"); 12 | 13 | const canvasTexture = new CanvasTexture(renderer.domElement); 14 | canvasTexture.encoding = sRGBEncoding; 15 | canvasTexture.minFilter = LinearFilter; 16 | 17 | const material = new SpriteMaterial({ 18 | map: canvasTexture 19 | // color: 0x00ffff, 20 | // depthWrite: false 21 | }); 22 | 23 | super(material); 24 | 25 | this.width = width; 26 | this.height = height; 27 | this.autoUpdate = false; 28 | this.renderer = renderer; 29 | const container = (this.container = new Tiny.Scene()); 30 | this.texture = canvasTexture; 31 | 32 | this.add = container.add.bind(container); 33 | this.remove = container.remove.bind(container); 34 | } 35 | 36 | onBeforeRender() { 37 | this.autoUpdate && this.update(); 38 | } 39 | 40 | update() { 41 | this.renderer.render(this.container); 42 | 43 | this.texture.needsUpdate = true; 44 | } 45 | } 46 | 47 | Tiny.Canvas2D = Canvas2D; 48 | -------------------------------------------------------------------------------- /plugins/three/objects/Canvas3D.js: -------------------------------------------------------------------------------- 1 | var THREE = require("three"), 2 | Mesh = THREE.Mesh, 3 | MeshBasicMaterial = THREE.MeshBasicMaterial, 4 | CanvasTexture = THREE.CanvasTexture, 5 | sRGBEncoding = THREE.sRGBEncoding, 6 | LinearFilter = THREE.LinearFilter, 7 | PlaneBufferGeometry = THREE.PlaneBufferGeometry; 8 | 9 | var geometry = null; 10 | 11 | class Canvas3D extends Mesh { 12 | constructor(width, height) { 13 | const renderer = new Tiny.CanvasRenderer(width, height, { transparent: true }); 14 | // renderer.setClearColor("#ffffff"); 15 | 16 | const canvasTexture = new CanvasTexture(renderer.domElement); 17 | canvasTexture.encoding = sRGBEncoding; 18 | canvasTexture.minFilter = LinearFilter; 19 | 20 | const material = new MeshBasicMaterial({ 21 | map: canvasTexture, 22 | transparent: true 23 | }); 24 | 25 | if (geometry == null) geometry = new PlaneBufferGeometry(1, 1); 26 | 27 | super(geometry, material); 28 | 29 | this.width = width; 30 | this.height = height; 31 | this.autoUpdate = false; 32 | this.renderer = renderer; 33 | const container = (this.container = new Tiny.Scene()); 34 | this.texture = canvasTexture; 35 | 36 | this.add = container.add.bind(container); 37 | this.remove = container.remove.bind(container); 38 | } 39 | 40 | onBeforeRender() { 41 | this.autoUpdate && this.update(); 42 | } 43 | 44 | update() { 45 | this.renderer.render(this.container); 46 | 47 | this.texture.needsUpdate = true; 48 | } 49 | } 50 | 51 | Tiny.Canvas3D = Canvas3D; 52 | -------------------------------------------------------------------------------- /plugins/three/objects/Screen2D.js: -------------------------------------------------------------------------------- 1 | var THREE = require("three"), 2 | Scene = THREE.Scene, 3 | OrthographicCamera = THREE.OrthographicCamera; 4 | 5 | class Screen2D extends Tiny.Canvas2D { 6 | constructor(width, height) { 7 | super(width, height); 8 | 9 | this.autoUpdate = true; 10 | 11 | this.scene = new Scene(); 12 | this.camera = new OrthographicCamera( 13 | -this.width / 2, 14 | this.width / 2, 15 | this.height / 2, 16 | -this.height / 2, 17 | 1, 18 | 10 19 | ); 20 | 21 | this.scale.set(this.width, this.height, 1); 22 | this.camera.position.z = 1; 23 | this.scene.add(this); 24 | 25 | // this.setSize(this.width, this.height) 26 | // const renderer = new Tiny.CanvasRenderer(width, height, { transparent: true }); 27 | // // renderer.setClearColor(0xffffff, 0.1); 28 | 29 | // const scene = new Tiny.Scene(); 30 | 31 | // const canvasTexture = new CanvasTexture(renderer.view); 32 | // canvasTexture.encoding = sRGBEncoding; 33 | // canvasTexture.minFilter = LinearFilter; 34 | 35 | // const material = new SpriteMaterial({ 36 | // map: canvasTexture, 37 | // // color: 0x00ffff, 38 | // // depthWrite: false 39 | // }); 40 | 41 | // super(material); 42 | 43 | // this.width = width; 44 | // this.height = height; 45 | // this.autoUpdate = false; 46 | // this.renderer = renderer; 47 | // this.scene = scene; 48 | // this.texture = canvasTexture; 49 | 50 | // this.add = scene.add.bind(scene); 51 | // this.remove = scene.remove.bind(scene); 52 | } 53 | 54 | setSize(width, height) { 55 | this.renderer.resize(width, height); 56 | 57 | this.width = width; 58 | this.height = height; 59 | 60 | this.camera.left = -this.width / 2; 61 | this.camera.right = this.width / 2; 62 | this.camera.top = this.height / 2; 63 | this.camera.bottom = -this.height / 2; 64 | this.camera.updateProjectionMatrix(); 65 | 66 | this.scale.set(this.width, this.height, 1); 67 | } 68 | } 69 | 70 | Tiny.Screen2D = Screen2D; 71 | -------------------------------------------------------------------------------- /plugins/three/objects/Text3D.js: -------------------------------------------------------------------------------- 1 | var THREE = require("three"), 2 | Mesh = THREE.Mesh, 3 | MeshBasicMaterial = THREE.MeshBasicMaterial, 4 | CanvasTexture = THREE.CanvasTexture, 5 | sRGBEncoding = THREE.sRGBEncoding, 6 | LinearFilter = THREE.LinearFilter, 7 | PlaneBufferGeometry = THREE.PlaneBufferGeometry; 8 | 9 | class Text3D extends Mesh { 10 | constructor(text, options) { 11 | options = options || {}; 12 | options.size = options.size || 1; 13 | 14 | const _text = new Tiny.Text(text, options); 15 | 16 | const canvasTexture = new CanvasTexture(_text.canvas); 17 | canvasTexture.encoding = sRGBEncoding; 18 | canvasTexture.minFilter = LinearFilter; 19 | 20 | const material = new MeshBasicMaterial({ 21 | map: canvasTexture, 22 | // color: 0xff4545, 23 | transparent: true 24 | }); 25 | 26 | const geometry = new PlaneBufferGeometry(1, 1); 27 | 28 | super(geometry, material); 29 | 30 | const max = Math.max(_text.width, _text.height); 31 | this.scale.set((options.size * _text.width) / max, (options.size * _text.height) / max, 1); 32 | 33 | this.size = options.size; 34 | this.text = _text; 35 | this.texture = canvasTexture; 36 | 37 | // this.text.updateCanvas(); 38 | } 39 | 40 | setText(text) { 41 | const _text = this.text; 42 | _text.setText(text); 43 | _text.updateText(); 44 | 45 | const max = Math.max(_text.width, _text.height); 46 | 47 | this.scale.set((this.size * _text.width) / max, (this.size * _text.height) / max, 1); 48 | 49 | this.texture.needsUpdate = true; 50 | } 51 | } 52 | 53 | Tiny.Text3D = Text3D; 54 | -------------------------------------------------------------------------------- /plugins/three/systems/Input.js: -------------------------------------------------------------------------------- 1 | var THREE = require("three"), 2 | Vector3 = THREE.Vector3, 3 | Box3 = THREE.Box3, 4 | Raycaster = THREE.Raycaster; 5 | 6 | const tempBox = new Box3(), 7 | hitBox = new Vector3(1, 1, 1), 8 | temp = new Vector3(); 9 | 10 | var ThreeInputSystem = { 11 | init: function () { 12 | this.raycaster = new Raycaster(); 13 | }, 14 | 15 | preHandle: function (x, y) { 16 | if (!this.game.camera) return; 17 | temp.set((x / this.game.width) * 2 - 1, -(y / this.game.height) * 2 + 1, 0); 18 | this.raycaster.setFromCamera(temp, this.game.camera); 19 | } 20 | }; 21 | 22 | Tiny.Input.systems.push(ThreeInputSystem); 23 | 24 | Tiny.Input.checkBounds3D = function (obj, x, y) { 25 | if (obj.input.hitBox) { 26 | hitBox.copy(obj.input.hitBox); 27 | } else { 28 | obj.getWorldScale(hitBox); 29 | } 30 | 31 | tempBox.setFromCenterAndSize(obj.position, hitBox); 32 | 33 | if (this.raycaster.ray.intersectsBox(tempBox)) { 34 | return true; 35 | } 36 | }; 37 | 38 | Tiny.Input.prototype.add3d = function (object, options) { 39 | options = options || {}; 40 | options.checkBounds = Tiny.Input.checkBounds3D; 41 | 42 | this.add(object, options); 43 | }; 44 | -------------------------------------------------------------------------------- /plugins/three/systems/Loader.js: -------------------------------------------------------------------------------- 1 | var THREE = require("three"), 2 | LoadingManager = THREE.LoadingManager, 3 | Texture = THREE.Texture, 4 | sRGBEncoding = THREE.sRGBEncoding; 5 | 6 | var gltfLoader = null; 7 | 8 | Tiny.Cache.gltf = {}; 9 | Tiny.Cache.texture3d = {}; 10 | Tiny.Cache.mesh3d = {}; 11 | Tiny.Cache.animation3d = {}; 12 | 13 | Tiny.Loader.prototype.gltf = function (key, json, splitObjects, cb) { 14 | this.list.push({ 15 | key: key, 16 | src: json, 17 | type: "gltf", 18 | split: splitObjects, 19 | cb: cb 20 | }); 21 | }; 22 | 23 | Tiny.Loader.prototype.texture3d = function (key, src, cb) { 24 | this.list.push({ 25 | key: key, 26 | src: src, 27 | type: "texture3d", 28 | cb: cb 29 | }); 30 | }; 31 | 32 | Tiny.Loader.gltf = function (resource, cb) { 33 | var key = resource.key; 34 | 35 | if (gltfLoader == null) { 36 | var manager = new LoadingManager(); 37 | gltfLoader = new window.GLTFLoader(manager); 38 | } 39 | 40 | function loaded(gltf) { 41 | Tiny.Cache.gltf[key] = gltf; 42 | 43 | if (resource.split) { 44 | gltf.scene.traverse(function (obj) { 45 | if (obj.isMesh) Tiny.Cache.mesh3d[key + "." + obj.name] = obj; 46 | }); 47 | 48 | for (var i = 0; i < gltf.animations.length; i++) { 49 | var obj = gltf.animations[i]; 50 | Tiny.Cache.animation3d[key + "." + obj.name] = obj; 51 | } 52 | } 53 | 54 | if (resource.cb) resource.cb(gltf); 55 | 56 | cb(); 57 | } 58 | 59 | if (resource.src.length > 200) { 60 | gltfLoader.parse(resource.src, "", loaded); 61 | } else { 62 | gltfLoader.load(resource.src, loaded); 63 | } 64 | }; 65 | 66 | Tiny.Loader.texture3d = function (resource, cb) { 67 | var key = resource.key; 68 | 69 | Tiny.Loader.image(resource, function (resource, image) { 70 | var texture = new Texture(image); 71 | texture.encoding = sRGBEncoding; 72 | texture.flipY = false; 73 | texture.needsUpdate = true; 74 | texture.key = key; 75 | 76 | Tiny.Cache.texture3d[resource.key] = texture; 77 | 78 | cb(); 79 | }); 80 | }; 81 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | var noop = function () {}; 2 | 3 | Tiny.App = function (states) { 4 | this.callbackContext = this; 5 | this.state = 0; 6 | this.timeScale = 1; 7 | this.width = 0; 8 | this.height = 0; 9 | this.systems = []; 10 | this.updatable = []; 11 | this.paused = false; 12 | this.pauseDuration = 0; 13 | this.inputView = document.body; 14 | 15 | if (!Tiny.app) Tiny.app = this; 16 | 17 | Tiny.EventEmitter.mixin(this); 18 | 19 | states = states || {}; 20 | this.boot = states.boot || this.boot || noop; 21 | this.preload = states.preload || this.preload || noop; 22 | this.create = states.create || this.create || noop; 23 | this.update = states.update || this.update || noop; 24 | this.render = states.render || this.render || noop; 25 | this._resize_cb = states.resize || noop; 26 | this._destroy_cb = states.destroy || noop; 27 | 28 | var self = this; 29 | setTimeout(function () { 30 | self._boot(); 31 | }, 0); 32 | }; 33 | 34 | Tiny.App.prototype._boot = function () { 35 | for (var i = 0; i < Tiny.systems.length; i++) { 36 | var system = Tiny.systems[i]; 37 | 38 | var _sys_ = new system._class_(this); 39 | this.systems.push(_sys_); 40 | if (_sys_.update) this.updatable.push(_sys_); 41 | 42 | if (system.name) this[system.name] = _sys_; 43 | } 44 | 45 | if (Tiny.RAF) { 46 | this.raf = new Tiny.RAF(this); 47 | } 48 | 49 | this.boot.call(this.callbackContext); 50 | 51 | var self = this; 52 | setTimeout(function () { 53 | if (self.load) self._preload(); 54 | else self._create(); 55 | }, 0); 56 | }; 57 | 58 | Tiny.App.prototype._preload = function () { 59 | this.preload.call(this.callbackContext); 60 | this.state = 1; 61 | this.load.start(this._create); 62 | }; 63 | 64 | Tiny.App.prototype._create = function () { 65 | this.emit('load'); 66 | this.create.call(this.callbackContext); 67 | 68 | if (this.raf) { 69 | this.raf.start(); 70 | } 71 | 72 | this.state = 2; 73 | }; 74 | 75 | Tiny.App.prototype.pause = function () { 76 | if (this.raf) { 77 | this.raf.reset(); 78 | } 79 | 80 | if (!this.paused) { 81 | for (var i = 0; i < this.systems.length; i++) { 82 | if (this.systems[i].pause) this.systems[i].pause(); 83 | } 84 | 85 | this.paused = true; 86 | } 87 | }; 88 | 89 | Tiny.App.prototype.resume = function () { 90 | if (this.raf) { 91 | this.raf.reset(); 92 | } 93 | 94 | if (this.paused) { 95 | for (var i = 0; i < this.systems.length; i++) { 96 | if (this.systems[i].resume) this.systems[i].resume(); 97 | } 98 | 99 | this.paused = false; 100 | } 101 | }; 102 | 103 | Tiny.App.prototype._update = function (time, delta) { 104 | if (!this.paused) { 105 | delta *= this.timeScale; 106 | this.update.call(this.callbackContext, time, delta); 107 | this.emit('update', delta); 108 | 109 | for (var i = 0; i < this.updatable.length; i++) { 110 | this.updatable[i].update(delta); 111 | } 112 | } else { 113 | this.pauseDuration += delta; 114 | } 115 | 116 | this.render(); 117 | this.emit('postrender'); 118 | }; 119 | 120 | Tiny.App.prototype.resize = function (width, height) { 121 | this.width = width || this.width; 122 | this.height = height || this.height; 123 | 124 | if (this.state > 0) { 125 | this._resize_cb.call(this.callbackContext, this.width, this.height); 126 | this.emit('resize', width, height); 127 | } 128 | 129 | var self = this; 130 | setTimeout(function () { 131 | if (self.input) self.input.updateBounds(); 132 | }, 0); 133 | }; 134 | 135 | Tiny.App.prototype.destroy = function (clearCache) { 136 | for (var i = 0; i < this.systems.length; i++) { 137 | if (this.systems[i].destroy) this.systems[i].destroy(clearCache); 138 | } 139 | 140 | this.paused = true; 141 | 142 | if (clearCache) { 143 | this.load.clearCache(); 144 | } 145 | 146 | if (this.raf) { 147 | this.raf.stop(); 148 | } 149 | 150 | this._destroy_cb.call(this.callbackContext); 151 | 152 | if (Tiny.app === this) Tiny.app = null; 153 | }; 154 | -------------------------------------------------------------------------------- /src/base.js: -------------------------------------------------------------------------------- 1 | require("./utils/polyfill.js"); 2 | 3 | window.Tiny = {}; 4 | 5 | require("./App.js"); 6 | require("./global.js"); 7 | require("./math/Math.js"); // 1 Kb 8 | require("./math/Point.js"); // 9 | require("./math/Matrix.js"); // 10 | require("./math/Rectangle.js"); // 8 Kb 11 | 12 | require("./objects/BaseObject2D.js"); // 13 | require("./objects/Object2D.js"); // 14 | require("./objects/Scene.js"); // 10 Kb 15 | 16 | require("./renderers/CanvasRenderer.js"); // 3 Kb 17 | -------------------------------------------------------------------------------- /src/global.js: -------------------------------------------------------------------------------- 1 | Tiny.VERSION = '2.2.2'; 2 | 3 | Tiny.systems = []; 4 | 5 | Tiny.registerSystem = function (name, system) { 6 | Tiny.systems.push({ 7 | name: name, 8 | _class_: system 9 | }); 10 | }; 11 | 12 | Tiny.Primitives = { 13 | POLY: 0, 14 | RECT: 1, 15 | CIRC: 2, 16 | ELIP: 3, 17 | RREC: 4, 18 | RREC_LJOIN: 5 19 | }; 20 | 21 | Tiny.rnd = function (min, max) { 22 | return min + Math.floor(Math.random() * (max - min + 1)); 23 | }; 24 | 25 | Tiny.style2hex = function (color) { 26 | return +color.replace('#', '0x'); 27 | }; 28 | 29 | Tiny.hex2style = function (hex) { 30 | return '#' + ('00000' + (hex | 0).toString(16)).substr(-6); 31 | }; 32 | 33 | Tiny.hex2rgb = function (hex) { 34 | return [((hex >> 16) & 0xff) / 255, ((hex >> 8) & 0xff) / 255, (hex & 0xff) / 255]; 35 | }; 36 | 37 | Tiny.rgb2hex = function (rgb) { 38 | return ((rgb[0] * 255) << 16) + ((rgb[1] * 255) << 8) + rgb[2] * 255; 39 | }; 40 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | require("./mini.js"); 2 | 3 | // require('./systems/ObjectCreator.js'); // 1 Kb 4 | // require('./systems/Loader.js'); // 3 Kb 5 | // require('./systems/Input.js'); // 1 Kb 6 | // require('./systems/Timer.js'); // 1 Kb 7 | require("./systems/Tween.js"); 8 | 9 | require("./math/RoundedRectangle.js"); // 10 | require("./math/Polygon.js"); // 11 | require("./math/Circle.js"); // 6 Kb 12 | 13 | require("./renderers/GraphicsRenderer.js"); // 4Kb 14 | 15 | require("./objects/Graphics.js"); // 10 Kb 16 | // require('./objects/TilingSprite.js'); // 4 Kb ############### TilingSprite game.add.tilesprite 17 | 18 | require("./textures/RenderTexture.js"); // 2 Kb 19 | 20 | require("./utils/CanvasBuffer.js"); // 1 Kb 21 | require("./renderers/CanvasMaskManager.js"); // 1Kb 22 | require("./renderers/CanvasTinter.js"); // 3 Kb ################ tint function 23 | -------------------------------------------------------------------------------- /src/math/Math.js: -------------------------------------------------------------------------------- 1 | Tiny.Math = { 2 | distance: function (x1, y1, x2, y2) { 3 | var dx = x1 - x2; 4 | var dy = y1 - y2; 5 | 6 | return Math.sqrt(dx * dx + dy * dy); 7 | } 8 | }; 9 | 10 | var degreeToRadiansFactor = Math.PI / 180; 11 | var radianToDegreesFactor = 180 / Math.PI; 12 | 13 | Tiny.Math.degToRad = function degToRad(degrees) { 14 | return degrees * degreeToRadiansFactor; 15 | }; 16 | 17 | Tiny.Math.radToDeg = function radToDeg(radians) { 18 | return radians * radianToDegreesFactor; 19 | }; 20 | -------------------------------------------------------------------------------- /src/math/Matrix.js: -------------------------------------------------------------------------------- 1 | Tiny.Matrix = function () { 2 | this.a = 1; 3 | 4 | this.b = 0; 5 | 6 | this.c = 0; 7 | 8 | this.d = 1; 9 | 10 | this.tx = 0; 11 | 12 | this.ty = 0; 13 | 14 | this.type = Tiny.MATRIX; 15 | }; 16 | 17 | Tiny.Matrix.prototype.fromArray = function (array) { 18 | this.a = array[0]; 19 | this.b = array[1]; 20 | this.c = array[3]; 21 | this.d = array[4]; 22 | this.tx = array[2]; 23 | this.ty = array[5]; 24 | }; 25 | 26 | Tiny.Matrix.prototype.toArray = function (transpose) { 27 | if (!this.array) { 28 | this.array = new Float32Array(9); 29 | } 30 | 31 | var array = this.array; 32 | 33 | if (transpose) { 34 | array[0] = this.a; 35 | array[1] = this.b; 36 | array[2] = 0; 37 | array[3] = this.c; 38 | array[4] = this.d; 39 | array[5] = 0; 40 | array[6] = this.tx; 41 | array[7] = this.ty; 42 | array[8] = 1; 43 | } else { 44 | array[0] = this.a; 45 | array[1] = this.c; 46 | array[2] = this.tx; 47 | array[3] = this.b; 48 | array[4] = this.d; 49 | array[5] = this.ty; 50 | array[6] = 0; 51 | array[7] = 0; 52 | array[8] = 1; 53 | } 54 | 55 | return array; 56 | }; 57 | 58 | Tiny.Matrix.prototype.apply = function (pos, newPos) { 59 | newPos = newPos || new Tiny.Point(); 60 | 61 | var x = pos.x; 62 | var y = pos.y; 63 | 64 | newPos.x = this.a * x + this.c * y + this.tx; 65 | newPos.y = this.b * x + this.d * y + this.ty; 66 | 67 | return newPos; 68 | }; 69 | 70 | Tiny.Matrix.prototype.applyInverse = function (pos, newPos) { 71 | newPos = newPos || new Tiny.Point(); 72 | 73 | var id = 1 / (this.a * this.d + this.c * -this.b); 74 | var x = pos.x; 75 | var y = pos.y; 76 | 77 | newPos.x = this.d * id * x + -this.c * id * y + (this.ty * this.c - this.tx * this.d) * id; 78 | newPos.y = this.a * id * y + -this.b * id * x + (-this.ty * this.a + this.tx * this.b) * id; 79 | 80 | return newPos; 81 | }; 82 | 83 | Tiny.Matrix.prototype.translate = function (x, y) { 84 | this.tx += x; 85 | this.ty += y; 86 | 87 | return this; 88 | }; 89 | 90 | Tiny.Matrix.prototype.scale = function (x, y) { 91 | this.a *= x; 92 | this.d *= y; 93 | this.c *= x; 94 | this.b *= y; 95 | this.tx *= x; 96 | this.ty *= y; 97 | 98 | return this; 99 | }; 100 | 101 | Tiny.Matrix.prototype.rotate = function (angle) { 102 | var cos = Math.cos(angle); 103 | var sin = Math.sin(angle); 104 | 105 | var a1 = this.a; 106 | var c1 = this.c; 107 | var tx1 = this.tx; 108 | 109 | this.a = a1 * cos - this.b * sin; 110 | this.b = a1 * sin + this.b * cos; 111 | this.c = c1 * cos - this.d * sin; 112 | this.d = c1 * sin + this.d * cos; 113 | this.tx = tx1 * cos - this.ty * sin; 114 | this.ty = tx1 * sin + this.ty * cos; 115 | 116 | return this; 117 | }; 118 | 119 | Tiny.Matrix.prototype.append = function (matrix) { 120 | var a1 = this.a; 121 | var b1 = this.b; 122 | var c1 = this.c; 123 | var d1 = this.d; 124 | 125 | this.a = matrix.a * a1 + matrix.b * c1; 126 | this.b = matrix.a * b1 + matrix.b * d1; 127 | this.c = matrix.c * a1 + matrix.d * c1; 128 | this.d = matrix.c * b1 + matrix.d * d1; 129 | 130 | this.tx = matrix.tx * a1 + matrix.ty * c1 + this.tx; 131 | this.ty = matrix.tx * b1 + matrix.ty * d1 + this.ty; 132 | 133 | return this; 134 | }; 135 | 136 | Tiny.Matrix.prototype.identity = function () { 137 | this.a = 1; 138 | this.b = 0; 139 | this.c = 0; 140 | this.d = 1; 141 | this.tx = 0; 142 | this.ty = 0; 143 | 144 | return this; 145 | }; 146 | 147 | Tiny.identityMatrix = new Tiny.Matrix(); 148 | -------------------------------------------------------------------------------- /src/math/Point.js: -------------------------------------------------------------------------------- 1 | Tiny.Point = function (x, y) { 2 | this.x = x || 0; 3 | this.y = y || 0; 4 | }; 5 | 6 | Tiny.Point.prototype = { 7 | set: function (x, y) { 8 | this.x = x || 0; 9 | this.y = y || (y !== 0 ? this.x : 0); 10 | 11 | return this; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /src/math/Polygon.js: -------------------------------------------------------------------------------- 1 | Tiny.Polygon = function () { 2 | this.area = 0; 3 | this._points = []; 4 | 5 | if (arguments.length > 0) { 6 | this.setTo.apply(this, arguments); 7 | } 8 | this.closed = true; 9 | this.type = Tiny.Primitives.POLY; 10 | }; 11 | 12 | Tiny.Polygon.prototype = { 13 | toNumberArray: function (output) { 14 | if (typeof output === "undefined") { 15 | output = []; 16 | } 17 | 18 | for (var i = 0; i < this._points.length; i++) { 19 | if (typeof this._points[i] === "number") { 20 | output.push(this._points[i]); 21 | output.push(this._points[i + 1]); 22 | i++; 23 | } else { 24 | output.push(this._points[i].x); 25 | output.push(this._points[i].y); 26 | } 27 | } 28 | 29 | return output; 30 | }, 31 | 32 | flatten: function () { 33 | this._points = this.toNumberArray(); 34 | 35 | return this; 36 | }, 37 | 38 | clone: function (output) { 39 | var points = this._points.slice(); 40 | 41 | if (typeof output === "undefined" || output === null) { 42 | output = new Tiny.Polygon(points); 43 | } else { 44 | output.setTo(points); 45 | } 46 | 47 | return output; 48 | }, 49 | 50 | contains: function (x, y) { 51 | var length = this._points.length; 52 | var inside = false; 53 | 54 | for (var i = -1, j = length - 1; ++i < length; j = i) { 55 | var ix = this._points[i].x; 56 | var iy = this._points[i].y; 57 | 58 | var jx = this._points[j].x; 59 | var jy = this._points[j].y; 60 | 61 | if (((iy <= y && y < jy) || (jy <= y && y < iy)) && x < ((jx - ix) * (y - iy)) / (jy - iy) + ix) { 62 | inside = !inside; 63 | } 64 | } 65 | 66 | return inside; 67 | }, 68 | 69 | setTo: function (points) { 70 | this.area = 0; 71 | this._points = []; 72 | 73 | if (arguments.length > 0) { 74 | // If points isn't an array, use arguments as the array 75 | if (!Array.isArray(points)) { 76 | points = Array.prototype.slice.call(arguments); 77 | } 78 | 79 | var y0 = Number.MAX_VALUE; 80 | 81 | // Allows for mixed-type arguments 82 | for (var i = 0, len = points.length; i < len; i++) { 83 | if (typeof points[i] === "number") { 84 | var p = new Tiny.Point(points[i], points[i + 1]); 85 | i++; 86 | } else { 87 | var p = new Tiny.Point(points[i].x, points[i].y); 88 | } 89 | 90 | this._points.push(p); 91 | 92 | // Lowest boundary 93 | if (p.y < y0) { 94 | y0 = p.y; 95 | } 96 | } 97 | 98 | this.calculateArea(y0); 99 | } 100 | 101 | return this; 102 | }, 103 | 104 | calculateArea: function (y0) { 105 | var p1; 106 | var p2; 107 | var avgHeight; 108 | var width; 109 | 110 | for (var i = 0, len = this._points.length; i < len; i++) { 111 | p1 = this._points[i]; 112 | 113 | if (i === len - 1) { 114 | p2 = this._points[0]; 115 | } else { 116 | p2 = this._points[i + 1]; 117 | } 118 | 119 | avgHeight = (p1.y - y0 + (p2.y - y0)) / 2; 120 | width = p1.x - p2.x; 121 | this.area += avgHeight * width; 122 | } 123 | 124 | return this.area; 125 | } 126 | }; 127 | 128 | Tiny.Polygon.prototype.constructor = Tiny.Polygon; 129 | 130 | Object.defineProperty(Tiny.Polygon.prototype, "points", { 131 | get: function () { 132 | return this._points; 133 | }, 134 | 135 | set: function (points) { 136 | if (points != null) { 137 | this.setTo(points); 138 | } else { 139 | // Clear the points 140 | this.setTo(); 141 | } 142 | } 143 | }); 144 | -------------------------------------------------------------------------------- /src/math/Rectangle.js: -------------------------------------------------------------------------------- 1 | Tiny.Rectangle = function (x, y, width, height) { 2 | x = x || 0; 3 | y = y || 0; 4 | width = width || 0; 5 | height = height || 0; 6 | 7 | this.x = x; 8 | this.y = y; 9 | 10 | this.width = width; 11 | this.height = height; 12 | 13 | this.type = Tiny.Primitives.RECT; 14 | }; 15 | 16 | Tiny.Rectangle.prototype = { 17 | setTo: function (x, y, width, height) { 18 | this.x = x; 19 | this.y = y; 20 | this.width = width; 21 | this.height = height; 22 | 23 | return this; 24 | }, 25 | 26 | contains: function (x, y) { 27 | return Tiny.Rectangle.contains(this, x, y); 28 | }, 29 | 30 | intersects: function (b) { 31 | return Tiny.Rectangle.intersects(this, b); 32 | } 33 | }; 34 | 35 | Object.defineProperty(Tiny.Rectangle.prototype, "bottom", { 36 | get: function () { 37 | return this.y + this.height; 38 | }, 39 | 40 | set: function (value) { 41 | if (value <= this.y) { 42 | this.height = 0; 43 | } else { 44 | this.height = value - this.y; 45 | } 46 | } 47 | }); 48 | 49 | Object.defineProperty(Tiny.Rectangle.prototype, "right", { 50 | get: function () { 51 | return this.x + this.width; 52 | }, 53 | 54 | set: function (value) { 55 | if (value <= this.x) { 56 | this.width = 0; 57 | } else { 58 | this.width = value - this.x; 59 | } 60 | } 61 | }); 62 | 63 | Object.defineProperty(Tiny.Rectangle.prototype, "volume", { 64 | get: function () { 65 | return this.width * this.height; 66 | } 67 | }); 68 | 69 | Tiny.Rectangle.prototype.constructor = Tiny.Rectangle; 70 | 71 | Tiny.Rectangle.contains = function (a, x, y) { 72 | if (a.width <= 0 || a.height <= 0) { 73 | return false; 74 | } 75 | 76 | return x >= a.x && x < a.right && y >= a.y && y < a.bottom; 77 | }; 78 | 79 | Tiny.Rectangle.containsPoint = function (a, point) { 80 | return Tiny.Rectangle.contains(a, point.x, point.y); 81 | }; 82 | 83 | Tiny.Rectangle.containsRect = function (a, b) { 84 | // If the given rect has a larger volume than this one then it can never contain it 85 | if (a.volume > b.volume) { 86 | return false; 87 | } 88 | 89 | return a.x >= b.x && a.y >= b.y && a.right < b.right && a.bottom < b.bottom; 90 | }; 91 | 92 | Tiny.Rectangle.intersects = function (a, b) { 93 | if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0) { 94 | return false; 95 | } 96 | 97 | return !(a.right < b.x || a.bottom < b.y || a.x > b.right || a.y > b.bottom); 98 | }; 99 | 100 | Tiny.EmptyRectangle = new Tiny.Rectangle(0, 0, 0, 0); 101 | -------------------------------------------------------------------------------- /src/math/RoundedRectangle.js: -------------------------------------------------------------------------------- 1 | Tiny.RoundedRectangle = function (x, y, width, height, radius) { 2 | this.x = x || 0; 3 | this.y = y || 0; 4 | this.width = width || 0; 5 | this.height = height || 0; 6 | this.radius = radius || 0; 7 | this.type = Tiny.Primitives.RREC; 8 | }; 9 | 10 | Tiny.RoundedRectangle.prototype.clone = function () { 11 | return new Tiny.RoundedRectangle(this.x, this.y, this.width, this.height, this.radius); 12 | }; 13 | 14 | Tiny.RoundedRectangle.prototype.contains = function (x, y) { 15 | if (this.width <= 0 || this.height <= 0) { 16 | return false; 17 | } 18 | 19 | var x1 = this.x; 20 | 21 | if (x >= x1 && x <= x1 + this.width) { 22 | var y1 = this.y; 23 | 24 | if (y >= y1 && y <= y1 + this.height) { 25 | return true; 26 | } 27 | } 28 | 29 | return false; 30 | }; 31 | 32 | Tiny.RoundedRectangle.prototype.constructor = Tiny.RoundedRectangle; 33 | -------------------------------------------------------------------------------- /src/mini.js: -------------------------------------------------------------------------------- 1 | require("./base.js"); 2 | 3 | require("./systems/RAF.js"); // 2 Kb 4 | // require('./systems/ObjectCreator.js'); // 1 Kb 5 | require("./systems/Loader.js"); // 3 Kb 6 | require("./systems/Input.js"); // 1 Kb 7 | require("./systems/Timer.js"); // 1 Kb 8 | 9 | require("./utils/EventEmitter.js"); 10 | 11 | require("./textures/Texture.js"); // 4 Kb 12 | 13 | require("./objects/Sprite.js"); // 3 Kb 14 | require("./objects/Text.js"); // 5 Kb 15 | -------------------------------------------------------------------------------- /src/objects/Scene.js: -------------------------------------------------------------------------------- 1 | Tiny.Scene = function (game) { 2 | Tiny.Object2D.call(this); 3 | this.worldTransform = new Tiny.Matrix(); 4 | this.game = game; 5 | }; 6 | 7 | Tiny.Scene.prototype = Object.create(Tiny.Object2D.prototype); 8 | Tiny.Scene.prototype.constructor = Tiny.Scene; 9 | 10 | Tiny.Scene.prototype.updateTransform = function () { 11 | this.worldAlpha = 1; 12 | 13 | for (var i = 0; i < this.children.length; i++) { 14 | this.children[i].updateTransform(); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /src/renderers/CanvasMaskManager.js: -------------------------------------------------------------------------------- 1 | Tiny.CanvasMaskManager = function () {}; 2 | 3 | Tiny.CanvasMaskManager.prototype.constructor = Tiny.CanvasMaskManager; 4 | 5 | Tiny.CanvasMaskManager.prototype.pushMask = function (maskData, renderSession) { 6 | var context = renderSession.context; 7 | 8 | context.save(); 9 | 10 | var cacheAlpha = maskData.alpha; 11 | var transform = maskData.worldTransform; 12 | 13 | var resolution = renderSession.resolution; 14 | 15 | context.setTransform( 16 | transform.a * resolution, 17 | transform.b * resolution, 18 | transform.c * resolution, 19 | transform.d * resolution, 20 | transform.tx * resolution, 21 | transform.ty * resolution 22 | ); 23 | 24 | Tiny.CanvasGraphics.renderGraphicsMask(maskData, context); 25 | 26 | context.clip(); 27 | 28 | maskData.worldAlpha = cacheAlpha; 29 | }; 30 | 31 | Tiny.CanvasMaskManager.prototype.popMask = function (renderSession) { 32 | renderSession.context.restore(); 33 | }; 34 | -------------------------------------------------------------------------------- /src/renderers/CanvasRenderer.js: -------------------------------------------------------------------------------- 1 | Tiny.CanvasRenderer = function (width, height, options) { 2 | options = options || {}; 3 | 4 | this.resolution = options.resolution != undefined ? options.resolution : 1; 5 | 6 | this.clearBeforeRender = options.clearBeforeRender != undefined ? options.clearBeforeRender : true; 7 | 8 | this.transparent = options.transparent != undefined ? options.transparent : false; 9 | 10 | this.autoResize = options.autoResize || false; 11 | 12 | // this.width = width || 800; 13 | // this.height = height || 600; 14 | 15 | // this.width *= this.resolution; 16 | // this.height *= this.resolution; 17 | 18 | if (!Tiny.defaultRenderer) Tiny.defaultRenderer = this; 19 | 20 | var view = (this.domElement = options.domElement || document.createElement("canvas")); 21 | 22 | this.context = view.getContext("2d", { alpha: this.transparent }); 23 | 24 | // view.width = this.width * this.resolution; 25 | // view.height = this.height * this.resolution; 26 | 27 | this.resize(width || 800, height || 600); 28 | 29 | this.setClearColor("#ffffff"); 30 | 31 | if (Tiny.CanvasMaskManager) this.maskManager = new Tiny.CanvasMaskManager(); 32 | 33 | this.renderSession = { 34 | context: this.context, 35 | maskManager: this.maskManager, 36 | smoothProperty: null, 37 | /** 38 | * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation. 39 | * Handy for crisp pixel art and speed on legacy devices. 40 | * 41 | */ 42 | roundPixels: false 43 | }; 44 | 45 | if ("imageSmoothingEnabled" in this.context) this.renderSession.smoothProperty = "imageSmoothingEnabled"; 46 | else if ("webkitImageSmoothingEnabled" in this.context) 47 | this.renderSession.smoothProperty = "webkitImageSmoothingEnabled"; 48 | else if ("mozImageSmoothingEnabled" in this.context) 49 | this.renderSession.smoothProperty = "mozImageSmoothingEnabled"; 50 | else if ("oImageSmoothingEnabled" in this.context) 51 | this.renderSession.smoothProperty = "oImageSmoothingEnabled"; 52 | else if ("msImageSmoothingEnabled" in this.context) 53 | this.renderSession.smoothProperty = "msImageSmoothingEnabled"; 54 | }; 55 | 56 | Tiny.CanvasRenderer.prototype.constructor = Tiny.CanvasRenderer; 57 | 58 | Tiny.CanvasRenderer.prototype.setClearColor = function (color) { 59 | this.clearColor = color; 60 | 61 | // if (color === null) { 62 | // this.clearColor = null; 63 | // return; 64 | // } 65 | 66 | // this.clearColor = color || 0x000000; 67 | // // this.backgroundColorSplit = Tiny.hex2rgb(this.backgroundColor); 68 | // var hex = this.clearColor.toString(16); 69 | // hex = '000000'.substr(0, 6 - hex.length) + hex; 70 | // this._clearColor = '#' + hex; 71 | }; 72 | 73 | // Tiny.CanvasRenderer.prototype.setPixelArt = function() { 74 | 75 | // var canvas = this.domElement; 76 | 77 | // var types = [ 'optimizeSpeed', '-moz-crisp-edges', '-o-crisp-edges', '-webkit-optimize-contrast', 'optimize-contrast', 'crisp-edges', 'pixelated' ]; 78 | 79 | // types.forEach(function (type) 80 | // { 81 | // canvas.style['image-rendering'] = type; 82 | // }); 83 | 84 | // canvas.style.msInterpolationMode = 'nearest-neighbor'; 85 | // this.renderSession.roundPixels = true; 86 | // } 87 | 88 | Tiny.CanvasRenderer.prototype.render = function (scene) { 89 | scene.updateTransform(); 90 | 91 | this.context.setTransform(1, 0, 0, 1, 0, 0); 92 | 93 | this.context.globalAlpha = 1; 94 | 95 | this.renderSession.currentBlendMode = "source-over"; 96 | this.context.globalCompositeOperation = "source-over"; 97 | 98 | if (navigator.isCocoonJS && this.domElement.screencanvas) { 99 | this.context.fillStyle = "black"; 100 | this.context.clear(); 101 | } 102 | 103 | if (this.clearBeforeRender) { 104 | if (this.transparent) { 105 | this.context.clearRect(0, 0, this.width * this.resolution, this.height * this.resolution); 106 | } else { 107 | this.context.fillStyle = this.clearColor; 108 | this.context.fillRect(0, 0, this.width * this.resolution, this.height * this.resolution); 109 | } 110 | } 111 | 112 | this.renderObject(scene); 113 | }; 114 | 115 | Tiny.CanvasRenderer.prototype.destroy = function (removeView) { 116 | if (typeof removeView === "undefined") { 117 | removeView = true; 118 | } 119 | 120 | if (removeView && this.domElement.parentNode) { 121 | this.domElement.parentNode.removeChild(this.domElement); 122 | } 123 | 124 | this.domElement = null; 125 | this.context = null; 126 | this.maskManager = null; 127 | this.renderSession = null; 128 | 129 | if (Tiny.defaultRenderer === this) Tiny.defaultRenderer = null; 130 | }; 131 | 132 | Tiny.CanvasRenderer.prototype.resize = function (width, height) { 133 | this.width = width; 134 | this.height = height; 135 | 136 | var view = this.domElement; 137 | 138 | view.width = Math.floor(this.width * this.resolution); 139 | view.height = Math.floor(this.height * this.resolution); 140 | 141 | if (this.autoResize) { 142 | view.style.width = width + "px"; 143 | view.style.height = height + "px"; 144 | } 145 | }; 146 | 147 | Tiny.CanvasRenderer.prototype.setPixelRatio = function (resolution) { 148 | this.resolution = resolution; 149 | 150 | var view = this.domElement; 151 | 152 | view.width = Math.floor(this.width * this.resolution); 153 | view.height = Math.floor(this.height * this.resolution); 154 | }; 155 | 156 | Tiny.CanvasRenderer.prototype.renderObject = function (displayObject, context) { 157 | this.renderSession.context = context || this.context; 158 | this.renderSession.resolution = this.resolution; 159 | displayObject.render(this.renderSession); 160 | }; 161 | -------------------------------------------------------------------------------- /src/renderers/CanvasTinter.js: -------------------------------------------------------------------------------- 1 | Tiny.CanvasTinter = function () {}; 2 | 3 | Tiny.CanvasTinter.getTintedTexture = function (sprite, color) { 4 | var texture = sprite.texture; 5 | 6 | if (!texture._tintCache) texture._tintCache = {}; 7 | 8 | if (texture._tintCache[color]) return texture._tintCache[color]; 9 | 10 | var canvas = Tiny.CanvasTinter.canvas || document.createElement("canvas"); 11 | 12 | Tiny.CanvasTinter.tintMethod(texture, color, canvas); 13 | 14 | if (Tiny.CanvasTinter.convertTintToImage) { 15 | // is this better? 16 | var tintImage = new Image(); 17 | tintImage.src = canvas.toDataURL(); 18 | 19 | // texture._tintCache[stringColor] = tintImage; 20 | } else { 21 | Tiny.CanvasTinter.canvas = null; 22 | } 23 | 24 | if (Tiny.CanvasTinter.cacheTint) texture._tintCache[color] = canvas; 25 | 26 | return canvas; 27 | }; 28 | 29 | Tiny.CanvasTinter.tintWithMultiply = function (texture, color, canvas) { 30 | var context = canvas.getContext("2d"); 31 | 32 | var crop = texture.crop; 33 | 34 | canvas.width = crop.width; 35 | canvas.height = crop.height; 36 | 37 | context.fillStyle = color; 38 | 39 | context.fillRect(0, 0, crop.width, crop.height); 40 | 41 | context.globalCompositeOperation = "multiply"; 42 | 43 | context.drawImage(texture.source, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height); 44 | 45 | context.globalCompositeOperation = "destination-atop"; 46 | 47 | context.drawImage(texture.source, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height); 48 | }; 49 | 50 | Tiny.CanvasTinter.tintWithPerPixel = function (texture, color, canvas) { 51 | var context = canvas.getContext("2d"); 52 | 53 | var crop = texture.crop; 54 | 55 | canvas.width = crop.width; 56 | canvas.height = crop.height; 57 | 58 | context.globalCompositeOperation = "copy"; 59 | context.drawImage(texture.source, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height); 60 | 61 | var rgbValues = Tiny.hex2rgb(Tiny.style2hex(color)); 62 | var r = rgbValues[0], 63 | g = rgbValues[1], 64 | b = rgbValues[2]; 65 | 66 | var pixelData = context.getImageData(0, 0, crop.width, crop.height); 67 | 68 | var pixels = pixelData.data; 69 | 70 | for (var i = 0; i < pixels.length; i += 4) { 71 | pixels[i + 0] *= r; 72 | pixels[i + 1] *= g; 73 | pixels[i + 2] *= b; 74 | 75 | if (!Tiny.canHandleAlpha) { 76 | var alpha = pixels[i + 3]; 77 | 78 | pixels[i + 0] /= 255 / alpha; 79 | pixels[i + 1] /= 255 / alpha; 80 | pixels[i + 2] /= 255 / alpha; 81 | } 82 | } 83 | 84 | context.putImageData(pixelData, 0, 0); 85 | }; 86 | 87 | function checkInverseAlpha() { 88 | var canvas = new Tiny.CanvasBuffer(2, 1, { willReadFrequently: true }); 89 | 90 | canvas.context.fillStyle = "rgba(10, 20, 30, 0.5)"; 91 | 92 | // Draw a single pixel 93 | canvas.context.fillRect(0, 0, 1, 1); 94 | 95 | // Get the color values 96 | var s1 = canvas.context.getImageData(0, 0, 1, 1); 97 | 98 | // Plot them to x2 99 | canvas.context.putImageData(s1, 1, 0); 100 | 101 | // Get those values 102 | var s2 = canvas.context.getImageData(1, 0, 1, 1); 103 | 104 | // Compare and return 105 | return ( 106 | s2.data[0] === s1.data[0] && 107 | s2.data[1] === s1.data[1] && 108 | s2.data[2] === s1.data[2] && 109 | s2.data[3] === s1.data[3] 110 | ); 111 | } 112 | 113 | function checkBlendMode() { 114 | var pngHead = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/"; 115 | var pngEnd = "AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg=="; 116 | 117 | var magenta = new Image(); 118 | 119 | magenta.onload = function () { 120 | var yellow = new Image(); 121 | 122 | yellow.onload = function () { 123 | var canvas = document.createElement("canvas"); 124 | canvas.width = 6; 125 | canvas.height = 1; 126 | var context = canvas.getContext("2d", { willReadFrequently: true }); 127 | 128 | context.globalCompositeOperation = "multiply"; 129 | 130 | context.drawImage(magenta, 0, 0); 131 | context.drawImage(yellow, 2, 0); 132 | 133 | if (!context.getImageData(2, 0, 1, 1)) { 134 | return false; 135 | } 136 | 137 | var data = context.getImageData(2, 0, 1, 1).data; 138 | 139 | Tiny.supportNewBlendModes = data[0] === 255 && data[1] === 0 && data[2] === 0; 140 | Tiny.CanvasTinter.tintMethod = Tiny.CanvasTinter.tintWithMultiply; 141 | }; 142 | 143 | yellow.src = pngHead + "/wCKxvRF" + pngEnd; 144 | }; 145 | 146 | magenta.src = pngHead + "AP804Oa6" + pngEnd; 147 | 148 | return false; 149 | } 150 | 151 | Tiny.CanvasTinter.convertTintToImage = false; 152 | 153 | Tiny.CanvasTinter.cacheTint = false; 154 | 155 | Tiny.canHandleAlpha = checkInverseAlpha(); 156 | 157 | Tiny.supportNewBlendModes = checkBlendMode(); 158 | 159 | Tiny.CanvasTinter.tintMethod = Tiny.supportNewBlendModes 160 | ? Tiny.CanvasTinter.tintWithMultiply 161 | : Tiny.CanvasTinter.tintWithPerPixel; 162 | -------------------------------------------------------------------------------- /src/systems/RAF.js: -------------------------------------------------------------------------------- 1 | var _isSetTimeOut, _onLoop, _timeOutID, _prevTime, _lastTime; 2 | 3 | var now = function () { 4 | return new Date().getTime(); 5 | }; 6 | 7 | if (self.performance !== undefined && self.performance.now !== undefined) { 8 | now = self.performance.now.bind(self.performance); 9 | } else if (Date.now !== undefined) { 10 | now = Date.now; 11 | } 12 | 13 | Tiny.RAF = function (game, forceSetTimeOut) { 14 | if (forceSetTimeOut === undefined) { 15 | forceSetTimeOut = false; 16 | } 17 | this.game = game; 18 | 19 | this.isRunning = false; 20 | this.forceSetTimeOut = forceSetTimeOut; 21 | 22 | var vendors = ["ms", "moz", "webkit", "o"]; 23 | 24 | for (var x = 0; x < vendors.length && !window.requestAnimationFrame; x++) { 25 | window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"]; 26 | window.cancelAnimationFrame = 27 | window[vendors[x] + "CancelAnimationFrame"] || window[vendors[x] + "CancelRequestAnimationFrame"]; 28 | } 29 | 30 | _isSetTimeOut = false; 31 | _onLoop = null; 32 | _timeOutID = null; 33 | 34 | _prevTime = 0; 35 | _lastTime = 0; 36 | }; 37 | 38 | Tiny.RAF.prototype = { 39 | start: function () { 40 | _prevTime = now(); 41 | 42 | this.isRunning = true; 43 | 44 | var _this = this; 45 | 46 | if (!window.requestAnimationFrame || this.forceSetTimeOut) { 47 | _isSetTimeOut = true; 48 | 49 | _onLoop = function () { 50 | return _this.updateSetTimeout(); 51 | }; 52 | 53 | _timeOutID = window.setTimeout(_onLoop, 0); 54 | } else { 55 | _isSetTimeOut = false; 56 | 57 | _onLoop = function () { 58 | return _this.updateRAF(); 59 | }; 60 | 61 | _timeOutID = window.requestAnimationFrame(_onLoop); 62 | } 63 | }, 64 | 65 | updateRAF: function () { 66 | _lastTime = now(); 67 | 68 | if (this.isRunning) { 69 | this.game._update(Math.floor(_lastTime), _lastTime - _prevTime); 70 | 71 | _timeOutID = window.requestAnimationFrame(_onLoop); 72 | } 73 | 74 | _prevTime = _lastTime; 75 | }, 76 | 77 | updateSetTimeout: function () { 78 | _lastTime = now(); 79 | if (this.isRunning) { 80 | this.game._update(Math.floor(_lastTime), _lastTime - _prevTime); 81 | 82 | _timeOutID = window.setTimeout(_onLoop, Tiny.RAF.timeToCall); 83 | } 84 | _prevTime = _lastTime; 85 | }, 86 | 87 | reset: function () { 88 | _prevTime = now(); 89 | }, 90 | 91 | stop: function () { 92 | if (_isSetTimeOut) { 93 | clearTimeout(_timeOutID); 94 | } else { 95 | window.cancelAnimationFrame(_timeOutID); 96 | } 97 | 98 | this.isRunning = false; 99 | } 100 | }; 101 | 102 | Tiny.RAF.timeToCall = 15; 103 | -------------------------------------------------------------------------------- /src/systems/Timer.js: -------------------------------------------------------------------------------- 1 | var noop = function () {}; 2 | 3 | var Timer = function (autoStart, autoRemove, game, cb, ctx, delay, loop, n, oncomplete) { 4 | this.game = game; 5 | this.cb = cb || noop; 6 | this.ctx = ctx || this; 7 | this.delay = delay == undefined ? 1000 : delay; 8 | this.loop = loop; 9 | this.count = n || 0; 10 | this.repeat = this.count > 0; 11 | this.running = !!autoStart; 12 | this._lastFrame = 0; 13 | this.autoRemove = autoRemove; 14 | this.onComplete = oncomplete || noop; 15 | }; 16 | 17 | Timer.prototype = { 18 | start: function () { 19 | this.running = true; 20 | }, 21 | pause: function () { 22 | this.running = false; 23 | }, 24 | stop: function () { 25 | this.running = false; 26 | this._lastFrame = 0; 27 | }, 28 | update: function (deltaTime) { 29 | if (this.running) { 30 | this._lastFrame += deltaTime; 31 | if (this._lastFrame >= this.delay) { 32 | this.cb.call(this.ctx); 33 | this._lastFrame = 0; 34 | if (this.repeat) { 35 | this.count--; 36 | if (this.count === 0) { 37 | this.running = false; 38 | this.autoRemove && this.game.timer.remove(this); 39 | this.onComplete(); 40 | } 41 | } else if (!this.loop) { 42 | this.running = false; 43 | this.autoRemove && this.game.timer.remove(this); 44 | } 45 | } 46 | } 47 | } 48 | }; 49 | 50 | Tiny.Timer = Timer; 51 | 52 | Tiny.TimerCreator = function (game) { 53 | this.game = game; 54 | this.list = []; 55 | this.autoStart = true; 56 | this.autoRemove = true; 57 | }; 58 | 59 | Tiny.TimerCreator.prototype = { 60 | update: function (delta) { 61 | for (var i = 0; i < this.list.length; i++) { 62 | this.list[i].update(delta); 63 | } 64 | }, 65 | removeAll: function () { 66 | for (var i = 0; i < this.list.length; i++) { 67 | this.list[i].stop(); 68 | } 69 | 70 | this.list = []; 71 | }, 72 | remove: function (tm) { 73 | var indexOf = this.list.indexOf(tm); 74 | if (indexOf > -1) { 75 | tm.stop(); 76 | this.list.splice(indexOf, 1); 77 | } 78 | }, 79 | add: function (delay, cb, ctx, autostart, autoremove) { 80 | autostart = autostart != undefined ? autostart : this.autoStart; 81 | autoremove = autoremove != undefined ? autoremove : this.autoRemove; 82 | 83 | var timer = new Timer(autostart, autoremove, this.game, cb, ctx, delay); 84 | this.list.push(timer); 85 | return timer; 86 | }, 87 | loop: function (delay, cb, ctx, autostart, autoremove) { 88 | autostart = autostart != undefined ? autostart : this.autoStart; 89 | autoremove = autoremove != undefined ? autoremove : this.autoRemove; 90 | 91 | var timer = new Timer(autostart, autoremove, this.game, cb, ctx, delay, true); 92 | this.list.push(timer); 93 | return timer; 94 | }, 95 | repeat: function (delay, n, cb, ctx, autostart, autoremove, complete) { 96 | autostart = autostart != undefined ? autostart : this.autoStart; 97 | autoremove = autoremove != undefined ? autoremove : this.autoRemove; 98 | 99 | var timer = new Timer(autostart, autoremove, this.game, cb, ctx, delay, false, n, complete); 100 | this.list.push(timer); 101 | return timer; 102 | }, 103 | destroy: function () { 104 | this.removeAll(); 105 | } 106 | }; 107 | 108 | Tiny.registerSystem("timer", Tiny.TimerCreator); 109 | -------------------------------------------------------------------------------- /src/textures/RenderTexture.js: -------------------------------------------------------------------------------- 1 | Tiny.RenderTexture = function (width, height, renderer, resolution) { 2 | this.width = width || 100; 3 | this.height = height || 100; 4 | 5 | // console.log(this); 6 | resolution = resolution || 1; 7 | 8 | // this.frame = new Tiny.Rectangle(0, 0, this.width * this.resolution, this.height * this.resolution); 9 | 10 | // this.crop = new Tiny.Rectangle(0, 0, this.width * this.resolution, this.height * this.resolution); 11 | 12 | // this.baseTexture = new Tiny.BaseTexture(); 13 | // this.baseTexture.width = this.width * this.resolution; 14 | // this.baseTexture.height = this.height * this.resolution; 15 | // this.baseTexture.resolution = this.resolution; 16 | 17 | // this.baseTexture.hasLoaded = true; 18 | this.textureBuffer = new Tiny.CanvasBuffer(this.width * resolution, this.height * resolution); 19 | 20 | Tiny.Texture.call( 21 | this, 22 | this.textureBuffer.canvas, 23 | new Tiny.Rectangle(0, 0, Math.floor(this.width * resolution), Math.floor(this.height * resolution)) 24 | ); 25 | 26 | this.resolution = resolution; 27 | 28 | // this.hasLoaded = true; 29 | 30 | this.renderer = renderer || Tiny.defaultRenderer; 31 | 32 | this.valid = true; 33 | }; 34 | 35 | Tiny.RenderTexture.prototype = Object.create(Tiny.Texture.prototype); 36 | Tiny.RenderTexture.prototype.constructor = Tiny.RenderTexture; 37 | 38 | Tiny.RenderTexture.prototype.resize = function (width, height, updateBase) { 39 | if (width === this.width && height === this.height) return; 40 | 41 | this.valid = width > 0 && height > 0; 42 | 43 | this.width = width; 44 | this.height = height; 45 | this.frame.width = this.crop.width = width * this.resolution; 46 | this.frame.height = this.crop.height = height * this.resolution; 47 | 48 | if (updateBase) { 49 | // this.baseTexture.width = this.width * this.resolution; 50 | // this.baseTexture.height = this.height * this.resolution; 51 | } 52 | 53 | if (!this.valid) return; 54 | 55 | this.textureBuffer.resize(this.width * this.resolution, this.height * this.resolution); 56 | }; 57 | 58 | Tiny.RenderTexture.prototype.clear = function () { 59 | if (!this.valid) return; 60 | 61 | this.textureBuffer.clear(); 62 | }; 63 | 64 | Tiny.RenderTexture.prototype.render = function (displayObject, matrix, clear) { 65 | if (!this.valid) return; 66 | 67 | var wt = displayObject.worldTransform; 68 | wt.identity(); 69 | if (matrix) wt.append(matrix); 70 | 71 | // setWorld Alpha to ensure that the object is renderer at full opacity 72 | displayObject.worldAlpha = 1; 73 | 74 | // Time to update all the children of the displayObject with the new matrix.. 75 | var children = displayObject.children; 76 | 77 | for (var i = 0, j = children.length; i < j; i++) { 78 | children[i].updateTransform(); 79 | } 80 | 81 | if (clear) this.textureBuffer.clear(); 82 | 83 | var context = this.textureBuffer.context; 84 | 85 | var realResolution = this.renderer.resolution; 86 | 87 | this.renderer.resolution = this.resolution; 88 | 89 | this.renderer.renderObject(displayObject, context); 90 | 91 | this.renderer.resolution = realResolution; 92 | }; 93 | 94 | Tiny.RenderTexture.prototype.getImage = function () { 95 | var image = new Image(); 96 | image.src = this.getBase64(); 97 | return image; 98 | }; 99 | 100 | Tiny.RenderTexture.prototype.getBase64 = function () { 101 | return this.getCanvas().toDataURL(); 102 | }; 103 | 104 | Tiny.RenderTexture.prototype.getCanvas = function () { 105 | return this.textureBuffer.canvas; 106 | }; 107 | -------------------------------------------------------------------------------- /src/textures/Texture.js: -------------------------------------------------------------------------------- 1 | // Tiny.TextureCache = {}; 2 | // Tiny.FrameCache = {}; 3 | Tiny.TextureCacheIdGenerator = 0; 4 | Tiny.TextureSilentFail = false; 5 | 6 | Tiny.Texture = function (source, frame, crop, trim) { 7 | // console.log(this); 8 | this.noFrame = false; 9 | 10 | this.resolution = 1; 11 | 12 | this.hasLoaded = false; 13 | 14 | if (!frame) { 15 | this.noFrame = true; 16 | frame = new Tiny.Rectangle(0, 0, 1, 1); 17 | } 18 | 19 | if (typeof source == 'string') { 20 | var key = source; 21 | 22 | source = Tiny.Cache.image[key]; 23 | 24 | if (!source) throw new Error('Cache Error: image ' + key + ' does`t found in cache'); 25 | 26 | Tiny.Cache.texture[key] = this; 27 | 28 | this.key = key; 29 | } 30 | 31 | this.source = source; 32 | 33 | this.frame = frame; 34 | 35 | this.trim = trim; 36 | 37 | this.valid = false; 38 | 39 | this.width = 0; 40 | 41 | this.height = 0; 42 | 43 | this.crop = crop || new Tiny.Rectangle(0, 0, 1, 1); 44 | 45 | if ((this.source.complete || this.source.getContext) && this.source.width && this.source.height) { 46 | this.onSourceLoaded(); 47 | } else { 48 | var scope = this; 49 | this.source.onload = function () { 50 | scope.onSourceLoaded(); 51 | }; 52 | } 53 | }; 54 | 55 | Tiny.Texture.prototype.constructor = Tiny.Texture; 56 | 57 | Tiny.Texture.prototype.onSourceLoaded = function () { 58 | this.hasLoaded = true; 59 | this.width = this.source.naturalWidth || this.source.width; 60 | this.height = this.source.naturalHeight || this.source.height; 61 | 62 | if (this.noFrame) this.frame = new Tiny.Rectangle(0, 0, this.width, this.height); 63 | 64 | this.setFrame(this.frame); 65 | }; 66 | 67 | Tiny.Texture.prototype.addToCache = function (key, frameName) { 68 | this.key = this.key || key; 69 | this.frame.name = this.frame.name || frameName; 70 | 71 | if (this.frame.name) key += '.' + this.frame.name; 72 | 73 | Tiny.Cache.texture[key] = this; 74 | }; 75 | 76 | Tiny.Texture.prototype.destroy = function () { 77 | if (this.key) { 78 | delete Tiny.Cache.texture[this.key]; 79 | } 80 | 81 | this.source = null; 82 | this.valid = false; 83 | }; 84 | 85 | Tiny.Texture.prototype.setFrame = function (frame) { 86 | this.noFrame = false; 87 | 88 | this.frame = frame; 89 | 90 | this.valid = frame && frame.width && frame.height && this.source && this.hasLoaded; 91 | 92 | if (!this.valid) return; 93 | 94 | // this.width = frame.width; 95 | // this.height = frame.height; 96 | 97 | this.crop.x = frame.x; 98 | this.crop.y = frame.y; 99 | this.crop.width = frame.width; 100 | this.crop.height = frame.height; 101 | 102 | if (!this.trim && (frame.x + frame.width > this.width || frame.y + frame.height > this.height)) { 103 | if (!Tiny.TextureSilentFail) { 104 | throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this); 105 | } 106 | 107 | this.valid = false; 108 | return; 109 | } 110 | 111 | if (this.trim) { 112 | // this.width = this.trim.width; 113 | // this.height = this.trim.height; 114 | this.frame.width = this.trim.width; 115 | this.frame.height = this.trim.height; 116 | } 117 | }; 118 | 119 | // Tiny.Texture.fromImage = function(key, imageUrl, crossorigin) 120 | // { 121 | // var texture = Tiny.TextureCache[key]; 122 | 123 | // if(!texture) 124 | // { 125 | // texture = new Tiny.Texture(Tiny.BaseTexture.fromImage(key, imageUrl, crossorigin)); 126 | // texture.key = key 127 | // Tiny.TextureCache[key] = texture; 128 | // } 129 | 130 | // return texture; 131 | // }; 132 | 133 | // Tiny.Texture.fromFrame = function(frameId) 134 | // { 135 | // var texture = Tiny.TextureCache[frameId]; 136 | // if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache '); 137 | // return texture; 138 | // }; 139 | 140 | Tiny.Texture.fromCanvas = function (canvas) { 141 | // if(!canvas._tinyId) 142 | // { 143 | // canvas._tinyId = '_from_canvas_' + Tiny.TextureCacheIdGenerator++; 144 | // } 145 | 146 | // var texture = Tiny.Cache.texture[canvas._tinyId]; 147 | 148 | // if(!texture) 149 | // { 150 | // texture = new Tiny.Texture( canvas ); 151 | // Tiny.Cache.texture[canvas._tinyId] = texture; 152 | // } 153 | 154 | // return texture; 155 | return new Tiny.Texture(canvas); 156 | }; 157 | 158 | // Tiny.Texture.addTextureToCache = function(texture, id) 159 | // { 160 | // Tiny.TextureCache[id] = texture; 161 | // }; 162 | 163 | // Tiny.Texture.removeTextureFromCache = function(id) 164 | // { 165 | // var texture = Tiny.TextureCache[id]; 166 | // delete Tiny.TextureCache[id]; 167 | // delete Tiny.BaseTextureCache[id]; 168 | // return texture; 169 | // }; 170 | -------------------------------------------------------------------------------- /src/utils/CanvasBuffer.js: -------------------------------------------------------------------------------- 1 | Tiny.CanvasBuffer = function (width, height, options) { 2 | this.width = width; 3 | this.height = height; 4 | 5 | this.canvas = document.createElement("canvas"); 6 | this.context = this.canvas.getContext("2d", options); 7 | 8 | this.canvas.width = width; 9 | this.canvas.height = height; 10 | }; 11 | 12 | Tiny.CanvasBuffer.prototype.constructor = Tiny.CanvasBuffer; 13 | 14 | Tiny.CanvasBuffer.prototype.clear = function () { 15 | this.context.setTransform(1, 0, 0, 1, 0, 0); 16 | this.context.clearRect(0, 0, this.width, this.height); 17 | }; 18 | 19 | Tiny.CanvasBuffer.prototype.resize = function (width, height) { 20 | this.width = this.canvas.width = width; 21 | this.height = this.canvas.height = height; 22 | }; 23 | -------------------------------------------------------------------------------- /src/utils/EventEmitter.js: -------------------------------------------------------------------------------- 1 | function EventListeners() { 2 | this.a = []; 3 | this.n = 0; 4 | } 5 | 6 | Tiny.EventEmitter = { 7 | call: function (obj) { 8 | if (obj) { 9 | obj = obj.prototype || obj; 10 | Tiny.EventEmitter.mixin(obj); 11 | } 12 | }, 13 | 14 | mixin: function (obj) { 15 | const listeners_events = {}; 16 | 17 | function pushListener(event, fn, context, once) { 18 | var listeners = listeners_events[event]; 19 | 20 | if (!listeners) { 21 | listeners = listeners_events[event] = new EventListeners(); 22 | } 23 | 24 | listeners.a.push(fn, context || null, once || false); 25 | listeners.n += 3; 26 | } 27 | 28 | obj.once = function (event, fn, context) { 29 | pushListener(event, fn, context, true); 30 | }; 31 | 32 | obj.on = pushListener; 33 | 34 | obj.off = function (event, fn, context) { 35 | var listeners = listeners_events[event]; 36 | 37 | if (!listeners) return; 38 | 39 | var fnArray = listeners_events[event].a; 40 | 41 | if (!fn) { 42 | fnArray.length = 0; 43 | } else if (!context) { 44 | for (var i = 0; i < fnArray.length; i += 3) { 45 | if (fnArray[i] == fn) { 46 | fnArray.splice(i, 3); 47 | i -= 3; 48 | } 49 | } 50 | } else { 51 | for (var i = 0; i < fnArray.length; i += 3) { 52 | if (fnArray[i] == fn && fnArray[i + 1] == context) { 53 | fnArray.splice(i, 3); 54 | i -= 3; 55 | } 56 | } 57 | } 58 | 59 | if (fnArray.length == 0) { 60 | delete listeners_events[event]; 61 | } 62 | }; 63 | 64 | obj.emit = function (event, a1, a2, a3) { 65 | var listeners = listeners_events[event]; 66 | 67 | if (!listeners) return; 68 | 69 | var fnArray = listeners.a; 70 | listeners.n = 0; 71 | 72 | var len = arguments.length; 73 | var fn, ctx; 74 | 75 | for (var i = 0; i < fnArray.length - listeners.n; i += 3) { 76 | fn = fnArray[i]; 77 | ctx = fnArray[i + 1]; 78 | 79 | if (fnArray[i + 2]) { 80 | fnArray.splice(i, 3); 81 | i -= 3; 82 | } 83 | 84 | if (len <= 1) fn.call(ctx); 85 | else if (len == 2) fn.call(ctx, a1); 86 | else if (len == 3) fn.call(ctx, a1, a2); 87 | else fn.call(ctx, a1, a2, a3); 88 | 89 | // if (fnArray[i + 2]) 90 | // { 91 | // fnArray.splice(i, 3); 92 | // i -= 3; 93 | // } 94 | } 95 | 96 | if (fnArray.length == 0) { 97 | delete listeners_events[event]; 98 | } 99 | }; 100 | } 101 | }; 102 | -------------------------------------------------------------------------------- /src/utils/polyfill.js: -------------------------------------------------------------------------------- 1 | if (!Date.now) { 2 | Date.now = function now() { 3 | return new Date().getTime(); 4 | }; 5 | } 6 | 7 | if (typeof Float32Array == "undefined") { 8 | window.Float32Array = Array; 9 | } 10 | -------------------------------------------------------------------------------- /webpack.build.js: -------------------------------------------------------------------------------- 1 | const TerserPlugin = require('terser-webpack-plugin'), 2 | Webpack = require('webpack'); 3 | 4 | const config = { 5 | mode: 'production', 6 | 7 | context: `${__dirname}/src`, 8 | 9 | entry: { 10 | 'tiny': './index.js', 11 | 'tiny.mini': './mini.js', 12 | 'tiny.base': './base.js' 13 | }, 14 | 15 | output: { 16 | path: `${__dirname}/build/`, 17 | filename: `[name].js`, 18 | environment: { 19 | arrowFunction: false 20 | } 21 | }, 22 | 23 | performance: { 24 | hints: false 25 | }, 26 | 27 | optimization: { 28 | minimize: true, 29 | minimizer: [ 30 | new TerserPlugin({ 31 | include: /\.js$/, 32 | parallel: true, 33 | terserOptions: { 34 | sourceMap: false, 35 | compress: true, 36 | ie8: false, 37 | ecma: 5, 38 | output: { 39 | comments: false 40 | }, 41 | warnings: false 42 | } 43 | }) 44 | ] 45 | }, 46 | 47 | plugins: [ 48 | new Webpack.DefinePlugin({ 49 | __DEBUG__: 'false' 50 | }) 51 | ], 52 | 53 | stats: { 54 | colors: true 55 | } 56 | }; 57 | 58 | module.exports = config; 59 | -------------------------------------------------------------------------------- /webpack.dev.js: -------------------------------------------------------------------------------- 1 | const Webpack = require('webpack'), 2 | // TerserPlugin = require('terser-webpack-plugin'), 3 | path = require('path'); 4 | 5 | const webpackConfig = { 6 | mode: 'development', 7 | // mode: 'production', 8 | // watch: true, 9 | 10 | devtool: 'inline-source-map', 11 | 12 | // context: `${__dirname}`, 13 | 14 | entry: { 15 | 'tiny': './src/index.js', 16 | 'tiny.mini': './src/mini.js', 17 | 'plugins/extra': './plugins/extra', 18 | 'plugins/particles': './plugins/particles', 19 | 'plugins/three': './plugins/three', 20 | 'plugins/create': './plugins/create', 21 | 'plugins/sound': './plugins/sound', 22 | 'plugins/anim': './plugins/anim' 23 | // 'particles_pack': './particles_pack.js', 24 | }, 25 | 26 | // optimization: { 27 | // minimize: true, 28 | // minimizer: [ 29 | // new TerserPlugin({ 30 | // include: /\.js$/, 31 | // parallel: true, 32 | // terserOptions: { 33 | // sourceMap: false, 34 | // compress: true, 35 | // ie8: false, 36 | // ecma: 5, 37 | // output: { 38 | // comments: false 39 | // }, 40 | // warnings: false 41 | // } 42 | // }) 43 | // ] 44 | // }, 45 | 46 | output: { 47 | path: path.resolve(__dirname, 'examples/libs/tiny'), 48 | filename: '[name].js', 49 | environment: { 50 | arrowFunction: false 51 | } 52 | }, 53 | 54 | plugins: [ 55 | new Webpack.DefinePlugin({ 56 | __DEBUG__: 'true' 57 | }) 58 | ], 59 | 60 | stats: { 61 | colors: true 62 | } 63 | 64 | // devServer: { 65 | // host: '0.0.0.0', 66 | // port: 3000, 67 | // // hot: true, 68 | // static: { 69 | // directory: path.resolve('examples') 70 | // // watch: true 71 | // } 72 | // } 73 | }; 74 | 75 | // const compiler = Webpack(webpackConfig); 76 | // const devServerOptions = { ...webpackConfig.devServer, open: true }; 77 | // const server = new WebpackDevServer(devServerOptions, compiler); 78 | 79 | // const runServer = async () => { 80 | // console.log('Starting server...'); 81 | // await server.start(); 82 | // }; 83 | 84 | // runServer(); 85 | 86 | module.exports = webpackConfig; 87 | --------------------------------------------------------------------------------