cirsim
Version:
Cirsim Circuit Simulator
162 lines (130 loc) • 4.01 kB
JavaScript
import {Component} from '../Component';
import {PaletteImage} from '../Graphics/PaletteImage';
import {CanvasHelper} from '../Graphics/CanvasHelper';
/**
* Component: AND gate
* @constructor
*/
export const And = function() {
Component.call(this);
this.height = 50;
this.width = 64;
// Two inputs and one output
this.addIn(-32, -16, 16);
this.addIn(-32, 16, 16);
this.addOut(32, 0, 16);
};
And.prototype = Object.create(Component.prototype);
And.prototype.constructor = And;
And.type = "And"; ///< Name to use in files
And.label = "AND"; ///< Label for the palette
And.desc = "AND gate"; ///< Description for the palette
And.order = 11; ///< Order of presentation in the palette
And.description = `<h2>AND Gate</h2><p>The output of an AND gate is <em>true</em> if both inputs are true.</p>`;
And.help = 'and';
/**
* Compute the gate result
* @param state
*/
And.prototype.compute = function(state) {
if(state[0] && state[1]) {
this.outs[0].set(true);
} else if(state[0] === false || state[1] === false) {
this.outs[0].set(false);
} else {
this.outs[0].set(undefined);
}
};
/**
* Clone this component object: AND gate.
* @return {And}
* @instance And
*/
And.prototype.clone = function() {
const copy = new And();
copy.copyFrom(this);
return copy;
};
/**
* Draw component object.
* @param context Display context
* @param view View object
*/
And.prototype.draw = function(context, view) {
this.selectStyle(context, view);
And.path(context, this.x, this.y, this.width, this.height);
CanvasHelper.fillWith(context);
// And.path(context, this.x, this.y, this.width, this.height);
context.stroke();
this.drawName(context, -2, 5);
this.drawIO(context, view);
};
/**
* Create a path in the basic AND gate shape.
* @param context
* @param x
* @param y
* @param width
* @param height
*/
And.path = function(context, x, y, width, height) {
var leftX = x - width/2 - 0.5;
var rightX = x + width/2 + 0.5;
var topY = y - height/2 - 0.5;
var botY = y + height/2 + 0.5;
// Left side
context.beginPath();
context.moveTo(leftX, botY);
context.lineTo(leftX, topY);
// Top
context.lineTo(rightX - height / 2, topY);
// Arc
context.arc(rightX - height / 2,
y, height/2 + 0.5, -Math.PI/2, Math.PI/2);
// Bottom
context.lineTo(leftX, botY);
}
/**
* Create a PaletteImage object for an And gate
* This is the base shape without input/outputs
* so we can use this code for 3-4 inputs and NAND
*/
And.paletteImageBase = function() {
var paletteImage = new PaletteImage(120, 70);
var context = paletteImage.context;
context.lineWidth = 1.5;
var x = paletteImage.width / 2;
var y = paletteImage.height / 2;
var scale = 0.5;
var width = scale * paletteImage.width;
var height = scale * paletteImage.height;
var arc = 26.5;
var leftX = x - width/2 - 0.5;
var rightX = x + width/2 + 0.5;
var topY = y - arc + 0.5;
var botY = y + arc - 0.5;
this.leftX = leftX - paletteImage.width/2;
this.rightX = rightX - paletteImage.width/2
// Left side
context.beginPath();
context.moveTo(leftX, botY);
context.lineTo(leftX, topY);
// Top
context.lineTo(rightX - arc, topY);
// Arc
context.arc(rightX - arc, y, arc, -Math.PI/2, Math.PI/2);
// Bottom
context.lineTo(leftX, botY);
paletteImage.fillStroke();
paletteImage.io(this.rightX, 0, 'e');
return paletteImage;
}
/**
* Create a PaletteImage object for an And gate
*/
And.paletteImage = function() {
var paletteImage = And.paletteImageBase();
paletteImage.io(this.leftX, -16, 'w');
paletteImage.io(this.leftX, +16, 'w');
return paletteImage;
}