First commit
This commit is contained in:
commit
be4aa54aaf
10
.editorconfig
Normal file
10
.editorconfig
Normal file
@ -0,0 +1,10 @@
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
194
.gitattributes
vendored
Normal file
194
.gitattributes
vendored
Normal file
@ -0,0 +1,194 @@
|
||||
## GITATTRIBUTES FOR WEB PROJECTS
|
||||
#
|
||||
# These settings are for any web project.
|
||||
#
|
||||
# Details per file setting:
|
||||
# text These files should be normalized (i.e. convert CRLF to LF).
|
||||
# binary These files are binary and should be left untouched.
|
||||
#
|
||||
# Note that binary is a macro for -text -diff.
|
||||
######################################################################
|
||||
|
||||
## AUTO-DETECT
|
||||
## Handle line endings automatically for files detected as
|
||||
## text and leave all files detected as binary untouched.
|
||||
## This will handle all files NOT defined below.
|
||||
* text=auto
|
||||
|
||||
## SOURCE CODE
|
||||
*.bat text eol=crlf
|
||||
*.coffee text
|
||||
*.css text
|
||||
*.htm text
|
||||
*.html text
|
||||
*.inc text
|
||||
*.ini text
|
||||
*.js text
|
||||
*.json text
|
||||
*.jsx text
|
||||
*.less text
|
||||
*.od text
|
||||
*.onlydata text
|
||||
*.php text
|
||||
*.pl text
|
||||
*.py text
|
||||
*.rb text
|
||||
*.sass text
|
||||
*.scm text
|
||||
*.scss text
|
||||
*.sh text eol=lf
|
||||
*.sql text
|
||||
*.styl text
|
||||
*.tag text
|
||||
*.ts text
|
||||
*.tsx text
|
||||
*.xml text
|
||||
*.xhtml text
|
||||
|
||||
## DOCKER
|
||||
*.dockerignore text
|
||||
Dockerfile text
|
||||
|
||||
## DOCUMENTATION
|
||||
*.markdown text
|
||||
*.md text
|
||||
*.mdwn text
|
||||
*.mdown text
|
||||
*.mkd text
|
||||
*.mkdn text
|
||||
*.mdtxt text
|
||||
*.mdtext text
|
||||
*.txt text
|
||||
AUTHORS text
|
||||
CHANGELOG text
|
||||
CHANGES text
|
||||
CONTRIBUTING text
|
||||
COPYING text
|
||||
copyright text
|
||||
*COPYRIGHT* text
|
||||
INSTALL text
|
||||
license text
|
||||
LICENSE text
|
||||
NEWS text
|
||||
readme text
|
||||
*README* text
|
||||
TODO text
|
||||
|
||||
## TEMPLATES
|
||||
*.dot text
|
||||
*.ejs text
|
||||
*.haml text
|
||||
*.handlebars text
|
||||
*.hbs text
|
||||
*.hbt text
|
||||
*.jade text
|
||||
*.latte text
|
||||
*.mustache text
|
||||
*.njk text
|
||||
*.phtml text
|
||||
*.tmpl text
|
||||
*.tpl text
|
||||
*.twig text
|
||||
|
||||
## LINTERS
|
||||
.babelrc text
|
||||
.csslintrc text
|
||||
.eslintrc text
|
||||
.htmlhintrc text
|
||||
.jscsrc text
|
||||
.jshintrc text
|
||||
.jshintignore text
|
||||
.prettierrc text
|
||||
.stylelintrc text
|
||||
|
||||
## CONFIGS
|
||||
*.bowerrc text
|
||||
*.cnf text
|
||||
*.conf text
|
||||
*.config text
|
||||
.browserslistrc text
|
||||
.editorconfig text
|
||||
.gitattributes text
|
||||
.gitconfig text
|
||||
.gitignore text
|
||||
.htaccess text
|
||||
*.npmignore text
|
||||
*.yaml text
|
||||
*.yml text
|
||||
browserslist text
|
||||
Makefile text
|
||||
makefile text
|
||||
|
||||
## HEROKU
|
||||
Procfile text
|
||||
.slugignore text
|
||||
|
||||
## GRAPHICS
|
||||
*.ai binary
|
||||
*.bmp binary
|
||||
*.eps binary
|
||||
*.gif binary
|
||||
*.ico binary
|
||||
*.jng binary
|
||||
*.jp2 binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.jpx binary
|
||||
*.jxr binary
|
||||
*.pdf binary
|
||||
*.png binary
|
||||
*.psb binary
|
||||
*.psd binary
|
||||
*.svg text
|
||||
*.svgz binary
|
||||
*.tif binary
|
||||
*.tiff binary
|
||||
*.wbmp binary
|
||||
*.webp binary
|
||||
|
||||
## AUDIO
|
||||
*.kar binary
|
||||
*.m4a binary
|
||||
*.mid binary
|
||||
*.midi binary
|
||||
*.mp3 binary
|
||||
*.ogg binary
|
||||
*.ra binary
|
||||
|
||||
## VIDEO
|
||||
*.3gpp binary
|
||||
*.3gp binary
|
||||
*.as binary
|
||||
*.asf binary
|
||||
*.asx binary
|
||||
*.fla binary
|
||||
*.flv binary
|
||||
*.m4v binary
|
||||
*.mng binary
|
||||
*.mov binary
|
||||
*.mp4 binary
|
||||
*.mpeg binary
|
||||
*.mpg binary
|
||||
*.ogv binary
|
||||
*.swc binary
|
||||
*.swf binary
|
||||
*.webm binary
|
||||
|
||||
## ARCHIVES
|
||||
*.7z binary
|
||||
*.gz binary
|
||||
*.jar binary
|
||||
*.rar binary
|
||||
*.tar binary
|
||||
*.zip binary
|
||||
|
||||
## FONTS
|
||||
*.ttf binary
|
||||
*.eot binary
|
||||
*.otf binary
|
||||
*.woff binary
|
||||
*.woff2 binary
|
||||
|
||||
## EXECUTABLES
|
||||
*.exe binary
|
||||
*.pyc binary
|
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Include your project-specific ignores in this file
|
||||
# Read about how to use .gitignore: https://help.github.com/articles/ignoring-files
|
||||
# Useful .gitignore templates: https://github.com/github/gitignore
|
||||
node_modules
|
||||
dist
|
||||
.cache
|
||||
doc/
|
||||
.idea/
|
62
404.html
Normal file
62
404.html
Normal file
@ -0,0 +1,62 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Page Not Found</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
* {
|
||||
line-height: 1.2;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
color: #888;
|
||||
display: table;
|
||||
font-family: sans-serif;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
margin: 2em auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #555;
|
||||
font-size: 2em;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 auto;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 280px) {
|
||||
|
||||
body,
|
||||
p {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.5em;
|
||||
margin: 0 0 0.3em;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Page Not Found</h1>
|
||||
<p>Sorry, but the page you were trying to view does not exist.</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- IE needs 512+ bytes: https://docs.microsoft.com/archive/blogs/ieinternals/friendly-http-error-pages -->
|
16
README.md
Normal file
16
README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# MatCat BrowserLogic
|
||||
|
||||
MatCat BrowserLogic https://www.logic.parts/ is a logic simulator written purely in HTML5 / Javascript using 2D Canvas.
|
||||
|
||||
## Status
|
||||
|
||||
This simulator is in extremely early stages, it is not even Alpha at this point but early development. Outside contribution is welcome, please contact me in #LogicParts on Freenode IRC network.
|
||||
|
||||
## License
|
||||
|
||||
To be decided, but at this moment this code is open source and free to use for non-commercial uses.
|
||||
|
||||
## Changelog
|
||||
|
||||
### 0.1.0
|
||||
Initial public release.
|
263
css/main.css
Normal file
263
css/main.css
Normal file
@ -0,0 +1,263 @@
|
||||
/*! HTML5 Boilerplate v8.0.0 | MIT License | https://html5boilerplate.com/ */
|
||||
|
||||
/* main.css 2.1.0 | MIT License | https://github.com/h5bp/main.css#readme */
|
||||
/*
|
||||
* What follows is the result of much research on cross-browser styling.
|
||||
* Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,
|
||||
* Kroc Camen, and the H5BP dev community and team.
|
||||
*/
|
||||
|
||||
/* ==========================================================================
|
||||
Base styles: opinionated defaults
|
||||
========================================================================== */
|
||||
|
||||
html {
|
||||
color: #222;
|
||||
font-size: 1em;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove text-shadow in selection highlight:
|
||||
* https://twitter.com/miketaylr/status/12228805301
|
||||
*
|
||||
* Vendor-prefixed and regular ::selection selectors cannot be combined:
|
||||
* https://stackoverflow.com/a/16982510/7133471
|
||||
*
|
||||
* Customize the background color to match your design.
|
||||
*/
|
||||
|
||||
::-moz-selection {
|
||||
background: #b3d4fc;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: #b3d4fc;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* A better looking default horizontal rule
|
||||
*/
|
||||
|
||||
hr {
|
||||
display: block;
|
||||
height: 1px;
|
||||
border: 0;
|
||||
border-top: 1px solid #ccc;
|
||||
margin: 1em 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the gap between audio, canvas, iframes,
|
||||
* images, videos and the bottom of their containers:
|
||||
* https://github.com/h5bp/html5-boilerplate/issues/440
|
||||
*/
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
iframe,
|
||||
img,
|
||||
svg,
|
||||
video {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove default fieldset styles.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow only vertical resizing of textareas.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Author's custom styles
|
||||
========================================================================== */
|
||||
|
||||
/* ==========================================================================
|
||||
Helper classes
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Hide visually and from screen readers
|
||||
*/
|
||||
|
||||
.hidden,
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hide only visually, but have it available for screen readers:
|
||||
* https://snook.ca/archives/html_and_css/hiding-content-for-accessibility
|
||||
*
|
||||
* 1. For long content, line feeds are not interpreted as spaces and small width
|
||||
* causes content to wrap 1 word per line:
|
||||
* https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe
|
||||
*/
|
||||
|
||||
.sr-only {
|
||||
border: 0;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
width: 1px;
|
||||
/* 1 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Extends the .sr-only class to allow the element
|
||||
* to be focusable when navigated to via the keyboard:
|
||||
* https://www.drupal.org/node/897638
|
||||
*/
|
||||
|
||||
.sr-only.focusable:active,
|
||||
.sr-only.focusable:focus {
|
||||
clip: auto;
|
||||
height: auto;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
position: static;
|
||||
white-space: inherit;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hide visually and from screen readers, but maintain layout
|
||||
*/
|
||||
|
||||
.invisible {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clearfix: contain floats
|
||||
*
|
||||
* For modern browsers
|
||||
* 1. The space content is one way to avoid an Opera bug when the
|
||||
* `contenteditable` attribute is included anywhere else in the document.
|
||||
* Otherwise it causes space to appear at the top and bottom of elements
|
||||
* that receive the `clearfix` class.
|
||||
* 2. The use of `table` rather than `block` is only necessary if using
|
||||
* `:before` to contain the top-margins of child elements.
|
||||
*/
|
||||
|
||||
.clearfix::before,
|
||||
.clearfix::after {
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
.clearfix::after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
EXAMPLE Media Queries for Responsive Design.
|
||||
These examples override the primary ('mobile first') styles.
|
||||
Modify as content requires.
|
||||
========================================================================== */
|
||||
|
||||
@media only screen and (min-width: 35em) {
|
||||
/* Style adjustments for viewports that meet the condition */
|
||||
}
|
||||
|
||||
@media print,
|
||||
(-webkit-min-device-pixel-ratio: 1.25),
|
||||
(min-resolution: 1.25dppx),
|
||||
(min-resolution: 120dpi) {
|
||||
/* Style adjustments for high resolution devices */
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Print styles.
|
||||
Inlined to avoid the additional HTTP request:
|
||||
https://www.phpied.com/delay-loading-your-print-css/
|
||||
========================================================================== */
|
||||
|
||||
@media print {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
background: #fff !important;
|
||||
color: #000 !important;
|
||||
/* Black prints faster */
|
||||
box-shadow: none !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a[href]::after {
|
||||
content: " (" attr(href) ")";
|
||||
}
|
||||
|
||||
abbr[title]::after {
|
||||
content: " (" attr(title) ")";
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't show links that are fragment identifiers,
|
||||
* or use the `javascript:` pseudo protocol
|
||||
*/
|
||||
a[href^="#"]::after,
|
||||
a[href^="javascript:"]::after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap !important;
|
||||
}
|
||||
|
||||
pre,
|
||||
blockquote {
|
||||
border: 1px solid #999;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Printing Tables:
|
||||
* https://web.archive.org/web/20180815150934/http://css-discuss.incutio.com/wiki/Printing_Tables
|
||||
*/
|
||||
thead {
|
||||
display: table-header-group;
|
||||
}
|
||||
|
||||
tr,
|
||||
img {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
p,
|
||||
h2,
|
||||
h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
|
||||
h2,
|
||||
h3 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
|
349
css/normalize.css
vendored
Normal file
349
css/normalize.css
vendored
Normal file
@ -0,0 +1,349 @@
|
||||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
|
||||
|
||||
/* Document
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Correct the line height in all browsers.
|
||||
* 2. Prevent adjustments of font size after orientation changes in iOS.
|
||||
*/
|
||||
|
||||
html {
|
||||
line-height: 1.15; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/* Sections
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the margin in all browsers.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the `main` element consistently in IE.
|
||||
*/
|
||||
|
||||
main {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the font size and margin on `h1` elements within `section` and
|
||||
* `article` contexts in Chrome, Firefox, and Safari.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in Firefox.
|
||||
* 2. Show the overflow in Edge and IE.
|
||||
*/
|
||||
|
||||
hr {
|
||||
box-sizing: content-box; /* 1 */
|
||||
height: 0; /* 1 */
|
||||
overflow: visible; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/* Text-level semantics
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the gray background on active links in IE 10.
|
||||
*/
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Remove the bottom border in Chrome 57-
|
||||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: none; /* 1 */
|
||||
text-decoration: underline; /* 2 */
|
||||
text-decoration: underline dotted; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||
* all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/* Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the border on images inside links in IE 10.
|
||||
*/
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
/* Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Change the font styles in all browsers.
|
||||
* 2. Remove the margin in Firefox and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 1 */
|
||||
line-height: 1.15; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the overflow in IE.
|
||||
* 1. Show the overflow in Edge.
|
||||
*/
|
||||
|
||||
button,
|
||||
input { /* 1 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||
* 1. Remove the inheritance of text transform in Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select { /* 1 */
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the inability to style clickable types in iOS and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
[type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner border and padding in Firefox.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the focus styles unset by the previous rule.
|
||||
*/
|
||||
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the padding in Firefox.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
padding: 0.35em 0.75em 0.625em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the text wrapping in Edge and IE.
|
||||
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||
* 3. Remove the padding so developers are not caught out when they zero out
|
||||
* `fieldset` elements in all browsers.
|
||||
*/
|
||||
|
||||
legend {
|
||||
box-sizing: border-box; /* 1 */
|
||||
color: inherit; /* 2 */
|
||||
display: table; /* 1 */
|
||||
max-width: 100%; /* 1 */
|
||||
padding: 0; /* 3 */
|
||||
white-space: normal; /* 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||
*/
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the default vertical scrollbar in IE 10+.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in IE 10.
|
||||
* 2. Remove the padding in IE 10.
|
||||
*/
|
||||
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||
*/
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the odd appearance in Chrome and Safari.
|
||||
* 2. Correct the outline style in Safari.
|
||||
*/
|
||||
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
outline-offset: -2px; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner padding in Chrome and Safari on macOS.
|
||||
*/
|
||||
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||
* 2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
}
|
||||
|
||||
/* Interactive
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Add the correct display in Edge, IE 10+, and Firefox.
|
||||
*/
|
||||
|
||||
details {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the correct display in all browsers.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/* Misc
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10+.
|
||||
*/
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
BIN
favicon.ico
Normal file
BIN
favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
0
humans.txt
Normal file
0
humans.txt
Normal file
0
img/.gitignore
vendored
Normal file
0
img/.gitignore
vendored
Normal file
48
index.html
Normal file
48
index.html
Normal file
@ -0,0 +1,48 @@
|
||||
<!doctype html>
|
||||
<html class="no-js" lang="">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title></title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<meta property="og:title" content="">
|
||||
<meta property="og:type" content="">
|
||||
<meta property="og:url" content="">
|
||||
<meta property="og:image" content="">
|
||||
|
||||
<link rel="manifest" href="site.webmanifest">
|
||||
<link rel="apple-touch-icon" href="icon.png">
|
||||
<!-- Place favicon.ico in the root directory -->
|
||||
|
||||
<link rel="stylesheet" href="css/normalize.css">
|
||||
<link rel="stylesheet" href="css/main.css">
|
||||
|
||||
<meta name="theme-color" content="#fafafa">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Add your site or application content here -->
|
||||
<script src="js/vendor/modernizr-3.11.2.min.js"></script>
|
||||
<div style="height: 50px; overflow: auto; margin: 0px; padding: 0px;">
|
||||
MatCat BrowserLogic <span id="version">0.1.0</span>
|
||||
<input type="button" id="btn_Link" value="<->"/>
|
||||
<input type="button" id="btn_AddAND" value="&"/>
|
||||
<input type="button" id="btn_AddNAND" value="!&"/>
|
||||
<input type="button" id="btn_AddOR" value="|"/>
|
||||
<input type="button" id="btn_AddNOR" value="!|"/>
|
||||
<input type="button" id="btn_AddXOR" value="^"/>
|
||||
<input type="button" id="btn_AddXNOR" value="!^"/>
|
||||
<input type="button" id="btn_AddBTN" value="[]"/>
|
||||
<input type="button" id="btn_Delete" value="Delete"/>
|
||||
</div>
|
||||
|
||||
<canvas id="LogicPlane" width="400" height="300" style="margin: 0px; padding: 0px;"></canvas>
|
||||
<script src="js/logicengine.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
635
js/logicengine.js
Normal file
635
js/logicengine.js
Normal file
@ -0,0 +1,635 @@
|
||||
/*
|
||||
First a few needed global functions
|
||||
*/
|
||||
function getMousePos(canvas, evt) {
|
||||
let rect = canvas.getBoundingClientRect();
|
||||
return {
|
||||
x: evt.clientX - rect.left,
|
||||
y: evt.clientY - rect.top
|
||||
};
|
||||
}
|
||||
|
||||
function averageArray(arr) {
|
||||
return arr.reduce((a, b) => (a + b)) / arr.length;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Now we can get into the classes
|
||||
*/
|
||||
class CanvasTools {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
textSize(ctx,text,fontStyle) {
|
||||
ctx.save();
|
||||
ctx.font = fontStyle;
|
||||
let tHeight = Math.round(ctx.measureText(text).actualBoundingBoxAscent + ctx.measureText(text).actualBoundingBoxDescent);
|
||||
let tWidth = Math.round(ctx.measureText(text).width);
|
||||
ctx.restore();
|
||||
return {
|
||||
width: tWidth,
|
||||
height: tHeight
|
||||
};
|
||||
}
|
||||
|
||||
drawBorderBox(ctx,x,y,drawWidth,drawHeight,borderWidth=1,borderColor="#000",fillColor="#f7e979") {
|
||||
let old_fillStyle = ctx.fillStyle;
|
||||
ctx.fillStyle = borderColor;
|
||||
ctx.fillRect(x,y,drawWidth,drawHeight);
|
||||
ctx.fillStyle = fillColor;
|
||||
ctx.fillRect(x+borderWidth,y+borderWidth,drawWidth-(borderWidth*2),drawHeight-(borderWidth*2));
|
||||
ctx.fillStyle = old_fillStyle;
|
||||
}
|
||||
|
||||
drawTextCentered(ctx,x,y,x2,y2,text,fontStyle="24px Console",fontColor = "#555") {
|
||||
let old_fillStyle = ctx.fillStyle;
|
||||
let old_font = ctx.font;
|
||||
ctx.font = fontStyle;
|
||||
ctx.fillStyle = fontColor;
|
||||
let tHeight = ctx.measureText(text).actualBoundingBoxAscent + ctx.measureText(text).actualBoundingBoxDescent;
|
||||
let tX = x+((x2/2)-(ctx.measureText(text).width/2));
|
||||
let tY = y+tHeight+((y2/2)-(tHeight/2));
|
||||
ctx.fillText(text,tX,tY);
|
||||
ctx.fillStyle = old_fillStyle;
|
||||
ctx.font = old_font;
|
||||
}
|
||||
|
||||
drawText(ctx,x,y,text,fontStyle="24px Console",fontColor = "#555") {
|
||||
let old_fillStyle = ctx.fillStyle;
|
||||
let old_font = ctx.font;
|
||||
ctx.font = fontStyle;
|
||||
ctx.fillStyle = fontColor;
|
||||
ctx.fillText(text,x,y);
|
||||
ctx.fillStyle = old_fillStyle;
|
||||
ctx.font = old_font;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ElementConnection {
|
||||
constructor(elementContainer,element,input) {
|
||||
this.Container = elementContainer;
|
||||
this.Element = element;
|
||||
this.Input = input;
|
||||
}
|
||||
}
|
||||
|
||||
class Element extends CanvasTools {
|
||||
|
||||
constructor(Inputs) {
|
||||
super();
|
||||
this.Name = "Element";
|
||||
this.Designator = "";
|
||||
this.Inputs = new Array(Inputs);
|
||||
this.totalInputs = Inputs;
|
||||
this.Width = 150;
|
||||
this.Height = 100;
|
||||
this.inputCircleRadius = 10;
|
||||
this.outputCircleRadius = 10;
|
||||
this.X = 0;
|
||||
this.Y = 0;
|
||||
this.OutputConnections = new Array();
|
||||
}
|
||||
|
||||
Delete() {
|
||||
// Just to clean up connections
|
||||
for (let a = 0; a < this.OutputConnections.length;a++) {
|
||||
this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input,false);
|
||||
}
|
||||
}
|
||||
MouseClick() {
|
||||
// Function for if mouse is clicked
|
||||
}
|
||||
|
||||
mouseInside(mousePos) {
|
||||
if (((mousePos.x >= this.X ) && (mousePos.x <= (this.X + this.Width))) & ((mousePos.y >= this.Y ) && (mousePos.y <= (this.Y + this.Height)))) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
addConnection(container, element, input) {
|
||||
let newConnection = new ElementConnection(container,element,input);
|
||||
this.OutputConnections.push(newConnection);
|
||||
element.setInput(input,this.getOutput());
|
||||
}
|
||||
|
||||
drawInputs(ctx,x,y,borderColor = "#000",circleColorFalse = "#ff0000",circleColorTrue="#00ff00") {
|
||||
let old_strokeStyle = ctx.strokeStyle;
|
||||
let old_fillStyle = ctx.fillStyle;
|
||||
if ((this.totalInputs * ((this.inputCircleRadius*2)+4)) > (this.Height-2)) {
|
||||
this.inputCircleRadius = ((this.Height-(2 + this.totalInputs * 4)) / this.totalInputs)/2;
|
||||
}
|
||||
|
||||
for (let a = 0; a < this.totalInputs;a++) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(x+20,y+(this.inputCircleRadius + 2)+(((a*(4+(this.inputCircleRadius*2))))-2)+(this.inputCircleRadius/2),this.inputCircleRadius,0,2*Math.PI);
|
||||
ctx.strokeStyle = borderColor;
|
||||
ctx.fillStyle = circleColorFalse;
|
||||
if (this.Inputs[a]) ctx.fillStyle = circleColorTrue;
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
}
|
||||
ctx.strokeStyle = old_strokeStyle;
|
||||
ctx.fillStyle = old_fillStyle;
|
||||
}
|
||||
|
||||
drawOutputs(ctx,x,y,borderColor = "#000",circleColorFalse = "#ff0000",circleColorTrue="#00ff00") {
|
||||
let old_strokeStyle = ctx.strokeStyle;
|
||||
let old_fillStyle = ctx.fillStyle;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x+(this.Width-20),y+(this.Height/2),this.outputCircleRadius,0,2*Math.PI);
|
||||
ctx.strokeStyle = borderColor;
|
||||
ctx.fillStyle = circleColorFalse;
|
||||
if (this.getOutput()) ctx.fillStyle = circleColorTrue;
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
ctx.strokeStyle = old_strokeStyle;
|
||||
ctx.fillStyle = old_fillStyle;
|
||||
}
|
||||
|
||||
drawConnections(ctx) {
|
||||
ctx.save();
|
||||
for (let a = 0; a < this.OutputConnections.length;a++) {
|
||||
if (!this.OutputConnections[a].Container.HasElement(this.OutputConnections[a].Element)) {
|
||||
// This is a ghosted connection, lets get rid of it
|
||||
this.OutputConnections.splice(a,1);
|
||||
a--;
|
||||
} else {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo((this.X + this.Width) - 20, this.Y + (this.Height / 2));
|
||||
ctx.lineTo(this.OutputConnections[a].Element.X + 20, this.OutputConnections[a].Element.Y + 20);
|
||||
ctx.strokeStyle = "#555";
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
setInput(Input,Value) {
|
||||
let oldOutput = this.getOutput();
|
||||
if (Value) {
|
||||
Value = true;
|
||||
} else {
|
||||
Value = false;
|
||||
}
|
||||
if (Input < this.totalInputs) {
|
||||
this.Inputs[Input] = Value;
|
||||
}
|
||||
if (this.getOutput() != oldOutput) {
|
||||
// The output changed, we need to notify connected elements
|
||||
for (let a = 0; a < this.OutputConnections.length;a++) {
|
||||
this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input,this.getOutput());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getOutput() {
|
||||
/*
|
||||
Should return true or false
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
drawElement(x,y,ctx) {
|
||||
/*
|
||||
Draw routine for the element
|
||||
*/
|
||||
this.drawBorderBox(ctx,x,y,drawWidth,drawHeight);
|
||||
this.drawTextCentered(ctx,x,y,this.Width,this.Height,"LOGIC");
|
||||
this.drawInputs(ctx,x,y);
|
||||
this.drawOutputs(ctx,x,y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class inputElement extends Element {
|
||||
constructor() {
|
||||
super(0);
|
||||
this.Output = false;
|
||||
this.Width = 100;
|
||||
this.Name = "InputElement";
|
||||
}
|
||||
|
||||
getOutput() {
|
||||
return this.Output;
|
||||
}
|
||||
|
||||
drawElement(x, y, ctx) {
|
||||
this.drawBorderBox(ctx, x,y,this.Width,this.Height);
|
||||
this.drawTextCentered(ctx,x,y,this.Width,this.Height,"IN");
|
||||
this.drawOutputs(ctx,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
class inputButton extends inputElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.Name = "Button";
|
||||
}
|
||||
|
||||
MouseClick() {
|
||||
this.Output = ~this.Output;
|
||||
for (let a = 0; a < this.OutputConnections.length;a++) {
|
||||
this.OutputConnections[a].Element.setInput(this.OutputConnections[a].Input,this.getOutput());
|
||||
}
|
||||
}
|
||||
|
||||
drawElement(x, y, ctx) {
|
||||
this.drawBorderBox(ctx, x,y,this.Width,this.Height);
|
||||
this.drawBorderBox(ctx,x+10,y+25,50,50,1,"#ccc","#777");
|
||||
this.drawOutputs(ctx,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
class LogicAND extends Element {
|
||||
constructor(Inputs) {
|
||||
super(Inputs);
|
||||
this.Name = "AND";
|
||||
}
|
||||
|
||||
getOutput() {
|
||||
let ANDResult = true;
|
||||
for (let a = 0; a < this.totalInputs;a++) {
|
||||
if (!this.Inputs[a]) ANDResult = false;
|
||||
}
|
||||
return ANDResult;
|
||||
}
|
||||
drawElement(x,y,ctx) {
|
||||
this.drawBorderBox(ctx, x,y,this.Width,this.Height);
|
||||
this.drawTextCentered(ctx,x,y,this.Width,this.Height,"|⊃");
|
||||
this.drawInputs(ctx,x,y);
|
||||
this.drawOutputs(ctx,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
class LogicNAND extends LogicAND {
|
||||
constructor(Inputs) {
|
||||
super(Inputs);
|
||||
this.Name = "NAND";
|
||||
}
|
||||
getOutput() {
|
||||
if (super.getOutput()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
drawElement(x,y,ctx) {
|
||||
this.drawBorderBox(ctx, x,y,this.Width,this.Height);
|
||||
this.drawTextCentered(ctx,x,y,this.Width,this.Height,"|⊃🞄");
|
||||
this.drawInputs(ctx,x,y);
|
||||
this.drawOutputs(ctx,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
class LogicOR extends Element {
|
||||
constructor(Inputs) {
|
||||
super(Inputs);
|
||||
this.Name = "OR";
|
||||
}
|
||||
|
||||
getOutput() {
|
||||
let ORResult = false;
|
||||
for (let a = 0; a < this.totalInputs;a++) {
|
||||
if (this.Inputs[a]) ORResult = true;
|
||||
}
|
||||
return ORResult;
|
||||
}
|
||||
drawElement(x,y,ctx) {
|
||||
let drawWidth = this.Width;
|
||||
let drawHeight = this.Height;
|
||||
|
||||
this.drawBorderBox(ctx, x,y,drawWidth,drawHeight);
|
||||
this.drawTextCentered(ctx,x,y,drawWidth,drawHeight,")⊃");
|
||||
this.drawInputs(ctx,x,y);
|
||||
this.drawOutputs(ctx,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
class LogicNOR extends LogicOR {
|
||||
constructor(Inputs) {
|
||||
super(Inputs);
|
||||
this.Name = "NOR";
|
||||
}
|
||||
getOutput() {
|
||||
if (super.getOutput()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
drawElement(x,y,ctx) {
|
||||
this.drawBorderBox(ctx, x,y,this.Width,this.Height);
|
||||
this.drawTextCentered(ctx,x,y,this.Width,this.Height,")⊃🞄");
|
||||
this.drawInputs(ctx,x,y);
|
||||
this.drawOutputs(ctx,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
class LogicXOR extends Element {
|
||||
constructor() {
|
||||
super(2); // Only 2 inputs on XOR
|
||||
this.Name = "XOR";
|
||||
}
|
||||
|
||||
getOutput() {
|
||||
let ORResult = false;
|
||||
if ( (this.Inputs[0] && !this.Inputs[1]) || (!this.Inputs[0] && this.Inputs[1]) ) ORResult = true;
|
||||
return ORResult;
|
||||
}
|
||||
|
||||
drawElement(x,y,ctx) {
|
||||
let drawWidth = this.Width;
|
||||
let drawHeight = this.Height;
|
||||
|
||||
this.drawBorderBox(ctx, x,y,drawWidth,drawHeight);
|
||||
this.drawTextCentered(ctx,x,y,drawWidth,drawHeight,"))⊃");
|
||||
this.drawInputs(ctx,x,y);
|
||||
this.drawOutputs(ctx,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
class LogicXNOR extends Element {
|
||||
constructor() {
|
||||
super(2); // Only 2 inputs on XOR
|
||||
this.Name = "XNOR";
|
||||
}
|
||||
|
||||
getOutput() {
|
||||
let ORResult = false;
|
||||
if ( (this.Inputs[0] && !this.Inputs[1]) || (!this.Inputs[0] && this.Inputs[1]) ) ORResult = true;
|
||||
return !ORResult;
|
||||
}
|
||||
|
||||
drawElement(x,y,ctx) {
|
||||
let drawWidth = this.Width;
|
||||
let drawHeight = this.Height;
|
||||
|
||||
this.drawBorderBox(ctx, x,y,drawWidth,drawHeight);
|
||||
this.drawTextCentered(ctx,x,y,drawWidth,drawHeight,"))⊃🞄");
|
||||
this.drawInputs(ctx,x,y);
|
||||
this.drawOutputs(ctx,x,y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class elementContainer {
|
||||
constructor() {
|
||||
this.Elements = new Array();
|
||||
this.Selected = false;
|
||||
}
|
||||
|
||||
AddElement(element) {
|
||||
let designatorNumber = 1;
|
||||
let designatorTest = element.Name + designatorNumber;
|
||||
let unused = false;
|
||||
|
||||
while (!unused) {
|
||||
let foundMatch = false;
|
||||
for (let a=0;a < this.Elements.length;a++) {
|
||||
if (this.Elements[a].Designator == designatorTest) foundMatch = true;
|
||||
}
|
||||
if (foundMatch) {
|
||||
designatorNumber++;
|
||||
designatorTest = element.Name + designatorNumber;
|
||||
} else {
|
||||
unused = true;
|
||||
element.Designator = designatorTest;
|
||||
this.Elements.push(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeleteElement(element) {
|
||||
// Can pass object or Designator
|
||||
for (let a = 0; a < this.Elements.length; a++) {
|
||||
if ((this.Elements[a] == element) || (this.Elements[a].Designator == element)) {
|
||||
this.Elements[a].Delete();
|
||||
this.Elements.splice(a,1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HasElement(element) {
|
||||
// Can pass object or Designator
|
||||
for (let a = 0; a < this.Elements.length; a++) {
|
||||
if ((this.Elements[a] == element) || (this.Elements[a].Designator == element)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DrawAll(ctx) {
|
||||
for (let a = 0;a < this.Elements.length;a++) {
|
||||
// Not ideal to loop twice but we need the connections drawn first
|
||||
this.Elements[a].drawConnections(ctx);
|
||||
}
|
||||
|
||||
for (let a = 0;a < this.Elements.length;a++) {
|
||||
if (this.Elements[a] == this.Selected) this.Elements[a].drawBorderBox(ctx,this.Elements[a].X - 2,this.Elements[a].Y - 2,this.Elements[a].Width+4,this.Elements[a].Height+4,2,"#5555FF","#5555ff");
|
||||
this.Elements[a].drawElement(this.Elements[a].X,this.Elements[a].Y,ctx);
|
||||
let old_font = ctx.font;
|
||||
let old_fillStyle = ctx.fillStyle;
|
||||
ctx.font = "10px Console";
|
||||
let x = this.Elements[a].X;
|
||||
let y = this.Elements[a].Y + (this.Elements[a].Height-12);
|
||||
let x2 = this.Elements[a].Width;
|
||||
let y2 = 10;
|
||||
this.Elements[a].drawTextCentered(ctx,x,y,x2,y2,this.Elements[a].Designator,ctx.font,"#000");
|
||||
ctx.font = old_font;
|
||||
ctx.fillStyle = old_fillStyle;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Select(element) {
|
||||
this.Selected = element;
|
||||
}
|
||||
|
||||
checkMouseBounds(mousePos) {
|
||||
// We go backwards so that the newest (highest drawn) element is clicked before one lower.
|
||||
for (let a = (this.Elements.length - 1); a >= 0; a--) {
|
||||
if (this.Elements[a].mouseInside(mousePos)) return this.Elements[a];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class LogicEngine {
|
||||
|
||||
Resize(evt) {
|
||||
this.Canvas.width = window.innerWidth;
|
||||
this.Canvas.height = window.innerHeight - 50;
|
||||
this.Mouse = false;
|
||||
}
|
||||
|
||||
Mouse_Down(evt) {
|
||||
let mousePos = getMousePos(this.Canvas, evt);
|
||||
this.MouseDown = true;
|
||||
this.MouseDownTime = performance.now();
|
||||
let element = this.ActiveContainer.checkMouseBounds(mousePos);
|
||||
if (element) {
|
||||
console.log("Moused down on " + element.Designator);
|
||||
this.MovingElement = element;
|
||||
this.MovingElementStartX = element.X;
|
||||
this.MovingElementStartY = element.Y;
|
||||
this.MovingElementMouseStartX = mousePos.x;
|
||||
this.MovingElementMouseStartY = mousePos.y;
|
||||
}
|
||||
}
|
||||
|
||||
Mouse_Up(evt) {
|
||||
this.MouseDown = false;
|
||||
if (this.MovingElement && (this.MovingElement.X == this.MovingElementStartX) && (this.MovingElement.Y == this.MovingElementStartY)) {
|
||||
if ((performance.now() - this.MouseDownTime) < 3000) {
|
||||
// Presume this was a click
|
||||
this.ActiveContainer.Select(this.MovingElement);
|
||||
if (this.ActiveLink) {
|
||||
this.Link();
|
||||
} else {
|
||||
this.MovingElement.MouseClick();
|
||||
}
|
||||
}
|
||||
//console.log("Mouse Up");
|
||||
}
|
||||
if (!this.MovingElement) this.ActiveContainer.Selected = false;
|
||||
this.ActiveLink = false;
|
||||
this.MovingElement = false;
|
||||
}
|
||||
|
||||
Mouse_Move(evt) {
|
||||
let mousePos = getMousePos(this.Canvas, evt);
|
||||
this.Mouse = mousePos;
|
||||
if(this.MouseDown) {
|
||||
//console.log('Mouse at position: ' + mousePos.x + ',' + mousePos.y);
|
||||
if (this.MovingElement) {
|
||||
if ((performance.now() - this.MouseDownTime) > 100) {
|
||||
this.ActiveContainer.Select(this.MovingElement);
|
||||
let xOffset = mousePos.x - this.MovingElementMouseStartX;
|
||||
let yOffset = mousePos.y - this.MovingElementMouseStartY;
|
||||
let diffxOffset = this.MovingElementMouseStartX - this.MovingElementStartX;
|
||||
let diffyOffset = this.MovingElementMouseStartY - this.MovingElementStartY;
|
||||
this.MovingElement.X = (this.MovingElementMouseStartX + xOffset) - diffxOffset;
|
||||
this.MovingElement.Y = (this.MovingElementMouseStartY + yOffset) - diffyOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Key_Press(evt) {
|
||||
if (evt.key == "Escape") {
|
||||
if (this.MovingElement && this.MouseDown) {
|
||||
this.MovingElement.X = this.MovingElementStartX;
|
||||
this.MovingElement.Y = this.MovingElementStartY;
|
||||
this.MovingElement = false;
|
||||
}
|
||||
}
|
||||
if (evt.key == "Delete") {
|
||||
if (this.ActiveContainer.Selected) {
|
||||
this.ActiveContainer.DeleteElement(this.ActiveContainer.Selected);
|
||||
this.ActiveContainer.Selected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor(canvas) {
|
||||
this.Canvas = canvas;
|
||||
this.Ctx = canvas.getContext("2d");
|
||||
|
||||
this.FPSCounter = 0;
|
||||
this.FPS = 0;
|
||||
this.PotentialFPS = 0;
|
||||
this.PotentialFPSAVGs = new Array(20);
|
||||
this.PotentialFPSAVGLoc = 0;
|
||||
this.LastFPSCheck = performance.now();
|
||||
this.MouseDown = false;
|
||||
this.MouseDownTime = 0;
|
||||
this.MovingElementContainer = false;
|
||||
this.MovingElement = false;
|
||||
this.MovingElementStartX = 0;
|
||||
this.MovingElementStartY = 0;
|
||||
this.MovingElementMouseStartX = 0;
|
||||
this.MovingElementMouseStartY = 0;
|
||||
this.ActiveContainer = new elementContainer();
|
||||
this.ActiveLink = false;
|
||||
|
||||
this.Canvas.setAttribute('tabindex','0');
|
||||
}
|
||||
|
||||
Link() {
|
||||
if (this.ActiveLink) {
|
||||
if (this.ActiveContainer.Selected && (this.ActiveContainer.Selected != this.ActiveLink)) {
|
||||
|
||||
let input = parseInt(prompt("Please enter the input number (0 - x)"));
|
||||
while (input == NaN) {
|
||||
input = parseInt(prompt("Please enter the input number (0 - x)"));
|
||||
}
|
||||
this.ActiveLink.addConnection(this.ActiveContainer,this.ActiveContainer.Selected,input);
|
||||
this.ActiveLink = false;
|
||||
} else {
|
||||
this.ActiveLink = false;
|
||||
}
|
||||
} else {
|
||||
if (this.ActiveContainer.Selected) {
|
||||
this.ActiveLink = this.ActiveContainer.Selected;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
DrawLoop() {
|
||||
let startLoop = performance.now();
|
||||
this.Canvas.focus();
|
||||
this.Ctx.clearRect(0,0,this.Canvas.width,this.Canvas.height);
|
||||
if (this.ActiveLink) {
|
||||
this.Ctx.save();
|
||||
this.Ctx.strokeStyle = "#5555AA";
|
||||
this.Ctx.lineWidth = 5;
|
||||
this.Ctx.beginPath();
|
||||
this.Ctx.moveTo(this.ActiveLink.X + (this.ActiveLink.Width/2), this.ActiveLink.Y + (this.ActiveLink.Height/2));
|
||||
this.Ctx.lineTo(this.Mouse.x, this.Mouse.y);
|
||||
this.Ctx.stroke();
|
||||
this.Ctx.restore();
|
||||
}
|
||||
this.ActiveContainer.DrawAll(this.Ctx);
|
||||
let ct = new CanvasTools();
|
||||
let FPSOffset = this.Canvas.width - 150;
|
||||
ct.drawText(this.Ctx,FPSOffset,650,"FPS: " + this.FPS,"12px console", "#005500");
|
||||
ct.drawText(this.Ctx,FPSOffset,670,"Potential FPS: " + this.PotentialFPS,"12px console", "#005500");
|
||||
let timeCheck = performance.now();
|
||||
this.FPSCounter++;
|
||||
|
||||
if (!(Math.round(timeCheck - this.LastFPSCheck) % 50)) {
|
||||
let frameTimeUS = (performance.now() - startLoop) * 1000;
|
||||
let potentialFPS = 1000000 / frameTimeUS;
|
||||
this.PotentialFPSAVGs[this.PotentialFPSAVGLoc] = Math.round(potentialFPS);
|
||||
this.PotentialFPSAVGLoc++;
|
||||
if (this.PotentialFPSAVGLoc == this.PotentialFPSAVGs.length) this.PotentialFPSAVGLoc = 0;
|
||||
this.PotentialFPS = averageArray(this.PotentialFPSAVGs);
|
||||
}
|
||||
|
||||
if ((timeCheck - this.LastFPSCheck) >= 1000) {
|
||||
this.FPS = this.FPSCounter;
|
||||
this.FPSCounter = 0;
|
||||
this.LastFPSCheck = performance.now();
|
||||
//console.log("Frame Time: " + frameTimeUS + "uS" + ", Potential FPS: " + potentialFPS);
|
||||
//console.log("FPS: " + FPS);
|
||||
}
|
||||
|
||||
requestAnimationFrame(this.DrawLoop.bind(this));
|
||||
}
|
||||
|
||||
StartEngine() {
|
||||
this.Resize("");
|
||||
this.DrawLoop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
144
js/main.js
Normal file
144
js/main.js
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
MatCat BrowserLogic Simulator
|
||||
*/
|
||||
|
||||
// get the canvas and get the engine object going
|
||||
let lCanvasElement = document.getElementById("LogicPlane");
|
||||
let logicEngine = new LogicEngine(lCanvasElement);
|
||||
|
||||
// Sadly this doesn't work well inside of the class so we will do it here real fast
|
||||
window.addEventListener('resize', function(evt) {
|
||||
logicEngine.Resize(evt);
|
||||
}, false);
|
||||
|
||||
lCanvasElement.addEventListener('keydown', function(evt) {
|
||||
logicEngine.Key_Press(evt);
|
||||
}, false);
|
||||
|
||||
lCanvasElement.addEventListener('mousedown', function(evt) {
|
||||
logicEngine.Mouse_Down(evt);
|
||||
}, false);
|
||||
|
||||
lCanvasElement.addEventListener('mouseup', function(evt) {
|
||||
logicEngine.Mouse_Up(evt);
|
||||
}, false);
|
||||
|
||||
lCanvasElement.addEventListener('mousemove', function(evt) {
|
||||
logicEngine.Mouse_Move(evt);
|
||||
}, false);
|
||||
|
||||
// Get the engine going
|
||||
logicEngine.StartEngine();
|
||||
|
||||
// Setup interface buttons
|
||||
let btn_Link = document.getElementById("btn_Link");
|
||||
btn_Link.addEventListener('click', function(evt) {
|
||||
logicEngine.Link();
|
||||
}, false);
|
||||
|
||||
let btn_Delete = document.getElementById("btn_Delete");
|
||||
btn_Delete.addEventListener('click', function(evt) {
|
||||
logicEngine.Key_Press({key: "Delete"});
|
||||
}, false);
|
||||
|
||||
let btn_AddAND = document.getElementById("btn_AddAND");
|
||||
btn_AddAND.addEventListener('click', function(evt) {
|
||||
let newAND = new LogicAND(2);
|
||||
newAND.X = 20;
|
||||
newAND.Y = 20;
|
||||
logicEngine.ActiveContainer.AddElement(newAND);
|
||||
}, false);
|
||||
|
||||
let btn_AddNAND = document.getElementById("btn_AddNAND");
|
||||
btn_AddNAND.addEventListener('click', function(evt) {
|
||||
let newNAND = new LogicNAND(2);
|
||||
newNAND.X = 20;
|
||||
newNAND.Y = 20;
|
||||
logicEngine.ActiveContainer.AddElement(newNAND);
|
||||
}, false);
|
||||
|
||||
let btn_AddOR = document.getElementById("btn_AddOR");
|
||||
btn_AddOR.addEventListener('click', function(evt) {
|
||||
let newOR = new LogicOR(2);
|
||||
newOR.X = 20;
|
||||
newOR.Y = 20;
|
||||
logicEngine.ActiveContainer.AddElement(newOR);
|
||||
}, false);
|
||||
|
||||
let btn_AddNOR = document.getElementById("btn_AddNOR");
|
||||
btn_AddNOR.addEventListener('click', function(evt) {
|
||||
let newNOR = new LogicNOR(2);
|
||||
newNOR.X = 20;
|
||||
newNOR.Y = 20;
|
||||
logicEngine.ActiveContainer.AddElement(newNOR);
|
||||
}, false);
|
||||
|
||||
let btn_AddXOR = document.getElementById("btn_AddXOR");
|
||||
btn_AddXOR.addEventListener('click', function(evt) {
|
||||
let newXOR = new LogicXOR();
|
||||
newXOR.X = 20;
|
||||
newXOR.Y = 20;
|
||||
logicEngine.ActiveContainer.AddElement(newXOR);
|
||||
}, false);
|
||||
|
||||
let btn_AddXNOR = document.getElementById("btn_AddXNOR");
|
||||
btn_AddXNOR.addEventListener('click', function(evt) {
|
||||
let newXNOR = new LogicXNOR();
|
||||
newXNOR.X = 20;
|
||||
newXNOR.Y = 20;
|
||||
logicEngine.ActiveContainer.AddElement(newXNOR);
|
||||
}, false);
|
||||
|
||||
let btn_AddBTN = document.getElementById("btn_AddBTN");
|
||||
btn_AddBTN.addEventListener('click', function(evt) {
|
||||
let newBTN = new inputButton();
|
||||
newBTN.X = 20;
|
||||
newBTN.Y = 20;
|
||||
logicEngine.ActiveContainer.AddElement(newBTN);
|
||||
}, false);
|
||||
|
||||
|
||||
/*
|
||||
let AND1 = new LogicAND(2);
|
||||
AND1.X = 430;
|
||||
AND1.Y = 70;
|
||||
logicEngine.ActiveContainer.AddElement(AND1);
|
||||
let OR1 = new LogicOR(6);
|
||||
OR1.X = 220;
|
||||
OR1.Y = 20;
|
||||
OR1.addConnection(logicEngine.ActiveContainer,AND1,0);
|
||||
logicEngine.ActiveContainer.AddElement(OR1);
|
||||
let NAND1 = new LogicNAND(2);
|
||||
NAND1.X = 220;
|
||||
NAND1.Y = 140;
|
||||
NAND1.addConnection(logicEngine.ActiveContainer,AND1,1);
|
||||
logicEngine.ActiveContainer.AddElement(NAND1);
|
||||
let AND2 = new LogicAND(2);
|
||||
AND2.X = 630;
|
||||
AND2.Y = 120;
|
||||
AND1.addConnection(logicEngine.ActiveContainer,AND2,0);
|
||||
logicEngine.ActiveContainer.AddElement(AND2);
|
||||
let NOR1 = new LogicNOR(2);
|
||||
NOR1.X = 430;
|
||||
NOR1.Y = 250;
|
||||
NOR1.addConnection(logicEngine.ActiveContainer,AND2,1);
|
||||
logicEngine.ActiveContainer.AddElement(NOR1);
|
||||
|
||||
let Button1 = new inputButton();
|
||||
Button1.X = 20;
|
||||
Button1.Y = 20;
|
||||
Button1.addConnection(logicEngine.ActiveContainer,OR1,1);
|
||||
logicEngine.ActiveContainer.AddElement(Button1);
|
||||
|
||||
let Button2 = new inputButton();
|
||||
Button2.X = 20;
|
||||
Button2.Y = 130;
|
||||
Button2.addConnection(logicEngine.ActiveContainer,NAND1,0);
|
||||
logicEngine.ActiveContainer.AddElement(Button2);
|
||||
|
||||
let Button3 = new inputButton();
|
||||
Button3.X = 20;
|
||||
Button3.Y = 240;
|
||||
Button3.addConnection(logicEngine.ActiveContainer,NAND1,1);
|
||||
logicEngine.ActiveContainer.AddElement(Button3);
|
||||
*/
|
24
js/plugins.js
Normal file
24
js/plugins.js
Normal file
@ -0,0 +1,24 @@
|
||||
// Avoid `console` errors in browsers that lack a console.
|
||||
(function() {
|
||||
var method;
|
||||
var noop = function () {};
|
||||
var methods = [
|
||||
'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
|
||||
'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
|
||||
'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
|
||||
'timeline', 'timelineEnd', 'timeStamp', 'trace', 'warn'
|
||||
];
|
||||
var length = methods.length;
|
||||
var console = (window.console = window.console || {});
|
||||
|
||||
while (length--) {
|
||||
method = methods[length];
|
||||
|
||||
// Only stub undefined methods.
|
||||
if (!console[method]) {
|
||||
console[method] = noop;
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
||||
// Place any jQuery/helper plugins in here.
|
3
js/vendor/modernizr-3.11.2.min.js
vendored
Normal file
3
js/vendor/modernizr-3.11.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
robots.txt
Normal file
5
robots.txt
Normal file
@ -0,0 +1,5 @@
|
||||
# www.robotstxt.org/
|
||||
|
||||
# Allow crawling of all content
|
||||
User-agent: *
|
||||
Disallow:
|
BIN
tile-wide.png
Normal file
BIN
tile-wide.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Loading…
Reference in New Issue
Block a user