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.