This Javascript program demonstrates a composite design pattern.
<!DOCTYPE html> <html> <head> <title>XoaX.net's Javascript</title> <script type="text/javascript" src="Composite.js"></script> </head> <body onload="Initialize()"> <canvas id="idCanvas" width="640" height ="480" style="background-color: #F0F0F0;"></canvas> </body> </html>
class CAGraphic { constructor() {} Draw(qContext, qT = CTransformation.GetIdentity()) {} } class CDisk extends CAGraphic { #mdR; #msColor; constructor(dR, sColor) { super(); this.#mdR = dR; this.#msColor = sColor; } Draw(qContext, qT = CTransformation.GetIdentity()) { qT.SetTransform(qContext); qContext.fillStyle = this.#msColor; qContext.beginPath(); qContext.arc(0, 0, this.#mdR, 0, 2 * Math.PI); qContext.fill(); } } class CRectangle extends CAGraphic { #mdW; #mdH; #msColor; constructor(dW, dH, sColor) { super(); this.#mdW = dW; this.#mdH = dH; this.#msColor = sColor; } Draw(qContext, qT = CTransformation.GetIdentity()) { qT.SetTransform(qContext); qContext.fillStyle = this.#msColor; qContext.fillRect(0, 0, this.#mdW, this.#mdH); } } class CComposite extends CAGraphic { // Transformation array #mdaT = new Array(); #mdaG = new Array(); constructor() { super(); } Add(qTransformation, qGraphic) { this.#mdaT.push(qTransformation); this.#mdaG.push(qGraphic); } Draw(qContext, qT = CTransformation.GetIdentity()) { var qCurr = qT; for (var i = 0; i < this.#mdaT.length; ++i) { qCurr = CTransformation.Multiply(qCurr, this.#mdaT[i]); this.#mdaG[i].Draw(qContext, qCurr); } } } class CTransformation { // [ A[0], A[2], A[4] ] // [ A[1], A[3], A[5] ] // [ 0, 0, 1 ] #mdaA; constructor(dA0, dA1, dA2, dA3, dA4, dA5) { this.#mdaA = new Array(dA0, dA1, dA2, dA3, dA4, dA5); } Apply(dX, dY) { return [this.#mdaA[0]*dX + this.#mdaA[2]*dY + this.#mdaA[4], this.#mdaA[1]*dX + this.#mdaA[3]*dY + this.#mdaA[5]]; } SetTransform(qContext) { qContext.setTransform( this.#mdaA[0], this.#mdaA[1], this.#mdaA[2], this.#mdaA[3], this.#mdaA[4], this.#mdaA[5]); } static GetIdentity(){ return new CTransformation(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); } static GetRotation(dAngle){ return new CTransformation(Math.cos(dAngle), Math.sin(dAngle), -Math.sin(dAngle), Math.cos(dAngle), 0.0, 0.0); } static GetTranslation(dDx, dDy){ return new CTransformation(1.0, 0.0, 0.0, 1.0, dDx, dDy); } static GetScaling(dS){ return new CTransformation(dS, 0.0, 0.0, dS, 0.0, 0.0); } static Multiply(qT1, qT2) { return new CTransformation( qT1.#mdaA[0]*qT2.#mdaA[0]+qT1.#mdaA[2]*qT2.#mdaA[1], qT1.#mdaA[1]*qT2.#mdaA[0]+qT1.#mdaA[3]*qT2.#mdaA[1], qT1.#mdaA[0]*qT2.#mdaA[2]+qT1.#mdaA[2]*qT2.#mdaA[3], qT1.#mdaA[1]*qT2.#mdaA[2]+qT1.#mdaA[3]*qT2.#mdaA[3], qT1.#mdaA[0]*qT2.#mdaA[4]+qT1.#mdaA[2]*qT2.#mdaA[5] + qT1.#mdaA[4], qT1.#mdaA[1]*qT2.#mdaA[4]+qT1.#mdaA[3]*qT2.#mdaA[5] + qT1.#mdaA[5]); } } function Initialize() { var qCanvas = document.getElementById("idCanvas"); var qContext = qCanvas.getContext("2d"); var qBackground = new CComposite(); var qSky = new CRectangle(640, 300, "darkblue"); var qGround = new CRectangle(640, 180, "green"); var qMoon = new CDisk(40, "white"); qBackground.Add(CTransformation.GetTranslation(0, 0), qSky); qBackground.Add(CTransformation.GetTranslation(0, 300), qGround); qBackground.Add(CTransformation.GetTranslation(500, -200), qMoon); qBackground.Draw(qContext); // The wheels are composite objects var qWheel = new CComposite(); var qTire = new CDisk(50, "black"); var qRim = new CDisk(30, "gray"); qWheel.Add(CTransformation.GetIdentity(), qTire); qWheel.Add(CTransformation.GetIdentity(), qRim); // Construct the car with two rectangles and two wheels var qCar = new CComposite(); var qCab = new CRectangle(200, 80, "orange"); var qBody = new CRectangle(500, 100, "orange"); qCar.Add(CTransformation.GetTranslation(220, 150), qCab); qCar.Add(CTransformation.GetTranslation(-150, 80), qBody); qCar.Add(CTransformation.GetTranslation(80, 100), qWheel); qCar.Add(CTransformation.GetTranslation(340, 0), qWheel); qCar.Draw(qContext); }
© 20072025 XoaX.net LLC. All rights reserved.