diff --git a/src/assets/!!!poster-bg.png b/src/assets/!!!poster-bg.png deleted file mode 100644 index 828abd7..0000000 Binary files a/src/assets/!!!poster-bg.png and /dev/null differ diff --git a/src/assets/and.svg b/src/assets/and.svg new file mode 100644 index 0000000..d80ab53 --- /dev/null +++ b/src/assets/and.svg @@ -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> diff --git a/src/assets/and_gate.jpg b/src/assets/and_gate.jpg deleted file mode 100644 index c9ee14f..0000000 Binary files a/src/assets/and_gate.jpg and /dev/null differ diff --git a/src/assets/nand.svg b/src/assets/nand.svg new file mode 100644 index 0000000..8bc391a --- /dev/null +++ b/src/assets/nand.svg @@ -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> diff --git a/src/assets/nor.svg b/src/assets/nor.svg new file mode 100644 index 0000000..6a44b33 --- /dev/null +++ b/src/assets/nor.svg @@ -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> diff --git a/src/assets/nor_gate.png b/src/assets/nor_gate.png deleted file mode 100644 index e683890..0000000 Binary files a/src/assets/nor_gate.png and /dev/null differ diff --git a/src/assets/not.svg b/src/assets/not.svg new file mode 100644 index 0000000..bf3fd26 --- /dev/null +++ b/src/assets/not.svg @@ -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> diff --git a/src/assets/or.svg b/src/assets/or.svg new file mode 100644 index 0000000..7f2dc88 --- /dev/null +++ b/src/assets/or.svg @@ -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> diff --git a/src/assets/or_gate.png b/src/assets/or_gate.png deleted file mode 100644 index 3a69c1c..0000000 Binary files a/src/assets/or_gate.png and /dev/null differ diff --git a/src/assets/xnor.svg b/src/assets/xnor.svg new file mode 100644 index 0000000..21f44e2 --- /dev/null +++ b/src/assets/xnor.svg @@ -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> diff --git a/src/assets/xor.svg b/src/assets/xor.svg new file mode 100644 index 0000000..8ac1ab9 --- /dev/null +++ b/src/assets/xor.svg @@ -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> diff --git a/src/assets/xor_gate.png b/src/assets/xor_gate.png deleted file mode 100644 index 0d29265..0000000 Binary files a/src/assets/xor_gate.png and /dev/null differ diff --git a/src/modules/activation/types/Context.ts b/src/modules/activation/types/Context.ts index 815e869..f4576da 100644 --- a/src/modules/activation/types/Context.ts +++ b/src/modules/activation/types/Context.ts @@ -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 { diff --git a/src/modules/logic-gates/components/LogicGateModal.tsx b/src/modules/logic-gates/components/LogicGateModal.tsx index 15e35f7..4504989 100644 --- a/src/modules/logic-gates/components/LogicGateModal.tsx +++ b/src/modules/logic-gates/components/LogicGateModal.tsx @@ -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"> diff --git a/src/modules/saving/constants.ts b/src/modules/saving/constants.ts index af1ecc4..e258fbd 100644 --- a/src/modules/saving/constants.ts +++ b/src/modules/saving/constants.ts @@ -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: { diff --git a/src/modules/simulation/classes/Gate.ts b/src/modules/simulation/classes/Gate.ts index c3c7456..4b2e9a0 100644 --- a/src/modules/simulation/classes/Gate.ts +++ b/src/modules/simulation/classes/Gate.ts @@ -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 + } } } diff --git a/src/modules/simulation/constants.ts b/src/modules/simulation/constants.ts index aaaa637..d5db891 100644 --- a/src/modules/simulation/constants.ts +++ b/src/modules/simulation/constants.ts @@ -6,7 +6,12 @@ export const DefaultGateTemplate: GateTemplate = { }, material: { type: 'color', - value: 'blue' + fill: 'blue', + stroke: { + active: '#76FF02', + normal: '#3FC4FF' + }, + colors: {} }, pins: { inputs: { diff --git a/src/modules/simulation/types/GateTemplate.ts b/src/modules/simulation/types/GateTemplate.ts index 1759811..95f6441 100644 --- a/src/modules/simulation/types/GateTemplate.ts +++ b/src/modules/simulation/types/GateTemplate.ts @@ -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 { diff --git a/src/modules/simulationRenderer/helpers/renderGate.ts b/src/modules/simulationRenderer/helpers/renderGate.ts index 1854d36..5d44069 100644 --- a/src/modules/simulationRenderer/helpers/renderGate.ts +++ b/src/modules/simulationRenderer/helpers/renderGate.ts @@ -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() } diff --git a/src/modules/simulationRenderer/helpers/renderPins.ts b/src/modules/simulationRenderer/helpers/renderPins.ts index c872069..7835691 100644 --- a/src/modules/simulationRenderer/helpers/renderPins.ts +++ b/src/modules/simulationRenderer/helpers/renderPins.ts @@ -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)