cpu-simulator/build/editor/js/bk/index.js

230 lines
7.7 KiB
JavaScript
Raw Normal View History

2023-12-15 19:43:36 +00:00
var canvas, ctx
var selectedItem
var mouseisdown
var chip = new Component("main");
var pinImages = [];
var wireVisuals = [];
var wireBeingDrawn = [];
images = {};
var x;
document.addEventListener("DOMContentLoaded", function(event){
canvas = document.getElementById('logicsim');
canvas.addEventListener("mousedown",selectItem);
canvas.addEventListener("mouseup", function(){mouseisdown=false});
canvas.addEventListener("mousemove",mousemove);
document.addEventListener("keydown",checkKey);
ctx = canvas.getContext('2d');
preloadAssets();
requestAnimationFrame(drawCanvas);
x=setInterval(function(){chip.process()},1);
});
function getMousePos(c,e){
var rect = c.getBoundingClientRect();
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
}
}
function checkKey(e){
e=e||window.event;
if(e.keyCode==27){
selectedPin={component:-1,pin:-1};
wireBeingDrawn=[];
}
}
function isInside(c,point){
return ( point.x > c.position.x && point.x < c.position.x + images[c.type].width) &&
( point.y > c.position.y && point.y < c.position.y + images[c.type].height);
}
function isInsidePin(p,point){
return Math.sqrt(Math.pow((p.position.x-point.x),2)+Math.pow((p.position.y-point.y),2)) < p.radius;
}
var clickpos;
var nWireAttempts=0;
var selectedPin = {component:-1,pin:-1};
var hoveredPin = {component:-1,pin:-1,type:-1};
function selectItem(e){
pos = getMousePos(canvas, e)
if(hoveredPin.component>=0){
if(hoveredPin.type==1){
chip.pins[hoveredPin.pin]=1-chip.pins[hoveredPin.pin];
} else {
if(wireBeingDrawn.length>0){
if(chip.connect(selectedPin, hoveredPin, nWireAttempts)){
wireBeingDrawn[wireBeingDrawn.length-1]={component:hoveredPin.component,pin:hoveredPin.pin};
wireVisuals.push({wireId:nWireAttempts,path:wireBeingDrawn.slice()});
wireBeingDrawn=[];
selectedPin={component:-1,pin:-1};
nWireAttempts+=1;
} else {
console.log("noooo");
}
} else {
wireBeingDrawn.push({component:hoveredPin.component,pin:hoveredPin.pin});
wireBeingDrawn.push({x:pos.x,y:pos.y});
selectedPin = {component:hoveredPin.component,pin:hoveredPin.pin};
}
}
} else {
if(wireBeingDrawn.length>0){
wireBeingDrawn[wireBeingDrawn.length-1]={x:pos.x,y:pos.y};
wireBeingDrawn.push({x:pos.x,y:pos.y})//slice());
}
}
chip.zIndex.forEach(function(c,i){
if (isInside(c, pos) && ctx.getImageData(pos.x,pos.y,1,1).data[3]) {
mouseisdown = true;
clickpos = pos;
chip.sendToFront(chip.getProperIndex(c));
// DELETE THIS LATER //
return;
}
});
}
var pos;
function mousemove(e){
pos = getMousePos(canvas,e);
if(wireBeingDrawn.length>0){
wireBeingDrawn[wireBeingDrawn.length-1]={x:pos.x,y:pos.y};
}
if(mouseisdown){
last = chip.zIndex.length-1;
chip.zIndex[last].position.x -= (clickpos.x - pos.x);
chip.zIndex[last].position.y -= (clickpos.y - pos.y);
clickpos = pos;
}
if(!pinImages.some(pi=>{
if(isInsidePin(pi,pos)){
hoveredPin = {component:pi.component,pin:pi.pin,type:pi.type}
return true;
}
})){
hoveredPin={component:-1,pin:-1};
}
}
function preloadAssets(){
Object.entries(chips).forEach(function(c){
if (!(c[1].image in images)){
images[c[0]] = new Image();
images[c[0]].src = c[1].image;
}
});
}
function makeArr(startValue, stopValue, cardinality) {
var arr = [];
var step = (stopValue - startValue) / (cardinality - 1);
for (var i = 0; i < cardinality; i++) {
arr.push(startValue + (step * i));
}
return arr;
}
function drawCircle(x,y,radius,colour){
ctx.beginPath();
ctx.arc(Math.floor(x),Math.floor(y),radius,0,2*Math.PI,false);
ctx.fillStyle=colour;
ctx.fill();
}
function drawLine(origin,destination,width,colour){
ctx.beginPath();
ctx.moveTo(origin.x,origin.y);
ctx.lineTo(destination.x,destination.y);
ctx.strokeStyle=colour;
ctx.lineWidth=width;
ctx.stroke();
}
function drawCanvas() {
pI = [];
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.canvas.width = 600;
ctx.canvas.height = 600;
ctx.fillStyle="lightgray";
ctx.fillRect(0,0,20,canvas.height);
//components.slice().reverse().forEach(function(c){
for(var i=0;i<wireBeingDrawn.length-1;i++){
if(i==0)
p1=pinImages.find(p=>p.component==wireBeingDrawn[0].component && p.pin==wireBeingDrawn[0].pin && p.type==0).position;
else
p1=wireBeingDrawn[i];
//if(i==wireBeingDrawn.length-2)
// p2=pinImages.find(p=>p.component==wireBeingDrawn[i+1].component&&p.pin==wireBeingDrawn[i+1].pin&&p.type==0).position;
//else
p2=wireBeingDrawn[i+1]
drawLine(p1,p2,3,["black","red"][chip.subComponents[wireBeingDrawn[0].component].pins[wireBeingDrawn[0].pin]]);
}
wireVisuals=wireVisuals.filter(wv=> {return chip.wires.findIndex(w=>w.wireId==wv.wireId)>=0});
wireVisuals.forEach(wv=>{
for(var i=0;i<wv.path.length-1;i++){
if(i==0)
p1=pinImages.find(p=>p.component==wv.path[0].component && p.pin==wv.path[0].pin && p.type==0).position;
else
p1=wv.path[i];
if(i==wv.path.length-2)
p2=pinImages.find(p=>p.component==wv.path[i+1].component&&p.pin==wv.path[i+1].pin&&p.type==0).position;
else
p2=wv.path[i+1];
drawLine(p1,p2,3,["black","red"][chip.subComponents[wv.path[0].component].pins[wv.path[0].pin]]);
}
});
chip.pins.forEach((p,i)=>{
if(i<chip.inputs){
centerX=10;
otherpins = chip.inputs;
pindex=i;
} else {
centerX = canvas.width - 10;
otherpins = chip.pins.length - chip.inputs;
pindex = i - chip.inputs;
}
ys = makeArr(0-(20/otherpins),0+canvas.height+(20/otherpins),otherpins+2);
ys.shift();
ys.pop();
centerY = ys[pindex];
pI.push({component:0,pin:i,position:{x:centerX,y:centerY},radius:10,type:1});
secondaryX=(i<chip.inputs?centerX+20:centerX-20);
pI.push({component:0,pin:i,position:{x:secondaryX,y:centerY},radius:5,type:0});
//ctx.beginPath();
//ctx.arc(Math.floor(centerX), Math.floor(centerY), 10, 0, 2*Math.PI, false);
(hoveredPin.component==0&&hoveredPin.pin==i&&hoveredPin.type==0) ? offset=2 : offset=0;
fillStyle1=["black","red","grey","pink"][chip.pins[i]+offset];
fillStyle2=(i<chip.inputs?["black","red","grey","pink"]:["black","red","black","red"])[chip.pins[i]+((hoveredPin.component==0&&hoveredPin.pin==i&&hoveredPin.type==1)?2:0)];
//ctx.fill();
drawLine({x:centerX,y:centerY},{x:secondaryX,y:centerY},1,["black","red"][chip.pins[i]]);
drawCircle(centerX,centerY,10,fillStyle2);
drawCircle(secondaryX,centerY,5,fillStyle1);
})
chip.zIndex.forEach(c=>{
img = images[c.type];
ctx.drawImage(img,c.position.x,c.position.y);
c.pins.forEach((p,i)=>{
//trueCenterY = (c.position.y+(c.position.y + c.height))/2
centerX = c.position.x+img.width+5;
otherpins = c.pins.length - c.inputs;
pindex = i - c.inputs;
if(i<c.inputs){
centerX = c.position.x-5;
if(["xor","nor","or"].includes(c.type)){
centerX += 9;
}
otherpins = c.inputs;
pindex=i;
}
ys = makeArr(c.position.y-(20/otherpins),c.position.y+img.height+(20/otherpins),otherpins+2);
ys.shift();
ys.pop();
centerY = ys[pindex];
pI.push({component:chip.subComponents.indexOf(c),pin:i,position:{x:centerX,y:centerY},radius:10,type:0});
ctx.beginPath();
ctx.arc(Math.floor(centerX), Math.floor(centerY), 5, 0, 2*Math.PI, false);
(hoveredPin.component==chip.subComponents.indexOf(c)&&hoveredPin.pin==i) ? offset=2 : offset=0;
ctx.fillStyle=["black","red","grey","pink"][c.pins[i]+offset];
ctx.fill();
});
});
pinImages=pI;
requestAnimationFrame(drawCanvas);
}