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
|
set: (index: number, state: boolean) => void
|
||||||
color: (color: string) => void
|
color: (color: string) => void
|
||||||
enviroment: SimulationEnv
|
enviroment: SimulationEnv
|
||||||
|
colors: Record<string, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InitialisationContext {
|
export interface InitialisationContext {
|
||||||
|
|
|
@ -53,8 +53,10 @@ const LogicGateModal = () => {
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className="logic-gate-item"
|
className="logic-gate-item"
|
||||||
onClick={() => {
|
onClick={e => {
|
||||||
addGate(renderer, name)
|
addGate(renderer, name)
|
||||||
|
|
||||||
|
e.stopPropagation()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon className="lgi-icon logic-gate-item-type">
|
<Icon className="lgi-icon logic-gate-item-type">
|
||||||
|
|
|
@ -9,7 +9,7 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
||||||
},
|
},
|
||||||
material: {
|
material: {
|
||||||
type: 'image',
|
type: 'image',
|
||||||
value: require('../../assets/and_gate')
|
fill: require('../../assets/and')
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
activation: `context.set(0, context.get(0) && context.get(1))`
|
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']
|
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: {
|
metadata: {
|
||||||
name: 'or'
|
name: 'or'
|
||||||
},
|
},
|
||||||
material: {
|
material: {
|
||||||
type: 'image',
|
type: 'image',
|
||||||
value: require('../../assets/or_gate.png')
|
fill: require('../../assets/or')
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
activation: `context.set(0, context.get(0) || context.get(1))`
|
activation: `context.set(0, context.get(0) || context.get(1))`
|
||||||
|
@ -45,7 +63,7 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
||||||
},
|
},
|
||||||
material: {
|
material: {
|
||||||
type: 'image',
|
type: 'image',
|
||||||
value: require('../../assets/nor_gate.png')
|
fill: require('../../assets/nor')
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
activation: `context.set(0, !(context.get(0) || context.get(1)))`
|
activation: `context.set(0, !(context.get(0) || context.get(1)))`
|
||||||
|
@ -63,7 +81,7 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
||||||
},
|
},
|
||||||
material: {
|
material: {
|
||||||
type: 'image',
|
type: 'image',
|
||||||
value: require('../../assets/xor_gate')
|
fill: require('../../assets/xor')
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
activation: `
|
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: {
|
metadata: {
|
||||||
name: 'not'
|
name: 'not'
|
||||||
},
|
},
|
||||||
material: {
|
material: {
|
||||||
value: 'red'
|
type: 'image',
|
||||||
|
fill: require('../../assets/not')
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
activation: `context.set(0, !context.get(0))`
|
activation: `context.set(0, !context.get(0))`
|
||||||
|
@ -97,7 +139,14 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
||||||
name: 'button'
|
name: 'button'
|
||||||
},
|
},
|
||||||
material: {
|
material: {
|
||||||
value: 'red'
|
fill: '#D32F2E',
|
||||||
|
stroke: {
|
||||||
|
normal: '#AB8C31',
|
||||||
|
active: '#7EF813'
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
pressed: '#7D1313'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
onClick: `
|
onClick: `
|
||||||
|
@ -105,7 +154,7 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
||||||
const state = !old
|
const state = !old
|
||||||
|
|
||||||
context.set(0, state)
|
context.set(0, state)
|
||||||
context.color(old ? 'red' : '#550000')
|
context.color(old ? context.colors.main : context.colors.pressed)
|
||||||
|
|
||||||
context.memory.state = state
|
context.memory.state = state
|
||||||
`
|
`
|
||||||
|
@ -128,11 +177,19 @@ export const baseTemplates: DeepPartial<GateTemplate>[] = [
|
||||||
radius: 50
|
radius: 50
|
||||||
},
|
},
|
||||||
material: {
|
material: {
|
||||||
value: 'white'
|
fill: '#1C1C1C',
|
||||||
|
stroke: {
|
||||||
|
normal: '#3C3C3C'
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
active: '#C6FF00'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
code: {
|
code: {
|
||||||
activation: `
|
activation: `
|
||||||
context.color(context.get(0) ? 'yellow' : 'white')
|
const { main, active } = context.colors
|
||||||
|
|
||||||
|
context.color(context.get(0) ? active : main)
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
integration: {
|
integration: {
|
||||||
|
|
|
@ -62,6 +62,10 @@ export class Gate {
|
||||||
|
|
||||||
this.transform.scale = this.template.shape.scale
|
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.functions.activation = toFunction(
|
||||||
this.template.code.activation,
|
this.template.code.activation,
|
||||||
'context'
|
'context'
|
||||||
|
@ -84,7 +88,7 @@ export class Gate {
|
||||||
)
|
)
|
||||||
|
|
||||||
if (this.template.material.type === 'image') {
|
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()
|
this.id = id !== undefined ? id : idStore.generate()
|
||||||
|
@ -223,10 +227,13 @@ export class Gate {
|
||||||
memory: this.memory,
|
memory: this.memory,
|
||||||
color: (color: string) => {
|
color: (color: string) => {
|
||||||
if (this.template.material.type === 'color') {
|
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: {
|
material: {
|
||||||
type: 'color',
|
type: 'color',
|
||||||
value: 'blue'
|
fill: 'blue',
|
||||||
|
stroke: {
|
||||||
|
active: '#76FF02',
|
||||||
|
normal: '#3FC4FF'
|
||||||
|
},
|
||||||
|
colors: {}
|
||||||
},
|
},
|
||||||
pins: {
|
pins: {
|
||||||
inputs: {
|
inputs: {
|
||||||
|
|
|
@ -7,7 +7,12 @@ export interface PinCount {
|
||||||
|
|
||||||
export interface Material {
|
export interface Material {
|
||||||
type: 'color' | 'image'
|
type: 'color' | 'image'
|
||||||
value: string
|
fill: string
|
||||||
|
stroke: {
|
||||||
|
active: string
|
||||||
|
normal: string
|
||||||
|
}
|
||||||
|
colors: Record<string, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Shape {
|
export interface Shape {
|
||||||
|
|
|
@ -13,16 +13,19 @@ export const renderGate = (
|
||||||
renderer: SimulationRenderer,
|
renderer: SimulationRenderer,
|
||||||
gate: Gate
|
gate: Gate
|
||||||
) => {
|
) => {
|
||||||
renderPins(ctx, renderer, gate)
|
const { active, normal } = gate.template.material.stroke
|
||||||
|
|
||||||
if (
|
const selected =
|
||||||
(renderer.mouseState >> 2 &&
|
(renderer.mouseState >> 2 &&
|
||||||
gatesInSelection(renderer.selectedArea, [gate]).length) ||
|
!!gatesInSelection(renderer.selectedArea, [gate]).length) ||
|
||||||
idIsSelected(renderer, gate.id)
|
idIsSelected(renderer, gate.id)
|
||||||
) {
|
|
||||||
ctx.strokeStyle = renderer.options.gates.gateStroke.active
|
renderPins(ctx, renderer, gate, selected)
|
||||||
|
|
||||||
|
if (selected) {
|
||||||
|
ctx.strokeStyle = active
|
||||||
} else {
|
} else {
|
||||||
ctx.strokeStyle = renderer.options.gates.gateStroke.normal
|
ctx.strokeStyle = normal
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.lineWidth = renderer.options.gates.gateStroke.width
|
ctx.lineWidth = renderer.options.gates.gateStroke.width
|
||||||
|
@ -41,7 +44,7 @@ export const renderGate = (
|
||||||
if (gate.template.material.type === 'image') {
|
if (gate.template.material.type === 'image') {
|
||||||
roundImage(
|
roundImage(
|
||||||
ctx,
|
ctx,
|
||||||
ImageStore.get(gate.template.material.value),
|
ImageStore.get(gate.template.material.fill),
|
||||||
...renderingParameters
|
...renderingParameters
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -49,7 +52,7 @@ export const renderGate = (
|
||||||
roundRect(ctx, ...renderingParameters)
|
roundRect(ctx, ...renderingParameters)
|
||||||
|
|
||||||
if (gate.template.material.type === 'color') {
|
if (gate.template.material.type === 'color') {
|
||||||
ctx.fillStyle = gate.template.material.value
|
ctx.fillStyle = gate.template.material.fill
|
||||||
|
|
||||||
ctx.fill()
|
ctx.fill()
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,21 +7,26 @@ import { pinFill } from './pinFill'
|
||||||
export const renderPins = (
|
export const renderPins = (
|
||||||
ctx: CanvasRenderingContext2D,
|
ctx: CanvasRenderingContext2D,
|
||||||
renderer: SimulationRenderer,
|
renderer: SimulationRenderer,
|
||||||
gate: Gate
|
gate: Gate,
|
||||||
|
selected: boolean
|
||||||
) => {
|
) => {
|
||||||
ctx.save()
|
ctx.save()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
connectionLength,
|
connectionLength,
|
||||||
pinRadius,
|
pinRadius,
|
||||||
pinStrokeColor,
|
|
||||||
pinStrokeWidth
|
pinStrokeWidth
|
||||||
} = renderer.options.gates
|
} = renderer.options.gates
|
||||||
const relativeTransform = useTransform(ctx, gate.transform)
|
const relativeTransform = useTransform(ctx, gate.transform)
|
||||||
|
|
||||||
ctx.strokeStyle = pinStrokeColor
|
|
||||||
ctx.lineWidth = pinStrokeWidth
|
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) {
|
for (const pin of gate.pins) {
|
||||||
ctx.fillStyle = pinFill(renderer, pin.value)
|
ctx.fillStyle = pinFill(renderer, pin.value)
|
||||||
|
|
||||||
|
|