added all the basic gates
Before Width: | Height: | Size: 96 KiB |
7
src/assets/and.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M800 0H0V800H800V0Z" fill="#0277BD"/>
|
||||
<path d="M412.471 285H290.034V515H412.471C536.599 515 540.406 285 412.471 285Z" fill="#0277BD" stroke="white" stroke-width="10"/>
|
||||
<path d="M510 401L569 400" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M231 471H290" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M230 323H289" stroke="#EEEEEE" stroke-width="10"/>
|
||||
</svg>
|
After Width: | Height: | Size: 468 B |
Before Width: | Height: | Size: 38 KiB |
8
src/assets/nand.svg
Normal file
|
@ -0,0 +1,8 @@
|
|||
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="800" height="800" fill="#0277BD"/>
|
||||
<path d="M412.471 285H290.034V515H412.471C536.599 515 540.406 285 412.471 285Z" fill="#0277BD" stroke="white" stroke-width="10"/>
|
||||
<path d="M510 401L583 400" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M231 471H290" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M230 323H289" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M538 400C538 409.587 531.484 416 525 416C518.516 416 512 409.587 512 400C512 390.413 518.516 384 525 384C531.484 384 538 390.413 538 400Z" fill="#0277BD" stroke="white" stroke-width="10"/>
|
||||
</svg>
|
After Width: | Height: | Size: 667 B |
8
src/assets/nor.svg
Normal file
|
@ -0,0 +1,8 @@
|
|||
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M800 0H0V800H800V0Z" fill="#0277BD"/>
|
||||
<path d="M400.437 286H278C278 286 331.5 302 329.5 401C327.5 500 278 516 278 516H400.437C524.565 516 528.372 286 400.437 286Z" fill="#0277BD" stroke="white" stroke-width="10"/>
|
||||
<path d="M495 401L576 400" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M261 471H320" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M261 323H320" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M529 400.5C529 406.908 523.031 413 514.5 413C505.969 413 500 406.908 500 400.5C500 394.092 505.969 388 514.5 388C523.031 388 529 394.092 529 400.5Z" fill="#0277BD" stroke="white" stroke-width="10"/>
|
||||
</svg>
|
After Width: | Height: | Size: 722 B |
Before Width: | Height: | Size: 14 KiB |
3
src/assets/not.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg width="800" height="799" viewBox="0 0 800 799" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M800 0H0V800H800V0Z" fill="#0277BD"/>
|
||||
</svg>
|
After Width: | Height: | Size: 154 B |
7
src/assets/or.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M800 0H0V800H800V0Z" fill="#0277BD"/>
|
||||
<path d="M400.437 281H278C278 281 331.5 297 329.5 396C327.5 495 278 511 278 511H400.437C524.565 511 528.372 281 400.437 281Z" fill="#0277BD" stroke="white" stroke-width="10"/>
|
||||
<path d="M495 401L554 400" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M261 471H320" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M261 323H320" stroke="#EEEEEE" stroke-width="10"/>
|
||||
</svg>
|
After Width: | Height: | Size: 514 B |
Before Width: | Height: | Size: 3.4 KiB |
9
src/assets/xnor.svg
Normal file
|
@ -0,0 +1,9 @@
|
|||
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M800 0H0V800H800V0Z" fill="#0277BD"/>
|
||||
<path d="M400.437 286H278C278 286 331.5 302 329.5 401C327.5 500 278 516 278 516H400.437C524.565 516 528.372 286 400.437 286Z" fill="#0277BD" stroke="white" stroke-width="10"/>
|
||||
<path d="M495 401L576 400" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M235 471H320" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M235 323H320" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M529 400.5C529 406.908 523.031 413 514.5 413C505.969 413 500 406.908 500 400.5C500 394.092 505.969 388 514.5 388C523.031 388 529 394.092 529 400.5Z" fill="#0277BD" stroke="white" stroke-width="10"/>
|
||||
<path d="M255.5 282.5C324.548 359.386 327.672 417.167 255.5 515.5" stroke="white" stroke-width="10"/>
|
||||
</svg>
|
After Width: | Height: | Size: 824 B |
8
src/assets/xor.svg
Normal file
|
@ -0,0 +1,8 @@
|
|||
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M800 0H0V800H800V0Z" fill="#0277BD"/>
|
||||
<path d="M400.437 286H278C278 286 331.5 302 329.5 401C327.5 500 278 516 278 516H400.437C524.565 516 528.372 286 400.437 286Z" fill="#0277BD" stroke="white" stroke-width="10"/>
|
||||
<path d="M495 401H551.5" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M235 471H320" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M235 323H320" stroke="#EEEEEE" stroke-width="10"/>
|
||||
<path d="M255.5 282.5C324.548 359.386 327.672 417.167 255.5 515.5" stroke="white" stroke-width="10"/>
|
||||
</svg>
|
After Width: | Height: | Size: 614 B |
Before Width: | Height: | Size: 4.2 KiB |
|
@ -8,6 +8,7 @@ export interface Context {
|
|||
set: (index: number, state: boolean) => void
|
||||
color: (color: string) => void
|
||||
enviroment: SimulationEnv
|
||||
colors: Record<string, string>
|
||||
}
|
||||
|
||||
export interface InitialisationContext {
|
||||
|
|
|
@ -53,8 +53,10 @@ const LogicGateModal = () => {
|
|||
<div
|
||||
key={index}
|
||||
className="logic-gate-item"
|
||||
onClick={() => {
|
||||
onClick={e => {
|
||||
addGate(renderer, name)
|
||||
|
||||
e.stopPropagation()
|
||||
}}
|
||||
>
|
||||
<Icon className="lgi-icon logic-gate-item-type">
|
||||
|
|
|
@ -9,7 +9,7 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
|||
},
|
||||
material: {
|
||||
type: 'image',
|
||||
value: require('../../assets/and_gate')
|
||||
fill: require('../../assets/and')
|
||||
},
|
||||
code: {
|
||||
activation: `context.set(0, context.get(0) && context.get(1))`
|
||||
|
@ -21,13 +21,31 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
|||
},
|
||||
info: ['https://en.wikipedia.org/wiki/AND_gate']
|
||||
},
|
||||
{
|
||||
metadata: {
|
||||
name: 'nand'
|
||||
},
|
||||
material: {
|
||||
type: 'image',
|
||||
fill: require('../../assets/nand')
|
||||
},
|
||||
code: {
|
||||
activation: `context.set(0, !context.get(0) || !context.get(1))`
|
||||
},
|
||||
pins: {
|
||||
inputs: {
|
||||
count: 2
|
||||
}
|
||||
},
|
||||
info: ['https://en.wikipedia.org/wiki/NAND_gate']
|
||||
},
|
||||
{
|
||||
metadata: {
|
||||
name: 'or'
|
||||
},
|
||||
material: {
|
||||
type: 'image',
|
||||
value: require('../../assets/or_gate.png')
|
||||
fill: require('../../assets/or')
|
||||
},
|
||||
code: {
|
||||
activation: `context.set(0, context.get(0) || context.get(1))`
|
||||
|
@ -45,7 +63,7 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
|||
},
|
||||
material: {
|
||||
type: 'image',
|
||||
value: require('../../assets/nor_gate.png')
|
||||
fill: require('../../assets/nor')
|
||||
},
|
||||
code: {
|
||||
activation: `context.set(0, !(context.get(0) || context.get(1)))`
|
||||
|
@ -63,7 +81,7 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
|||
},
|
||||
material: {
|
||||
type: 'image',
|
||||
value: require('../../assets/xor_gate')
|
||||
fill: require('../../assets/xor')
|
||||
},
|
||||
code: {
|
||||
activation: `
|
||||
|
@ -80,12 +98,36 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
metadata: {
|
||||
name: 'xnor'
|
||||
},
|
||||
material: {
|
||||
type: 'image',
|
||||
fill: require('../../assets/xnor')
|
||||
},
|
||||
code: {
|
||||
activation: `
|
||||
const a = context.get(0)
|
||||
const b = context.get(1)
|
||||
const c = (a && b) || !(a || b)
|
||||
|
||||
context.set(0, c)`
|
||||
},
|
||||
info: ['https://en.wikipedia.org/wiki/XNOR_gate'],
|
||||
pins: {
|
||||
inputs: {
|
||||
count: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
metadata: {
|
||||
name: 'not'
|
||||
},
|
||||
material: {
|
||||
value: 'red'
|
||||
type: 'image',
|
||||
fill: require('../../assets/not')
|
||||
},
|
||||
code: {
|
||||
activation: `context.set(0, !context.get(0))`
|
||||
|
@ -97,7 +139,14 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
|||
name: 'button'
|
||||
},
|
||||
material: {
|
||||
value: 'red'
|
||||
fill: '#D32F2E',
|
||||
stroke: {
|
||||
normal: '#AB8C31',
|
||||
active: '#7EF813'
|
||||
},
|
||||
colors: {
|
||||
pressed: '#7D1313'
|
||||
}
|
||||
},
|
||||
code: {
|
||||
onClick: `
|
||||
|
@ -105,7 +154,7 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
|||
const state = !old
|
||||
|
||||
context.set(0, state)
|
||||
context.color(old ? 'red' : '#550000')
|
||||
context.color(old ? context.colors.main : context.colors.pressed)
|
||||
|
||||
context.memory.state = state
|
||||
`
|
||||
|
@ -128,11 +177,19 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
|||
radius: 50
|
||||
},
|
||||
material: {
|
||||
value: 'white'
|
||||
fill: '#1C1C1C',
|
||||
stroke: {
|
||||
normal: '#3C3C3C'
|
||||
},
|
||||
colors: {
|
||||
active: '#C6FF00'
|
||||
}
|
||||
},
|
||||
code: {
|
||||
activation: `
|
||||
context.color(context.get(0) ? 'yellow' : 'white')
|
||||
const { main, active } = context.colors
|
||||
|
||||
context.color(context.get(0) ? active : main)
|
||||
`
|
||||
},
|
||||
integration: {
|
||||
|
|
|
@ -62,6 +62,10 @@ export class Gate {
|
|||
|
||||
this.transform.scale = this.template.shape.scale
|
||||
|
||||
if (this.template.material.type === 'color') {
|
||||
this.template.material.colors.main = this.template.material.fill
|
||||
}
|
||||
|
||||
this.functions.activation = toFunction(
|
||||
this.template.code.activation,
|
||||
'context'
|
||||
|
@ -84,7 +88,7 @@ export class Gate {
|
|||
)
|
||||
|
||||
if (this.template.material.type === 'image') {
|
||||
ImageStore.set(this.template.material.value)
|
||||
ImageStore.set(this.template.material.fill)
|
||||
}
|
||||
|
||||
this.id = id !== undefined ? id : idStore.generate()
|
||||
|
@ -223,10 +227,13 @@ export class Gate {
|
|||
memory: this.memory,
|
||||
color: (color: string) => {
|
||||
if (this.template.material.type === 'color') {
|
||||
this.template.material.value = color
|
||||
this.template.material.fill = color
|
||||
}
|
||||
},
|
||||
enviroment: this.env
|
||||
enviroment: this.env,
|
||||
colors: {
|
||||
...this.template.material.colors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,12 @@ export const DefaultGateTemplate: GateTemplate = {
|
|||
},
|
||||
material: {
|
||||
type: 'color',
|
||||
value: 'blue'
|
||||
fill: 'blue',
|
||||
stroke: {
|
||||
active: '#76FF02',
|
||||
normal: '#3FC4FF'
|
||||
},
|
||||
colors: {}
|
||||
},
|
||||
pins: {
|
||||
inputs: {
|
||||
|
|
|
@ -7,7 +7,12 @@ export interface PinCount {
|
|||
|
||||
export interface Material {
|
||||
type: 'color' | 'image'
|
||||
value: string
|
||||
fill: string
|
||||
stroke: {
|
||||
active: string
|
||||
normal: string
|
||||
}
|
||||
colors: Record<string, string>
|
||||
}
|
||||
|
||||
export interface Shape {
|
||||
|
|
|
@ -13,16 +13,19 @@ export const renderGate = (
|
|||
renderer: SimulationRenderer,
|
||||
gate: Gate
|
||||
) => {
|
||||
renderPins(ctx, renderer, gate)
|
||||
const { active, normal } = gate.template.material.stroke
|
||||
|
||||
if (
|
||||
const selected =
|
||||
(renderer.mouseState >> 2 &&
|
||||
gatesInSelection(renderer.selectedArea, [gate]).length) ||
|
||||
!!gatesInSelection(renderer.selectedArea, [gate]).length) ||
|
||||
idIsSelected(renderer, gate.id)
|
||||
) {
|
||||
ctx.strokeStyle = renderer.options.gates.gateStroke.active
|
||||
|
||||
renderPins(ctx, renderer, gate, selected)
|
||||
|
||||
if (selected) {
|
||||
ctx.strokeStyle = active
|
||||
} else {
|
||||
ctx.strokeStyle = renderer.options.gates.gateStroke.normal
|
||||
ctx.strokeStyle = normal
|
||||
}
|
||||
|
||||
ctx.lineWidth = renderer.options.gates.gateStroke.width
|
||||
|
@ -41,7 +44,7 @@ export const renderGate = (
|
|||
if (gate.template.material.type === 'image') {
|
||||
roundImage(
|
||||
ctx,
|
||||
ImageStore.get(gate.template.material.value),
|
||||
ImageStore.get(gate.template.material.fill),
|
||||
...renderingParameters
|
||||
)
|
||||
}
|
||||
|
@ -49,7 +52,7 @@ export const renderGate = (
|
|||
roundRect(ctx, ...renderingParameters)
|
||||
|
||||
if (gate.template.material.type === 'color') {
|
||||
ctx.fillStyle = gate.template.material.value
|
||||
ctx.fillStyle = gate.template.material.fill
|
||||
|
||||
ctx.fill()
|
||||
}
|
||||
|
|
|
@ -7,21 +7,26 @@ import { pinFill } from './pinFill'
|
|||
export const renderPins = (
|
||||
ctx: CanvasRenderingContext2D,
|
||||
renderer: SimulationRenderer,
|
||||
gate: Gate
|
||||
gate: Gate,
|
||||
selected: boolean
|
||||
) => {
|
||||
ctx.save()
|
||||
|
||||
const {
|
||||
connectionLength,
|
||||
pinRadius,
|
||||
pinStrokeColor,
|
||||
pinStrokeWidth
|
||||
} = renderer.options.gates
|
||||
const relativeTransform = useTransform(ctx, gate.transform)
|
||||
|
||||
ctx.strokeStyle = pinStrokeColor
|
||||
ctx.lineWidth = pinStrokeWidth
|
||||
|
||||
if (selected) {
|
||||
ctx.strokeStyle = gate.template.material.stroke.active
|
||||
} else {
|
||||
ctx.strokeStyle = renderer.options.gates.pinStrokeColor
|
||||
}
|
||||
|
||||
for (const pin of gate.pins) {
|
||||
ctx.fillStyle = pinFill(renderer, pin.value)
|
||||
|
||||
|
|