var Camera = require('../../camera/2d/Camera.js'); var CanvasPool = require('../../display/canvas/CanvasPool'); var Class = require('../../utils/Class'); var Commands = require('./Commands'); var Components = require('../components'); var Ellipse = require('../../geom/ellipse/'); var GameObject = require('../GameObject'); var GetValue = require('../../utils/object/GetValue'); var MATH_CONST = require('../../math/const'); var Matrix4 = require('../../math/Matrix4'); var Mesh = require('../../geom/mesh/Mesh'); var Render = require('./GraphicsRender'); var Vector3 = require('../../math/Vector3'); var Graphics = new Class({ Extends: GameObject, Mixins: [Components.Alpha, Components.BlendMode, Components.Transform, Components.RenderTarget, Components.Visible, Components.ScrollFactor, Render] , initialize: function Graphics(scene, options){ var x = GetValue(options, 'x', 0); var y = GetValue(options, 'y', 0); GameObject.call(this, scene, 'Graphics'); this.setPosition(x, y); this.displayOriginX = 0; this.displayOriginY = 0; this.commandBuffer = [] ; this.defaultFillColor = -1; this.defaultFillAlpha = 1; this.defaultStrokeWidth = 1; this.defaultStrokeColor = -1; this.defaultStrokeAlpha = 1; this._lineWidth = 1; this.setDefaultStyles(options); this.viewportWidth = scene.sys.game.config.width; this.viewportHeight = scene.sys.game.config.height; this.camera = { position: new Vector3(), target: new Vector3()} ; this.up = new Vector3().up(); this.projectionMatrix = new Matrix4(); this.viewMatrix = new Matrix4().lookAt(this.camera.position, _AN_Read_target('target', this.camera), this.up); this.setViewport(this.viewportWidth, this.viewportHeight); var resourceManager = scene.sys.game.renderer.resourceManager; if (resourceManager !== undefined) { this.resourceManager = resourceManager; this.gl = scene.sys.game.renderer.gl; } } , setDefaultStyles: function (options){ if (GetValue(options, 'lineStyle', null )) { this.defaultStrokeWidth = GetValue(options, 'lineStyle.width', 1); this.defaultStrokeColor = GetValue(options, 'lineStyle.color', 16777215); this.defaultStrokeAlpha = GetValue(options, 'lineStyle.alpha', 1); this.lineStyle(this.defaultStrokeWidth, this.defaultStrokeColor, this.defaultStrokeAlpha); } if (GetValue(options, 'fillStyle', null )) { this.defaultFillColor = GetValue(options, 'fillStyle.color', 16777215); this.defaultFillAlpha = GetValue(options, 'fillStyle.alpha', 1); this.fillStyle(this.defaultFillColor, this.defaultFillAlpha); } return this; } , lineStyle: function (lineWidth, color, alpha){ if (alpha === undefined) { alpha = 1; } this.commandBuffer.push(Commands.LINE_STYLE, lineWidth, color, alpha); this._lineWidth = lineWidth; return this; } , fillStyle: function (color, alpha){ if (alpha === undefined) { alpha = 1; } this.commandBuffer.push(Commands.FILL_STYLE, color, alpha); return this; } , beginPath: function (){ this.commandBuffer.push(Commands.BEGIN_PATH); return this; } , closePath: function (){ this.commandBuffer.push(Commands.CLOSE_PATH); return this; } , fillPath: function (){ this.commandBuffer.push(Commands.FILL_PATH); return this; } , strokePath: function (){ this.commandBuffer.push(Commands.STROKE_PATH); return this; } , fillCircleShape: function (circle){ return this.fillCircle(circle.x, circle.y, circle.radius); } , strokeCircleShape: function (circle){ return this.strokeCircle(circle.x, circle.y, circle.radius); } , fillCircle: function (x, y, radius){ this.beginPath(); this.arc(x, y, radius, 0, MATH_CONST.PI2); this.closePath(); this.fillPath(); return this; } , strokeCircle: function (x, y, radius){ this.beginPath(); this.arc(x, y, radius, 0, MATH_CONST.PI2); this.closePath(); this.strokePath(); return this; } , fillRectShape: function (rect){ return this.fillRect(rect.x, rect.y, rect.width, rect.height); } , strokeRectShape: function (rect){ return this.strokeRect(rect.x, rect.y, rect.width, rect.height); } , fillRect: function (x, y, width, height){ this.commandBuffer.push(Commands.FILL_RECT, x, y, width, height); return this; } , strokeRect: function (x, y, width, height){ var lineWidthHalf = this._lineWidth / 2; var minx = x - lineWidthHalf; var maxx = x + lineWidthHalf; this.beginPath(); this.moveTo(x, y); this.lineTo(x, y + height); this.strokePath(); this.closePath(); this.beginPath(); this.moveTo(x + width, y); this.lineTo(x + width, y + height); this.strokePath(); this.closePath(); this.beginPath(); this.moveTo(minx, y); this.lineTo(maxx + width, y); this.strokePath(); this.closePath(); this.beginPath(); this.moveTo(minx, y + height); this.lineTo(maxx + width, y + height); this.strokePath(); this.closePath(); return this; } , fillPointShape: function (point, size){ return this.fillPoint(point.x, point.y, size); } , fillPoint: function (x, y, size){ this.commandBuffer.push(Commands.FILL_RECT, x, y, size, size); return this; } , fillTriangleShape: function (triangle){ return this.fillTriangle(triangle.x1, triangle.y1, triangle.x2, triangle.y2, triangle.x3, triangle.y3); } , strokeTriangleShape: function (triangle){ return this.strokeTriangle(triangle.x1, triangle.y1, triangle.x2, triangle.y2, triangle.x3, triangle.y3); } , fillTriangle: function (x0, y0, x1, y1, x2, y2){ this.commandBuffer.push(Commands.FILL_TRIANGLE, x0, y0, x1, y1, x2, y2); return this; } , strokeTriangle: function (x0, y0, x1, y1, x2, y2){ this.commandBuffer.push(Commands.STROKE_TRIANGLE, x0, y0, x1, y1, x2, y2); return this; } , strokeLineShape: function (line){ return this.lineBetween(line.x1, line.y1, line.x2, line.y2); } , lineBetween: function (x1, y1, x2, y2){ this.beginPath(); this.moveTo(x1, y1); this.lineTo(x2, y2); this.strokePath(); return this; } , lineTo: function (x, y){ this.commandBuffer.push(Commands.LINE_TO, x, y); return this; } , moveTo: function (x, y){ this.commandBuffer.push(Commands.MOVE_TO, x, y); return this; } , lineFxTo: function (x, y, width, rgb){ this.commandBuffer.push(Commands.LINE_FX_TO, x, y, width, rgb, 1); return this; } , moveFxTo: function (x, y, width, rgb){ this.commandBuffer.push(Commands.MOVE_FX_TO, x, y, width, rgb, 1); return this; } , strokePoints: function (points, autoClose, endIndex){ if (autoClose === undefined) { autoClose = false ; } if (endIndex === undefined) { endIndex = _AN_Read_length('length', points); } this.beginPath(); this.moveTo(points[0].x, points[0].y); for (var i = 1; i < endIndex; i++ ){ this.lineTo(points[i].x, points[i].y); } if (autoClose) { this.lineTo(points[0].x, points[0].y); } this.strokePath(); return this; } , fillPoints: function (points, autoClose, endIndex){ if (autoClose === undefined) { autoClose = false ; } if (endIndex === undefined) { endIndex = _AN_Read_length('length', points); } this.beginPath(); this.moveTo(points[0].x, points[0].y); for (var i = 1; i < endIndex; i++ ){ this.lineTo(points[i].x, points[i].y); } if (autoClose) { this.lineTo(points[0].x, points[0].y); } this.fillPath(); return this; } , strokeEllipseShape: function (ellipse, smoothness){ if (smoothness === undefined) { smoothness = 32; } var points = ellipse.getPoints(smoothness); return this.strokePoints(points, true ); } , strokeEllipse: function (x, y, width, height, smoothness){ if (smoothness === undefined) { smoothness = 32; } var ellipse = new Ellipse(x, y, width, height); var points = ellipse.getPoints(smoothness); return this.strokePoints(points, true ); } , arc: function (x, y, radius, startAngle, endAngle, anticlockwise){ this.commandBuffer.push(Commands.ARC, x, y, radius, startAngle, endAngle, anticlockwise); return this; } , cameraX: { get: function (){ return this.camera.position.x; } , set: function (value){ this.camera.position.x = value; this.viewMatrix.lookAt(this.camera.position, _AN_Read_target('target', this.camera), this.up); } } , cameraY: { get: function (){ return this.camera.position.y; } , set: function (value){ this.camera.position.y = value; this.viewMatrix.lookAt(this.camera.position, _AN_Read_target('target', this.camera), this.up); } } , cameraZ: { get: function (){ return this.camera.position.z; } , set: function (value){ this.camera.position.z = value; this.viewMatrix.lookAt(this.camera.position, _AN_Read_target('target', this.camera), this.up); } } , cameraTargetX: { get: function (){ return (_AN_Read_target('target', this.camera)).x; } , set: function (value){ _AN_Read_target('target', this.camera).x = value; this.viewMatrix.lookAt(this.camera.position, _AN_Read_target('target', this.camera), this.up); } } , cameraTargetY: { get: function (){ return (_AN_Read_target('target', this.camera)).y; } , set: function (value){ _AN_Read_target('target', this.camera).y = value; this.viewMatrix.lookAt(this.camera.position, _AN_Read_target('target', this.camera), this.up); } } , cameraTargetZ: { get: function (){ return (_AN_Read_target('target', this.camera)).z; } , set: function (value){ _AN_Read_target('target', this.camera).z = value; this.viewMatrix.lookAt(this.camera.position, _AN_Read_target('target', this.camera), this.up); } } , setCameraPosition: function (x, y, z){ this.camera.position.set(x, y, z); this.viewMatrix.lookAt(this.camera.position, _AN_Read_target('target', this.camera), this.up); return this; } , setCameraTarget: function (x, y, z){ _AN_Read_target('target', this.camera).set(x, y, z); this.viewMatrix.lookAt(this.camera.position, _AN_Read_target('target', this.camera), this.up); return this; } , setViewport: function (width, height, fov, near, far){ if (fov === undefined) { fov = 0.8; } if (near === undefined) { near = 0.01; } if (far === undefined) { far = 1; } this.viewportWidth = width; this.viewportHeight = height; this.projectionMatrix.perspective(fov, width / height, near, far); return this; } , createMesh: function (key, x, y, z){ var data = this.scene.sys.cache.obj.get(key); var mesh = new Mesh(data, x, y, z); return mesh; } , fillMesh: function (mesh){ mesh.fill(this); return this; } , strokeMesh: function (mesh){ mesh.stroke(this); return this; } , save: function (){ this.commandBuffer.push(Commands.SAVE); return this; } , restore: function (){ this.commandBuffer.push(Commands.RESTORE); return this; } , translate: function (x, y){ this.commandBuffer.push(Commands.TRANSLATE, x, y); return this; } , scale: function (x, y){ this.commandBuffer.push(Commands.SCALE, x, y); return this; } , rotate: function (radian){ this.commandBuffer.push(Commands.ROTATE, radian); return this; } , clear: function (){ this.commandBuffer.length = 0; if (this.defaultFillColor > -1) { this.fillStyle(this.defaultFillColor, this.defaultFillAlpha); } if (this.defaultStrokeColor > -1) { this.lineStyle(this.defaultStrokeWidth, this.defaultStrokeColor, this.defaultStrokeAlpha); } return this; } , generateTexture: function (key, width, height){ var sys = this.scene.sys; if (width === undefined) { width = sys.game.config.width; } if (height === undefined) { height = sys.game.config.height; } Graphics.TargetCamera.setViewport(0, 0, width, height); Graphics.TargetCamera.scrollX = this.x; Graphics.TargetCamera.scrollY = this.y; var texture; var ctx; if (typeof key === 'string') { if (sys.textures.exists(key)) { texture = sys.textures.get(key); var src = texture.getSourceImage(); if (src instanceof HTMLCanvasElement) { ctx = src.getContext('2d'); } } else { texture = sys.textures.createCanvas(key, width, height); ctx = texture.getSourceImage().getContext('2d'); } } else if (key instanceof HTMLCanvasElement) { ctx = key.getContext('2d'); } if (ctx) { this.renderCanvas(sys.game.renderer, this, 0, Graphics.TargetCamera, ctx); if (this.gl && texture) { sys.game.renderer.uploadCanvasToGPU(ctx.canvas, texture.source[0].glTexture, true ); } } return this; } } ); Graphics.TargetCamera = new Camera(0, 0, 0, 0); module.exports = Graphics;