Remove legacy unused files (#57)
9
.vscode/extensions.json
vendored
@@ -1,9 +0,0 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
|
||||
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
||||
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"],
|
||||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
|
||||
"unwantedRecommendations": []
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
.litegraph-editor {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
background-color: #333;
|
||||
color: #eee;
|
||||
font: 14px Tahoma;
|
||||
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.litegraph-editor h1 {
|
||||
font-family: "Metro Light", Tahoma;
|
||||
color: #ddd;
|
||||
font-size: 28px;
|
||||
padding-left: 10px;
|
||||
/*text-shadow: 0 1px 1px #333, 0 -1px 1px #777;*/
|
||||
margin: 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.litegraph-editor h1 span {
|
||||
font-family: "Arial";
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.litegraph-editor h2 {
|
||||
font-family: "Metro Light";
|
||||
padding: 5px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.litegraph-editor * {
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
.litegraph-editor .content {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: calc(100% - 80px);
|
||||
background-color: #1a1a1a;
|
||||
}
|
||||
|
||||
.litegraph-editor .header,
|
||||
.litegraph-editor .footer {
|
||||
position: relative;
|
||||
height: 40px;
|
||||
background-color: #333;
|
||||
/*border-radius: 10px 10px 0 0;*/
|
||||
}
|
||||
|
||||
.litegraph-editor .tools,
|
||||
.litegraph-editor .tools-left,
|
||||
.litegraph-editor .tools-right {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 0px;
|
||||
vertical-align: top;
|
||||
|
||||
margin: 2px 5px 0 0px;
|
||||
}
|
||||
|
||||
.litegraph-editor .tools-left {
|
||||
right: auto;
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.litegraph-editor .footer {
|
||||
height: 40px;
|
||||
position: relative;
|
||||
/*border-radius: 0 0 10px 10px;*/
|
||||
}
|
||||
|
||||
.litegraph-editor .miniwindow {
|
||||
background-color: #333;
|
||||
border: 1px solid #111;
|
||||
}
|
||||
|
||||
.litegraph-editor .miniwindow .corner-button {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
font-family: "Tahoma";
|
||||
font-size: 14px;
|
||||
color: #aaa;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* BUTTONS **********************/
|
||||
|
||||
.litegraph-editor .btn {
|
||||
/*font-family: "Metro Light";*/
|
||||
color: #ccc;
|
||||
font-size: 20px;
|
||||
min-width: 30px;
|
||||
/*border-radius: 0.3em;*/
|
||||
border: 0 solid #666;
|
||||
background-color: #3f3f3f;
|
||||
/*box-shadow: 0 0 3px black;*/
|
||||
padding: 4px 10px;
|
||||
cursor: pointer;
|
||||
transition: all 1s;
|
||||
-moz-transition: all 1s;
|
||||
-webkit-transition: all 0.4s;
|
||||
}
|
||||
|
||||
.litegraph-editor button:hover {
|
||||
background-color: #999;
|
||||
color: #fff;
|
||||
transition: all 1s;
|
||||
-moz-transition: all 1s;
|
||||
-webkit-transition: all 0.4s;
|
||||
}
|
||||
|
||||
.litegraph-editor button:active {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.litegraph-editor button.fixed {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.litegraph-editor button img {
|
||||
margin: -4px;
|
||||
vertical-align: top;
|
||||
opacity: 0.8;
|
||||
transition: all 1s;
|
||||
}
|
||||
|
||||
.litegraph-editor button:hover img {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.litegraph-editor .header button {
|
||||
height: 32px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.litegraph-editor .footer button {
|
||||
/*font-size: 16px;*/
|
||||
}
|
||||
|
||||
.litegraph-editor .toolbar-widget {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.litegraph-editor .editor-area {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* METER *********************/
|
||||
|
||||
.litegraph-editor .loadmeter {
|
||||
font-family: "Tahoma";
|
||||
color: #aaa;
|
||||
font-size: 12px;
|
||||
border-radius: 2px;
|
||||
width: 130px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.litegraph-editor .strong {
|
||||
vertical-align: top;
|
||||
padding: 3px;
|
||||
width: 30px;
|
||||
display: inline-block;
|
||||
line-height: 8px;
|
||||
}
|
||||
|
||||
.litegraph-editor .cpuload .bgload,
|
||||
.litegraph-editor .gpuload .bgload {
|
||||
display: inline-block;
|
||||
width: 90px;
|
||||
height: 15px;
|
||||
background-image: url("../editor/imgs/load-progress-empty.png");
|
||||
}
|
||||
|
||||
.litegraph-editor .cpuload .fgload,
|
||||
.litegraph-editor .gpuload .fgload {
|
||||
display: inline-block;
|
||||
width: 4px;
|
||||
height: 15px;
|
||||
max-width: 90px;
|
||||
background-image: url("../editor/imgs/load-progress-full.png");
|
||||
}
|
||||
|
||||
.litegraph-editor textarea.code, .litegraph-editor div.code {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: black;
|
||||
padding: 4px;
|
||||
font: 16px monospace;
|
||||
overflow: auto;
|
||||
resize: none;
|
||||
outline: none;
|
||||
color: #DDD;
|
||||
}
|
||||
|
||||
.litegraph-editor .codeflask {
|
||||
background-color: #2a2a2a;
|
||||
}
|
||||
|
||||
.litegraph-editor .codeflask textarea {
|
||||
opacity: 0;
|
||||
}
|
||||
14
doc/api.js
@@ -1,14 +0,0 @@
|
||||
YUI.add("yuidoc-meta", function(Y) {
|
||||
Y.YUIDoc = { meta: {
|
||||
"classes": [
|
||||
"ContextMenu",
|
||||
"LGraph",
|
||||
"LGraphCanvas",
|
||||
"LGraphNode",
|
||||
"LiteGraph"
|
||||
],
|
||||
"modules": [],
|
||||
"allModules": [],
|
||||
"elements": []
|
||||
} };
|
||||
});
|
||||
|
Before Width: | Height: | Size: 491 B |
|
Before Width: | Height: | Size: 7.0 KiB |
@@ -1,783 +0,0 @@
|
||||
/*
|
||||
Font sizes for all selectors other than the body are given in percentages,
|
||||
with 100% equal to 13px. To calculate a font size percentage, multiply the
|
||||
desired size in pixels by 7.6923076923.
|
||||
|
||||
Here's a quick lookup table:
|
||||
|
||||
10px - 76.923%
|
||||
11px - 84.615%
|
||||
12px - 92.308%
|
||||
13px - 100%
|
||||
14px - 107.692%
|
||||
15px - 115.385%
|
||||
16px - 123.077%
|
||||
17px - 130.769%
|
||||
18px - 138.462%
|
||||
19px - 146.154%
|
||||
20px - 153.846%
|
||||
*/
|
||||
|
||||
html {
|
||||
background: #fff;
|
||||
color: #333;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
body {
|
||||
/*font: 13px/1.4 'Lucida Grande', 'Lucida Sans Unicode', 'DejaVu Sans', 'Bitstream Vera Sans', 'Helvetica', 'Arial', sans-serif;*/
|
||||
font: 13px/1.4 'Helvetica', 'Arial', sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* -- Links ----------------------------------------------------------------- */
|
||||
a {
|
||||
color: #356de4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a:hover { text-decoration: underline; }
|
||||
|
||||
/* "Jump to Table of Contents" link is shown to assistive tools, but hidden from
|
||||
sight until it's focused. */
|
||||
.jump {
|
||||
position: absolute;
|
||||
padding: 3px 6px;
|
||||
left: -99999px;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.jump:focus { left: 40%; }
|
||||
|
||||
/* -- Paragraphs ------------------------------------------------------------ */
|
||||
p { margin: 1.3em 0; }
|
||||
dd p, td p { margin-bottom: 0; }
|
||||
dd p:first-child, td p:first-child { margin-top: 0; }
|
||||
|
||||
/* -- Headings -------------------------------------------------------------- */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #D98527;/*was #f80*/
|
||||
font-family: 'Trebuchet MS', sans-serif;
|
||||
font-weight: bold;
|
||||
line-height: 1.1;
|
||||
margin: 1.1em 0 0.5em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 184.6%;
|
||||
color: #30418C;
|
||||
margin: 0.75em 0 0.5em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 153.846%;
|
||||
color: #E48A2B;
|
||||
}
|
||||
|
||||
h3 { font-size: 138.462%; }
|
||||
|
||||
h4 {
|
||||
border-bottom: 1px solid #DBDFEA;
|
||||
color: #E48A2B;
|
||||
font-size: 115.385%;
|
||||
font-weight: normal;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
h5, h6 { font-size: 107.692%; }
|
||||
|
||||
/* -- Code and examples ----------------------------------------------------- */
|
||||
code, kbd, pre, samp {
|
||||
font-family: Menlo, Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;
|
||||
font-size: 92.308%;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
p code, p kbd, p samp, li code {
|
||||
background: #FCFBFA;
|
||||
border: 1px solid #EFEEED;
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
a code, a kbd, a samp,
|
||||
pre code, pre kbd, pre samp,
|
||||
table code, table kbd, table samp,
|
||||
.intro code, .intro kbd, .intro samp,
|
||||
.toc code, .toc kbd, .toc samp {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
pre.code, pre.terminal, pre.cmd {
|
||||
overflow-x: auto;
|
||||
*overflow-x: scroll;
|
||||
padding: 0.3em 0.6em;
|
||||
}
|
||||
|
||||
pre.code {
|
||||
background: #FCFBFA;
|
||||
border: 1px solid #EFEEED;
|
||||
border-left-width: 5px;
|
||||
}
|
||||
|
||||
pre.terminal, pre.cmd {
|
||||
background: #F0EFFC;
|
||||
border: 1px solid #D0CBFB;
|
||||
border-left: 5px solid #D0CBFB;
|
||||
}
|
||||
|
||||
/* Don't reduce the font size of <code>/<kbd>/<samp> elements inside <pre>
|
||||
blocks. */
|
||||
pre code, pre kbd, pre samp { font-size: 100%; }
|
||||
|
||||
/* Used to denote text that shouldn't be selectable, such as line numbers or
|
||||
shell prompts. Guess which browser this doesn't work in. */
|
||||
.noselect {
|
||||
-moz-user-select: -moz-none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* -- Lists ----------------------------------------------------------------- */
|
||||
dd { margin: 0.2em 0 0.7em 1em; }
|
||||
dl { margin: 1em 0; }
|
||||
dt { font-weight: bold; }
|
||||
|
||||
/* -- Tables ---------------------------------------------------------------- */
|
||||
caption, th { text-align: left; }
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td, th {
|
||||
border: 1px solid #fff;
|
||||
padding: 5px 12px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
td { background: #E6E9F5; }
|
||||
td dl { margin: 0; }
|
||||
td dl dl { margin: 1em 0; }
|
||||
td pre:first-child { margin-top: 0; }
|
||||
|
||||
th {
|
||||
background: #D2D7E6;/*#97A0BF*/
|
||||
border-bottom: none;
|
||||
border-top: none;
|
||||
color: #000;/*#FFF1D5*/
|
||||
font-family: 'Trebuchet MS', sans-serif;
|
||||
font-weight: bold;
|
||||
line-height: 1.3;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
/* -- Layout and Content ---------------------------------------------------- */
|
||||
#doc {
|
||||
margin: auto;
|
||||
min-width: 1024px;
|
||||
}
|
||||
|
||||
.content { padding: 0 20px 0 25px; }
|
||||
|
||||
.sidebar {
|
||||
padding: 0 15px 0 10px;
|
||||
}
|
||||
#bd {
|
||||
padding: 7px 0 130px;
|
||||
position: relative;
|
||||
width: 99%;
|
||||
}
|
||||
|
||||
/* -- Table of Contents ----------------------------------------------------- */
|
||||
|
||||
/* The #toc id refers to the single global table of contents, while the .toc
|
||||
class refers to generic TOC lists that could be used throughout the page. */
|
||||
|
||||
.toc code, .toc kbd, .toc samp { font-size: 100%; }
|
||||
.toc li { font-weight: bold; }
|
||||
.toc li li { font-weight: normal; }
|
||||
|
||||
/* -- Intro and Example Boxes ----------------------------------------------- */
|
||||
/*
|
||||
.intro, .example { margin-bottom: 2em; }
|
||||
.example {
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-moz-box-shadow: 0 0 5px #bfbfbf;
|
||||
-webkit-box-shadow: 0 0 5px #bfbfbf;
|
||||
box-shadow: 0 0 5px #bfbfbf;
|
||||
padding: 1em;
|
||||
}
|
||||
.intro {
|
||||
background: none repeat scroll 0 0 #F0F1F8; border: 1px solid #D4D8EB; padding: 0 1em;
|
||||
}
|
||||
*/
|
||||
|
||||
/* -- Other Styles ---------------------------------------------------------- */
|
||||
|
||||
/* These are probably YUI-specific, and should be moved out of Selleck's default
|
||||
theme. */
|
||||
|
||||
.button {
|
||||
border: 1px solid #dadada;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
color: #444;
|
||||
display: inline-block;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 92.308%;
|
||||
font-weight: bold;
|
||||
padding: 4px 13px 3px;
|
||||
-moz-text-shadow: 1px 1px 0 #fff;
|
||||
-webkit-text-shadow: 1px 1px 0 #fff;
|
||||
text-shadow: 1px 1px 0 #fff;
|
||||
white-space: nowrap;
|
||||
|
||||
background: #EFEFEF; /* old browsers */
|
||||
background: -moz-linear-gradient(top, #f5f5f5 0%, #efefef 50%, #e5e5e5 51%, #dfdfdf 100%); /* firefox */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f5f5f5), color-stop(50%,#efefef), color-stop(51%,#e5e5e5), color-stop(100%,#dfdfdf)); /* webkit */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5f5f5', endColorstr='#dfdfdf',GradientType=0 ); /* ie */
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
border-color: #466899;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
-moz-text-shadow: 1px 1px 0 #222;
|
||||
-webkit-text-shadow: 1px 1px 0 #222;
|
||||
text-shadow: 1px 1px 0 #222;
|
||||
|
||||
background: #6396D8; /* old browsers */
|
||||
background: -moz-linear-gradient(top, #6396D8 0%, #5A83BC 50%, #547AB7 51%, #466899 100%); /* firefox */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6396D8), color-stop(50%,#5A83BC), color-stop(51%,#547AB7), color-stop(100%,#466899)); /* webkit */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#6396D8', endColorstr='#466899',GradientType=0 ); /* ie */
|
||||
}
|
||||
|
||||
.newwindow { text-align: center; }
|
||||
|
||||
.header .version em {
|
||||
display: block;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
||||
#classdocs .item {
|
||||
border-bottom: 1px solid #466899;
|
||||
margin: 1em 0;
|
||||
padding: 1.5em;
|
||||
}
|
||||
|
||||
#classdocs .item .params p,
|
||||
#classdocs .item .returns p,{
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#classdocs .item em code, #classdocs .item em.comment {
|
||||
color: green;
|
||||
}
|
||||
|
||||
#classdocs .item em.comment a {
|
||||
color: green;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#classdocs .foundat {
|
||||
font-size: 11px;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.attrs .emits {
|
||||
margin-left: 2em;
|
||||
padding: .5em;
|
||||
border-left: 1px dashed #ccc;
|
||||
}
|
||||
|
||||
abbr {
|
||||
border-bottom: 1px dashed #ccc;
|
||||
font-size: 80%;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.prettyprint li.L0,
|
||||
.prettyprint li.L1,
|
||||
.prettyprint li.L2,
|
||||
.prettyprint li.L3,
|
||||
.prettyprint li.L5,
|
||||
.prettyprint li.L6,
|
||||
.prettyprint li.L7,
|
||||
.prettyprint li.L8 {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
ul li p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.method .name {
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
.apidocs .methods .extends .method,
|
||||
.apidocs .properties .extends .property,
|
||||
.apidocs .attrs .extends .attr,
|
||||
.apidocs .events .extends .event {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.apidocs .methods .extends .inherited,
|
||||
.apidocs .properties .extends .inherited,
|
||||
.apidocs .attrs .extends .inherited,
|
||||
.apidocs .events .extends .inherited {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#hd {
|
||||
background: whiteSmoke;
|
||||
background: -moz-linear-gradient(top,#DCDBD9 0,#F6F5F3 100%);
|
||||
background: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#DCDBD9),color-stop(100%,#F6F5F3));
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dcdbd9',endColorstr='#F6F5F3',GradientType=0);
|
||||
border-bottom: 1px solid #DFDFDF;
|
||||
padding: 0 15px 1px 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#hd img {
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
/* -- API Docs CSS ---------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
This file is organized so that more generic styles are nearer the top, and more
|
||||
specific styles are nearer the bottom of the file. This allows us to take full
|
||||
advantage of the cascade to avoid redundant style rules. Please respect this
|
||||
convention when making changes.
|
||||
*/
|
||||
|
||||
/* -- Generic TabView styles ------------------------------------------------ */
|
||||
|
||||
/*
|
||||
These styles apply to all API doc tabviews. To change styles only for a
|
||||
specific tabview, see the other sections below.
|
||||
*/
|
||||
|
||||
.yui3-js-enabled .apidocs .tabview {
|
||||
visibility: hidden; /* Hide until the TabView finishes rendering. */
|
||||
_visibility: visible;
|
||||
}
|
||||
|
||||
.apidocs .tabview.yui3-tabview-content { visibility: visible; }
|
||||
.apidocs .tabview .yui3-tabview-panel { background: #fff; }
|
||||
|
||||
/* -- Generic Content Styles ------------------------------------------------ */
|
||||
|
||||
/* Headings */
|
||||
h2, h3, h4, h5, h6 {
|
||||
border: none;
|
||||
color: #30418C;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.link-docs {
|
||||
float: right;
|
||||
font-size: 15px;
|
||||
margin: 4px 4px 6px;
|
||||
padding: 6px 30px 5px;
|
||||
}
|
||||
|
||||
.apidocs { zoom: 1; }
|
||||
|
||||
/* Generic box styles. */
|
||||
.apidocs .box {
|
||||
border: 1px solid;
|
||||
border-radius: 3px;
|
||||
margin: 1em 0;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
/* A flag is a compact, capsule-like indicator of some kind. It's used to
|
||||
indicate private and protected items, item return types, etc. in an
|
||||
attractive and unobtrusive way. */
|
||||
.apidocs .flag {
|
||||
background: #bababa;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
margin: 0 0.5em;
|
||||
padding: 2px 4px 1px;
|
||||
}
|
||||
|
||||
/* Class/module metadata such as "Uses", "Extends", "Defined in", etc. */
|
||||
.apidocs .meta {
|
||||
background: #f9f9f9;
|
||||
border-color: #efefef;
|
||||
color: #555;
|
||||
font-size: 11px;
|
||||
padding: 3px 6px;
|
||||
}
|
||||
|
||||
.apidocs .meta p { margin: 0; }
|
||||
|
||||
/* Deprecation warning. */
|
||||
.apidocs .box.deprecated,
|
||||
.apidocs .flag.deprecated {
|
||||
background: #fdac9f;
|
||||
border: 1px solid #fd7775;
|
||||
}
|
||||
|
||||
.apidocs .box.deprecated p { margin: 0.5em 0; }
|
||||
.apidocs .flag.deprecated { color: #333; }
|
||||
|
||||
/* Module/Class intro description. */
|
||||
.apidocs .intro {
|
||||
background: #f0f1f8;
|
||||
border-color: #d4d8eb;
|
||||
}
|
||||
|
||||
/* Loading spinners. */
|
||||
#bd.loading .apidocs,
|
||||
#api-list.loading .yui3-tabview-panel {
|
||||
background: #fff url(../img/spinner.gif) no-repeat center 70px;
|
||||
min-height: 150px;
|
||||
}
|
||||
|
||||
#bd.loading .apidocs .content,
|
||||
#api-list.loading .yui3-tabview-panel .apis {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.apidocs .no-visible-items { color: #666; }
|
||||
|
||||
/* Generic inline list. */
|
||||
.apidocs ul.inline {
|
||||
display: inline;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.apidocs ul.inline li { display: inline; }
|
||||
|
||||
/* Comma-separated list. */
|
||||
.apidocs ul.commas li:after { content: ','; }
|
||||
.apidocs ul.commas li:last-child:after { content: ''; }
|
||||
|
||||
/* Keyboard shortcuts. */
|
||||
kbd .cmd { font-family: Monaco, Helvetica; }
|
||||
|
||||
/* -- Generic Access Level styles ------------------------------------------- */
|
||||
.apidocs .item.protected,
|
||||
.apidocs .item.private,
|
||||
.apidocs .index-item.protected,
|
||||
.apidocs .index-item.deprecated,
|
||||
.apidocs .index-item.private {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.show-deprecated .item.deprecated,
|
||||
.show-deprecated .index-item.deprecated,
|
||||
.show-protected .item.protected,
|
||||
.show-protected .index-item.protected,
|
||||
.show-private .item.private,
|
||||
.show-private .index-item.private {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.hide-inherited .item.inherited,
|
||||
.hide-inherited .index-item.inherited {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* -- Generic Item Index styles --------------------------------------------- */
|
||||
.apidocs .index { margin: 1.5em 0 3em; }
|
||||
|
||||
.apidocs .index h3 {
|
||||
border-bottom: 1px solid #efefef;
|
||||
color: #333;
|
||||
font-size: 13px;
|
||||
margin: 2em 0 0.6em;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.apidocs .index .no-visible-items { margin-top: 2em; }
|
||||
|
||||
.apidocs .index-list {
|
||||
border-color: #efefef;
|
||||
font-size: 12px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-moz-column-count: 4;
|
||||
-moz-column-gap: 10px;
|
||||
-moz-column-width: 170px;
|
||||
-ms-column-count: 4;
|
||||
-ms-column-gap: 10px;
|
||||
-ms-column-width: 170px;
|
||||
-o-column-count: 4;
|
||||
-o-column-gap: 10px;
|
||||
-o-column-width: 170px;
|
||||
-webkit-column-count: 4;
|
||||
-webkit-column-gap: 10px;
|
||||
-webkit-column-width: 170px;
|
||||
column-count: 4;
|
||||
column-gap: 10px;
|
||||
column-width: 170px;
|
||||
}
|
||||
|
||||
.apidocs .no-columns .index-list {
|
||||
-moz-column-count: 1;
|
||||
-ms-column-count: 1;
|
||||
-o-column-count: 1;
|
||||
-webkit-column-count: 1;
|
||||
column-count: 1;
|
||||
}
|
||||
|
||||
.apidocs .index-item { white-space: nowrap; }
|
||||
|
||||
.apidocs .index-item .flag {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #afafaf;
|
||||
display: inline;
|
||||
margin: 0 0 0 0.2em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* -- Generic API item styles ----------------------------------------------- */
|
||||
.apidocs .args {
|
||||
display: inline;
|
||||
margin: 0 0.5em;
|
||||
}
|
||||
|
||||
.apidocs .flag.chainable { background: #46ca3b; }
|
||||
.apidocs .flag.protected { background: #9b86fc; }
|
||||
.apidocs .flag.private { background: #fd6b1b; }
|
||||
.apidocs .flag.async { background: #356de4; }
|
||||
.apidocs .flag.required { background: #e60923; }
|
||||
|
||||
.apidocs .item {
|
||||
border-bottom: 1px solid #efefef;
|
||||
margin: 1.5em 0 2em;
|
||||
padding-bottom: 2em;
|
||||
}
|
||||
|
||||
.apidocs .item h4,
|
||||
.apidocs .item h5,
|
||||
.apidocs .item h6 {
|
||||
color: #333;
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.apidocs .item .description p,
|
||||
.apidocs .item pre.code {
|
||||
margin: 1em 0 0;
|
||||
}
|
||||
|
||||
.apidocs .item .meta {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.apidocs .item .name {
|
||||
display: inline;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.apidocs .item .type,
|
||||
.apidocs .item .type a,
|
||||
.apidocs .returns-inline {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.apidocs .item .type,
|
||||
.apidocs .returns-inline {
|
||||
font-size: 11px;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
|
||||
.apidocs .item .type a { border-bottom: 1px dotted #afafaf; }
|
||||
.apidocs .item .type a:hover { border: none; }
|
||||
|
||||
/* -- Item Parameter List --------------------------------------------------- */
|
||||
.apidocs .params-list {
|
||||
list-style: square;
|
||||
margin: 1em 0 0 2em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.apidocs .param { margin-bottom: 1em; }
|
||||
|
||||
.apidocs .param .type,
|
||||
.apidocs .param .type a {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.apidocs .param .type {
|
||||
margin: 0 0 0 0.5em;
|
||||
*margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.apidocs .param-name { font-weight: bold; }
|
||||
|
||||
/* -- Item "Emits" block ---------------------------------------------------- */
|
||||
.apidocs .item .emits {
|
||||
background: #f9f9f9;
|
||||
border-color: #eaeaea;
|
||||
}
|
||||
|
||||
/* -- Item "Returns" block -------------------------------------------------- */
|
||||
.apidocs .item .returns .type,
|
||||
.apidocs .item .returns .type a {
|
||||
font-size: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* -- Class Constructor block ----------------------------------------------- */
|
||||
.apidocs .constructor .item {
|
||||
border: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
/* -- File Source View ------------------------------------------------------ */
|
||||
.apidocs .file pre.code,
|
||||
#doc .apidocs .file pre.prettyprint {
|
||||
background: inherit;
|
||||
border: none;
|
||||
overflow: visible;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.apidocs .L0,
|
||||
.apidocs .L1,
|
||||
.apidocs .L2,
|
||||
.apidocs .L3,
|
||||
.apidocs .L4,
|
||||
.apidocs .L5,
|
||||
.apidocs .L6,
|
||||
.apidocs .L7,
|
||||
.apidocs .L8,
|
||||
.apidocs .L9 {
|
||||
background: inherit;
|
||||
}
|
||||
|
||||
/* -- Submodule List -------------------------------------------------------- */
|
||||
.apidocs .module-submodule-description {
|
||||
font-size: 12px;
|
||||
margin: 0.3em 0 1em;
|
||||
}
|
||||
|
||||
.apidocs .module-submodule-description p:first-child { margin-top: 0; }
|
||||
|
||||
/* -- Sidebar TabView ------------------------------------------------------- */
|
||||
#api-tabview { margin-top: 0.6em; }
|
||||
|
||||
#api-tabview-filter,
|
||||
#api-tabview-panel {
|
||||
border: 1px solid #dfdfdf;
|
||||
}
|
||||
|
||||
#api-tabview-filter {
|
||||
border-bottom: none;
|
||||
border-top: none;
|
||||
padding: 0.6em 10px 0 10px;
|
||||
}
|
||||
|
||||
#api-tabview-panel { border-top: none; }
|
||||
#api-filter { width: 97%; }
|
||||
|
||||
/* -- Content TabView ------------------------------------------------------- */
|
||||
#classdocs .yui3-tabview-panel { border: none; }
|
||||
|
||||
/* -- Source File Contents -------------------------------------------------- */
|
||||
.prettyprint li.L0,
|
||||
.prettyprint li.L1,
|
||||
.prettyprint li.L2,
|
||||
.prettyprint li.L3,
|
||||
.prettyprint li.L5,
|
||||
.prettyprint li.L6,
|
||||
.prettyprint li.L7,
|
||||
.prettyprint li.L8 {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
/* -- API options ----------------------------------------------------------- */
|
||||
#api-options {
|
||||
font-size: 11px;
|
||||
margin-top: 2.2em;
|
||||
position: absolute;
|
||||
right: 1.5em;
|
||||
}
|
||||
|
||||
/*#api-options label { margin-right: 0.6em; }*/
|
||||
|
||||
/* -- API list -------------------------------------------------------------- */
|
||||
#api-list {
|
||||
margin-top: 1.5em;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.apis {
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0.5em 0 0.5em 0.4em;
|
||||
}
|
||||
|
||||
.apis a {
|
||||
border: 1px solid transparent;
|
||||
display: block;
|
||||
margin: 0 0 0 -4px;
|
||||
padding: 1px 4px 0;
|
||||
text-decoration: none;
|
||||
_border: none;
|
||||
_display: inline;
|
||||
}
|
||||
|
||||
.apis a:hover,
|
||||
.apis a:focus {
|
||||
background: #E8EDFC;
|
||||
background: -moz-linear-gradient(top, #e8edfc 0%, #becef7 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#E8EDFC), color-stop(100%,#BECEF7));
|
||||
border-color: #AAC0FA;
|
||||
border-radius: 3px;
|
||||
color: #333;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.api-list-item a:hover,
|
||||
.api-list-item a:focus {
|
||||
font-weight: bold;
|
||||
text-shadow: 1px 1px 1px #fff;
|
||||
}
|
||||
|
||||
.apis .message { color: #888; }
|
||||
.apis .result a { padding: 3px 5px 2px; }
|
||||
|
||||
.apis .result .type {
|
||||
right: 4px;
|
||||
top: 7px;
|
||||
}
|
||||
|
||||
.api-list-item .yui3-highlight {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
@@ -1,10 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Redirector</title>
|
||||
<meta http-equiv="refresh" content="0;url=../">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../">Click here to redirect</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,56 +0,0 @@
|
||||
YUI.add('api-filter', function (Y) {
|
||||
|
||||
Y.APIFilter = Y.Base.create('apiFilter', Y.Base, [Y.AutoCompleteBase], {
|
||||
// -- Initializer ----------------------------------------------------------
|
||||
initializer: function () {
|
||||
this._bindUIACBase();
|
||||
this._syncUIACBase();
|
||||
},
|
||||
getDisplayName: function(name) {
|
||||
|
||||
Y.each(Y.YUIDoc.meta.allModules, function(i) {
|
||||
if (i.name === name && i.displayName) {
|
||||
name = i.displayName;
|
||||
}
|
||||
});
|
||||
|
||||
if (this.get('queryType') === 'elements') {
|
||||
name = '<' + name + '>';
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
}, {
|
||||
// -- Attributes -----------------------------------------------------------
|
||||
ATTRS: {
|
||||
resultHighlighter: {
|
||||
value: 'phraseMatch'
|
||||
},
|
||||
|
||||
// May be set to "classes", "elements" or "modules".
|
||||
queryType: {
|
||||
value: 'classes'
|
||||
},
|
||||
|
||||
source: {
|
||||
valueFn: function() {
|
||||
var self = this;
|
||||
return function(q) {
|
||||
var data = Y.YUIDoc.meta[self.get('queryType')],
|
||||
out = [];
|
||||
Y.each(data, function(v) {
|
||||
if (v.toLowerCase().indexOf(q.toLowerCase()) > -1) {
|
||||
out.push(v);
|
||||
}
|
||||
});
|
||||
return out;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}, '3.4.0', {requires: [
|
||||
'autocomplete-base', 'autocomplete-highlighters', 'autocomplete-sources'
|
||||
]});
|
||||
@@ -1,255 +0,0 @@
|
||||
YUI.add('api-list', function (Y) {
|
||||
|
||||
var Lang = Y.Lang,
|
||||
YArray = Y.Array,
|
||||
|
||||
APIList = Y.namespace('APIList'),
|
||||
|
||||
classesNode = Y.one('#api-classes'),
|
||||
elementsNode = Y.one('#api-elements'),
|
||||
inputNode = Y.one('#api-filter'),
|
||||
modulesNode = Y.one('#api-modules'),
|
||||
tabviewNode = Y.one('#api-tabview'),
|
||||
|
||||
tabs = APIList.tabs = {},
|
||||
|
||||
filter = APIList.filter = new Y.APIFilter({
|
||||
inputNode : inputNode,
|
||||
maxResults: 1000,
|
||||
|
||||
on: {
|
||||
results: onFilterResults
|
||||
}
|
||||
}),
|
||||
|
||||
search = APIList.search = new Y.APISearch({
|
||||
inputNode : inputNode,
|
||||
maxResults: 100,
|
||||
|
||||
on: {
|
||||
clear : onSearchClear,
|
||||
results: onSearchResults
|
||||
}
|
||||
}),
|
||||
|
||||
tabview = APIList.tabview = new Y.TabView({
|
||||
srcNode : tabviewNode,
|
||||
panelNode: '#api-tabview-panel',
|
||||
render : true,
|
||||
|
||||
on: {
|
||||
selectionChange: onTabSelectionChange
|
||||
}
|
||||
}),
|
||||
|
||||
focusManager = APIList.focusManager = tabviewNode.plug(Y.Plugin.NodeFocusManager, {
|
||||
circular : true,
|
||||
descendants: '#api-filter, .yui3-tab-panel-selected .api-list-item a, .yui3-tab-panel-selected .result a',
|
||||
keys : {next: 'down:40', previous: 'down:38'}
|
||||
}).focusManager,
|
||||
|
||||
LIST_ITEM_TEMPLATE =
|
||||
'<li class="api-list-item {typeSingular}">' +
|
||||
'<a href="{rootPath}{typePlural}/{name}.html">{displayName}</a>' +
|
||||
'</li>';
|
||||
|
||||
// -- Init ---------------------------------------------------------------------
|
||||
|
||||
// Duckpunch FocusManager's key event handling to prevent it from handling key
|
||||
// events when a modifier is pressed.
|
||||
Y.before(function (e, activeDescendant) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
|
||||
return new Y.Do.Prevent();
|
||||
}
|
||||
}, focusManager, '_focusPrevious', focusManager);
|
||||
|
||||
Y.before(function (e, activeDescendant) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
|
||||
return new Y.Do.Prevent();
|
||||
}
|
||||
}, focusManager, '_focusNext', focusManager);
|
||||
|
||||
// Create a mapping of tabs in the tabview so we can refer to them easily later.
|
||||
tabview.each(function (tab, index) {
|
||||
var name = tab.get('label').toLowerCase();
|
||||
|
||||
tabs[name] = {
|
||||
index: index,
|
||||
name : name,
|
||||
tab : tab
|
||||
};
|
||||
});
|
||||
|
||||
// Switch tabs on Ctrl/Cmd-Left/Right arrows.
|
||||
tabviewNode.on('key', onTabSwitchKey, 'down:37,39');
|
||||
|
||||
// Focus the filter input when the `/` key is pressed.
|
||||
Y.one(Y.config.doc).on('key', onSearchKey, 'down:83');
|
||||
|
||||
// Keep the Focus Manager up to date.
|
||||
inputNode.on('focus', function () {
|
||||
focusManager.set('activeDescendant', inputNode);
|
||||
});
|
||||
|
||||
// Update all tabview links to resolved URLs.
|
||||
tabview.get('panelNode').all('a').each(function (link) {
|
||||
link.setAttribute('href', link.get('href'));
|
||||
});
|
||||
|
||||
// -- Private Functions --------------------------------------------------------
|
||||
function getFilterResultNode() {
|
||||
var queryType = filter.get('queryType');
|
||||
return queryType === 'classes' ? classesNode
|
||||
: queryType === 'elements' ? elementsNode : modulesNode;
|
||||
}
|
||||
|
||||
// -- Event Handlers -----------------------------------------------------------
|
||||
function onFilterResults(e) {
|
||||
var frag = Y.one(Y.config.doc.createDocumentFragment()),
|
||||
resultNode = getFilterResultNode(),
|
||||
typePlural = filter.get('queryType'),
|
||||
typeSingular = typePlural === 'classes' ? 'class' : typePlural === 'elements' ? 'element' : 'module';
|
||||
|
||||
if (e.results.length) {
|
||||
YArray.each(e.results, function (result) {
|
||||
frag.append(Lang.sub(LIST_ITEM_TEMPLATE, {
|
||||
rootPath : APIList.rootPath,
|
||||
displayName : filter.getDisplayName(result.highlighted),
|
||||
name : result.text,
|
||||
typePlural : typePlural,
|
||||
typeSingular: typeSingular
|
||||
}));
|
||||
});
|
||||
} else {
|
||||
frag.append(
|
||||
'<li class="message">' +
|
||||
'No ' + typePlural + ' found.' +
|
||||
'</li>'
|
||||
);
|
||||
}
|
||||
|
||||
resultNode.empty(true);
|
||||
resultNode.append(frag);
|
||||
|
||||
focusManager.refresh();
|
||||
}
|
||||
|
||||
function onSearchClear(e) {
|
||||
|
||||
focusManager.refresh();
|
||||
}
|
||||
|
||||
function onSearchKey(e) {
|
||||
var target = e.target;
|
||||
|
||||
if (target.test('input,select,textarea')
|
||||
|| target.get('isContentEditable')) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
inputNode.focus();
|
||||
focusManager.refresh();
|
||||
}
|
||||
|
||||
function onSearchResults(e) {
|
||||
var frag = Y.one(Y.config.doc.createDocumentFragment());
|
||||
|
||||
if (e.results.length) {
|
||||
YArray.each(e.results, function (result) {
|
||||
frag.append(result.display);
|
||||
});
|
||||
} else {
|
||||
frag.append(
|
||||
'<li class="message">' +
|
||||
'No results found. Maybe you\'ll have better luck with a ' +
|
||||
'different query?' +
|
||||
'</li>'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
focusManager.refresh();
|
||||
}
|
||||
|
||||
function onTabSelectionChange(e) {
|
||||
var tab = e.newVal,
|
||||
name = tab.get('label').toLowerCase();
|
||||
|
||||
tabs.selected = {
|
||||
index: tab.get('index'),
|
||||
name : name,
|
||||
tab : tab
|
||||
};
|
||||
|
||||
switch (name) {
|
||||
case 'elements':// fallthru
|
||||
case 'classes': // fallthru
|
||||
case 'modules':
|
||||
filter.setAttrs({
|
||||
minQueryLength: 0,
|
||||
queryType : name
|
||||
});
|
||||
|
||||
search.set('minQueryLength', -1);
|
||||
|
||||
// Only send a request if this isn't the initially-selected tab.
|
||||
if (e.prevVal) {
|
||||
filter.sendRequest(filter.get('value'));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'everything':
|
||||
filter.set('minQueryLength', -1);
|
||||
search.set('minQueryLength', 1);
|
||||
|
||||
if (search.get('value')) {
|
||||
search.sendRequest(search.get('value'));
|
||||
} else {
|
||||
inputNode.focus();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// WTF? We shouldn't be here!
|
||||
filter.set('minQueryLength', -1);
|
||||
search.set('minQueryLength', -1);
|
||||
}
|
||||
|
||||
if (focusManager) {
|
||||
setTimeout(function () {
|
||||
focusManager.refresh();
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function onTabSwitchKey(e) {
|
||||
var currentTabIndex = tabs.selected.index;
|
||||
|
||||
if (!(e.ctrlKey || e.metaKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
switch (e.keyCode) {
|
||||
case 37: // left arrow
|
||||
if (currentTabIndex > 0) {
|
||||
tabview.selectChild(currentTabIndex - 1);
|
||||
inputNode.focus();
|
||||
}
|
||||
break;
|
||||
|
||||
case 39: // right arrow
|
||||
if (currentTabIndex < (Y.Object.size(tabs) - 2)) {
|
||||
tabview.selectChild(currentTabIndex + 1);
|
||||
inputNode.focus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}, '3.4.0', {requires: [
|
||||
'api-filter', 'api-search', 'event-key', 'node-focusmanager', 'tabview'
|
||||
]});
|
||||
@@ -1,98 +0,0 @@
|
||||
YUI.add('api-search', function (Y) {
|
||||
|
||||
var Lang = Y.Lang,
|
||||
Node = Y.Node,
|
||||
YArray = Y.Array;
|
||||
|
||||
Y.APISearch = Y.Base.create('apiSearch', Y.Base, [Y.AutoCompleteBase], {
|
||||
// -- Public Properties ----------------------------------------------------
|
||||
RESULT_TEMPLATE:
|
||||
'<li class="result {resultType}">' +
|
||||
'<a href="{url}">' +
|
||||
'<h3 class="title">{name}</h3>' +
|
||||
'<span class="type">{resultType}</span>' +
|
||||
'<div class="description">{description}</div>' +
|
||||
'<span class="className">{class}</span>' +
|
||||
'</a>' +
|
||||
'</li>',
|
||||
|
||||
// -- Initializer ----------------------------------------------------------
|
||||
initializer: function () {
|
||||
this._bindUIACBase();
|
||||
this._syncUIACBase();
|
||||
},
|
||||
|
||||
// -- Protected Methods ----------------------------------------------------
|
||||
_apiResultFilter: function (query, results) {
|
||||
// Filter components out of the results.
|
||||
return YArray.filter(results, function (result) {
|
||||
return result.raw.resultType === 'component' ? false : result;
|
||||
});
|
||||
},
|
||||
|
||||
_apiResultFormatter: function (query, results) {
|
||||
return YArray.map(results, function (result) {
|
||||
var raw = Y.merge(result.raw), // create a copy
|
||||
desc = raw.description || '';
|
||||
|
||||
// Convert description to text and truncate it if necessary.
|
||||
desc = Node.create('<div>' + desc + '</div>').get('text');
|
||||
|
||||
if (desc.length > 65) {
|
||||
desc = Y.Escape.html(desc.substr(0, 65)) + ' …';
|
||||
} else {
|
||||
desc = Y.Escape.html(desc);
|
||||
}
|
||||
|
||||
raw['class'] || (raw['class'] = '');
|
||||
raw.description = desc;
|
||||
|
||||
// Use the highlighted result name.
|
||||
raw.name = result.highlighted;
|
||||
|
||||
return Lang.sub(this.RESULT_TEMPLATE, raw);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_apiTextLocator: function (result) {
|
||||
return result.displayName || result.name;
|
||||
}
|
||||
}, {
|
||||
// -- Attributes -----------------------------------------------------------
|
||||
ATTRS: {
|
||||
resultFormatter: {
|
||||
valueFn: function () {
|
||||
return this._apiResultFormatter;
|
||||
}
|
||||
},
|
||||
|
||||
resultFilters: {
|
||||
valueFn: function () {
|
||||
return this._apiResultFilter;
|
||||
}
|
||||
},
|
||||
|
||||
resultHighlighter: {
|
||||
value: 'phraseMatch'
|
||||
},
|
||||
|
||||
resultListLocator: {
|
||||
value: 'data.results'
|
||||
},
|
||||
|
||||
resultTextLocator: {
|
||||
valueFn: function () {
|
||||
return this._apiTextLocator;
|
||||
}
|
||||
},
|
||||
|
||||
source: {
|
||||
value: '/api/v1/search?q={query}&count={maxResults}'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}, '3.4.0', {requires: [
|
||||
'autocomplete-base', 'autocomplete-highlighters', 'autocomplete-sources',
|
||||
'escape'
|
||||
]});
|
||||
@@ -1,376 +0,0 @@
|
||||
YUI().use(
|
||||
'yuidoc-meta',
|
||||
'api-list', 'history-hash', 'node-screen', 'node-style', 'pjax',
|
||||
function (Y) {
|
||||
|
||||
var win = Y.config.win,
|
||||
localStorage = win.localStorage,
|
||||
|
||||
bdNode = Y.one('#bd'),
|
||||
|
||||
pjax,
|
||||
defaultRoute,
|
||||
|
||||
classTabView,
|
||||
selectedTab;
|
||||
|
||||
// Kill pjax functionality unless serving over HTTP.
|
||||
if (!Y.getLocation().protocol.match(/^https?\:/)) {
|
||||
Y.Router.html5 = false;
|
||||
}
|
||||
|
||||
// Create the default route with middleware which enables syntax highlighting
|
||||
// on the loaded content.
|
||||
defaultRoute = Y.Pjax.defaultRoute.concat(function (req, res, next) {
|
||||
prettyPrint();
|
||||
bdNode.removeClass('loading');
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
pjax = new Y.Pjax({
|
||||
container : '#docs-main',
|
||||
contentSelector: '#docs-main > .content',
|
||||
linkSelector : '#bd a',
|
||||
titleSelector : '#xhr-title',
|
||||
|
||||
navigateOnHash: true,
|
||||
root : '/',
|
||||
routes : [
|
||||
// -- / ----------------------------------------------------------------
|
||||
{
|
||||
path : '/(index.html)?',
|
||||
callbacks: defaultRoute
|
||||
},
|
||||
|
||||
// -- /elements/* -------------------------------------------------------
|
||||
{
|
||||
path : '/elements/:element.html*',
|
||||
callbacks: defaultRoute
|
||||
},
|
||||
|
||||
// -- /classes/* -------------------------------------------------------
|
||||
{
|
||||
path : '/classes/:class.html*',
|
||||
callbacks: [defaultRoute, 'handleClasses']
|
||||
},
|
||||
|
||||
// -- /files/* ---------------------------------------------------------
|
||||
{
|
||||
path : '/files/*file',
|
||||
callbacks: [defaultRoute, 'handleFiles']
|
||||
},
|
||||
|
||||
// -- /modules/* -------------------------------------------------------
|
||||
{
|
||||
path : '/modules/:module.html*',
|
||||
callbacks: defaultRoute
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// -- Utility Functions --------------------------------------------------------
|
||||
|
||||
pjax.checkVisibility = function (tab) {
|
||||
tab || (tab = selectedTab);
|
||||
|
||||
if (!tab) { return; }
|
||||
|
||||
var panelNode = tab.get('panelNode'),
|
||||
visibleItems;
|
||||
|
||||
// If no items are visible in the tab panel due to the current visibility
|
||||
// settings, display a message to that effect.
|
||||
visibleItems = panelNode.all('.item,.index-item').some(function (itemNode) {
|
||||
if (itemNode.getComputedStyle('display') !== 'none') {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
panelNode.all('.no-visible-items').remove();
|
||||
|
||||
if (!visibleItems) {
|
||||
if (Y.one('#index .index-item')) {
|
||||
panelNode.append(
|
||||
'<div class="no-visible-items">' +
|
||||
'<p>' +
|
||||
'Some items are not shown due to the current visibility ' +
|
||||
'settings. Use the checkboxes at the upper right of this ' +
|
||||
'page to change the visibility settings.' +
|
||||
'</p>' +
|
||||
'</div>'
|
||||
);
|
||||
} else {
|
||||
panelNode.append(
|
||||
'<div class="no-visible-items">' +
|
||||
'<p>' +
|
||||
'This class doesn\'t provide any methods, properties, ' +
|
||||
'attributes, or events.' +
|
||||
'</p>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Hide index sections without any visible items.
|
||||
Y.all('.index-section').each(function (section) {
|
||||
var items = 0,
|
||||
visibleItems = 0;
|
||||
|
||||
section.all('.index-item').each(function (itemNode) {
|
||||
items += 1;
|
||||
|
||||
if (itemNode.getComputedStyle('display') !== 'none') {
|
||||
visibleItems += 1;
|
||||
}
|
||||
});
|
||||
|
||||
section.toggleClass('hidden', !visibleItems);
|
||||
section.toggleClass('no-columns', visibleItems < 4);
|
||||
});
|
||||
};
|
||||
|
||||
pjax.initClassTabView = function () {
|
||||
if (!Y.all('#classdocs .api-class-tab').size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (classTabView) {
|
||||
classTabView.destroy();
|
||||
selectedTab = null;
|
||||
}
|
||||
|
||||
classTabView = new Y.TabView({
|
||||
srcNode: '#classdocs',
|
||||
|
||||
on: {
|
||||
selectionChange: pjax.onTabSelectionChange
|
||||
}
|
||||
});
|
||||
|
||||
pjax.updateTabState();
|
||||
classTabView.render();
|
||||
};
|
||||
|
||||
pjax.initLineNumbers = function () {
|
||||
var hash = win.location.hash.substring(1),
|
||||
container = pjax.get('container'),
|
||||
hasLines, node;
|
||||
|
||||
// Add ids for each line number in the file source view.
|
||||
container.all('.linenums>li').each(function (lineNode, index) {
|
||||
lineNode.set('id', 'l' + (index + 1));
|
||||
lineNode.addClass('file-line');
|
||||
hasLines = true;
|
||||
});
|
||||
|
||||
// Scroll to the desired line.
|
||||
if (hasLines && /^l\d+$/.test(hash)) {
|
||||
if ((node = container.getById(hash))) {
|
||||
win.scroll(0, node.getY());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pjax.initRoot = function () {
|
||||
var terminators = /^(?:classes|files|elements|modules)$/,
|
||||
parts = pjax._getPathRoot().split('/'),
|
||||
root = [],
|
||||
i, len, part;
|
||||
|
||||
for (i = 0, len = parts.length; i < len; i += 1) {
|
||||
part = parts[i];
|
||||
|
||||
if (part.match(terminators)) {
|
||||
// Makes sure the path will end with a "/".
|
||||
root.push('');
|
||||
break;
|
||||
}
|
||||
|
||||
root.push(part);
|
||||
}
|
||||
|
||||
pjax.set('root', root.join('/'));
|
||||
};
|
||||
|
||||
pjax.updateTabState = function (src) {
|
||||
var hash = win.location.hash.substring(1),
|
||||
defaultTab, node, tab, tabPanel;
|
||||
|
||||
function scrollToNode() {
|
||||
if (node.hasClass('protected')) {
|
||||
Y.one('#api-show-protected').set('checked', true);
|
||||
pjax.updateVisibility();
|
||||
}
|
||||
|
||||
if (node.hasClass('private')) {
|
||||
Y.one('#api-show-private').set('checked', true);
|
||||
pjax.updateVisibility();
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
// For some reason, unless we re-get the node instance here,
|
||||
// getY() always returns 0.
|
||||
var node = Y.one('#classdocs').getById(hash);
|
||||
win.scrollTo(0, node.getY() - 70);
|
||||
}, 1);
|
||||
}
|
||||
|
||||
if (!classTabView) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (src === 'hashchange' && !hash) {
|
||||
defaultTab = 'index';
|
||||
} else {
|
||||
if (localStorage) {
|
||||
defaultTab = localStorage.getItem('tab_' + pjax.getPath()) ||
|
||||
'index';
|
||||
} else {
|
||||
defaultTab = 'index';
|
||||
}
|
||||
}
|
||||
|
||||
if (hash && (node = Y.one('#classdocs').getById(hash))) {
|
||||
if ((tabPanel = node.ancestor('.api-class-tabpanel', true))) {
|
||||
if ((tab = Y.one('#classdocs .api-class-tab.' + tabPanel.get('id')))) {
|
||||
if (classTabView.get('rendered')) {
|
||||
Y.Widget.getByNode(tab).set('selected', 1);
|
||||
} else {
|
||||
tab.addClass('yui3-tab-selected');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll to the desired element if this is a hash URL.
|
||||
if (node) {
|
||||
if (classTabView.get('rendered')) {
|
||||
scrollToNode();
|
||||
} else {
|
||||
classTabView.once('renderedChange', scrollToNode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tab = Y.one('#classdocs .api-class-tab.' + defaultTab);
|
||||
|
||||
// When the `defaultTab` node isn't found, `localStorage` is stale.
|
||||
if (!tab && defaultTab !== 'index') {
|
||||
tab = Y.one('#classdocs .api-class-tab.index');
|
||||
}
|
||||
|
||||
if (classTabView.get('rendered')) {
|
||||
Y.Widget.getByNode(tab).set('selected', 1);
|
||||
} else {
|
||||
tab.addClass('yui3-tab-selected');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pjax.updateVisibility = function () {
|
||||
var container = pjax.get('container');
|
||||
|
||||
container.toggleClass('hide-inherited',
|
||||
!Y.one('#api-show-inherited').get('checked'));
|
||||
|
||||
container.toggleClass('show-deprecated',
|
||||
Y.one('#api-show-deprecated').get('checked'));
|
||||
|
||||
container.toggleClass('show-protected',
|
||||
Y.one('#api-show-protected').get('checked'));
|
||||
|
||||
container.toggleClass('show-private',
|
||||
Y.one('#api-show-private').get('checked'));
|
||||
|
||||
pjax.checkVisibility();
|
||||
};
|
||||
|
||||
// -- Route Handlers -----------------------------------------------------------
|
||||
|
||||
pjax.handleClasses = function (req, res, next) {
|
||||
var status = res.ioResponse.status;
|
||||
|
||||
// Handles success and local filesystem XHRs.
|
||||
if (res.ioResponse.readyState === 4 && (!status || (status >= 200 && status < 300))) {
|
||||
pjax.initClassTabView();
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
pjax.handleFiles = function (req, res, next) {
|
||||
var status = res.ioResponse.status;
|
||||
|
||||
// Handles success and local filesystem XHRs.
|
||||
if (res.ioResponse.readyState === 4 && (!status || (status >= 200 && status < 300))) {
|
||||
pjax.initLineNumbers();
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
|
||||
// -- Event Handlers -----------------------------------------------------------
|
||||
|
||||
pjax.onNavigate = function (e) {
|
||||
var hash = e.hash,
|
||||
originTarget = e.originEvent && e.originEvent.target,
|
||||
tab;
|
||||
|
||||
if (hash) {
|
||||
tab = originTarget && originTarget.ancestor('.yui3-tab', true);
|
||||
|
||||
if (hash === win.location.hash) {
|
||||
pjax.updateTabState('hashchange');
|
||||
} else if (!tab) {
|
||||
win.location.hash = hash;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
// Only scroll to the top of the page when the URL doesn't have a hash.
|
||||
this.set('scrollToTop', !e.url.match(/#.+$/));
|
||||
|
||||
bdNode.addClass('loading');
|
||||
};
|
||||
|
||||
pjax.onOptionClick = function (e) {
|
||||
pjax.updateVisibility();
|
||||
};
|
||||
|
||||
pjax.onTabSelectionChange = function (e) {
|
||||
var tab = e.newVal,
|
||||
tabId = tab.get('contentBox').getAttribute('href').substring(1);
|
||||
|
||||
selectedTab = tab;
|
||||
|
||||
// If switching from a previous tab (i.e., this is not the default tab),
|
||||
// replace the history entry with a hash URL that will cause this tab to
|
||||
// be selected if the user navigates away and then returns using the back
|
||||
// or forward buttons.
|
||||
if (e.prevVal && localStorage) {
|
||||
localStorage.setItem('tab_' + pjax.getPath(), tabId);
|
||||
}
|
||||
|
||||
pjax.checkVisibility(tab);
|
||||
};
|
||||
|
||||
// -- Init ---------------------------------------------------------------------
|
||||
|
||||
pjax.on('navigate', pjax.onNavigate);
|
||||
|
||||
pjax.initRoot();
|
||||
pjax.upgrade();
|
||||
pjax.initClassTabView();
|
||||
pjax.initLineNumbers();
|
||||
pjax.updateVisibility();
|
||||
|
||||
Y.APIList.rootPath = pjax.get('root');
|
||||
|
||||
Y.one('#api-options').delegate('click', pjax.onOptionClick, 'input');
|
||||
|
||||
Y.on('hashchange', function (e) {
|
||||
pjax.updateTabState('hashchange');
|
||||
}, win);
|
||||
|
||||
});
|
||||
17
doc/assets/js/yui-prettify.js
vendored
@@ -1,17 +0,0 @@
|
||||
YUI().use('node', function(Y) {
|
||||
var code = Y.all('.prettyprint.linenums');
|
||||
if (code.size()) {
|
||||
code.each(function(c) {
|
||||
var lis = c.all('ol li'),
|
||||
l = 1;
|
||||
lis.each(function(n) {
|
||||
n.prepend('<a name="LINENUM_' + l + '"></a>');
|
||||
l++;
|
||||
});
|
||||
});
|
||||
var h = location.hash;
|
||||
location.hash = '';
|
||||
h = h.replace('LINE_', 'LINENUM_');
|
||||
location.hash = h;
|
||||
}
|
||||
});
|
||||
130
doc/assets/vendor/prettify/CHANGES.html
vendored
@@ -1,130 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Change Log</title>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<a style="float:right" href="README.html">README</a>
|
||||
|
||||
<h1>Known Issues</h1>
|
||||
<ul>
|
||||
<li>Perl formatting is really crappy. Partly because the author is lazy and
|
||||
partly because Perl is
|
||||
<a href="http://www.perlmonks.org/?node_id=663393">hard</a> to parse.
|
||||
<li>On some browsers, <code><code></code> elements with newlines in the text
|
||||
which use CSS to specify <code>white-space:pre</code> will have the newlines
|
||||
improperly stripped if the element is not attached to the document at the time
|
||||
the stripping is done. Also, on IE 6, all newlines will be stripped from
|
||||
<code><code></code> elements because of the way IE6 produces
|
||||
<code>innerHTML</code>. Workaround: use <code><pre></code> for code with
|
||||
newlines.
|
||||
</ul>
|
||||
|
||||
<h1>Change Log</h1>
|
||||
<h2>29 March 2007</h2>
|
||||
<ul>
|
||||
<li>Added <a href="tests/prettify_test.html#PHP">tests</a> for PHP support
|
||||
to address
|
||||
<a href="http://code.google.com/p/google-code-prettify/issues/detail?id=3"
|
||||
>issue 3</a>.
|
||||
<li>Fixed
|
||||
<a href="http://code.google.com/p/google-code-prettify/issues/detail?id=6"
|
||||
>bug</a>: <code>prettyPrintOne</code> was not halting. This was not
|
||||
reachable through the normal entry point.
|
||||
<li>Fixed
|
||||
<a href="http://code.google.com/p/google-code-prettify/issues/detail?id=4"
|
||||
>bug</a>: recursing into a script block or PHP tag that was not properly
|
||||
closed would not silently drop the content.
|
||||
(<a href="tests/prettify_test.html#issue4">test</a>)
|
||||
<li>Fixed
|
||||
<a href="http://code.google.com/p/google-code-prettify/issues/detail?id=8"
|
||||
>bug</a>: was eating tabs
|
||||
(<a href="tests/prettify_test.html#issue8">test</a>)
|
||||
<li>Fixed entity handling so that the caveat
|
||||
<blockquote>
|
||||
<p>Caveats: please properly escape less-thans. <tt>x&lt;y</tt>
|
||||
instead of <tt>x<y</tt>, and use <tt>"</tt> instead of
|
||||
<tt>&quot;</tt> for string delimiters.</p>
|
||||
</blockquote>
|
||||
is no longer applicable.
|
||||
<li>Added noisefree's C#
|
||||
<a href="http://code.google.com/p/google-code-prettify/issues/detail?id=4"
|
||||
>patch</a>
|
||||
<li>Added a <a href="http://google-code-prettify.googlecode.com/files/prettify-small.zip">distribution</a> that has comments and
|
||||
whitespace removed to reduce download size from 45.5kB to 12.8kB.
|
||||
</ul>
|
||||
<h2>4 Jul 2008</h2>
|
||||
<ul>
|
||||
<li>Added <a href="http://code.google.com/p/google-code-prettify/issues/detail?id=17">language specific formatters</a> that are triggered by the presence
|
||||
of a <code>lang-<language-file-extension></code></li>
|
||||
<li>Fixed <a href="http://code.google.com/p/google-code-prettify/issues/detail?id=29">bug</a>: python handling of <code>'''string'''</code>
|
||||
<li>Fixed bug: <code>/</code> in regex <code>[charsets] should not end regex</code>
|
||||
</ul>
|
||||
<h2>5 Jul 2008</h2>
|
||||
<ul>
|
||||
<li>Defined language extensions for Lisp and Lua</code>
|
||||
</ul>
|
||||
<h2>14 Jul 2008</h2>
|
||||
<ul>
|
||||
<li>Language handlers for F#, OCAML, SQL</code>
|
||||
<li>Support for <code>nocode</code> spans to allow embedding of line
|
||||
numbers and code annotations which should not be styled or otherwise
|
||||
affect the tokenization of prettified code.
|
||||
See the issue 22
|
||||
<a href="tests/prettify_test.html#issue22">testcase</a>.</code>
|
||||
</ul>
|
||||
<h2>6 Jan 2009</h2>
|
||||
<ul>
|
||||
<li>Language handlers for Visual Basic, Haskell, CSS, and WikiText</li>
|
||||
<li>Added <tt>.mxml</tt> extension to the markup style handler for
|
||||
Flex <a href="http://en.wikipedia.org/wiki/MXML">MXML files</a>. See
|
||||
<a
|
||||
href="http://code.google.com/p/google-code-prettify/issues/detail?id=37"
|
||||
>issue 37</a>.
|
||||
<li>Added <tt>.m</tt> extension to the C style handler so that Objective
|
||||
C source files properly highlight. See
|
||||
<a
|
||||
href="http://code.google.com/p/google-code-prettify/issues/detail?id=58"
|
||||
>issue 58</a>.
|
||||
<li>Changed HTML lexer to use the same embedded source mechanism as the
|
||||
wiki language handler, and changed to use the registered
|
||||
CSS handler for STYLE element content.
|
||||
</ul>
|
||||
<h2>21 May 2009</h2>
|
||||
<ul>
|
||||
<li>Rewrote to improve performance on large files.
|
||||
See <a href="http://mikesamuel.blogspot.com/2009/05/efficient-parsing-in-javascript.html">benchmarks</a>.</li>
|
||||
<li>Fixed bugs with highlighting of Haskell line comments, Lisp
|
||||
number literals, Lua strings, C preprocessor directives,
|
||||
newlines in Wiki code on Windows, and newlines in IE6.</li>
|
||||
</ul>
|
||||
<h2>14 August 2009</h2>
|
||||
<ul>
|
||||
<li>Fixed prettifying of <code><code></code> blocks with embedded newlines.
|
||||
</ul>
|
||||
<h2>3 October 2009</h2>
|
||||
<ul>
|
||||
<li>Fixed prettifying of XML/HTML tags that contain uppercase letters.
|
||||
</ul>
|
||||
<h2>19 July 2010</h2>
|
||||
<ul>
|
||||
<li>Added support for line numbers. Bug
|
||||
<a href="http://code.google.com/p/google-code-prettify/issues/detail?id=22"
|
||||
>22</a></li>
|
||||
<li>Added YAML support. Bug
|
||||
<a href="http://code.google.com/p/google-code-prettify/issues/detail?id=123"
|
||||
>123</a></li>
|
||||
<li>Added VHDL support courtesy Le Poussin.</li>
|
||||
<li>IE performance improvements. Bug
|
||||
<a href="http://code.google.com/p/google-code-prettify/issues/detail?id=102"
|
||||
>102</a> courtesy jacobly.</li>
|
||||
<li>A variety of markup formatting fixes courtesy smain and thezbyg.</li>
|
||||
<li>Fixed copy and paste in IE[678].
|
||||
<li>Changed output to use <code>&#160;</code> instead of
|
||||
<code>&nbsp;</code> so that the output works when embedded in XML.
|
||||
Bug
|
||||
<a href="http://code.google.com/p/google-code-prettify/issues/detail?id=108"
|
||||
>108</a>.</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
202
doc/assets/vendor/prettify/COPYING
vendored
@@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
203
doc/assets/vendor/prettify/README.html
vendored
@@ -1,203 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Javascript code prettifier</title>
|
||||
|
||||
<link href="src/prettify.css" type="text/css" rel="stylesheet" />
|
||||
|
||||
<script src="src/prettify.js" type="text/javascript"></script>
|
||||
|
||||
<style type="text/css">
|
||||
body { margin-left: .5in }
|
||||
h1, h2, h3, h4, .footer { margin-left: -.4in; }
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body onload="prettyPrint()" bgcolor="white">
|
||||
<small style="float: right">Languages : <a href="README-zh-Hans.html">CH</a></small>
|
||||
<h1>Javascript code prettifier</h1>
|
||||
|
||||
<h2>Setup</h2>
|
||||
<ol>
|
||||
<li><a href="http://code.google.com/p/google-code-prettify/downloads/list">Download</a> a distribution
|
||||
<li>Include the script and stylesheets in your document
|
||||
(you will need to make sure the css and js file are on your server, and
|
||||
adjust the paths in the <tt>script</tt> and <tt>link</tt> tag)
|
||||
<pre class="prettyprint">
|
||||
<link href="prettify.css" type="text/css" rel="stylesheet" />
|
||||
<script type="text/javascript" src="prettify.js"></script></pre>
|
||||
<li>Add <code class="prettyprint lang-html">onload="prettyPrint()"</code> to your
|
||||
document's body tag.
|
||||
<li>Modify the stylesheet to get the coloring you prefer</li>
|
||||
</ol>
|
||||
|
||||
<h2>Usage</h2>
|
||||
<p>Put code snippets in
|
||||
<tt><pre class="prettyprint">...</pre></tt>
|
||||
or <tt><code class="prettyprint">...</code></tt>
|
||||
and it will automatically be pretty printed.
|
||||
|
||||
<table summary="code examples">
|
||||
<tr>
|
||||
<th>The original
|
||||
<th>Prettier
|
||||
<tr>
|
||||
<td><pre style="border: 1px solid #888;padding: 2px"
|
||||
><a name="voila1"></a>class Voila {
|
||||
public:
|
||||
// Voila
|
||||
static const string VOILA = "Voila";
|
||||
|
||||
// will not interfere with embedded <a href="#voila1">tags</a>.
|
||||
}</pre>
|
||||
|
||||
<td><pre class="prettyprint"><a name="voila2"></a>class Voila {
|
||||
public:
|
||||
// Voila
|
||||
static const string VOILA = "Voila";
|
||||
|
||||
// will not interfere with embedded <a href="#voila2">tags</a>.
|
||||
}</pre>
|
||||
</table>
|
||||
|
||||
<h2>FAQ</h2>
|
||||
<h3 id="langs">Which languages does it work for?</h3>
|
||||
<p>The comments in <tt>prettify.js</tt> are authoritative but the lexer
|
||||
should work on a number of languages including C and friends,
|
||||
Java, Python, Bash, SQL, HTML, XML, CSS, Javascript, and Makefiles.
|
||||
It works passably on Ruby, PHP, VB, and Awk and a decent subset of Perl
|
||||
and Ruby, but, because of commenting conventions, doesn't work on
|
||||
Smalltalk, or CAML-like languages.</p>
|
||||
|
||||
<p>LISPy languages are supported via an extension:
|
||||
<a href="http://code.google.com/p/google-code-prettify/source/browse/trunk/src/lang-lisp.js"
|
||||
><code>lang-lisp.js</code></a>.</p>
|
||||
<p>And similarly for
|
||||
<a href="http://code.google.com/p/google-code-prettify/source/browse/trunk/src/lang-css.js"
|
||||
><code>CSS</code></a>,
|
||||
<a href="http://code.google.com/p/google-code-prettify/source/browse/trunk/src/lang-hs.js"
|
||||
><code>Haskell</code></a>,
|
||||
<a href="http://code.google.com/p/google-code-prettify/source/browse/trunk/src/lang-lua.js"
|
||||
><code>Lua</code></a>,
|
||||
<a href="http://code.google.com/p/google-code-prettify/source/browse/trunk/src/lang-ml.js"
|
||||
><code>OCAML, SML, F#</code></a>,
|
||||
<a href="http://code.google.com/p/google-code-prettify/source/browse/trunk/src/lang-vb.js"
|
||||
><code>Visual Basic</code></a>,
|
||||
<a href="http://code.google.com/p/google-code-prettify/source/browse/trunk/src/lang-sql.js"
|
||||
><code>SQL</code></a>,
|
||||
<a href="http://code.google.com/p/google-code-prettify/source/browse/trunk/src/lang-proto.js"
|
||||
><code>Protocol Buffers</code></a>, and
|
||||
<a href="http://code.google.com/p/google-code-prettify/source/browse/trunk/src/lang-wiki.js"
|
||||
><code>WikiText</code></a>..
|
||||
|
||||
<p>If you'd like to add an extension for your favorite language, please
|
||||
look at <tt>src/lang-lisp.js</tt> and file an
|
||||
<a href="http://code.google.com/p/google-code-prettify/issues/list"
|
||||
>issue</a> including your language extension, and a testcase.</p>
|
||||
|
||||
<h3>How do I specify which language my code is in?</h3>
|
||||
<p>You don't need to specify the language since <code>prettyprint()</code>
|
||||
will guess. You can specify a language by specifying the language extension
|
||||
along with the <code>prettyprint</code> class like so:</p>
|
||||
<pre class="prettyprint lang-html"
|
||||
><pre class="prettyprint <b>lang-html</b>">
|
||||
The lang-* class specifies the language file extensions.
|
||||
File extensions supported by default include
|
||||
"bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm", "html",
|
||||
"java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
|
||||
"xhtml", "xml", "xsl".
|
||||
</pre></pre>
|
||||
|
||||
<h3>It doesn't work on <tt><obfuscated code sample></tt>?</h3>
|
||||
<p>Yes. Prettifying obfuscated code is like putting lipstick on a pig
|
||||
— i.e. outside the scope of this tool.</p>
|
||||
|
||||
<h3>Which browsers does it work with?</h3>
|
||||
<p>It's been tested with IE 6, Firefox 1.5 & 2, and Safari 2.0.4.
|
||||
Look at <a href="tests/prettify_test.html">the test page</a> to see if it
|
||||
works in your browser.</p>
|
||||
|
||||
<h3>What's changed?</h3>
|
||||
<p>See the <a href="CHANGES.html">change log</a></p>
|
||||
|
||||
<h3>Why doesn't Prettyprinting of strings work on WordPress?</h3>
|
||||
<p>Apparently wordpress does "smart quoting" which changes close quotes.
|
||||
This causes end quotes to not match up with open quotes.
|
||||
<p>This breaks prettifying as well as copying and pasting of code samples.
|
||||
See
|
||||
<a href="http://wordpress.org/support/topic/125038"
|
||||
>WordPress's help center</a> for info on how to stop smart quoting of code
|
||||
snippets.</p>
|
||||
|
||||
<h3 id="linenums">How do I put line numbers in my code?</h3>
|
||||
<p>You can use the <code>linenums</code> class to turn on line
|
||||
numbering. If your code doesn't start at line number 1, you can
|
||||
add a colon and a line number to the end of that class as in
|
||||
<code>linenums:52</code>.
|
||||
|
||||
<p>For example
|
||||
<pre class="prettyprint"><pre class="prettyprint linenums:<b>4</b>"
|
||||
>// This is line 4.
|
||||
foo();
|
||||
bar();
|
||||
baz();
|
||||
boo();
|
||||
far();
|
||||
faz();
|
||||
<pre></pre>
|
||||
produces
|
||||
<pre class="prettyprint linenums:4"
|
||||
>// This is line 4.
|
||||
foo();
|
||||
bar();
|
||||
baz();
|
||||
boo();
|
||||
far();
|
||||
faz();
|
||||
</pre>
|
||||
|
||||
<h3>How do I prevent a portion of markup from being marked as code?</h3>
|
||||
<p>You can use the <code>nocode</code> class to identify a span of markup
|
||||
that is not code.
|
||||
<pre class="prettyprint"><pre class=prettyprint>
|
||||
int x = foo(); /* This is a comment <span class="nocode">This is not code</span>
|
||||
Continuation of comment */
|
||||
int y = bar();
|
||||
</pre></pre>
|
||||
produces
|
||||
<pre class="prettyprint">
|
||||
int x = foo(); /* This is a comment <span class="nocode">This is not code</span>
|
||||
Continuation of comment */
|
||||
int y = bar();
|
||||
</pre>
|
||||
|
||||
<p>For a more complete example see the issue22
|
||||
<a href="tests/prettify_test.html#issue22">testcase</a>.</p>
|
||||
|
||||
<h3>I get an error message "a is not a function" or "opt_whenDone is not a function"</h3>
|
||||
<p>If you are calling <code>prettyPrint</code> via an event handler, wrap it in a function.
|
||||
Instead of doing
|
||||
<blockquote>
|
||||
<code class="prettyprint lang-js"
|
||||
>addEventListener('load', prettyPrint, false);</code>
|
||||
</blockquote>
|
||||
wrap it in a closure like
|
||||
<blockquote>
|
||||
<code class="prettyprint lang-js"
|
||||
>addEventListener('load', function (event) { prettyPrint() }, false);</code>
|
||||
</blockquote>
|
||||
so that the browser does not pass an event object to <code>prettyPrint</code> which
|
||||
will confuse it.
|
||||
|
||||
<br><br><br>
|
||||
|
||||
<div class="footer">
|
||||
<!-- Created: Tue Oct 3 17:51:56 PDT 2006 -->
|
||||
<!-- hhmts start -->
|
||||
Last modified: Wed Jul 19 13:56:00 PST 2010
|
||||
<!-- hhmts end -->
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1
doc/assets/vendor/prettify/prettify-min.css
vendored
@@ -1 +0,0 @@
|
||||
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
|
||||
1
doc/assets/vendor/prettify/prettify-min.js
vendored
@@ -1,212 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>ContextMenu</title>
|
||||
<link rel="stylesheet" href="http://yui.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css">
|
||||
<link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
|
||||
<link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
|
||||
<link rel="icon" href="../assets/favicon.ico">
|
||||
<script src="http://yui.yahooapis.com/combo?3.9.1/build/yui/yui-min.js"></script>
|
||||
</head>
|
||||
<body class="yui3-skin-sam">
|
||||
|
||||
<div id="doc">
|
||||
<div id="hd" class="yui3-g header">
|
||||
<div class="yui3-u-3-4">
|
||||
<h1><img src="../assets/css/logo.png" title="" width="117" height="52"></h1>
|
||||
</div>
|
||||
<div class="yui3-u-1-4 version">
|
||||
<em>API Docs for: </em>
|
||||
</div>
|
||||
</div>
|
||||
<div id="bd" class="yui3-g">
|
||||
|
||||
<div class="yui3-u-1-4">
|
||||
<div id="docs-sidebar" class="sidebar apidocs">
|
||||
<div id="api-list">
|
||||
<h2 class="off-left">APIs</h2>
|
||||
<div id="api-tabview" class="tabview">
|
||||
<ul class="tabs">
|
||||
<li><a href="#api-classes">Classes</a></li>
|
||||
<li><a href="#api-modules">Modules</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="api-tabview-filter">
|
||||
<input type="search" id="api-filter" placeholder="Type to filter APIs">
|
||||
</div>
|
||||
|
||||
<div id="api-tabview-panel">
|
||||
<ul id="api-classes" class="apis classes">
|
||||
<li><a href="../classes/ContextMenu.html">ContextMenu</a></li>
|
||||
<li><a href="../classes/LGraph.html">LGraph</a></li>
|
||||
<li><a href="../classes/LGraphCanvas.html">LGraphCanvas</a></li>
|
||||
<li><a href="../classes/LGraphNode.html">LGraphNode</a></li>
|
||||
<li><a href="../classes/LiteGraph.html">LiteGraph</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul id="api-modules" class="apis modules">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="yui3-u-3-4">
|
||||
<div id="api-options">
|
||||
Show:
|
||||
<label for="api-show-inherited">
|
||||
<input type="checkbox" id="api-show-inherited" checked>
|
||||
Inherited
|
||||
</label>
|
||||
|
||||
<label for="api-show-protected">
|
||||
<input type="checkbox" id="api-show-protected">
|
||||
Protected
|
||||
</label>
|
||||
|
||||
<label for="api-show-private">
|
||||
<input type="checkbox" id="api-show-private">
|
||||
Private
|
||||
</label>
|
||||
<label for="api-show-deprecated">
|
||||
<input type="checkbox" id="api-show-deprecated">
|
||||
Deprecated
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="apidocs">
|
||||
<div id="docs-main">
|
||||
<div class="content">
|
||||
<h1>ContextMenu Class</h1>
|
||||
<div class="box meta">
|
||||
|
||||
|
||||
<div class="foundat">
|
||||
Defined in: <a href="../files/.._src_litegraph.js.html#l8395"><code>../src/litegraph.js:8395</code></a>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="box intro">
|
||||
<p>ContextMenu from LiteGUI</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="constructor">
|
||||
<h2>Constructor</h2>
|
||||
<div id="method_ContextMenu" class="method item">
|
||||
<h3 class="name"><code>ContextMenu</code></h3>
|
||||
|
||||
<div class="args">
|
||||
<span class="paren">(</span><ul class="args-list inline commas">
|
||||
<li class="arg">
|
||||
<code>values</code>
|
||||
</li>
|
||||
<li class="arg">
|
||||
<code>options</code>
|
||||
</li>
|
||||
</ul><span class="paren">)</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="meta">
|
||||
<p>
|
||||
Defined in
|
||||
<a href="../files/.._src_litegraph.js.html#l8395"><code>../src/litegraph.js:8395</code></a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="params">
|
||||
<h4>Parameters:</h4>
|
||||
|
||||
<ul class="params-list">
|
||||
<li class="param">
|
||||
<code class="param-name">values</code>
|
||||
<span class="type">Array</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>(allows object { title: "Nice text", callback: function ... })</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
<li class="param">
|
||||
<code class="param-name">options</code>
|
||||
<span class="type">Object</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>[optional] Some options:\</p>
|
||||
<ul>
|
||||
<li>title: title to show on top of the menu</li>
|
||||
<li>callback: function to call when an option is clicked, it receives the item information</li>
|
||||
<li>ignore_item_callbacks: ignores the callback inside the item, it just calls the options.callback</li>
|
||||
<li>event: you can pass a MouseEvent, this way the ContextMenu appears in that position</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="classdocs" class="tabview">
|
||||
<ul class="api-class-tabs">
|
||||
<li class="api-class-tab index"><a href="#index">Index</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div>
|
||||
<div id="index" class="api-class-tabpanel index">
|
||||
<h2 class="off-left">Item Index</h2>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="../assets/vendor/prettify/prettify-min.js"></script>
|
||||
<script>prettyPrint();</script>
|
||||
<script src="../assets/js/yui-prettify.js"></script>
|
||||
<script src="../assets/../api.js"></script>
|
||||
<script src="../assets/js/api-filter.js"></script>
|
||||
<script src="../assets/js/api-list.js"></script>
|
||||
<script src="../assets/js/api-search.js"></script>
|
||||
<script src="../assets/js/apidocs.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,697 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>LiteGraph</title>
|
||||
<link rel="stylesheet" href="http://yui.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css">
|
||||
<link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
|
||||
<link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
|
||||
<link rel="icon" href="../assets/favicon.ico">
|
||||
<script src="http://yui.yahooapis.com/combo?3.9.1/build/yui/yui-min.js"></script>
|
||||
</head>
|
||||
<body class="yui3-skin-sam">
|
||||
|
||||
<div id="doc">
|
||||
<div id="hd" class="yui3-g header">
|
||||
<div class="yui3-u-3-4">
|
||||
<h1><img src="../assets/css/logo.png" title="" width="117" height="52"></h1>
|
||||
</div>
|
||||
<div class="yui3-u-1-4 version">
|
||||
<em>API Docs for: </em>
|
||||
</div>
|
||||
</div>
|
||||
<div id="bd" class="yui3-g">
|
||||
|
||||
<div class="yui3-u-1-4">
|
||||
<div id="docs-sidebar" class="sidebar apidocs">
|
||||
<div id="api-list">
|
||||
<h2 class="off-left">APIs</h2>
|
||||
<div id="api-tabview" class="tabview">
|
||||
<ul class="tabs">
|
||||
<li><a href="#api-classes">Classes</a></li>
|
||||
<li><a href="#api-modules">Modules</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="api-tabview-filter">
|
||||
<input type="search" id="api-filter" placeholder="Type to filter APIs">
|
||||
</div>
|
||||
|
||||
<div id="api-tabview-panel">
|
||||
<ul id="api-classes" class="apis classes">
|
||||
<li><a href="../classes/ContextMenu.html">ContextMenu</a></li>
|
||||
<li><a href="../classes/LGraph.html">LGraph</a></li>
|
||||
<li><a href="../classes/LGraphCanvas.html">LGraphCanvas</a></li>
|
||||
<li><a href="../classes/LGraphNode.html">LGraphNode</a></li>
|
||||
<li><a href="../classes/LiteGraph.html">LiteGraph</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul id="api-modules" class="apis modules">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="yui3-u-3-4">
|
||||
<div id="api-options">
|
||||
Show:
|
||||
<label for="api-show-inherited">
|
||||
<input type="checkbox" id="api-show-inherited" checked>
|
||||
Inherited
|
||||
</label>
|
||||
|
||||
<label for="api-show-protected">
|
||||
<input type="checkbox" id="api-show-protected">
|
||||
Protected
|
||||
</label>
|
||||
|
||||
<label for="api-show-private">
|
||||
<input type="checkbox" id="api-show-private">
|
||||
Private
|
||||
</label>
|
||||
<label for="api-show-deprecated">
|
||||
<input type="checkbox" id="api-show-deprecated">
|
||||
Deprecated
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="apidocs">
|
||||
<div id="docs-main">
|
||||
<div class="content">
|
||||
<h1>LiteGraph Class</h1>
|
||||
<div class="box meta">
|
||||
|
||||
|
||||
<div class="foundat">
|
||||
Defined in: <a href="../files/.._src_litegraph.js.html#l6"><code>../src/litegraph.js:6</code></a>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="box intro">
|
||||
<p>The Global Scope. It contains all the registered node classes.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="constructor">
|
||||
<h2>Constructor</h2>
|
||||
<div id="method_LiteGraph" class="method item">
|
||||
<h3 class="name"><code>LiteGraph</code></h3>
|
||||
|
||||
<span class="paren">()</span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="meta">
|
||||
<p>
|
||||
Defined in
|
||||
<a href="../files/.._src_litegraph.js.html#l6"><code>../src/litegraph.js:6</code></a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="classdocs" class="tabview">
|
||||
<ul class="api-class-tabs">
|
||||
<li class="api-class-tab index"><a href="#index">Index</a></li>
|
||||
|
||||
<li class="api-class-tab methods"><a href="#methods">Methods</a></li>
|
||||
</ul>
|
||||
|
||||
<div>
|
||||
<div id="index" class="api-class-tabpanel index">
|
||||
<h2 class="off-left">Item Index</h2>
|
||||
|
||||
<div class="index-section methods">
|
||||
<h3>Methods</h3>
|
||||
|
||||
<ul class="index-list methods">
|
||||
<li class="index-item method">
|
||||
<a href="#method_addNodeMethod">addNodeMethod</a>
|
||||
|
||||
</li>
|
||||
<li class="index-item method">
|
||||
<a href="#method_createNode">createNode</a>
|
||||
|
||||
</li>
|
||||
<li class="index-item method">
|
||||
<a href="#method_getNodeType">getNodeType</a>
|
||||
|
||||
</li>
|
||||
<li class="index-item method">
|
||||
<a href="#method_getNodeType">getNodeType</a>
|
||||
|
||||
</li>
|
||||
<li class="index-item method">
|
||||
<a href="#method_getNodeTypesCategories">getNodeTypesCategories</a>
|
||||
|
||||
</li>
|
||||
<li class="index-item method">
|
||||
<a href="#method_registerNodeType">registerNodeType</a>
|
||||
|
||||
</li>
|
||||
<li class="index-item method">
|
||||
<a href="#method_wrapFunctionAsNode">wrapFunctionAsNode</a>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="methods" class="api-class-tabpanel">
|
||||
<h2 class="off-left">Methods</h2>
|
||||
|
||||
<div id="method_addNodeMethod" class="method item">
|
||||
<h3 class="name"><code>addNodeMethod</code></h3>
|
||||
|
||||
<div class="args">
|
||||
<span class="paren">(</span><ul class="args-list inline commas">
|
||||
<li class="arg">
|
||||
<code>func</code>
|
||||
</li>
|
||||
</ul><span class="paren">)</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="meta">
|
||||
<p>
|
||||
Defined in
|
||||
<a href="../files/.._src_litegraph.js.html#l193"><code>../src/litegraph.js:193</code></a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<p>Adds this method to all nodetypes, existing and to be created
|
||||
(You can add it to LGraphNode.prototype but then existing node types wont have it)</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="params">
|
||||
<h4>Parameters:</h4>
|
||||
|
||||
<ul class="params-list">
|
||||
<li class="param">
|
||||
<code class="param-name">func</code>
|
||||
<span class="type">Function</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div id="method_createNode" class="method item">
|
||||
<h3 class="name"><code>createNode</code></h3>
|
||||
|
||||
<div class="args">
|
||||
<span class="paren">(</span><ul class="args-list inline commas">
|
||||
<li class="arg">
|
||||
<code>type</code>
|
||||
</li>
|
||||
<li class="arg">
|
||||
<code>name</code>
|
||||
</li>
|
||||
<li class="arg">
|
||||
<code>options</code>
|
||||
</li>
|
||||
</ul><span class="paren">)</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="meta">
|
||||
<p>
|
||||
Defined in
|
||||
<a href="../files/.._src_litegraph.js.html#l211"><code>../src/litegraph.js:211</code></a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<p>Create a node of a given type with a name. The node is not attached to any graph yet.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="params">
|
||||
<h4>Parameters:</h4>
|
||||
|
||||
<ul class="params-list">
|
||||
<li class="param">
|
||||
<code class="param-name">type</code>
|
||||
<span class="type">String</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>full name of the node class. p.e. "math/sin"</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
<li class="param">
|
||||
<code class="param-name">name</code>
|
||||
<span class="type">String</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>a name to distinguish from other nodes</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
<li class="param">
|
||||
<code class="param-name">options</code>
|
||||
<span class="type">Object</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>to set options</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div id="method_getNodeType" class="method item">
|
||||
<h3 class="name"><code>getNodeType</code></h3>
|
||||
|
||||
<div class="args">
|
||||
<span class="paren">(</span><ul class="args-list inline commas">
|
||||
<li class="arg">
|
||||
<code>type</code>
|
||||
</li>
|
||||
</ul><span class="paren">)</span>
|
||||
</div>
|
||||
|
||||
<span class="returns-inline">
|
||||
<span class="type">Class</span>
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="meta">
|
||||
<p>
|
||||
Defined in
|
||||
<a href="../files/.._src_litegraph.js.html#l270"><code>../src/litegraph.js:270</code></a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<p>Returns a registered node type with a given name</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="params">
|
||||
<h4>Parameters:</h4>
|
||||
|
||||
<ul class="params-list">
|
||||
<li class="param">
|
||||
<code class="param-name">type</code>
|
||||
<span class="type">String</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>full name of the node class. p.e. "math/sin"</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="returns">
|
||||
<h4>Returns:</h4>
|
||||
|
||||
<div class="returns-description">
|
||||
<span class="type">Class</span>:
|
||||
<p>the node class</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div id="method_getNodeType" class="method item">
|
||||
<h3 class="name"><code>getNodeType</code></h3>
|
||||
|
||||
<div class="args">
|
||||
<span class="paren">(</span><ul class="args-list inline commas">
|
||||
<li class="arg">
|
||||
<code>category</code>
|
||||
</li>
|
||||
</ul><span class="paren">)</span>
|
||||
</div>
|
||||
|
||||
<span class="returns-inline">
|
||||
<span class="type">Array</span>
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="meta">
|
||||
<p>
|
||||
Defined in
|
||||
<a href="../files/.._src_litegraph.js.html#l281"><code>../src/litegraph.js:281</code></a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<p>Returns a list of node types matching one category</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="params">
|
||||
<h4>Parameters:</h4>
|
||||
|
||||
<ul class="params-list">
|
||||
<li class="param">
|
||||
<code class="param-name">category</code>
|
||||
<span class="type">String</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>category name</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="returns">
|
||||
<h4>Returns:</h4>
|
||||
|
||||
<div class="returns-description">
|
||||
<span class="type">Array</span>:
|
||||
<p>array with all the node classes</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div id="method_getNodeTypesCategories" class="method item">
|
||||
<h3 class="name"><code>getNodeTypesCategories</code></h3>
|
||||
|
||||
<span class="paren">()</span>
|
||||
|
||||
<span class="returns-inline">
|
||||
<span class="type">Array</span>
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="meta">
|
||||
<p>
|
||||
Defined in
|
||||
<a href="../files/.._src_litegraph.js.html#l309"><code>../src/litegraph.js:309</code></a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<p>Returns a list with all the node type categories</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="returns">
|
||||
<h4>Returns:</h4>
|
||||
|
||||
<div class="returns-description">
|
||||
<span class="type">Array</span>:
|
||||
<p>array with all the names of the categories</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div id="method_registerNodeType" class="method item">
|
||||
<h3 class="name"><code>registerNodeType</code></h3>
|
||||
|
||||
<div class="args">
|
||||
<span class="paren">(</span><ul class="args-list inline commas">
|
||||
<li class="arg">
|
||||
<code>type</code>
|
||||
</li>
|
||||
<li class="arg">
|
||||
<code>base_class</code>
|
||||
</li>
|
||||
</ul><span class="paren">)</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="meta">
|
||||
<p>
|
||||
Defined in
|
||||
<a href="../files/.._src_litegraph.js.html#l93"><code>../src/litegraph.js:93</code></a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<p>Register a node class so it can be listed when the user wants to create a new one</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="params">
|
||||
<h4>Parameters:</h4>
|
||||
|
||||
<ul class="params-list">
|
||||
<li class="param">
|
||||
<code class="param-name">type</code>
|
||||
<span class="type">String</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>name of the node and path</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
<li class="param">
|
||||
<code class="param-name">base_class</code>
|
||||
<span class="type">Class</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>class containing the structure of a node</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div id="method_wrapFunctionAsNode" class="method item">
|
||||
<h3 class="name"><code>wrapFunctionAsNode</code></h3>
|
||||
|
||||
<div class="args">
|
||||
<span class="paren">(</span><ul class="args-list inline commas">
|
||||
<li class="arg">
|
||||
<code>name</code>
|
||||
</li>
|
||||
<li class="arg">
|
||||
<code>func</code>
|
||||
</li>
|
||||
<li class="arg">
|
||||
<code>param_types</code>
|
||||
</li>
|
||||
<li class="arg">
|
||||
<code>return_type</code>
|
||||
</li>
|
||||
<li class="arg">
|
||||
<code>properties</code>
|
||||
</li>
|
||||
</ul><span class="paren">)</span>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="meta">
|
||||
<p>
|
||||
Defined in
|
||||
<a href="../files/.._src_litegraph.js.html#l160"><code>../src/litegraph.js:160</code></a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<p>Create a new node type by passing a function, it wraps it with a propper class and generates inputs according to the parameters of the function.
|
||||
Useful to wrap simple methods that do not require properties, and that only process some input to generate an output.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="params">
|
||||
<h4>Parameters:</h4>
|
||||
|
||||
<ul class="params-list">
|
||||
<li class="param">
|
||||
<code class="param-name">name</code>
|
||||
<span class="type">String</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>node name with namespace (p.e.: 'math/sum')</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
<li class="param">
|
||||
<code class="param-name">func</code>
|
||||
<span class="type">Function</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
<li class="param">
|
||||
<code class="param-name">param_types</code>
|
||||
<span class="type">Array</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>[optional] an array containing the type of every parameter, otherwise parameters will accept any type</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
<li class="param">
|
||||
<code class="param-name">return_type</code>
|
||||
<span class="type">String</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>[optional] string with the return type, otherwise it will be generic</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
<li class="param">
|
||||
<code class="param-name">properties</code>
|
||||
<span class="type">Object</span>
|
||||
|
||||
|
||||
<div class="param-description">
|
||||
<p>[optional] properties to be configurable</p>
|
||||
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="../assets/vendor/prettify/prettify-min.js"></script>
|
||||
<script>prettyPrint();</script>
|
||||
<script src="../assets/js/yui-prettify.js"></script>
|
||||
<script src="../assets/../api.js"></script>
|
||||
<script src="../assets/js/api-filter.js"></script>
|
||||
<script src="../assets/js/api-list.js"></script>
|
||||
<script src="../assets/js/api-search.js"></script>
|
||||
<script src="../assets/js/apidocs.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Redirector</title>
|
||||
<meta http-equiv="refresh" content="0;url=../">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../">Click here to redirect</a>
|
||||
</body>
|
||||
</html>
|
||||
2114
doc/data.json
@@ -1,10 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Redirector</title>
|
||||
<meta http-equiv="refresh" content="0;url=../">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../">Click here to redirect</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Redirector</title>
|
||||
<meta http-equiv="refresh" content="0;url=../">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../">Click here to redirect</a>
|
||||
</body>
|
||||
</html>
|
||||
119
doc/index.html
@@ -1,119 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title></title>
|
||||
<link rel="stylesheet" href="http://yui.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css">
|
||||
<link rel="stylesheet" href="./assets/vendor/prettify/prettify-min.css">
|
||||
<link rel="stylesheet" href="./assets/css/main.css" id="site_styles">
|
||||
<link rel="icon" href="./assets/favicon.ico">
|
||||
<script src="http://yui.yahooapis.com/combo?3.9.1/build/yui/yui-min.js"></script>
|
||||
</head>
|
||||
<body class="yui3-skin-sam">
|
||||
|
||||
<div id="doc">
|
||||
<div id="hd" class="yui3-g header">
|
||||
<div class="yui3-u-3-4">
|
||||
<h1><img src="./assets/css/logo.png" title="" width="117" height="52"></h1>
|
||||
</div>
|
||||
<div class="yui3-u-1-4 version">
|
||||
<em>API Docs for: </em>
|
||||
</div>
|
||||
</div>
|
||||
<div id="bd" class="yui3-g">
|
||||
|
||||
<div class="yui3-u-1-4">
|
||||
<div id="docs-sidebar" class="sidebar apidocs">
|
||||
<div id="api-list">
|
||||
<h2 class="off-left">APIs</h2>
|
||||
<div id="api-tabview" class="tabview">
|
||||
<ul class="tabs">
|
||||
<li><a href="#api-classes">Classes</a></li>
|
||||
<li><a href="#api-modules">Modules</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="api-tabview-filter">
|
||||
<input type="search" id="api-filter" placeholder="Type to filter APIs">
|
||||
</div>
|
||||
|
||||
<div id="api-tabview-panel">
|
||||
<ul id="api-classes" class="apis classes">
|
||||
<li><a href="./classes/ContextMenu.html">ContextMenu</a></li>
|
||||
<li><a href="./classes/LGraph.html">LGraph</a></li>
|
||||
<li><a href="./classes/LGraphCanvas.html">LGraphCanvas</a></li>
|
||||
<li><a href="./classes/LGraphNode.html">LGraphNode</a></li>
|
||||
<li><a href="./classes/LiteGraph.html">LiteGraph</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul id="api-modules" class="apis modules">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="yui3-u-3-4">
|
||||
<div id="api-options">
|
||||
Show:
|
||||
<label for="api-show-inherited">
|
||||
<input type="checkbox" id="api-show-inherited" checked>
|
||||
Inherited
|
||||
</label>
|
||||
|
||||
<label for="api-show-protected">
|
||||
<input type="checkbox" id="api-show-protected">
|
||||
Protected
|
||||
</label>
|
||||
|
||||
<label for="api-show-private">
|
||||
<input type="checkbox" id="api-show-private">
|
||||
Private
|
||||
</label>
|
||||
<label for="api-show-deprecated">
|
||||
<input type="checkbox" id="api-show-deprecated">
|
||||
Deprecated
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="apidocs">
|
||||
<div id="docs-main">
|
||||
<div class="content">
|
||||
<div class="apidocs">
|
||||
<div id="docs-main" class="content">
|
||||
<p>
|
||||
Browse to a module or class using the sidebar to view its API documentation.
|
||||
</p>
|
||||
|
||||
<h2>Keyboard Shortcuts</h2>
|
||||
|
||||
<ul>
|
||||
<li><p>Press <kbd>s</kbd> to focus the API search box.</p></li>
|
||||
|
||||
<li><p>Use <kbd>Up</kbd> and <kbd>Down</kbd> to select classes, modules, and search results.</p></li>
|
||||
|
||||
<li class="mac-only"><p>With the API search box or sidebar focused, use <kbd><span class="cmd">⌘</span>-Left</kbd> or <kbd><span class="cmd">⌘</span>-Right</kbd> to switch sidebar tabs.</p></li>
|
||||
|
||||
<li class="pc-only"><p>With the API search box or sidebar focused, use <kbd>Ctrl+Left</kbd> and <kbd>Ctrl+Right</kbd> to switch sidebar tabs.</p></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="./assets/vendor/prettify/prettify-min.js"></script>
|
||||
<script>prettyPrint();</script>
|
||||
<script src="./assets/js/yui-prettify.js"></script>
|
||||
<script src="./assets/../api.js"></script>
|
||||
<script src="./assets/js/api-filter.js"></script>
|
||||
<script src="./assets/js/api-list.js"></script>
|
||||
<script src="./assets/js/api-search.js"></script>
|
||||
<script src="./assets/js/apidocs.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Redirector</title>
|
||||
<meta http-equiv="refresh" content="0;url=../">
|
||||
</head>
|
||||
<body>
|
||||
<a href="../">Click here to redirect</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,144 +0,0 @@
|
||||
<!-- Javi Agenjo (@tamat) on 31/9/2011 -->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>LiteGraph</title>
|
||||
<!--<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">-->
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="../css/litegraph.css">
|
||||
<link rel="stylesheet" type="text/css" href="../css/litegraph-editor.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="../external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="https://tamats.com/projects/sillyserver/src/sillyclient.js"></script>
|
||||
<!-- <script type="text/javascript" src="https://unpkg.com/codeflask/build/codeflask.min.js"></script> -->
|
||||
<script type="text/javascript" src="js/libs/gl-matrix-min.js"></script>
|
||||
<script type="text/javascript" src="js/libs/audiosynth.js"></script>
|
||||
<script type="text/javascript" src="js/libs/midi-parser.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/litegraph.js"></script>
|
||||
<script type="text/javascript" src="../src/litegraph-editor.js"></script>
|
||||
<script type="text/javascript" src="js/defaults_mobile.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/nodes/base.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/logic.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/events.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/math.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/math3d.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/strings.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/interface.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/geometry.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/graphics.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/input.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/midi.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/audio.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/network.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/demos.js"></script>
|
||||
<script type="text/javascript" src="js/code.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/nodes/others.js"></script>
|
||||
|
||||
<!-- htmlConsole use to debug on mobile, include and set editorUseHtmlConsole in defaults.js -->
|
||||
<!-- enable console style, html, js enabling/disabling this comment here-> -->
|
||||
|
||||
<link rel="stylesheet" href="//htmlacademy.github.io/console.js/latest/css/style.css">
|
||||
<style>
|
||||
.invisible{ display: none; }
|
||||
.console__row{
|
||||
margin: 1px;
|
||||
padding: 2px;
|
||||
}
|
||||
.console-container{
|
||||
min-width: 200px;
|
||||
background: rgba(255,255,255,0.1);
|
||||
position: fixed;
|
||||
top: 38px;
|
||||
left: 0;
|
||||
overflow: auto;
|
||||
height: calc(100%-38px);
|
||||
}
|
||||
.console-container.small{
|
||||
max-width: 30%;
|
||||
}
|
||||
.graphcanvas{
|
||||
/*WONT WORK touch-action: manipulation;*/
|
||||
/*touch-action: none;*/
|
||||
touch-action: pinch-zoom;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="console-container" class="litegraph-editor console-container small invisible" style="">
|
||||
<div class="console-tools" style="position: absolute; top: 0; right:0; z-index:2;">
|
||||
<button class='btn' id='btn_console_close'>close</button>
|
||||
<button class='btn' id='btn_console_clear'>clear</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="//htmlacademy.github.io/console.js/latest/js/index.js"></script>
|
||||
<script>
|
||||
|
||||
var editorUseHtmlConsole = true; // enable html console to debug on mobile
|
||||
|
||||
// ToBarSelector
|
||||
if(editorUseHtmlConsole){
|
||||
document.getElementById("LGEditorTopBarSelector").innerHTML = "<button class='btn' id='btn_console'>Console</button> "
|
||||
+document.getElementById("LGEditorTopBarSelector").innerHTML;
|
||||
}
|
||||
|
||||
// html console
|
||||
if(editorUseHtmlConsole){
|
||||
elem.querySelector("#btn_console").addEventListener("click", function(){
|
||||
var consoleCnt = document.getElementById('console-container');
|
||||
if (consoleCnt.classList.contains("invisible")){
|
||||
consoleCnt.classList.remove("invisible");
|
||||
}else{
|
||||
jsConsole.clean();
|
||||
consoleCnt.classList.add("invisible");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const params = {
|
||||
expandDepth : 1,
|
||||
common : {
|
||||
excludeProperties : ['__proto__'],
|
||||
removeProperties: ['__proto__'],
|
||||
maxFieldsInHead : 5,
|
||||
minFieldsToAutoexpand : 5,
|
||||
maxFieldsToAutoexpand : 15
|
||||
}
|
||||
};
|
||||
var jsConsole = new Console(document.querySelector('.console-container'), params);
|
||||
jsConsole.log("Here is console.log!");
|
||||
|
||||
// map console log-debug to jsConsole
|
||||
console.log = function(par){
|
||||
jsConsole.log(par);
|
||||
var objDiv = document.getElementById("console-container");
|
||||
objDiv.scrollTop = objDiv.scrollHeight;
|
||||
}
|
||||
console.debug = console.log;
|
||||
|
||||
console.log("going into html console");
|
||||
|
||||
document.getElementById("btn_console_clear").addEventListener("click", function(){
|
||||
var consoleCnt = document.getElementById('console-container');
|
||||
jsConsole.clean();
|
||||
});
|
||||
document.getElementById("btn_console_close").addEventListener("click", function(){
|
||||
var consoleCnt = document.getElementById('console-container');
|
||||
consoleCnt.classList.add("invisible");
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<!-- -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
{"last_node_id":16,"last_link_id":16,"nodes":[{"id":9,"type":"widget/knob","pos":[440,81],"size":[80,100],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[8,9]}],"properties":{"min":0,"max":4,"value":0.24000000000000002,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":10,"type":"basic/watch","pos":[537,81],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"value","type":0,"link":9,"label":"0.000"}],"outputs":[{"name":"value","type":0,"links":null,"label":""}],"properties":{"value":0.24000000000000002}},{"id":1,"type":"audio/destination","pos":[699,83],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"in","type":"audio","link":1}],"properties":{}},{"id":6,"type":"widget/knob","pos":[116,179],"size":[80,100],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[5]}],"properties":{"min":0,"max":1,"value":0.5099999999999996,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":0,"type":"audio/source","pos":[272,192],"size":{"0":140,"1":86},"flags":{},"mode":0,"inputs":[{"name":"gain","type":"number","link":5},{"name":"Play","type":-1,"link":6},{"name":"Stop","type":-1,"link":7},{"name":"playbackRate","type":"number","link":8}],"outputs":[{"name":"out","type":"audio","links":[0]}],"properties":{"src":"demodata/audio.wav","gain":0.5,"loop":true,"autoplay":true,"playbackRate":0.24000000000000002},"boxcolor":"#AA4"},{"id":2,"type":"audio/biquadfilter","pos":[442,228],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"in","type":"audio","link":0},{"name":"frequency","type":"number","link":4}],"outputs":[{"name":"out","type":"audio","links":[1,2]}],"properties":{"frequency":350,"detune":0,"Q":1,"type":"lowpass"}},{"id":3,"type":"audio/analyser","pos":[704,231],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"in","type":"audio","link":2}],"outputs":[{"name":"freqs","type":"array","links":[3,10]},{"name":"samples","type":"array","links":null}],"properties":{"fftSize":2048,"minDecibels":-100,"maxDecibels":-10,"smoothingTimeConstant":0.5}},{"id":11,"type":"audio/signal","pos":[882,395],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"freqs","type":"array","link":10},{"name":"band","type":"number","link":11}],"outputs":[{"name":"signal","type":"number","links":[12]}],"properties":{"band":440,"amplitude":1,"samplerate":44100}},{"id":4,"type":"audio/visualization","pos":[885,503],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"freqs","type":"array","link":3},{"name":"mark","type":"number","link":13}],"properties":{"continuous":true,"mark":12000.000000000005,"samplerate":44100}},{"id":5,"type":"widget/knob","pos":[112,314],"size":[80,100],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[4]}],"properties":{"min":0,"max":20000,"value":14800.00000000001,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":13,"type":"basic/watch","pos":[110,458],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"value","type":0,"link":12,"label":"0.000"}],"outputs":[{"name":"value","type":0,"links":[14],"label":""}],"title":"Max. Signal","properties":{"value":0.3843137254901945}},{"id":14,"type":"widget/progress","pos":[300,460],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"","type":"number","link":14}],"properties":{"min":0,"max":1,"value":0.3843137254901945,"wcolor":"#AAF"}},{"id":12,"type":"widget/knob","pos":[460,458],"size":[80,100],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[11,13,15]}],"properties":{"min":0,"max":24000,"value":12000.000000000005,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":15,"type":"basic/watch","pos":[888,598],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"value","type":0,"link":15,"label":"0.000"}],"outputs":[{"name":"value","type":0,"links":null,"label":""}],"properties":{"value":12000.000000000005}},{"id":7,"type":"widget/button","pos":[113,83],"size":{"0":141,"1":60},"flags":{},"mode":0,"outputs":[{"name":"clicked","type":-1,"links":[6]}],"properties":{"text":"Play","font_size":30,"message":"","font":"40px Arial"}},{"id":8,"type":"widget/button","pos":[273,83],"size":{"0":143,"1":62},"flags":{},"mode":0,"outputs":[{"name":"clicked","type":-1,"links":[7]}],"properties":{"text":"Stop","font_size":30,"message":"","font":"40px Arial"}}],"links":[[0,0,0,2,0,null],[1,2,0,1,0,null],[2,2,0,3,0,null],[3,3,0,4,0,null],[4,5,0,2,1,null],[5,6,0,0,0,null],[6,7,0,0,1,null],[7,8,0,0,2,null],[8,9,0,0,3,null],[9,9,0,10,0,null],[10,3,0,11,0,null],[11,12,0,11,1,null],[12,11,0,13,0,null],[13,12,0,4,1,null],[14,13,0,14,0,null],[15,12,0,15,0,null]],"groups":[],"config":{}}
|
||||
@@ -1 +0,0 @@
|
||||
{"last_node_id":7,"last_link_id":7,"nodes":[{"id":6,"type":"widget/knob","pos":[199,296],"size":[64,84],"flags":{},"order":3,"mode":0,"outputs":[{"name":"","type":"number","links":[6]}],"properties":{"min":0,"max":2,"value":0.8799999999999999,"color":"#7AF","precision":2,"wcolor":"#7AF","size":50},"boxcolor":"rgba(112,112,112,1.0)"},{"id":0,"type":"audio/source","pos":[195,187],"size":{"0":137,"1":33},"flags":{},"order":0,"mode":0,"inputs":[{"name":"gain","type":"number","link":null}],"outputs":[{"name":"out","type":"audio","links":[0,1]}],"properties":{"src":"demodata/audio.wav","gain":0.5,"loop":true,"autoplay":true,"playbackRate":1},"boxcolor":"#AA4"},{"id":4,"type":"widget/knob","pos":[408,59],"size":[82,75],"flags":{},"order":1,"mode":0,"outputs":[{"name":"","type":"number","links":[4]}],"properties":{"min":0,"max":1,"value":0.24000000000000007,"color":"#7AF","precision":2,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":2,"type":"audio/delay","pos":[385,255],"size":{"0":143,"1":49},"flags":{},"order":4,"mode":0,"inputs":[{"name":"in","type":"audio","link":1},{"name":"time","type":"number","link":6}],"outputs":[{"name":"out","type":"audio","links":[2]}],"properties":{"delayTime":0.5,"time":1}},{"id":5,"type":"widget/knob","pos":[433,371],"size":[79,79],"flags":{},"order":2,"mode":0,"outputs":[{"name":"","type":"number","links":[5]}],"properties":{"min":0,"max":1,"value":0.5199999999999996,"color":"#7AF","precision":2,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":1,"type":"audio/mixer","pos":[657,180],"size":{"0":147,"1":91},"flags":{},"order":5,"mode":0,"inputs":[{"name":"in1","type":"audio","link":0},{"name":"in1 gain","type":"number","link":4},{"name":"in2","type":"audio","link":2},{"name":"in2 gain","type":"number","link":5}],"outputs":[{"name":"out","type":"audio","links":[3]}],"properties":{"gain1":0.5,"gain2":0.8}},{"id":3,"type":"audio/destination","pos":[911,180],"size":{"0":145,"1":30},"flags":{},"order":6,"mode":0,"inputs":[{"name":"in","type":"audio","link":3}],"properties":{}}],"links":[[0,0,0,1,0,null],[1,0,0,2,0,null],[2,2,0,1,2,null],[3,1,0,3,0,null],[4,4,0,1,1,null],[5,5,0,1,3,null],[6,6,0,2,1,null]],"groups":[],"config":{},"version":0.4}
|
||||
@@ -1 +0,0 @@
|
||||
{"last_node_id":8,"last_link_id":9,"nodes":[{"id":4,"type":"widget/knob","pos":[408,59],"size":[81,93],"flags":{},"order":2,"mode":0,"outputs":[{"name":"","type":"number","links":[4]}],"title":"Main","properties":{"min":0,"max":1,"value":0.21000000000000002,"color":"#7AF","precision":2,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":5,"type":"widget/knob","pos":[398,350],"size":[84,100],"flags":{},"order":1,"mode":0,"outputs":[{"name":"","type":"number","links":[5]}],"title":"Reverb","properties":{"min":0,"max":1,"value":0.4099999999999999,"color":"#7AF","precision":2,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":7,"type":"audio/convolver","pos":[421,253],"size":{"0":140,"1":31},"flags":{},"order":3,"mode":0,"inputs":[{"name":"in","type":"audio","link":7}],"outputs":[{"name":"out","type":"audio","links":[8]}],"properties":{"impulse_src":"demodata/impulse.wav","normalize":true}},{"id":1,"type":"audio/mixer","pos":[655,183],"size":{"0":145,"1":94},"flags":{},"order":4,"mode":0,"inputs":[{"name":"in1","type":"audio","link":0},{"name":"in1 gain","type":"number","link":4},{"name":"in2","type":"audio","link":8},{"name":"in2 gain","type":"number","link":5}],"outputs":[{"name":"out","type":"audio","links":[3]}],"properties":{"gain1":0.5,"gain2":0.8}},{"id":3,"type":"audio/destination","pos":[911,180],"size":{"0":141,"1":34},"flags":{},"order":5,"mode":0,"inputs":[{"name":"in","type":"audio","link":3}],"properties":{}},{"id":0,"type":"audio/source","pos":[195,187],"size":{"0":143,"1":30},"flags":{},"order":0,"mode":0,"inputs":[{"name":"gain","type":"number","link":null}],"outputs":[{"name":"out","type":"audio","links":[0,7]}],"properties":{"src":"demodata/audio.wav","gain":0.5,"loop":true,"autoplay":true,"playbackRate":1},"boxcolor":"#AA4"}],"links":[[0,0,0,1,0,null],[1,0,0,2,0,null],[3,1,0,3,0,null],[4,4,0,1,1,null],[5,5,0,1,3,null],[6,6,0,2,1,null],[7,0,0,7,0,null],[8,7,0,1,2,null]],"groups":[],"config":{},"version":0.4}
|
||||
@@ -1 +0,0 @@
|
||||
{"last_node_id":14,"last_link_id":14,"nodes":[{"id":9,"type":"features/slots","pos":[847,479],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":6}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":7,"type":"features/slots","pos":[757,380],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":13}],"outputs":[{"name":"A","type":"number","links":[10]},{"name":"B","type":"number","links":[6]}],"properties":{}},{"id":8,"type":"features/slots","pos":[672,481],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":10}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":5,"type":"math/operation","pos":[413,101],"size":[140,34],"flags":{"collapsed":true},"mode":0,"inputs":[{"name":"A","type":"number","link":null},{"name":"B","type":"number","link":null}],"outputs":[{"name":"=","type":"number","links":[2]}],"properties":{"A":1,"B":1,"OP":"+"},"shape":2},{"id":12,"type":"input/gamepad","pos":[593,208],"size":{"0":175,"1":74},"flags":{},"mode":0,"outputs":[{"name":"left_x_axis","type":"number","links":null},{"name":"left_y_axis","type":"number","links":null},{"name":"button_pressed","type":-1,"links":[12]}],"properties":{"gamepad_index":0,"threshold":0.1}},{"id":13,"type":"events/log","pos":[862,246],"size":{"0":144,"1":32},"flags":{},"mode":0,"inputs":[{"name":"event","type":-1,"link":12}],"properties":{}},{"id":14,"type":"features/widgets","pos":[441,365],"size":{"0":180,"1":170},"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[13]}],"properties":{}},{"id":10,"type":"widget/knob","pos":[421,197],"size":[74,92],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[9]}],"properties":{"min":0,"max":1,"value":0.5,"wcolor":"#7AF","size":50}},{"id":4,"type":"math/operation","pos":[596,116],"size":[148,48],"flags":{},"mode":0,"inputs":[{"name":"A","type":"number","link":2},{"name":"B","type":"number","link":9}],"outputs":[{"name":"=","type":"number","links":[1]}],"properties":{"A":1,"B":1,"OP":"+"},"shape":2},{"id":2,"type":"features/shape","pos":[850,97],"size":{"0":140,"1":39},"flags":{},"mode":0,"inputs":[{"name":"","type":"number","link":1}],"outputs":[{"name":"","type":"number","links":null}],"properties":{}}],"links":[[1,4,0,2,0,"number"],[2,5,0,4,0,"number"],[6,7,1,9,0,"number"],[9,10,0,4,1,"number"],[10,7,0,8,0,"number"],[12,12,2,13,0,-1],[13,14,0,7,0,"number"]],"groups":[{"title":"Group","bounding":[418,298,609,255],"color":"#3f789e"}],"config":{}}
|
||||
@@ -1 +0,0 @@
|
||||
{"last_node_id":6,"last_link_id":5,"nodes":[{"id":3,"type":"basic/time","pos":[312,145],"size":{"0":140,"1":46},"flags":{},"mode":0,"outputs":[{"name":"in ms","type":"number","links":null},{"name":"in sec","type":"number","links":[1]}],"properties":{}},{"id":4,"type":"basic/watch","pos":[864,156],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"value","type":0,"link":2,"label":"5.000"}],"properties":{}},{"id":6,"type":"events/counter","pos":[864,229],"size":{"0":140,"1":66},"flags":{},"mode":0,"inputs":[{"name":"inc","type":-1,"link":4},{"name":"dec","type":-1,"link":null},{"name":"reset","type":-1,"link":null}],"outputs":[{"name":"change","type":-1,"links":null},{"name":"num","type":"number","links":null}],"properties":{}},{"id":2,"type":"graph/subgraph","pos":[573,168],"size":{"0":140,"1":86},"flags":{},"mode":0,"inputs":[{"name":"enabled","type":"boolean","link":null},{"name":"foo","type":"","link":1},{"name":"EV","type":-1,"link":3}],"outputs":[{"name":"faa","type":0,"links":[2]},{"name":"EV","type":-1,"links":[4]}],"properties":{"enabled":true},"subgraph":{"last_node_id":7,"last_link_id":6,"nodes":[{"id":3,"type":"graph/output","pos":[1119,139],"size":[180,60],"flags":{},"mode":0,"inputs":[{"name":"","type":0,"link":2}],"properties":{"name":"faa","type":0}},{"id":4,"type":"math/floor","pos":[872,194],"size":[112,28],"flags":{},"mode":0,"inputs":[{"name":"in","type":"number","link":1}],"outputs":[{"name":"out","type":"number","links":[2]}],"properties":{}},{"id":2,"type":"graph/input","pos":[440,149],"size":[180,60],"flags":{},"mode":0,"outputs":[{"name":"","type":"","links":[1]}],"properties":{"name":"foo","type":""}},{"id":5,"type":"graph/input","pos":[460,282],"size":[180,60],"flags":{},"mode":0,"outputs":[{"name":"","type":-1,"links":[4]}],"properties":{"name":"EV","type":-1}},{"id":6,"type":"graph/output","pos":[1054,293],"size":[180,60],"flags":{},"mode":0,"inputs":[{"name":"","type":-1,"link":5}],"properties":{"name":"EV","type":-1}},{"id":7,"type":"events/delay","pos":[742,300],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"event","type":-1,"link":4}],"outputs":[{"name":"on_time","type":-1,"links":[5]}],"properties":{"time_in_ms":1000}}],"links":[[1,2,0,4,0,"number"],[2,4,0,3,0,0],[4,5,0,7,0,-1],[5,7,0,6,0,-1]],"groups":[],"config":{},"version":0.4}},{"id":5,"type":"events/timer","pos":[311,240],"size":{"0":140,"1":26},"flags":{},"mode":0,"outputs":[{"name":"on_tick","type":-1,"links":[3]}],"properties":{"interval":2000,"event":"tick"},"boxcolor":"#222"}],"links":[[1,3,1,2,1,0],[2,2,0,4,0,0],[3,5,0,2,2,-1],[4,2,1,6,0,-1]],"groups":[],"config":{},"version":0.4}
|
||||
|
Before Width: | Height: | Size: 350 B |
|
Before Width: | Height: | Size: 368 B |
|
Before Width: | Height: | Size: 607 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 346 B |
|
Before Width: | Height: | Size: 344 B |
|
Before Width: | Height: | Size: 349 B |
|
Before Width: | Height: | Size: 330 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 179 B |
|
Before Width: | Height: | Size: 836 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 281 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,47 +0,0 @@
|
||||
<!-- Javi Agenjo (@tamat) on 31/9/2011 -->
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<title>LiteGraph</title>
|
||||
<!--<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">-->
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="../css/litegraph.css">
|
||||
<link rel="stylesheet" type="text/css" href="../css/litegraph-editor.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="main">
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="../external/jquery-1.6.2.min.js"></script>
|
||||
<script type="text/javascript" src="https://tamats.com/projects/sillyserver/src/sillyclient.js"></script>
|
||||
<!-- <script type="text/javascript" src="https://unpkg.com/codeflask/build/codeflask.min.js"></script> -->
|
||||
<script type="text/javascript" src="js/libs/gl-matrix-min.js"></script>
|
||||
<script type="text/javascript" src="js/libs/audiosynth.js"></script>
|
||||
<script type="text/javascript" src="js/libs/midi-parser.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/litegraph.js"></script>
|
||||
<script type="text/javascript" src="../src/litegraph-editor.js"></script>
|
||||
<script type="text/javascript" src="js/defaults.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/nodes/base.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/logic.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/events.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/math.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/math3d.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/strings.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/interface.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/geometry.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/graphics.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/input.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/midi.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/audio.js"></script>
|
||||
<script type="text/javascript" src="../src/nodes/network.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/demos.js"></script>
|
||||
<script type="text/javascript" src="js/code.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/nodes/others.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,195 +0,0 @@
|
||||
var webgl_canvas = null;
|
||||
|
||||
LiteGraph.node_images_path = "../nodes_data/";
|
||||
|
||||
var editor = new LiteGraph.Editor("main",{miniwindow:false});
|
||||
window.graphcanvas = editor.graphcanvas;
|
||||
window.graph = editor.graph;
|
||||
updateEditorHiPPICanvas();
|
||||
window.addEventListener("resize", function() {
|
||||
editor.graphcanvas.resize();
|
||||
updateEditorHiPPICanvas();
|
||||
} );
|
||||
//window.addEventListener("keydown", editor.graphcanvas.processKey.bind(editor.graphcanvas) );
|
||||
window.onbeforeunload = function(){
|
||||
var data = JSON.stringify( graph.serialize() );
|
||||
localStorage.setItem("litegraphg demo backup", data );
|
||||
}
|
||||
|
||||
function updateEditorHiPPICanvas() {
|
||||
const ratio = window.devicePixelRatio;
|
||||
if(ratio == 1) { return }
|
||||
const rect = editor.canvas.parentNode.getBoundingClientRect();
|
||||
const { width, height } = rect;
|
||||
editor.canvas.width = width * ratio;
|
||||
editor.canvas.height = height * ratio;
|
||||
editor.canvas.style.width = width + "px";
|
||||
editor.canvas.style.height = height + "px";
|
||||
editor.canvas.getContext("2d").scale(ratio, ratio);
|
||||
return editor.canvas;
|
||||
}
|
||||
|
||||
//enable scripting
|
||||
LiteGraph.allow_scripts = true;
|
||||
|
||||
//test
|
||||
//editor.graphcanvas.viewport = [200,200,400,400];
|
||||
|
||||
//create scene selector
|
||||
var elem = document.createElement("span");
|
||||
elem.id = "LGEditorTopBarSelector";
|
||||
elem.className = "selector";
|
||||
elem.innerHTML = "";
|
||||
elem.innerHTML += "Demo <select><option>Empty</option></select> <button class='btn' id='save'>Save</button><button class='btn' id='load'>Load</button><button class='btn' id='download'>Download</button> | <button class='btn' id='webgl'>WebGL</button> <button class='btn' id='multiview'>Multiview</button>";
|
||||
editor.tools.appendChild(elem);
|
||||
var select = elem.querySelector("select");
|
||||
select.addEventListener("change", function(e){
|
||||
var option = this.options[this.selectedIndex];
|
||||
var url = option.dataset["url"];
|
||||
|
||||
if(url)
|
||||
graph.load( url );
|
||||
else if(option.callback)
|
||||
option.callback();
|
||||
else
|
||||
graph.clear();
|
||||
});
|
||||
|
||||
elem.querySelector("#save").addEventListener("click",function(){
|
||||
console.log("saved");
|
||||
localStorage.setItem( "graphdemo_save", JSON.stringify( graph.serialize() ) );
|
||||
});
|
||||
|
||||
elem.querySelector("#load").addEventListener("click",function(){
|
||||
var data = localStorage.getItem( "graphdemo_save" );
|
||||
if(data)
|
||||
graph.configure( JSON.parse( data ) );
|
||||
console.log("loaded");
|
||||
});
|
||||
|
||||
elem.querySelector("#download").addEventListener("click",function(){
|
||||
var data = JSON.stringify( graph.serialize() );
|
||||
var file = new Blob( [ data ] );
|
||||
var url = URL.createObjectURL( file );
|
||||
var element = document.createElement("a");
|
||||
element.setAttribute('href', url);
|
||||
element.setAttribute('download', "graph.JSON" );
|
||||
element.style.display = 'none';
|
||||
document.body.appendChild(element);
|
||||
element.click();
|
||||
document.body.removeChild(element);
|
||||
setTimeout( function(){ URL.revokeObjectURL( url ); }, 1000*60 ); //wait one minute to revoke url
|
||||
});
|
||||
|
||||
elem.querySelector("#webgl").addEventListener("click", enableWebGL );
|
||||
elem.querySelector("#multiview").addEventListener("click", function(){ editor.addMultiview() } );
|
||||
|
||||
|
||||
function addDemo( name, url )
|
||||
{
|
||||
var option = document.createElement("option");
|
||||
if(url.constructor === String)
|
||||
option.dataset["url"] = url;
|
||||
else
|
||||
option.callback = url;
|
||||
option.innerHTML = name;
|
||||
select.appendChild( option );
|
||||
}
|
||||
|
||||
//some examples
|
||||
addDemo("Features", "examples/features.json");
|
||||
addDemo("Benchmark", "examples/benchmark.json");
|
||||
addDemo("Subgraph", "examples/subgraph.json");
|
||||
addDemo("Audio", "examples/audio.json");
|
||||
addDemo("Audio Delay", "examples/audio_delay.json");
|
||||
addDemo("Audio Reverb", "examples/audio_reverb.json");
|
||||
addDemo("MIDI Generation", "examples/midi_generation.json");
|
||||
addDemo("Copy Paste", "examples/copypaste.json");
|
||||
addDemo("autobackup", function(){
|
||||
var data = localStorage.getItem("litegraphg demo backup");
|
||||
if(!data)
|
||||
return;
|
||||
var graph_data = JSON.parse(data);
|
||||
graph.configure( graph_data );
|
||||
});
|
||||
|
||||
//allows to use the WebGL nodes like textures
|
||||
function enableWebGL()
|
||||
{
|
||||
if( webgl_canvas )
|
||||
{
|
||||
webgl_canvas.style.display = (webgl_canvas.style.display == "none" ? "block" : "none");
|
||||
return;
|
||||
}
|
||||
|
||||
var libs = [
|
||||
"js/libs/gl-matrix-min.js",
|
||||
"js/libs/litegl.js",
|
||||
"../src/nodes/gltextures.js",
|
||||
"../src/nodes/glfx.js",
|
||||
"../src/nodes/glshaders.js",
|
||||
"../src/nodes/geometry.js"
|
||||
];
|
||||
|
||||
function fetchJS()
|
||||
{
|
||||
if(libs.length == 0)
|
||||
return on_ready();
|
||||
|
||||
var script = null;
|
||||
script = document.createElement("script");
|
||||
script.onload = fetchJS;
|
||||
script.src = libs.shift();
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
fetchJS();
|
||||
|
||||
function on_ready()
|
||||
{
|
||||
console.log(this.src);
|
||||
if(!window.GL)
|
||||
return;
|
||||
webgl_canvas = document.createElement("canvas");
|
||||
webgl_canvas.width = 400;
|
||||
webgl_canvas.height = 300;
|
||||
webgl_canvas.style.position = "absolute";
|
||||
webgl_canvas.style.top = "0px";
|
||||
webgl_canvas.style.right = "0px";
|
||||
webgl_canvas.style.border = "1px solid #AAA";
|
||||
|
||||
webgl_canvas.addEventListener("click", function(){
|
||||
var rect = webgl_canvas.parentNode.getBoundingClientRect();
|
||||
if( webgl_canvas.width != rect.width )
|
||||
{
|
||||
webgl_canvas.width = rect.width;
|
||||
webgl_canvas.height = rect.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
webgl_canvas.width = 400;
|
||||
webgl_canvas.height = 300;
|
||||
}
|
||||
});
|
||||
|
||||
var parent = document.querySelector(".editor-area");
|
||||
parent.appendChild( webgl_canvas );
|
||||
var gl = GL.create({ canvas: webgl_canvas });
|
||||
if(!gl)
|
||||
return;
|
||||
|
||||
editor.graph.onBeforeStep = ondraw;
|
||||
|
||||
console.log("webgl ready");
|
||||
function ondraw ()
|
||||
{
|
||||
gl.clearColor(0,0,0,0);
|
||||
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
|
||||
gl.viewport(0,0,gl.canvas.width, gl.canvas.height );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tests
|
||||
// CopyPasteWithConnectionToUnselectedOutputTest();
|
||||
// demo();
|
||||
@@ -1,32 +0,0 @@
|
||||
|
||||
LiteGraph.debug = false;
|
||||
LiteGraph.catch_exceptions = true;
|
||||
LiteGraph.throw_errors = true;
|
||||
LiteGraph.allow_scripts = false; //if set to true some nodes like Formula would be allowed to evaluate code that comes from unsafe sources (like node configuration); which could lead to exploits
|
||||
|
||||
LiteGraph.searchbox_extras = {}; //used to add extra features to the search box
|
||||
LiteGraph.auto_sort_node_types = true; // [true!] If set to true; will automatically sort node types / categories in the context menus
|
||||
LiteGraph.node_box_coloured_when_on = true; // [true!] this make the nodes box (top left circle) coloured when triggered (execute/action); visual feedback
|
||||
LiteGraph.node_box_coloured_by_mode = true; // [true!] nodebox based on node mode; visual feedback
|
||||
LiteGraph.dialog_close_on_mouse_leave = true; // [false on mobile] better true if not touch device;
|
||||
LiteGraph.dialog_close_on_mouse_leave_delay = 500;
|
||||
LiteGraph.shift_click_do_break_link_from = false; // [false!] prefer false if results too easy to break links
|
||||
LiteGraph.click_do_break_link_to = false; // [false!]prefer false; way too easy to break links
|
||||
LiteGraph.search_hide_on_mouse_leave = true; // [false on mobile] better true if not touch device;
|
||||
LiteGraph.search_filter_enabled = true; // [true!] enable filtering slots type in the search widget; !requires auto_load_slot_types or manual set registered_slot_[in/out]_types and slot_types_[in/out]
|
||||
LiteGraph.search_show_all_on_open = true; // [true!] opens the results list when opening the search widget
|
||||
|
||||
LiteGraph.auto_load_slot_types = true; // [if want false; use true; run; get vars values to be statically set; than disable] nodes types and nodeclass association with node types need to be calculated; if dont want this; calculate once and set registered_slot_[in/out]_types and slot_types_[in/out]
|
||||
/*// set these values if not using auto_load_slot_types
|
||||
LiteGraph.registered_slot_in_types = {}; // slot types for nodeclass
|
||||
LiteGraph.registered_slot_out_types = {}; // slot types for nodeclass
|
||||
LiteGraph.slot_types_in = []; // slot types IN
|
||||
LiteGraph.slot_types_out = []; // slot types OUT*/
|
||||
|
||||
LiteGraph.alt_drag_do_clone_nodes = true; // [true!] very handy; ALT click to clone and drag the new node
|
||||
LiteGraph.do_add_triggers_slots = true; // [true!] will create and connect event slots when using action/events connections; !WILL CHANGE node mode when using onTrigger (enable mode colors); onExecuted does not need this
|
||||
LiteGraph.allow_multi_output_for_events = false; // [false!] being events; it is strongly reccomended to use them sequentially; one by one
|
||||
LiteGraph.middle_click_slot_add_default_node = true; //[true!] allows to create and connect a ndoe clicking with the third button (wheel)
|
||||
LiteGraph.release_link_on_empty_shows_menu = true; //[true!] dragging a link to empty space will open a menu, add from list, search or defaults
|
||||
LiteGraph.pointerevents_method = "mouse"; // "mouse"|"pointer" use mouse for retrocompatibility issues? (none found @ now)
|
||||
LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs = true; //[true!] allows ctrl + shift + v to paste nodes with the outputs of the unselected nodes connected with the inputs of the newly pasted nodes
|
||||
@@ -1,32 +0,0 @@
|
||||
|
||||
LiteGraph.debug = false;
|
||||
LiteGraph.catch_exceptions = true;
|
||||
LiteGraph.throw_errors = true;
|
||||
LiteGraph.allow_scripts = false; //if set to true some nodes like Formula would be allowed to evaluate code that comes from unsafe sources (like node configuration); which could lead to exploits
|
||||
|
||||
LiteGraph.searchbox_extras = {}; //used to add extra features to the search box
|
||||
LiteGraph.auto_sort_node_types = true; // [true!] If set to true; will automatically sort node types / categories in the context menus
|
||||
LiteGraph.node_box_coloured_when_on = true; // [true!] this make the nodes box (top left circle) coloured when triggered (execute/action); visual feedback
|
||||
LiteGraph.node_box_coloured_by_mode = true; // [true!] nodebox based on node mode; visual feedback
|
||||
LiteGraph.dialog_close_on_mouse_leave = false; // [false on mobile] better true if not touch device;
|
||||
LiteGraph.dialog_close_on_mouse_leave_delay = 500;
|
||||
LiteGraph.shift_click_do_break_link_from = false; // [false!] prefer false if results too easy to break links
|
||||
LiteGraph.click_do_break_link_to = false; // [false!]prefer false; way too easy to break links
|
||||
LiteGraph.search_hide_on_mouse_leave = false; // [false on mobile] better true if not touch device;
|
||||
LiteGraph.search_filter_enabled = true; // [true!] enable filtering slots type in the search widget; !requires auto_load_slot_types or manual set registered_slot_[in/out]_types and slot_types_[in/out]
|
||||
LiteGraph.search_show_all_on_open = true; // [true!] opens the results list when opening the search widget
|
||||
|
||||
LiteGraph.auto_load_slot_types = true; // [if want false; use true; run; get vars values to be statically set; than disable] nodes types and nodeclass association with node types need to be calculated; if dont want this; calculate once and set registered_slot_[in/out]_types and slot_types_[in/out]
|
||||
/*// set these values if not using auto_load_slot_types
|
||||
LiteGraph.registered_slot_in_types = {}; // slot types for nodeclass
|
||||
LiteGraph.registered_slot_out_types = {}; // slot types for nodeclass
|
||||
LiteGraph.slot_types_in = []; // slot types IN
|
||||
LiteGraph.slot_types_out = []; // slot types OUT*/
|
||||
|
||||
LiteGraph.alt_drag_do_clone_nodes = true; // [true!] very handy; ALT click to clone and drag the new node
|
||||
LiteGraph.do_add_triggers_slots = true; // [true!] will create and connect event slots when using action/events connections; !WILL CHANGE node mode when using onTrigger (enable mode colors); onExecuted does not need this
|
||||
LiteGraph.allow_multi_output_for_events = false; // [false!] being events; it is strongly reccomended to use them sequentially; one by one
|
||||
LiteGraph.middle_click_slot_add_default_node = true; //[true!] allows to create and connect a ndoe clicking with the third button (wheel)
|
||||
LiteGraph.release_link_on_empty_shows_menu = true; //[true!] dragging a link to empty space will open a menu, add from list, search or defaults
|
||||
LiteGraph.pointerevents_method = "pointer"; // "mouse"|"pointer" use mouse for retrocompatibility issues? (none found @ now)
|
||||
LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs = true; //[true!] allows ctrl + shift + v to paste nodes with the outputs of the unselected nodes connected with the inputs of the newly pasted nodes
|
||||
@@ -1,307 +0,0 @@
|
||||
|
||||
function demo()
|
||||
{
|
||||
multiConnection();
|
||||
}
|
||||
|
||||
function multiConnection()
|
||||
{
|
||||
var node_button = LiteGraph.createNode("widget/button");
|
||||
node_button.pos = [100,400];
|
||||
graph.add(node_button);
|
||||
|
||||
var node_console = LiteGraph.createNode("basic/console");
|
||||
node_console.pos = [400,400];
|
||||
graph.add(node_console);
|
||||
node_button.connect(0, node_console );
|
||||
|
||||
var node_const_A = LiteGraph.createNode("basic/const");
|
||||
node_const_A.pos = [200,200];
|
||||
graph.add(node_const_A);
|
||||
node_const_A.setValue(4.5);
|
||||
|
||||
var node_const_B = LiteGraph.createNode("basic/const");
|
||||
node_const_B.pos = [200,300];
|
||||
graph.add(node_const_B);
|
||||
node_const_B.setValue(10);
|
||||
|
||||
var node_math = LiteGraph.createNode("math/operation");
|
||||
node_math.pos = [400,200];
|
||||
graph.add(node_math);
|
||||
|
||||
var node_watch = LiteGraph.createNode("basic/watch");
|
||||
node_watch.pos = [700,200];
|
||||
graph.add(node_watch);
|
||||
|
||||
var node_watch2 = LiteGraph.createNode("basic/watch");
|
||||
node_watch2.pos = [700,300];
|
||||
graph.add(node_watch2);
|
||||
|
||||
node_const_A.connect(0,node_math,0 );
|
||||
node_const_B.connect(0,node_math,1 );
|
||||
node_math.connect(0,node_watch,0 );
|
||||
node_math.connect(0,node_watch2,0 );
|
||||
}
|
||||
|
||||
function CopyPasteWithConnectionToUnselectedOutputTest()
|
||||
{
|
||||
// number
|
||||
var nodeConstA = LiteGraph.createNode("basic/const");
|
||||
nodeConstA.pos = [200,200];
|
||||
graph.add(nodeConstA);
|
||||
nodeConstA.setValue(4.5);
|
||||
|
||||
// number
|
||||
var nodeConstB = LiteGraph.createNode("basic/const");
|
||||
nodeConstB.pos = [200,300];
|
||||
graph.add(nodeConstB);
|
||||
nodeConstB.setValue(10);
|
||||
|
||||
// math
|
||||
var nodeMath = LiteGraph.createNode("math/operation");
|
||||
nodeMath.pos = [400,200];
|
||||
graph.add(nodeMath);
|
||||
|
||||
// connection
|
||||
nodeConstA.connect(0,nodeMath,0 );
|
||||
nodeConstB.connect(0,nodeMath,1 );
|
||||
|
||||
// copy with unselected nodes connected
|
||||
graphcanvas.selectNodes([nodeMath]);
|
||||
graphcanvas.copyToClipboard();
|
||||
graphcanvas.pasteFromClipboard(true);
|
||||
|
||||
var count = 1;
|
||||
var lastNode = null;
|
||||
for (const [key, element] of Object.entries(graphcanvas.selected_nodes)) {
|
||||
element.pos = [nodeMath.pos[0], nodeMath.pos[1] + 100 * count];
|
||||
lastNode = element
|
||||
count++;
|
||||
}
|
||||
|
||||
// copy with unselected nodes unconnected
|
||||
graphcanvas.pasteFromClipboard(false);
|
||||
var count = 1;
|
||||
for (const [key, element] of Object.entries(graphcanvas.selected_nodes)) {
|
||||
element.pos = [nodeMath.pos[0], lastNode.pos[1] + 100 * count];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
function sortTest()
|
||||
{
|
||||
var rand = LiteGraph.createNode("math/rand",null, {pos: [10,100] });
|
||||
graph.add(rand);
|
||||
|
||||
var nodes = [];
|
||||
for(var i = 4; i >= 1; i--)
|
||||
{
|
||||
var n = LiteGraph.createNode("basic/watch",null, {pos: [i * 120,100] });
|
||||
graph.add(n);
|
||||
nodes[i-1] = n;
|
||||
}
|
||||
|
||||
rand.connect(0, nodes[0], 0);
|
||||
|
||||
for(var i = 0; i < nodes.length - 1; i++)
|
||||
nodes[i].connect(0,nodes[i+1], 0);
|
||||
}
|
||||
|
||||
function benchmark()
|
||||
{
|
||||
var num_nodes = 200;
|
||||
var nodes = [];
|
||||
for(var i = 0; i < num_nodes; i++)
|
||||
{
|
||||
var n = LiteGraph.createNode("basic/watch",null, {pos: [(2000 * Math.random())|0, (2000 * Math.random())|0] });
|
||||
graph.add(n);
|
||||
nodes.push(n);
|
||||
}
|
||||
|
||||
for(var i = 0; i < nodes.length; i++)
|
||||
nodes[ (Math.random() * nodes.length)|0 ].connect(0, nodes[ (Math.random() * nodes.length)|0 ], 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Show value inside the debug console
|
||||
function TestWidgetsNode()
|
||||
{
|
||||
this.addOutput("","number");
|
||||
this.properties = {};
|
||||
var that = this;
|
||||
this.slider = this.addWidget("slider","Slider", 0.5, function(v){}, { min: 0, max: 1} );
|
||||
this.number = this.addWidget("number","Number", 0.5, function(v){}, { min: 0, max: 100} );
|
||||
this.combo = this.addWidget("combo","Combo", "red", function(v){}, { values:["red","green","blue"]} );
|
||||
this.text = this.addWidget("text","Text", "edit me", function(v){}, {} );
|
||||
this.text2 = this.addWidget("text","Text", "multiline", function(v){}, { multiline:true } );
|
||||
this.toggle = this.addWidget("toggle","Toggle", true, function(v){}, { on: "enabled", off:"disabled"} );
|
||||
this.button = this.addWidget("button","Button", null, function(v){}, {} );
|
||||
this.toggle2 = this.addWidget("toggle","Disabled", true, function(v){}, { on: "enabled", off:"disabled"} );
|
||||
this.toggle2.disabled = true;
|
||||
this.size = this.computeSize();
|
||||
this.serialize_widgets = true;
|
||||
}
|
||||
|
||||
TestWidgetsNode.title = "Widgets";
|
||||
|
||||
LiteGraph.registerNodeType("features/widgets", TestWidgetsNode );
|
||||
|
||||
//Show value inside the debug console
|
||||
function TestSpecialNode()
|
||||
{
|
||||
this.addInput("","number");
|
||||
this.addOutput("","number");
|
||||
this.properties = {};
|
||||
var that = this;
|
||||
this.size = this.computeSize();
|
||||
this.enabled = false;
|
||||
this.visible = false;
|
||||
}
|
||||
|
||||
TestSpecialNode.title = "Custom Shapes";
|
||||
TestSpecialNode.title_mode = LiteGraph.TRANSPARENT_TITLE;
|
||||
TestSpecialNode.slot_start_y = 20;
|
||||
|
||||
TestSpecialNode.prototype.onDrawBackground = function(ctx)
|
||||
{
|
||||
if(this.flags.collapsed)
|
||||
return;
|
||||
|
||||
ctx.fillStyle = "#555";
|
||||
ctx.fillRect(0,0,this.size[0],20);
|
||||
|
||||
if(this.enabled)
|
||||
{
|
||||
ctx.fillStyle = "#AFB";
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.size[0]-20,0);
|
||||
ctx.lineTo(this.size[0]-25,20);
|
||||
ctx.lineTo(this.size[0],20);
|
||||
ctx.lineTo(this.size[0],0);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
if(this.visible)
|
||||
{
|
||||
ctx.fillStyle = "#ABF";
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.size[0]-40,0);
|
||||
ctx.lineTo(this.size[0]-45,20);
|
||||
ctx.lineTo(this.size[0]-25,20);
|
||||
ctx.lineTo(this.size[0]-20,0);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
ctx.strokeStyle = "#333";
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0,20);
|
||||
ctx.lineTo(this.size[0]+1,20);
|
||||
ctx.moveTo(this.size[0]-20,0);
|
||||
ctx.lineTo(this.size[0]-25,20);
|
||||
ctx.moveTo(this.size[0]-40,0);
|
||||
ctx.lineTo(this.size[0]-45,20);
|
||||
ctx.stroke();
|
||||
|
||||
if( this.mouseOver )
|
||||
{
|
||||
ctx.fillStyle = "#AAA";
|
||||
ctx.fillText( "Example of helper", 0, this.size[1] + 14 );
|
||||
}
|
||||
}
|
||||
|
||||
TestSpecialNode.prototype.onMouseDown = function(e, pos)
|
||||
{
|
||||
if(pos[1] > 20)
|
||||
return;
|
||||
|
||||
if( pos[0] > this.size[0] - 20)
|
||||
this.enabled = !this.enabled;
|
||||
else if( pos[0] > this.size[0] - 40)
|
||||
this.visible = !this.visible;
|
||||
}
|
||||
|
||||
TestSpecialNode.prototype.onBounding = function(rect)
|
||||
{
|
||||
if(!this.flags.collapsed && this.mouseOver )
|
||||
rect[3] = this.size[1] + 20;
|
||||
}
|
||||
|
||||
LiteGraph.registerNodeType("features/shape", TestSpecialNode );
|
||||
|
||||
|
||||
|
||||
//Show value inside the debug console
|
||||
function TestSlotsNode()
|
||||
{
|
||||
this.addInput("C","number");
|
||||
this.addOutput("A","number");
|
||||
this.addOutput("B","number");
|
||||
this.horizontal = true;
|
||||
this.size = [100,40];
|
||||
}
|
||||
|
||||
TestSlotsNode.title = "Flat Slots";
|
||||
|
||||
|
||||
LiteGraph.registerNodeType("features/slots", TestSlotsNode );
|
||||
|
||||
|
||||
//Show value inside the debug console
|
||||
function TestPropertyEditorsNode()
|
||||
{
|
||||
this.properties = {
|
||||
name: "foo",
|
||||
age: 10,
|
||||
alive: true,
|
||||
children: ["John","Emily","Charles"],
|
||||
skills: {
|
||||
speed: 10,
|
||||
dexterity: 100
|
||||
}
|
||||
}
|
||||
|
||||
var that = this;
|
||||
this.addWidget("button","Log",null,function(){
|
||||
console.log(that.properties);
|
||||
});
|
||||
}
|
||||
|
||||
TestPropertyEditorsNode.title = "Properties";
|
||||
|
||||
|
||||
LiteGraph.registerNodeType("features/properties_editor", TestPropertyEditorsNode );
|
||||
|
||||
|
||||
|
||||
//Show value inside the debug console
|
||||
function LargeInputNode()
|
||||
{
|
||||
this.addInput("in 1","number");
|
||||
this.addInput("in 2","number");
|
||||
this.addInput("in 3","number");
|
||||
this.addInput("in 4","number");
|
||||
this.addInput("in 5","number");
|
||||
this.addInput("in 6","number");
|
||||
this.addInput("in 7","number");
|
||||
this.addInput("in 8","number");
|
||||
this.addInput("in 9","number");
|
||||
this.addInput("in 10","number");
|
||||
this.addInput("in 11","number");
|
||||
this.addInput("in 12","number");
|
||||
this.addInput("in 13","number");
|
||||
this.addInput("in 14","number");
|
||||
this.addInput("in 15","number");
|
||||
this.addInput("in 16","number");
|
||||
this.addInput("in 17","number");
|
||||
this.addInput("in 18","number");
|
||||
this.addInput("in 19","number");
|
||||
this.addInput("in 20","number");
|
||||
this.size = [200,410];
|
||||
}
|
||||
|
||||
LargeInputNode.title = "Large Input Node";
|
||||
|
||||
|
||||
LiteGraph.registerNodeType("features/largeinput_editor", LargeInputNode);
|
||||
|
||||
@@ -1,356 +0,0 @@
|
||||
var Synth, AudioSynth, AudioSynthInstrument;
|
||||
!function(){
|
||||
|
||||
var URL = window.URL || window.webkitURL;
|
||||
var Blob = window.Blob;
|
||||
|
||||
if(!URL || !Blob) {
|
||||
throw new Error('This browser does not support AudioSynth');
|
||||
}
|
||||
|
||||
var _encapsulated = false;
|
||||
var AudioSynthInstance = null;
|
||||
var pack = function(c,arg){ return [new Uint8Array([arg, arg >> 8]), new Uint8Array([arg, arg >> 8, arg >> 16, arg >> 24])][c]; };
|
||||
var setPrivateVar = function(n,v,w,e){Object.defineProperty(this,n,{value:v,writable:!!w,enumerable:!!e});};
|
||||
var setPublicVar = function(n,v,w){setPrivateVar.call(this,n,v,w,true);};
|
||||
AudioSynthInstrument = function AudioSynthInstrument(){this.__init__.apply(this,arguments);};
|
||||
var setPriv = setPrivateVar.bind(AudioSynthInstrument.prototype);
|
||||
var setPub = setPublicVar.bind(AudioSynthInstrument.prototype);
|
||||
setPriv('__init__', function(a,b,c) {
|
||||
if(!_encapsulated) { throw new Error('AudioSynthInstrument can only be instantiated from the createInstrument method of the AudioSynth object.'); }
|
||||
setPrivateVar.call(this, '_parent', a);
|
||||
setPublicVar.call(this, 'name', b);
|
||||
setPrivateVar.call(this, '_soundID', c);
|
||||
});
|
||||
setPub('play', function(note, octave, duration,volume) {
|
||||
return this._parent.play(this._soundID, note, octave, duration, volume);
|
||||
});
|
||||
setPub('generate', function(note, octave, duration) {
|
||||
return this._parent.generate(this._soundID, note, octave, duration);
|
||||
});
|
||||
AudioSynth = function AudioSynth(){if(AudioSynthInstance instanceof AudioSynth){return AudioSynthInstance;}else{ this.__init__(); return this; }};
|
||||
setPriv = setPrivateVar.bind(AudioSynth.prototype);
|
||||
setPub = setPublicVar.bind(AudioSynth.prototype);
|
||||
setPriv('_debug',false,true);
|
||||
setPriv('_bitsPerSample',16);
|
||||
setPriv('_channels',1);
|
||||
setPriv('_sampleRate',44100,true);
|
||||
setPub('setSampleRate', function(v) {
|
||||
this._sampleRate = Math.max(Math.min(v|0,44100), 4000);
|
||||
this._clearCache();
|
||||
return this._sampleRate;
|
||||
});
|
||||
setPub('getSampleRate', function() { return this._sampleRate; });
|
||||
setPriv('_volume',32768,true);
|
||||
setPub('setVolume', function(v) {
|
||||
v = parseFloat(v); if(isNaN(v)) { v = 0; }
|
||||
v = Math.round(v*32768);
|
||||
this._volume = Math.max(Math.min(v|0,32768), 0);
|
||||
this._clearCache();
|
||||
return this._volume;
|
||||
});
|
||||
setPub('getVolume', function() { return Math.round(this._volume/32768*10000)/10000; });
|
||||
setPriv('_notes',{'C':261.63,'C#':277.18,'D':293.66,'D#':311.13,'E':329.63,'F':346.23,'F#':369.99,'G':392.00,'G#':415.30,'A':440.00,'A#':466.16,'B':493.88});
|
||||
setPriv('_fileCache',[],true);
|
||||
setPriv('_temp',{},true);
|
||||
setPriv('_sounds',[],true);
|
||||
setPriv('_mod',[function(i,s,f,x){return Math.sin((2 * Math.PI)*(i/s)*f+x);}]);
|
||||
setPriv('_resizeCache', function() {
|
||||
var f = this._fileCache;
|
||||
var l = this._sounds.length;
|
||||
while(f.length<l) {
|
||||
var octaveList = [];
|
||||
for(var i = 0; i < 8; i++) {
|
||||
var noteList = {};
|
||||
for(var k in this._notes) {
|
||||
noteList[k] = {};
|
||||
}
|
||||
octaveList.push(noteList);
|
||||
}
|
||||
f.push(octaveList);
|
||||
}
|
||||
});
|
||||
setPriv('_clearCache', function() {
|
||||
this._fileCache = [];
|
||||
this._resizeCache();
|
||||
});
|
||||
setPub('generate', function(sound, note, octave, duration) {
|
||||
var thisSound = this._sounds[sound];
|
||||
if(!thisSound) {
|
||||
for(var i=0;i<this._sounds.length;i++) {
|
||||
if(this._sounds[i].name==sound) {
|
||||
thisSound = this._sounds[i];
|
||||
sound = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!thisSound) { throw new Error('Invalid sound or sound ID: ' + sound); }
|
||||
var t = (new Date).valueOf();
|
||||
this._temp = {};
|
||||
octave |= 0;
|
||||
octave = Math.min(8, Math.max(1, octave));
|
||||
var time = !duration?2:parseFloat(duration);
|
||||
if(typeof(this._notes[note])=='undefined') { throw new Error(note + ' is not a valid note.'); }
|
||||
if(typeof(this._fileCache[sound][octave-1][note][time])!='undefined') {
|
||||
if(this._debug) { console.log((new Date).valueOf() - t, 'ms to retrieve (cached)'); }
|
||||
return this._fileCache[sound][octave-1][note][time];
|
||||
} else {
|
||||
var frequency = this._notes[note] * Math.pow(2,octave-4);
|
||||
var sampleRate = this._sampleRate;
|
||||
var volume = this._volume;
|
||||
var channels = this._channels;
|
||||
var bitsPerSample = this._bitsPerSample;
|
||||
var attack = thisSound.attack(sampleRate, frequency, volume);
|
||||
var dampen = thisSound.dampen(sampleRate, frequency, volume);
|
||||
var waveFunc = thisSound.wave;
|
||||
var waveBind = {modulate: this._mod, vars: this._temp};
|
||||
var val = 0;
|
||||
var curVol = 0;
|
||||
|
||||
var data = new Uint8Array(new ArrayBuffer(Math.ceil(sampleRate * time * 2)));
|
||||
var attackLen = (sampleRate * attack) | 0;
|
||||
var decayLen = (sampleRate * time) | 0;
|
||||
|
||||
for (var i = 0 | 0; i !== attackLen; i++) {
|
||||
|
||||
val = volume * (i/(sampleRate*attack)) * waveFunc.call(waveBind, i, sampleRate, frequency, volume);
|
||||
|
||||
data[i << 1] = val;
|
||||
data[(i << 1) + 1] = val >> 8;
|
||||
|
||||
}
|
||||
|
||||
for (; i !== decayLen; i++) {
|
||||
|
||||
val = volume * Math.pow((1-((i-(sampleRate*attack))/(sampleRate*(time-attack)))),dampen) * waveFunc.call(waveBind, i, sampleRate, frequency, volume);
|
||||
|
||||
data[i << 1] = val;
|
||||
data[(i << 1) + 1] = val >> 8;
|
||||
|
||||
}
|
||||
|
||||
var out = [
|
||||
'RIFF',
|
||||
pack(1, 4 + (8 + 24/* chunk 1 length */) + (8 + 8/* chunk 2 length */)), // Length
|
||||
'WAVE',
|
||||
// chunk 1
|
||||
'fmt ', // Sub-chunk identifier
|
||||
pack(1, 16), // Chunk length
|
||||
pack(0, 1), // Audio format (1 is linear quantization)
|
||||
pack(0, channels),
|
||||
pack(1, sampleRate),
|
||||
pack(1, sampleRate * channels * bitsPerSample / 8), // Byte rate
|
||||
pack(0, channels * bitsPerSample / 8),
|
||||
pack(0, bitsPerSample),
|
||||
// chunk 2
|
||||
'data', // Sub-chunk identifier
|
||||
pack(1, data.length * channels * bitsPerSample / 8), // Chunk length
|
||||
data
|
||||
];
|
||||
var blob = new Blob(out, {type: 'audio/wav'});
|
||||
var dataURI = URL.createObjectURL(blob);
|
||||
this._fileCache[sound][octave-1][note][time] = dataURI;
|
||||
if(this._debug) { console.log((new Date).valueOf() - t, 'ms to generate'); }
|
||||
return dataURI;
|
||||
}
|
||||
});
|
||||
setPub('play', function(sound, note, octave, duration, volume) {
|
||||
var src = this.generate( sound, note, octave, duration );
|
||||
var audio = new Audio(src);
|
||||
if(volume != null)
|
||||
{
|
||||
if(volume <= 0)
|
||||
return true;
|
||||
audio.volume = volume > 1 ? 1 : volume;
|
||||
}
|
||||
audio.play();
|
||||
return true;
|
||||
});
|
||||
setPub('debug', function() { this._debug = true; });
|
||||
setPub('createInstrument', function(sound) {
|
||||
var n = 0;
|
||||
var found = false;
|
||||
if(typeof(sound)=='string') {
|
||||
for(var i=0;i<this._sounds.length;i++) {
|
||||
if(this._sounds[i].name==sound) {
|
||||
found = true;
|
||||
n = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(this._sounds[sound]) {
|
||||
n = sound;
|
||||
sound = this._sounds[n].name;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if(!found) { throw new Error('Invalid sound or sound ID: ' + sound); }
|
||||
_encapsulated = true;
|
||||
var ins = new AudioSynthInstrument(this, sound, n);
|
||||
_encapsulated = false;
|
||||
return ins;
|
||||
});
|
||||
setPub('listSounds', function() {
|
||||
var r = [];
|
||||
for(var i=0;i<this._sounds.length;i++) {
|
||||
r.push(this._sounds[i].name);
|
||||
}
|
||||
return r;
|
||||
});
|
||||
setPriv('__init__', function(){
|
||||
this._resizeCache();
|
||||
});
|
||||
setPub('loadSoundProfile', function() {
|
||||
for(var i=0,len=arguments.length;i<len;i++) {
|
||||
o = arguments[i];
|
||||
if(!(o instanceof Object)) { throw new Error('Invalid sound profile.'); }
|
||||
this._sounds.push(o);
|
||||
}
|
||||
this._resizeCache();
|
||||
return true;
|
||||
});
|
||||
setPub('loadModulationFunction', function() {
|
||||
for(var i=0,len=arguments.length;i<len;i++) {
|
||||
f = arguments[i];
|
||||
if(typeof(f)!='function') { throw new Error('Invalid modulation function.'); }
|
||||
this._mod.push(f);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
AudioSynthInstance = new AudioSynth();
|
||||
Synth = AudioSynthInstance;
|
||||
}();
|
||||
|
||||
Synth.loadModulationFunction(
|
||||
function(i, sampleRate, frequency, x) { return 1 * Math.sin(2 * Math.PI * ((i / sampleRate) * frequency) + x); },
|
||||
function(i, sampleRate, frequency, x) { return 1 * Math.sin(4 * Math.PI * ((i / sampleRate) * frequency) + x); },
|
||||
function(i, sampleRate, frequency, x) { return 1 * Math.sin(8 * Math.PI * ((i / sampleRate) * frequency) + x); },
|
||||
function(i, sampleRate, frequency, x) { return 1 * Math.sin(0.5 * Math.PI * ((i / sampleRate) * frequency) + x); },
|
||||
function(i, sampleRate, frequency, x) { return 1 * Math.sin(0.25 * Math.PI * ((i / sampleRate) * frequency) + x); },
|
||||
function(i, sampleRate, frequency, x) { return 0.5 * Math.sin(2 * Math.PI * ((i / sampleRate) * frequency) + x); },
|
||||
function(i, sampleRate, frequency, x) { return 0.5 * Math.sin(4 * Math.PI * ((i / sampleRate) * frequency) + x); },
|
||||
function(i, sampleRate, frequency, x) { return 0.5 * Math.sin(8 * Math.PI * ((i / sampleRate) * frequency) + x); },
|
||||
function(i, sampleRate, frequency, x) { return 0.5 * Math.sin(0.5 * Math.PI * ((i / sampleRate) * frequency) + x); },
|
||||
function(i, sampleRate, frequency, x) { return 0.5 * Math.sin(0.25 * Math.PI * ((i / sampleRate) * frequency) + x); }
|
||||
);
|
||||
|
||||
Synth.loadSoundProfile({
|
||||
name: 'piano',
|
||||
attack: function() { return 0.002; },
|
||||
dampen: function(sampleRate, frequency, volume) {
|
||||
return Math.pow(0.5*Math.log((frequency*volume)/sampleRate),2);
|
||||
},
|
||||
wave: function(i, sampleRate, frequency, volume) {
|
||||
var base = this.modulate[0];
|
||||
return this.modulate[1](
|
||||
i,
|
||||
sampleRate,
|
||||
frequency,
|
||||
Math.pow(base(i, sampleRate, frequency, 0), 2) +
|
||||
(0.75 * base(i, sampleRate, frequency, 0.25)) +
|
||||
(0.1 * base(i, sampleRate, frequency, 0.5))
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'organ',
|
||||
attack: function() { return 0.3 },
|
||||
dampen: function(sampleRate, frequency) { return 1+(frequency * 0.01); },
|
||||
wave: function(i, sampleRate, frequency) {
|
||||
var base = this.modulate[0];
|
||||
return this.modulate[1](
|
||||
i,
|
||||
sampleRate,
|
||||
frequency,
|
||||
base(i, sampleRate, frequency, 0) +
|
||||
0.5*base(i, sampleRate, frequency, 0.25) +
|
||||
0.25*base(i, sampleRate, frequency, 0.5)
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'acoustic',
|
||||
attack: function() { return 0.002; },
|
||||
dampen: function() { return 1; },
|
||||
wave: function(i, sampleRate, frequency) {
|
||||
|
||||
var vars = this.vars;
|
||||
vars.valueTable = !vars.valueTable?[]:vars.valueTable;
|
||||
if(typeof(vars.playVal)=='undefined') { vars.playVal = 0; }
|
||||
if(typeof(vars.periodCount)=='undefined') { vars.periodCount = 0; }
|
||||
|
||||
var valueTable = vars.valueTable;
|
||||
var playVal = vars.playVal;
|
||||
var periodCount = vars.periodCount;
|
||||
|
||||
var period = sampleRate/frequency;
|
||||
var p_hundredth = Math.floor((period-Math.floor(period))*100);
|
||||
|
||||
var resetPlay = false;
|
||||
|
||||
if(valueTable.length<=Math.ceil(period)) {
|
||||
|
||||
valueTable.push(Math.round(Math.random())*2-1);
|
||||
|
||||
return valueTable[valueTable.length-1];
|
||||
|
||||
} else {
|
||||
|
||||
valueTable[playVal] = (valueTable[playVal>=(valueTable.length-1)?0:playVal+1] + valueTable[playVal]) * 0.5;
|
||||
|
||||
if(playVal>=Math.floor(period)) {
|
||||
if(playVal<Math.ceil(period)) {
|
||||
if((periodCount%100)>=p_hundredth) {
|
||||
// Reset
|
||||
resetPlay = true;
|
||||
valueTable[playVal+1] = (valueTable[0] + valueTable[playVal+1]) * 0.5;
|
||||
vars.periodCount++;
|
||||
}
|
||||
} else {
|
||||
resetPlay = true;
|
||||
}
|
||||
}
|
||||
|
||||
var _return = valueTable[playVal];
|
||||
if(resetPlay) { vars.playVal = 0; } else { vars.playVal++; }
|
||||
|
||||
return _return;
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'edm',
|
||||
attack: function() { return 0.002; },
|
||||
dampen: function() { return 1; },
|
||||
wave: function(i, sampleRate, frequency) {
|
||||
var base = this.modulate[0];
|
||||
var mod = this.modulate.slice(1);
|
||||
return mod[0](
|
||||
i,
|
||||
sampleRate,
|
||||
frequency,
|
||||
mod[9](
|
||||
i,
|
||||
sampleRate,
|
||||
frequency,
|
||||
mod[2](
|
||||
i,
|
||||
sampleRate,
|
||||
frequency,
|
||||
Math.pow(base(i, sampleRate, frequency, 0), 3) +
|
||||
Math.pow(base(i, sampleRate, frequency, 0.5), 5) +
|
||||
Math.pow(base(i, sampleRate, frequency, 1), 7)
|
||||
)
|
||||
) +
|
||||
mod[8](
|
||||
i,
|
||||
sampleRate,
|
||||
frequency,
|
||||
base(i, sampleRate, frequency, 1.75)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
28
editor/js/libs/gl-matrix-min.js
vendored
13432
editor/js/libs/litegl.js
@@ -1,356 +0,0 @@
|
||||
/*
|
||||
Project Name : midi-parser-js
|
||||
Project Url : https://github.com/colxi/midi-parser-js/
|
||||
Author : colxi
|
||||
Author URL : http://www.colxi.info/
|
||||
Description : MidiParser library reads .MID binary files, Base64 encoded MIDI Data,
|
||||
or UInt8 Arrays, and outputs as a readable and structured JS object.
|
||||
*/
|
||||
|
||||
(function(){
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* CROSSBROWSER & NODEjs POLYFILL for ATOB() -
|
||||
* By: https://github.com/MaxArt2501 (modified)
|
||||
* @param {string} string [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
const _atob = function(string) {
|
||||
// base64 character set, plus padding character (=)
|
||||
let b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
// Regular expression to check formal correctness of base64 encoded strings
|
||||
let b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
|
||||
// remove data type signatures at the begining of the string
|
||||
// eg : "data:audio/mid;base64,"
|
||||
string = string.replace( /^.*?base64,/ , '');
|
||||
// atob can work with strings with whitespaces, even inside the encoded part,
|
||||
// but only \t, \n, \f, \r and ' ', which can be stripped.
|
||||
string = String(string).replace(/[\t\n\f\r ]+/g, '');
|
||||
if (!b64re.test(string))
|
||||
throw new TypeError('Failed to execute _atob() : The string to be decoded is not correctly encoded.');
|
||||
|
||||
// Adding the padding if missing, for semplicity
|
||||
string += '=='.slice(2 - (string.length & 3));
|
||||
let bitmap, result = '';
|
||||
let r1, r2, i = 0;
|
||||
for (; i < string.length;) {
|
||||
bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12
|
||||
| (r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++)));
|
||||
|
||||
result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255)
|
||||
: r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255)
|
||||
: String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* [MidiParser description]
|
||||
* @type {Object}
|
||||
*/
|
||||
const MidiParser = {
|
||||
// debug (bool), when enabled will log in console unimplemented events
|
||||
// warnings and internal handled errors.
|
||||
debug: false,
|
||||
|
||||
/**
|
||||
* [parse description]
|
||||
* @param {[type]} input [description]
|
||||
* @param {[type]} _callback [description]
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
parse: function(input, _callback){
|
||||
if(input instanceof Uint8Array) return MidiParser.Uint8(input);
|
||||
else if(typeof input === 'string') return MidiParser.Base64(input);
|
||||
else if(input instanceof HTMLElement && input.type === 'file') return MidiParser.addListener(input , _callback);
|
||||
else throw new Error('MidiParser.parse() : Invalid input provided');
|
||||
},
|
||||
|
||||
/**
|
||||
* addListener() should be called in order attach a listener to the INPUT HTML element
|
||||
* that will provide the binary data automating the conversion, and returning
|
||||
* the structured data to the provided callback function.
|
||||
*/
|
||||
addListener: function(_fileElement, _callback){
|
||||
if(!File || !FileReader) throw new Error('The File|FileReader APIs are not supported in this browser. Use instead MidiParser.Base64() or MidiParser.Uint8()');
|
||||
|
||||
// validate provided element
|
||||
if( _fileElement === undefined ||
|
||||
!(_fileElement instanceof HTMLElement) ||
|
||||
_fileElement.tagName !== 'INPUT' ||
|
||||
_fileElement.type.toLowerCase() !== 'file'
|
||||
){
|
||||
console.warn('MidiParser.addListener() : Provided element is not a valid FILE INPUT element');
|
||||
return false;
|
||||
}
|
||||
_callback = _callback || function(){};
|
||||
|
||||
_fileElement.addEventListener('change', function(InputEvt){ // set the 'file selected' event handler
|
||||
if (!InputEvt.target.files.length) return false; // return false if no elements where selected
|
||||
console.log('MidiParser.addListener() : File detected in INPUT ELEMENT processing data..');
|
||||
let reader = new FileReader(); // prepare the file Reader
|
||||
reader.readAsArrayBuffer(InputEvt.target.files[0]); // read the binary data
|
||||
reader.onload = function(e){
|
||||
_callback( MidiParser.Uint8(new Uint8Array(e.target.result))); // encode data with Uint8Array and call the parser
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Base64() : convert baset4 string into uint8 array buffer, before performing the
|
||||
* parsing subroutine.
|
||||
*/
|
||||
Base64 : function(b64String){
|
||||
b64String = String(b64String);
|
||||
|
||||
let raw = _atob(b64String);
|
||||
let rawLength = raw.length;
|
||||
let t_array = new Uint8Array(new ArrayBuffer(rawLength));
|
||||
|
||||
for(let i=0; i<rawLength; i++) t_array[i] = raw.charCodeAt(i);
|
||||
return MidiParser.Uint8(t_array) ;
|
||||
},
|
||||
|
||||
/**
|
||||
* parse() : function reads the binary data, interpreting and spliting each chuck
|
||||
* and parsing it to a structured Object. When job is finised returns the object
|
||||
* or 'false' if any error was generated.
|
||||
*/
|
||||
Uint8: function(FileAsUint8Array){
|
||||
let file = {
|
||||
data: null,
|
||||
pointer: 0,
|
||||
movePointer: function(_bytes){ // move the pointer negative and positive direction
|
||||
this.pointer += _bytes;
|
||||
return this.pointer;
|
||||
},
|
||||
readInt: function(_bytes){ // get integer from next _bytes group (big-endian)
|
||||
_bytes = Math.min(_bytes, this.data.byteLength-this.pointer);
|
||||
if (_bytes < 1) return -1; // EOF
|
||||
let value = 0;
|
||||
if(_bytes > 1){
|
||||
for(let i=1; i<= (_bytes-1); i++){
|
||||
value += this.data.getUint8(this.pointer) * Math.pow(256, (_bytes - i));
|
||||
this.pointer++;
|
||||
}
|
||||
}
|
||||
value += this.data.getUint8(this.pointer);
|
||||
this.pointer++;
|
||||
return value;
|
||||
},
|
||||
readStr: function(_bytes){ // read as ASCII chars, the followoing _bytes
|
||||
let text = '';
|
||||
for(let char=1; char <= _bytes; char++) text += String.fromCharCode(this.readInt(1));
|
||||
return text;
|
||||
},
|
||||
readIntVLV: function(){ // read a variable length value
|
||||
let value = 0;
|
||||
if ( this.pointer >= this.data.byteLength ){
|
||||
return -1; // EOF
|
||||
}else if(this.data.getUint8(this.pointer) < 128){ // ...value in a single byte
|
||||
value = this.readInt(1);
|
||||
}else{ // ...value in multiple bytes
|
||||
let FirstBytes = [];
|
||||
while(this.data.getUint8(this.pointer) >= 128){
|
||||
FirstBytes.push(this.readInt(1) - 128);
|
||||
}
|
||||
let lastByte = this.readInt(1);
|
||||
for(let dt = 1; dt <= FirstBytes.length; dt++){
|
||||
value += FirstBytes[FirstBytes.length - dt] * Math.pow(128, dt);
|
||||
}
|
||||
value += lastByte;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
file.data = new DataView(FileAsUint8Array.buffer, FileAsUint8Array.byteOffset, FileAsUint8Array.byteLength); // 8 bits bytes file data array
|
||||
// ** read FILE HEADER
|
||||
if(file.readInt(4) !== 0x4D546864){
|
||||
console.warn('Header validation failed (not MIDI standard or file corrupt.)');
|
||||
return false; // Header validation failed (not MIDI standard or file corrupt.)
|
||||
}
|
||||
let headerSize = file.readInt(4); // header size (unused var), getted just for read pointer movement
|
||||
let MIDI = {}; // create new midi object
|
||||
MIDI.formatType = file.readInt(2); // get MIDI Format Type
|
||||
MIDI.tracks = file.readInt(2); // get ammount of track chunks
|
||||
MIDI.track = []; // create array key for track data storing
|
||||
let timeDivisionByte1 = file.readInt(1); // get Time Division first byte
|
||||
let timeDivisionByte2 = file.readInt(1); // get Time Division second byte
|
||||
if(timeDivisionByte1 >= 128){ // discover Time Division mode (fps or tpf)
|
||||
MIDI.timeDivision = [];
|
||||
MIDI.timeDivision[0] = timeDivisionByte1 - 128; // frames per second MODE (1st byte)
|
||||
MIDI.timeDivision[1] = timeDivisionByte2; // ticks in each frame (2nd byte)
|
||||
}else MIDI.timeDivision = (timeDivisionByte1 * 256) + timeDivisionByte2;// else... ticks per beat MODE (2 bytes value)
|
||||
|
||||
// ** read TRACK CHUNK
|
||||
for(let t=1; t <= MIDI.tracks; t++){
|
||||
MIDI.track[t-1] = {event: []}; // create new Track entry in Array
|
||||
let headerValidation = file.readInt(4);
|
||||
if ( headerValidation === -1 ) break; // EOF
|
||||
if(headerValidation !== 0x4D54726B) return false; // Track chunk header validation failed.
|
||||
file.readInt(4); // move pointer. get chunk size (bytes length)
|
||||
let e = 0; // init event counter
|
||||
let endOfTrack = false; // FLAG for track reading secuence breaking
|
||||
// ** read EVENT CHUNK
|
||||
let statusByte;
|
||||
let laststatusByte;
|
||||
while(!endOfTrack){
|
||||
e++; // increase by 1 event counter
|
||||
MIDI.track[t-1].event[e-1] = {}; // create new event object, in events array
|
||||
MIDI.track[t-1].event[e-1].deltaTime = file.readIntVLV(); // get DELTA TIME OF MIDI event (Variable Length Value)
|
||||
statusByte = file.readInt(1); // read EVENT TYPE (STATUS BYTE)
|
||||
if(statusByte === -1) break; // EOF
|
||||
else if(statusByte >= 128) laststatusByte = statusByte; // NEW STATUS BYTE DETECTED
|
||||
else{ // 'RUNNING STATUS' situation detected
|
||||
statusByte = laststatusByte; // apply last loop, Status Byte
|
||||
file.movePointer(-1); // move back the pointer (cause readed byte is not status byte)
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// ** IS META EVENT
|
||||
//
|
||||
if(statusByte === 0xFF){ // Meta Event type
|
||||
MIDI.track[t-1].event[e-1].type = 0xFF; // assign metaEvent code to array
|
||||
MIDI.track[t-1].event[e-1].metaType = file.readInt(1); // assign metaEvent subtype
|
||||
let metaEventLength = file.readIntVLV(); // get the metaEvent length
|
||||
switch(MIDI.track[t-1].event[e-1].metaType){
|
||||
case 0x2F: // end of track, has no data byte
|
||||
case -1: // EOF
|
||||
endOfTrack = true; // change FLAG to force track reading loop breaking
|
||||
break;
|
||||
case 0x01: // Text Event
|
||||
case 0x02: // Copyright Notice
|
||||
case 0x03:
|
||||
case 0x04: // Instrument Name
|
||||
case 0x05: // Lyrics)
|
||||
case 0x07: // Cue point // Sequence/Track Name (documentation: http://www.ta7.de/txt/musik/musi0006.htm)
|
||||
case 0x06: // Marker
|
||||
MIDI.track[t-1].event[e-1].data = file.readStr(metaEventLength);
|
||||
break;
|
||||
case 0x21: // MIDI PORT
|
||||
case 0x59: // Key Signature
|
||||
case 0x51: // Set Tempo
|
||||
MIDI.track[t-1].event[e-1].data = file.readInt(metaEventLength);
|
||||
break;
|
||||
case 0x54: // SMPTE Offset
|
||||
MIDI.track[t-1].event[e-1].data = [];
|
||||
MIDI.track[t-1].event[e-1].data[0] = file.readInt(1);
|
||||
MIDI.track[t-1].event[e-1].data[1] = file.readInt(1);
|
||||
MIDI.track[t-1].event[e-1].data[2] = file.readInt(1);
|
||||
MIDI.track[t-1].event[e-1].data[3] = file.readInt(1);
|
||||
MIDI.track[t-1].event[e-1].data[4] = file.readInt(1);
|
||||
break;
|
||||
case 0x58: // Time Signature
|
||||
MIDI.track[t-1].event[e-1].data = [];
|
||||
MIDI.track[t-1].event[e-1].data[0] = file.readInt(1);
|
||||
MIDI.track[t-1].event[e-1].data[1] = file.readInt(1);
|
||||
MIDI.track[t-1].event[e-1].data[2] = file.readInt(1);
|
||||
MIDI.track[t-1].event[e-1].data[3] = file.readInt(1);
|
||||
break;
|
||||
default :
|
||||
// if user provided a custom interpreter, call it
|
||||
// and assign to event the returned data
|
||||
if( this.customInterpreter !== null){
|
||||
MIDI.track[t-1].event[e-1].data = this.customInterpreter( MIDI.track[t-1].event[e-1].metaType, file, metaEventLength);
|
||||
}
|
||||
// if no customInterpretr is provided, or returned
|
||||
// false (=apply default), perform default action
|
||||
if(this.customInterpreter === null || MIDI.track[t-1].event[e-1].data === false){
|
||||
file.readInt(metaEventLength);
|
||||
MIDI.track[t-1].event[e-1].data = file.readInt(metaEventLength);
|
||||
if (this.debug) console.info('Unimplemented 0xFF meta event! data block readed as Integer');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// IS REGULAR EVENT
|
||||
//
|
||||
else{ // MIDI Control Events OR System Exclusive Events
|
||||
statusByte = statusByte.toString(16).split(''); // split the status byte HEX representation, to obtain 4 bits values
|
||||
if(!statusByte[1]) statusByte.unshift('0'); // force 2 digits
|
||||
MIDI.track[t-1].event[e-1].type = parseInt(statusByte[0], 16);// first byte is EVENT TYPE ID
|
||||
MIDI.track[t-1].event[e-1].channel = parseInt(statusByte[1], 16);// second byte is channel
|
||||
switch(MIDI.track[t-1].event[e-1].type){
|
||||
case 0xF:{ // System Exclusive Events
|
||||
|
||||
// if user provided a custom interpreter, call it
|
||||
// and assign to event the returned data
|
||||
if( this.customInterpreter !== null){
|
||||
MIDI.track[t-1].event[e-1].data = this.customInterpreter( MIDI.track[t-1].event[e-1].type, file , false);
|
||||
}
|
||||
|
||||
// if no customInterpretr is provided, or returned
|
||||
// false (=apply default), perform default action
|
||||
if(this.customInterpreter === null || MIDI.track[t-1].event[e-1].data === false){
|
||||
let event_length = file.readIntVLV();
|
||||
MIDI.track[t-1].event[e-1].data = file.readInt(event_length);
|
||||
if (this.debug) console.info('Unimplemented 0xF exclusive events! data block readed as Integer');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0xA: // Note Aftertouch
|
||||
case 0xB: // Controller
|
||||
case 0xE: // Pitch Bend Event
|
||||
case 0x8: // Note off
|
||||
case 0x9: // Note On
|
||||
MIDI.track[t-1].event[e-1].data = [];
|
||||
MIDI.track[t-1].event[e-1].data[0] = file.readInt(1);
|
||||
MIDI.track[t-1].event[e-1].data[1] = file.readInt(1);
|
||||
break;
|
||||
case 0xC: // Program Change
|
||||
case 0xD: // Channel Aftertouch
|
||||
MIDI.track[t-1].event[e-1].data = file.readInt(1);
|
||||
break;
|
||||
case -1: // EOF
|
||||
endOfTrack = true; // change FLAG to force track reading loop breaking
|
||||
break;
|
||||
default:
|
||||
// if user provided a custom interpreter, call it
|
||||
// and assign to event the returned data
|
||||
if( this.customInterpreter !== null){
|
||||
MIDI.track[t-1].event[e-1].data = this.customInterpreter( MIDI.track[t-1].event[e-1].metaType, file , false);
|
||||
}
|
||||
|
||||
// if no customInterpretr is provided, or returned
|
||||
// false (=apply default), perform default action
|
||||
if(this.customInterpreter === null || MIDI.track[t-1].event[e-1].data === false){
|
||||
console.log('Unknown EVENT detected... reading cancelled!');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return MIDI;
|
||||
},
|
||||
|
||||
/**
|
||||
* custom function to handle unimplemented, or custom midi messages.
|
||||
* If message is a meta-event, the value of metaEventLength will be >0.
|
||||
* Function must return the value to store, and pointer of dataView needs
|
||||
* to be manually increased
|
||||
* If you want default action to be performed, return false
|
||||
*/
|
||||
customInterpreter : null // function( e_type , arrayByffer, metaEventLength){ return e_data_int }
|
||||
};
|
||||
|
||||
|
||||
// if running in NODE export module
|
||||
if(typeof module !== 'undefined') module.exports = MidiParser;
|
||||
else{
|
||||
// if running in Browser, set a global variable.
|
||||
let _global = typeof window === 'object' && window.self === window && window ||
|
||||
typeof self === 'object' && self.self === self && self ||
|
||||
typeof global === 'object' && global.global === global && global;
|
||||
|
||||
_global.MidiParser = MidiParser;
|
||||
}
|
||||
|
||||
|
||||
|
||||
})();
|
||||
260
editor/style.css
@@ -1,260 +0,0 @@
|
||||
html,body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #333;
|
||||
color: #EEE;
|
||||
font: 14px Tahoma;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: "Metro Light",Tahoma;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: "Metro Light";
|
||||
}
|
||||
|
||||
#main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
|
||||
#status {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
color: #FAA;
|
||||
font-size: 18px;
|
||||
padding: 5px;
|
||||
/*border-radius: 5px;*/
|
||||
width: -moz-calc( 50% - 30px);
|
||||
min-height: 30px;
|
||||
overflow: hidden;
|
||||
background-color: #644;
|
||||
}
|
||||
|
||||
#help-message {
|
||||
padding: 2px;
|
||||
font-size: 0.8em;
|
||||
background-color: #464;
|
||||
/*border-radius: 2px;*/
|
||||
}
|
||||
|
||||
#content {
|
||||
position: relative;
|
||||
min-height: 500px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fullscreen #content {
|
||||
min-height: -moz-calc(100% - 80px);
|
||||
min-height: -webkit-calc(100% - 80px);
|
||||
min-height: calc(100% - 80px);
|
||||
}
|
||||
|
||||
.info-section p {
|
||||
padding-left: 20px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.info-section strong {
|
||||
color: #FEA;
|
||||
}
|
||||
|
||||
#visual {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: black;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
.item-list .item {
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
font-size: 1.2em;
|
||||
|
||||
background-color: transparent;
|
||||
color: #999;
|
||||
padding-left: 5px;
|
||||
transition: background-color 300ms, color 300ms, padding-left 300ms;
|
||||
-moz-transition: background-color 300ms, color 300ms, padding-left 300ms;
|
||||
-webkit-transition: background-color 300ms, color 300ms, padding-left 300ms;
|
||||
}
|
||||
|
||||
.item-list .item:hover {
|
||||
background-color: #33A;
|
||||
/*border-radius: 4px;*/
|
||||
color: white;
|
||||
padding-left: 15px;
|
||||
transition: background-color 300ms, color 300ms, padding-left 300ms;
|
||||
-moz-transition: background-color 300ms, color 300ms, padding-left 300ms;
|
||||
-webkit-transition: background-color 300ms, color 300ms, padding-left 300ms;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#gallery .item-list .item:hover {
|
||||
background-color: #A83;
|
||||
}
|
||||
|
||||
.item-list .item strong {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.form label {
|
||||
font-size: 1.2em;
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
color: #AAF;
|
||||
}
|
||||
|
||||
.header input {
|
||||
color: #EEE;
|
||||
background-color: #555;
|
||||
font-size: 1.2em;
|
||||
border: 1px solid black;
|
||||
/*border-radius: 4px;*/
|
||||
padding: 2px;
|
||||
/*box-shadow: inset 0 0 3px #333; */
|
||||
font-family: Verdana;
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#block-app {
|
||||
width:100%;
|
||||
height:100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
text-align: center;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
#block-app span {
|
||||
display: block;
|
||||
font-size: 30px;
|
||||
margin: auto;
|
||||
margin-top: 300px;
|
||||
}
|
||||
|
||||
#block-app span a {
|
||||
display: inline-block;
|
||||
/*border-radius: 4px;*/
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
background-color: red;
|
||||
padding: 0 4px 0 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
height: 12px;
|
||||
width: 6px;
|
||||
background: #222;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(200,200,200,0.4);
|
||||
}
|
||||
::-webkit-scrollbar-corner {
|
||||
background: #766;
|
||||
}
|
||||
|
||||
#editor {
|
||||
position: relative;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#editor .toolsbar {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background-color: #262626;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#editor .toolsbar button {
|
||||
padding: 2px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
margin: 3px 0 0 3px;
|
||||
}
|
||||
|
||||
#editor .toolsbar button.enabled {
|
||||
background-color: #66A;
|
||||
}
|
||||
|
||||
#world {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#worldcanvas {
|
||||
background-color: #343;
|
||||
}
|
||||
|
||||
.popup {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
background-color: rgba(50,50,90,0.8);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.popup .header, .nodepanel .header {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
font-size: 20px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#help {
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
#help p {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.selector {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
|
||||
.selector select {
|
||||
color: white;
|
||||
background-color: black;
|
||||
border: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.graphcanvas{
|
||||
/*touch-action: manipulation; WONT WORK*/
|
||||
/*touch-action: none; DESIDERABLE: implement zoom and pan*/
|
||||
touch-action: pinch-zoom;
|
||||
}
|
||||
BIN
external/Basica.otf
vendored
BIN
external/Criticized.otf
vendored
BIN
external/DS-Digital.otf
vendored
BIN
external/beat.otf
vendored
18
external/jquery-1.6.2.min.js
vendored
47
gruntfile.js
@@ -1,47 +0,0 @@
|
||||
module.exports = function (grunt) {
|
||||
grunt.initConfig({
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
projectFiles: ['src/litegraph.js',
|
||||
'src/nodes/base.js',
|
||||
'src/nodes/events.js',
|
||||
'src/nodes/interface.js',
|
||||
'src/nodes/input.js',
|
||||
'src/nodes/math.js',
|
||||
'src/nodes/logic.js',
|
||||
'src/nodes/image.js',
|
||||
'src/nodes/gltextures.js',
|
||||
'src/nodes/glfx.js',
|
||||
'src/nodes/midi.js',
|
||||
'src/nodes/audio.js',
|
||||
'src/nodes/network.js'
|
||||
],
|
||||
concat: {
|
||||
build: {
|
||||
src: '<%= projectFiles %>',
|
||||
dest: 'build/litegraph.js'
|
||||
}
|
||||
},
|
||||
closureCompiler: {
|
||||
|
||||
options: {
|
||||
compilerFile: 'node_modules/google-closure-compiler/compiler.jar',
|
||||
compilerOpts: {
|
||||
formatting: 'pretty_print',
|
||||
warning_level: 'default'
|
||||
},
|
||||
d32: false, // will use 'java -client -d32 -jar compiler.jar'
|
||||
TieredCompilation: false// will use 'java -server -XX:+TieredCompilation -jar compiler.jar',
|
||||
// ,output_wrapper: '"var LiteGraph = (function(){%output% return LiteGraph;}).call(this);"' //* Make container for all
|
||||
},
|
||||
targetName: {
|
||||
src: '<%= projectFiles %>',
|
||||
dest: 'build/litegraph.min.js'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-concat')
|
||||
grunt.loadNpmTasks('grunt-closure-tools')
|
||||
|
||||
grunt.registerTask('build', ['concat:build', 'closureCompiler'])
|
||||
}
|
||||
344
guides/README.md
@@ -1,344 +0,0 @@
|
||||
# LiteGraph
|
||||
|
||||
Here is a list of useful info when working with LiteGraph.
|
||||
The library is divided in four levels:
|
||||
* **LGraphNode**: the base class of a node (this library uses is own system of inheritance)
|
||||
* **LGraph**: the container of a whole graph made of nodes
|
||||
* **LGraphCanvas**: the class in charge of rendering/interaction with the nodes inside the browser.
|
||||
|
||||
And in ```the src/``` folder there is also another class included:
|
||||
* **LiteGraph.Editor**: A wrapper around LGraphCanvas that adds buttons around it.
|
||||
|
||||
## LGraphNode
|
||||
|
||||
LGraphNode is the base class used for all the nodes classes.
|
||||
To extend the other classes all the methods contained in LGraphNode.prototype are copied to the classes when registered.
|
||||
|
||||
When you create a new node type you do not have to inherit from that class, when the node is registered all the methods are copied to your node prototype. This is done inside the functions ```LiteGraph.registerNodeType(...)```.
|
||||
|
||||
Here is an example of how to create your own node:
|
||||
|
||||
```javascript
|
||||
//your node constructor class
|
||||
function MyAddNode()
|
||||
{
|
||||
//add some input slots
|
||||
this.addInput("A","number");
|
||||
this.addInput("B","number");
|
||||
//add some output slots
|
||||
this.addOutput("A+B","number");
|
||||
//add some properties
|
||||
this.properties = { precision: 1 };
|
||||
}
|
||||
|
||||
//name to show on the canvas
|
||||
MyAddNode.title = "Sum";
|
||||
|
||||
//function to call when the node is executed
|
||||
MyAddNode.prototype.onExecute = function()
|
||||
{
|
||||
//retrieve data from inputs
|
||||
var A = this.getInputData(0);
|
||||
if( A === undefined )
|
||||
A = 0;
|
||||
var B = this.getInputData(1);
|
||||
if( B === undefined )
|
||||
B = 0;
|
||||
//assing data to outputs
|
||||
this.setOutputData( 0, A + B );
|
||||
}
|
||||
|
||||
//register in the system
|
||||
LiteGraph.registerNodeType("basic/sum", MyAddNode );
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Node settings
|
||||
|
||||
There are several settings that could be defined or modified per node:
|
||||
* **size**: ```[width,height]``` the size of the area inside the node (excluding title). Every row is LiteGraph.NODE_SLOT_HEIGHT pixels height.
|
||||
* **properties**: object containing the properties that could be configured by the user, and serialized when saving the graph
|
||||
* **shape**: the shape of the object (could be LiteGraph.BOX_SHAPE,LiteGraph.ROUND_SHAPE,LiteGraph.CARD_SHAPE)
|
||||
* **flags**: flags that can be changed by the user and will be stored when serialized
|
||||
* **collapsed**: if it is shown collapsed (small)
|
||||
* **redraw_on_mouse**: forces a redraw if the mouse passes over the widget
|
||||
* **widgets_up**: widgets do not start after the slots
|
||||
* **widgets_start_y**: widgets should start being drawn from this Y
|
||||
* **clip_area**: clips the content when rendering the node
|
||||
* **resizable**: if it can be resized dragging the corner
|
||||
* **horizontal**: if the slots should be placed horizontally on the top and bottom of the node
|
||||
|
||||
There are several callbacks that could be defined by the user:
|
||||
* **onAdded**: called when added to graph
|
||||
* **onRemoved**: called when removed from graph
|
||||
* **onStart**: called when the graph starts playing
|
||||
* **onStop**: called when the graph stops playing
|
||||
* **onDrawBackground**: render custom node content on canvas (not visible in Live mode)
|
||||
* **onDrawForeground**: render custom node content on canvas (on top of slots)
|
||||
* **onMouseDown,onMouseMove,onMouseUp,onMouseEnter,onMouseLeave** to catch mouse events
|
||||
* **onDblClick**: double clicked in the editor
|
||||
* **onExecute**: called when it is time to execute the node
|
||||
* **onPropertyChanged**: when a property is changed in the panel (return true to skip default behaviour)
|
||||
* **onGetInputs**: returns an array of possible inputs in the form of [ ["name","type"], [...], [...] ]
|
||||
* **onGetOutputs**: returns an array of possible outputs
|
||||
* **onSerialize**: before serializing, receives an object where to store data
|
||||
* **onSelected**: selected in the editor, receives an object where to read data
|
||||
* **onDeselected**: deselected from the editor
|
||||
* **onDropItem**: DOM item dropped over the node
|
||||
* **onDropFile**: file dropped over the node
|
||||
* **onConnectInput**: if returns false the incoming connection will be canceled
|
||||
* **onConnectionsChange**: a connection changed (new one or removed) (LiteGraph.INPUT or LiteGraph.OUTPUT, slot, true if connected, link_info, input_info )
|
||||
|
||||
|
||||
### Node slots
|
||||
|
||||
Every node could have several slots, stored in node.inputs and node.outputs.
|
||||
|
||||
You can add new slots by calling node.addInput or node.addOutput
|
||||
|
||||
The main difference between inputs and outputs is that an input can only have one connection link while outputs could have several.
|
||||
|
||||
To get information about an slot you can access node.inputs[ slot_index ] or node.outputs[ slot_index ]
|
||||
|
||||
Slots have the next information:
|
||||
|
||||
* **name**: string with the name of the slot (used also to show in the canvas)
|
||||
* **type**: string specifying the data type traveling through this link
|
||||
* **link or links**: depending if the slot is input or output contains the id of the link or an array of ids
|
||||
* **label**: optional, string used to rename the name as shown in the canvas.
|
||||
* **dir**: optional, could be LiteGraph.UP, LiteGraph.RIGHT, LiteGraph.DOWN, LiteGraph.LEFT
|
||||
* **color_on**: color to render when it is connected
|
||||
* **color_off**: color to render when it is not connected
|
||||
|
||||
To retrieve the data traveling through a link you can call ```node.getInputData``` or ```node.getOutputData```
|
||||
|
||||
### Define your Graph Node
|
||||
|
||||
When creating a class for a graph node here are some useful points:
|
||||
|
||||
- The constructor should create the default inputs and outputs (use ```addInput``` and ```addOutput```)
|
||||
- Properties that can be edited are stored in ```this.properties = {};```
|
||||
- the ```onExecute``` is the method that will be called when the graph is executed
|
||||
- you can catch if a property was changed defining a ```onPropertyChanged```
|
||||
- you must register your node using ```LiteGraph.registerNodeType("type/name", MyGraphNodeClass );```
|
||||
- you can alter the default priority of execution by defining the ```MyGraphNodeClass.priority``` (default is 0)
|
||||
- you can overwrite how the node is rendered using the ```onDrawBackground``` and ```onDrawForeground```
|
||||
|
||||
### Custom Node Appearance
|
||||
|
||||
You can configure the node shape or the title color if you want it to be different from the body color:
|
||||
```js
|
||||
MyNodeClass.title_color = "#345";
|
||||
MyNodeClass.shape = LiteGraph.ROUND_SHAPE;
|
||||
```
|
||||
|
||||
You can draw something inside a node using the callbacks ```onDrawForeground``` and ```onDrawBackground```. The only difference is that onDrawForeground gets called in Live Mode and onDrawBackground not.
|
||||
|
||||
Both functions receive the [Canvas2D rendering context](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D) and the LGraphCanvas instance where the node is being rendered.
|
||||
|
||||
You do not have to worry about the coordinates system, (0,0) is the top-left corner of the node content area (not the title).
|
||||
|
||||
```js
|
||||
node.onDrawForeground = function(ctx, graphcanvas)
|
||||
{
|
||||
if(this.flags.collapsed)
|
||||
return;
|
||||
ctx.save();
|
||||
ctx.fillColor = "black";
|
||||
ctx.fillRect(0,0,10,this.size[1]);
|
||||
ctx.restore();
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Node Behaviour
|
||||
|
||||
You can also grab events from the mouse in case your node has some sort of special interactivity.
|
||||
|
||||
The second parameter is the position in node coordinates, where 0,0 represents the top-left corner of the node content (below the title).
|
||||
|
||||
```js
|
||||
node.onMouseDown = function( event, pos, graphcanvas )
|
||||
{
|
||||
return true; //return true is the event was used by your node, to block other behaviours
|
||||
}
|
||||
```
|
||||
|
||||
Other methods are:
|
||||
- onMouseMove
|
||||
- onMouseUp
|
||||
- onMouseEnter
|
||||
- onMouseLeave
|
||||
- onKey
|
||||
|
||||
### Node Widgets
|
||||
|
||||
You can add widgets inside the node to edit text, values, etc.
|
||||
|
||||
To do so you must create them in the constructor by calling ```node.addWidget```, the returned value is the object containing all the info about the widget, it is handy to store it in case you want to change the value later from code.
|
||||
|
||||
The syntax is:
|
||||
|
||||
```js
|
||||
function MyNodeType()
|
||||
{
|
||||
this.slider_widget = this.addWidget("slider","Slider", 0.5, function(value, widget, node){ /* do something with the value */ }, { min: 0, max: 1} );
|
||||
}
|
||||
```
|
||||
|
||||
This is the list of supported widgets:
|
||||
* **"number"** to change a value of a number, the syntax is ```this.addWidget("number","Number", current_value, callback, { min: 0, max: 100, step: 1, precision: 3 } );```
|
||||
* **"slider"** to change a number by dragging the mouse, the syntax is the same as number.
|
||||
* **"combo"** to select between multiple choices, the syntax is:
|
||||
|
||||
```this.addWidget("combo","Combo", "red", callback, { values:["red","green","blue"]} );```
|
||||
|
||||
or if you want to use objects:
|
||||
|
||||
```this.addWidget("combo","Combo", value1, callback, { values: { "title1":value1, "title2":value2 } } );```
|
||||
|
||||
* **"text"** to edit a short string
|
||||
* **"toggle"** like a checkbox
|
||||
* **"button"**
|
||||
|
||||
The fourth optional parameter could be options for the widget, the parameters accepted are:
|
||||
* **property**: specifies the name of a property to modify when the widget changes
|
||||
* **min**: min value
|
||||
* **max**: max value
|
||||
* **precision**: set the number of digits after decimal point
|
||||
* **callback**: function to call when the value changes.
|
||||
|
||||
Widget's value is not serialized by default when storing the node state, but if you want to store the value of widgets just set serialize_widgets to true:
|
||||
|
||||
```js
|
||||
function MyNode()
|
||||
{
|
||||
this.addWidget("text","name","");
|
||||
this.serialize_widgets = true;
|
||||
}
|
||||
```
|
||||
|
||||
Or if you want to associate a widget with a property of the node, then specify it in the options:
|
||||
|
||||
```js
|
||||
function MyNode()
|
||||
{
|
||||
this.properties = { surname: "smith" };
|
||||
this.addWidget("text","Surname","", { property: "surname"}); //this will modify the node.properties
|
||||
}
|
||||
```
|
||||
## LGraphCanvas
|
||||
LGraphCanvas is the class in charge of rendering/interaction with the nodes inside the browser.
|
||||
|
||||
## LGraphCanvas settings
|
||||
There are graph canvas settings that could be defined or modified to change behaviour:
|
||||
|
||||
* **allow_interaction**: when set to `false` disable interaction with the canvas (`flags.allow_interaction` on node can be used to override graph canvas setting)
|
||||
|
||||
### Canvas Shortcuts
|
||||
* Space - Holding space key while moving the cursor moves the canvas around. It works when holding the mouse button down so it is easier to connect different nodes when the canvas gets too large.
|
||||
* Ctrl/Shift + Click - Add clicked node to selection.
|
||||
* Ctrl + A - Select all nodes
|
||||
* Ctrl + C/Ctrl + V - Copy and paste selected nodes, without maintaining the connection to the outputs of unselected nodes.
|
||||
* Ctrl + C/Ctrl + Shift + V - Copy and paste selected nodes, and maintaining the connection from the outputs of unselected nodes to the inputs of the newly pasted nodes.
|
||||
* Holding Shift and drag selected nodes - Move multiple selected nodes at the same time.
|
||||
|
||||
# Execution Flow
|
||||
To execute a graph you must call ```graph.runStep()```.
|
||||
|
||||
This function will call the method ```node.onExecute()``` for every node in the graph.
|
||||
|
||||
The order of execution is determined by the system according to the morphology of the graph (nodes without inputs are considered level 0, then nodes connected to nodes of level 0 are level 1, and so on). This order is computed only when the graph morphology changes (new nodes are created, connections change).
|
||||
|
||||
It is up to the developer to decide how to handle inputs and outputs from inside the node.
|
||||
|
||||
The data send through outputs using ```this.setOutputData(0,data)``` is stored in the link, so if the node connected through that link does ```this.getInputData(0)``` it will receive the same data sent.
|
||||
|
||||
For rendering, the nodes are executed according to their order in the ```graph._nodes``` array, which changes when the user interact with the GraphCanvas (clicked nodes are moved to the back of the array so they are rendered the last).
|
||||
|
||||
|
||||
## Integration
|
||||
|
||||
To integrate in you HTML application:
|
||||
|
||||
```js
|
||||
var graph = new LiteGraph.LGraph();
|
||||
var graph_canvas = new LiteGraph.LGraphCanvas( canvas, graph );
|
||||
```
|
||||
|
||||
If you want to start the graph then:
|
||||
```js
|
||||
graph.start();
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
When we run a step in a graph (using ```graph.runStep()```) every node onExecute method will be called.
|
||||
But sometimes you want that actions are only performed when some trigger is activated, for this situations you can use Events.
|
||||
|
||||
Events allow to trigger executions in nodes only when an event is dispatched from one node.
|
||||
|
||||
To define slots for nodes you must use the type LiteGraph.ACTION for inputs, and LIteGraph.EVENT for outputs:
|
||||
|
||||
```js
|
||||
function MyNode()
|
||||
{
|
||||
this.addInput("play", LiteGraph.ACTION );
|
||||
this.addInput("onFinish", LiteGraph.EVENT );
|
||||
}
|
||||
```
|
||||
|
||||
Now to execute some code when an event is received from an input, you must define the method onAction:
|
||||
|
||||
```js
|
||||
MyNode.prototype.onAction = function(action, data)
|
||||
{
|
||||
if(action == "play")
|
||||
{
|
||||
//do your action...
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
And the last thing is to trigger events when something in your node happens. You could trigger them from inside the onExecute or from any other interaction:
|
||||
|
||||
```js
|
||||
MyNode.prototype.onAction = function(action, data)
|
||||
{
|
||||
if( this.button_was_clicked )
|
||||
this.triggerSlot(0); //triggers event in slot 0
|
||||
}
|
||||
```
|
||||
|
||||
There are some nodes already available to handle events, like delaying, counting, etc.
|
||||
|
||||
|
||||
### Customising Link Tooltips
|
||||
|
||||
When hovering over a link that connects two nodes together, a tooltip will be shown allowing the user to see the data that is being output from one node to the other.
|
||||
|
||||
Sometimes, you may have a node that outputs an object, rather than a primitive value that can be easily represented (like a string). In these instances, the tooltip will default to showing `[Object]`.
|
||||
|
||||
If you need a more descriptive tooltip, you can achieve this by adding a `toToolTip` function to your object which returns the text you wish to display in the tooltip.
|
||||
|
||||
For example, to ensure the link from output slot 0 shows `A useful description`, the output object would look like this:
|
||||
|
||||
```javascript
|
||||
this.setOutputData(0, {
|
||||
complexObject: {
|
||||
yes: true,
|
||||
},
|
||||
toToolTip: () => 'A useful description',
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
86
index.html
@@ -1,86 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<!--
|
||||
<meta property="og:title" content="GameEditor" />
|
||||
<meta property="og:description" content="GameEditor for simple games" />
|
||||
<meta property="og:image" content="" />
|
||||
-->
|
||||
|
||||
<title>litegraph.js</title>
|
||||
<link type="text/css" rel="stylesheet" media="all" href="https://github.com/assets/github-c066013be20516a6aae45467044fa109f18bd0c6.css">
|
||||
<link type="text/css" rel="stylesheet" media="all" href="https://github.com/assets/github2-97081caeb5890bc349a9ff52de33ac5ba1a4b6cc.css">
|
||||
<link type="text/css" rel="stylesheet" media="all" href="https://github.com/assets/styleguide-4a2ef42768c9e616cf8022dec2fe99290430ac2c.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<style type='text/css'>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="wrap">
|
||||
<div id="main">
|
||||
<div id="content" class="markdown-body">
|
||||
<h1>litegraph.js</h1>
|
||||
<p>Litegraph.js is a library that allows to create modular graphs on the web, similar to PureData.</p>
|
||||
<p>Graphs can be used to create workflows, image processing, audio, or any kind of network of modules interacting with each other.</p>
|
||||
<p>Some of the main features:</p>
|
||||
<ul>
|
||||
<li>Automatic sorting of modules according to basic rules.</li>
|
||||
<li>Dynamic number of input/outputs per module.</li>
|
||||
<li>Persistence, graphs can be serialized in a JSON.</li>
|
||||
<li>Optimized render in a HTML5 Canvas (supports hundres of modules on the screen).</li>
|
||||
<li>Allows to run the graphs without the need of the canvas (standalone mode).</li>
|
||||
<li>Simple API. It is very easy to create new modules.</li>
|
||||
<li>Edit and Live mode, (in live mode only modules with widgets are rendered.</li>
|
||||
<li>Contextual menu in the editor.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Usage</h2>
|
||||
|
||||
<p>Include the library</p>
|
||||
<pre>
|
||||
<script type="text/javascript" src="../src/litegraph.js"></script></pre>
|
||||
|
||||
<p>Create a graph</p>
|
||||
<pre>
|
||||
var graph = new LGraph();</pre>
|
||||
|
||||
<p>Create a canvas renderer</p>
|
||||
<pre>
|
||||
var canvas = new LGraphCanvas("#mycanvas");</pre>
|
||||
|
||||
<p>Add some nodes to the graph</p>
|
||||
<pre>
|
||||
var node_const = LiteGraph.createNode("basic/const");
|
||||
node_const.pos = [200,200];
|
||||
graph.add(node_const);
|
||||
node_const.setValue(4.5);
|
||||
|
||||
var node_watch = LiteGraph.createNode("basic/watch");
|
||||
node_watch.pos = [700,200];
|
||||
graph.add(node_watch);</pre>
|
||||
|
||||
<p>Connect them</p>
|
||||
<pre>
|
||||
node_const.connect(0, node_watch, 0 );</pre>
|
||||
|
||||
<p>Run the graph</p>
|
||||
<pre>
|
||||
graph.start();</pre>
|
||||
|
||||
<h2>Example of editor</h2>
|
||||
<ul>
|
||||
<li><a href="editor">Module editor</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Documentation</h2>
|
||||
<p>Here you can check <a href="doc">automatically generated documentation</a>.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
Before Width: | Height: | Size: 862 B |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 564 B |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 366 B |
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -23,8 +23,6 @@
|
||||
"build": "tsc && vite build",
|
||||
"dev": "vite",
|
||||
"preview": "vite preview",
|
||||
"deprecated-prebuild": "rimraf build",
|
||||
"deprecated-start": "nodemon utils/server.js",
|
||||
"deprecated-test": "jest",
|
||||
"deprecated-test:allVersions": "./utils/test.sh",
|
||||
"deprecated-prettier": "npx prettier --write src/**/*.* css/**/*.*",
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
//Creates an interface to access extra features from a graph (like play, stop, live, etc)
|
||||
function Editor(container_id, options) {
|
||||
options = options || {};
|
||||
|
||||
//fill container
|
||||
var html = "<div class='header'><div class='tools tools-left'></div><div class='tools tools-right'></div></div>";
|
||||
html += "<div class='content'><div class='editor-area'><canvas class='graphcanvas' width='1000' height='500' tabindex=10></canvas></div></div>";
|
||||
html += "<div class='footer'><div class='tools tools-left'></div><div class='tools tools-right'></div></div>";
|
||||
|
||||
var root = document.createElement("div");
|
||||
this.root = root;
|
||||
root.className = "litegraph litegraph-editor";
|
||||
root.innerHTML = html;
|
||||
|
||||
this.tools = root.querySelector(".tools");
|
||||
this.content = root.querySelector(".content");
|
||||
this.footer = root.querySelector(".footer");
|
||||
|
||||
var canvas = this.canvas = root.querySelector(".graphcanvas");
|
||||
|
||||
//create graph
|
||||
var graph = (this.graph = new LGraph());
|
||||
var graphcanvas = this.graphcanvas = new LGraphCanvas(canvas, graph);
|
||||
graphcanvas.background_image = "imgs/grid.png";
|
||||
graph.onAfterExecute = function() {
|
||||
graphcanvas.draw(true);
|
||||
};
|
||||
|
||||
graphcanvas.onDropItem = this.onDropItem.bind(this);
|
||||
|
||||
//add stuff
|
||||
//this.addToolsButton("loadsession_button","Load","imgs/icon-load.png", this.onLoadButton.bind(this), ".tools-left" );
|
||||
//this.addToolsButton("savesession_button","Save","imgs/icon-save.png", this.onSaveButton.bind(this), ".tools-left" );
|
||||
this.addLoadCounter();
|
||||
this.addToolsButton(
|
||||
"playnode_button",
|
||||
"Play",
|
||||
"imgs/icon-play.png",
|
||||
this.onPlayButton.bind(this),
|
||||
".tools-right"
|
||||
);
|
||||
this.addToolsButton(
|
||||
"playstepnode_button",
|
||||
"Step",
|
||||
"imgs/icon-playstep.png",
|
||||
this.onPlayStepButton.bind(this),
|
||||
".tools-right"
|
||||
);
|
||||
|
||||
if (!options.skip_livemode) {
|
||||
this.addToolsButton(
|
||||
"livemode_button",
|
||||
"Live",
|
||||
"imgs/icon-record.png",
|
||||
this.onLiveButton.bind(this),
|
||||
".tools-right"
|
||||
);
|
||||
}
|
||||
if (!options.skip_maximize) {
|
||||
this.addToolsButton(
|
||||
"maximize_button",
|
||||
"",
|
||||
"imgs/icon-maximize.png",
|
||||
this.onFullscreenButton.bind(this),
|
||||
".tools-right"
|
||||
);
|
||||
}
|
||||
if (options.miniwindow) {
|
||||
this.addMiniWindow(300, 200);
|
||||
}
|
||||
|
||||
//append to DOM
|
||||
var parent = document.getElementById(container_id);
|
||||
if (parent) {
|
||||
parent.appendChild(root);
|
||||
}
|
||||
|
||||
graphcanvas.resize();
|
||||
//graphcanvas.draw(true,true);
|
||||
}
|
||||
|
||||
Editor.prototype.addLoadCounter = function() {
|
||||
var meter = document.createElement("div");
|
||||
meter.className = "headerpanel loadmeter toolbar-widget";
|
||||
|
||||
var html =
|
||||
"<div class='cpuload'><strong>CPU</strong> <div class='bgload'><div class='fgload'></div></div></div>";
|
||||
html +=
|
||||
"<div class='gpuload'><strong>GFX</strong> <div class='bgload'><div class='fgload'></div></div></div>";
|
||||
|
||||
meter.innerHTML = html;
|
||||
this.root.querySelector(".header .tools-left").appendChild(meter);
|
||||
var self = this;
|
||||
|
||||
setInterval(function() {
|
||||
meter.querySelector(".cpuload .fgload").style.width =
|
||||
2 * self.graph.execution_time * 90 + "px";
|
||||
if (self.graph.status == LGraph.STATUS_RUNNING) {
|
||||
meter.querySelector(".gpuload .fgload").style.width =
|
||||
self.graphcanvas.render_time * 10 * 90 + "px";
|
||||
} else {
|
||||
meter.querySelector(".gpuload .fgload").style.width = 4 + "px";
|
||||
}
|
||||
}, 200);
|
||||
};
|
||||
|
||||
Editor.prototype.addToolsButton = function( id, name, icon_url, callback, container ) {
|
||||
if (!container) {
|
||||
container = ".tools";
|
||||
}
|
||||
|
||||
var button = this.createButton(name, icon_url, callback);
|
||||
button.id = id;
|
||||
this.root.querySelector(container).appendChild(button);
|
||||
};
|
||||
|
||||
Editor.prototype.createButton = function(name, icon_url, callback) {
|
||||
var button = document.createElement("button");
|
||||
if (icon_url) {
|
||||
button.innerHTML = "<img src='" + icon_url + "'/> ";
|
||||
}
|
||||
button.classList.add("btn");
|
||||
button.innerHTML += name;
|
||||
if(callback)
|
||||
button.addEventListener("click", callback );
|
||||
return button;
|
||||
};
|
||||
|
||||
Editor.prototype.onLoadButton = function() {
|
||||
var panel = this.graphcanvas.createPanel("Load session",{closable:true});
|
||||
//TO DO
|
||||
|
||||
this.root.appendChild(panel);
|
||||
};
|
||||
|
||||
Editor.prototype.onSaveButton = function() {};
|
||||
|
||||
Editor.prototype.onPlayButton = function() {
|
||||
var graph = this.graph;
|
||||
var button = this.root.querySelector("#playnode_button");
|
||||
|
||||
if (graph.status == LGraph.STATUS_STOPPED) {
|
||||
button.innerHTML = "<img src='imgs/icon-stop.png'/> Stop";
|
||||
graph.start();
|
||||
} else {
|
||||
button.innerHTML = "<img src='imgs/icon-play.png'/> Play";
|
||||
graph.stop();
|
||||
}
|
||||
};
|
||||
|
||||
Editor.prototype.onPlayStepButton = function() {
|
||||
var graph = this.graph;
|
||||
graph.runStep(1);
|
||||
this.graphcanvas.draw(true, true);
|
||||
};
|
||||
|
||||
Editor.prototype.onLiveButton = function() {
|
||||
var is_live_mode = !this.graphcanvas.live_mode;
|
||||
this.graphcanvas.switchLiveMode(true);
|
||||
this.graphcanvas.draw();
|
||||
var url = this.graphcanvas.live_mode
|
||||
? "imgs/gauss_bg_medium.jpg"
|
||||
: "imgs/gauss_bg.jpg";
|
||||
var button = this.root.querySelector("#livemode_button");
|
||||
button.innerHTML = !is_live_mode
|
||||
? "<img src='imgs/icon-record.png'/> Live"
|
||||
: "<img src='imgs/icon-gear.png'/> Edit";
|
||||
};
|
||||
|
||||
Editor.prototype.onDropItem = function(e)
|
||||
{
|
||||
var that = this;
|
||||
for(var i = 0; i < e.dataTransfer.files.length; ++i)
|
||||
{
|
||||
var file = e.dataTransfer.files[i];
|
||||
var ext = LGraphCanvas.getFileExtension(file.name);
|
||||
var reader = new FileReader();
|
||||
if(ext == "json")
|
||||
{
|
||||
reader.onload = function(event) {
|
||||
var data = JSON.parse( event.target.result );
|
||||
that.graph.configure(data);
|
||||
};
|
||||
reader.readAsText(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Editor.prototype.goFullscreen = function() {
|
||||
if (this.root.requestFullscreen) {
|
||||
this.root.requestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
|
||||
} else if (this.root.mozRequestFullscreen) {
|
||||
this.root.requestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
|
||||
} else if (this.root.webkitRequestFullscreen) {
|
||||
this.root.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
|
||||
} else {
|
||||
throw "Fullscreen not supported";
|
||||
}
|
||||
|
||||
var self = this;
|
||||
setTimeout(function() {
|
||||
self.graphcanvas.resize();
|
||||
}, 100);
|
||||
};
|
||||
|
||||
Editor.prototype.onFullscreenButton = function() {
|
||||
this.goFullscreen();
|
||||
};
|
||||
|
||||
Editor.prototype.addMiniWindow = function(w, h) {
|
||||
var miniwindow = document.createElement("div");
|
||||
miniwindow.className = "litegraph miniwindow";
|
||||
miniwindow.innerHTML =
|
||||
"<canvas class='graphcanvas' width='" +
|
||||
w +
|
||||
"' height='" +
|
||||
h +
|
||||
"' tabindex=10></canvas>";
|
||||
var canvas = miniwindow.querySelector("canvas");
|
||||
var that = this;
|
||||
|
||||
var graphcanvas = new LGraphCanvas( canvas, this.graph );
|
||||
graphcanvas.show_info = false;
|
||||
graphcanvas.background_image = "imgs/grid.png";
|
||||
graphcanvas.scale = 0.25;
|
||||
graphcanvas.allow_dragnodes = false;
|
||||
graphcanvas.allow_interaction = false;
|
||||
graphcanvas.render_shadows = false;
|
||||
graphcanvas.max_zoom = 0.25;
|
||||
this.miniwindow_graphcanvas = graphcanvas;
|
||||
graphcanvas.onClear = function() {
|
||||
graphcanvas.scale = 0.25;
|
||||
graphcanvas.allow_dragnodes = false;
|
||||
graphcanvas.allow_interaction = false;
|
||||
};
|
||||
graphcanvas.onRenderBackground = function(canvas, ctx) {
|
||||
ctx.strokeStyle = "#567";
|
||||
var tl = that.graphcanvas.convertOffsetToCanvas([0, 0]);
|
||||
var br = that.graphcanvas.convertOffsetToCanvas([
|
||||
that.graphcanvas.canvas.width,
|
||||
that.graphcanvas.canvas.height
|
||||
]);
|
||||
tl = this.convertCanvasToOffset(tl);
|
||||
br = this.convertCanvasToOffset(br);
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeRect(
|
||||
Math.floor(tl[0]) + 0.5,
|
||||
Math.floor(tl[1]) + 0.5,
|
||||
Math.floor(br[0] - tl[0]),
|
||||
Math.floor(br[1] - tl[1])
|
||||
);
|
||||
};
|
||||
|
||||
miniwindow.style.position = "absolute";
|
||||
miniwindow.style.top = "4px";
|
||||
miniwindow.style.right = "4px";
|
||||
|
||||
var close_button = document.createElement("div");
|
||||
close_button.className = "corner-button";
|
||||
close_button.innerHTML = "❌";
|
||||
close_button.addEventListener("click", function(e) {
|
||||
graphcanvas.setGraph(null);
|
||||
miniwindow.parentNode.removeChild(miniwindow);
|
||||
});
|
||||
miniwindow.appendChild(close_button);
|
||||
|
||||
this.root.querySelector(".content").appendChild(miniwindow);
|
||||
};
|
||||
|
||||
Editor.prototype.addMultiview = function()
|
||||
{
|
||||
var canvas = this.canvas;
|
||||
this.graphcanvas.ctx.fillStyle = "black";
|
||||
this.graphcanvas.ctx.fillRect(0,0,canvas.width,canvas.height);
|
||||
this.graphcanvas.viewport = [0,0,canvas.width*0.5-2,canvas.height];
|
||||
|
||||
var graphcanvas = new LGraphCanvas( canvas, this.graph );
|
||||
graphcanvas.background_image = "imgs/grid.png";
|
||||
this.graphcanvas2 = graphcanvas;
|
||||
this.graphcanvas2.viewport = [canvas.width*0.5,0,canvas.width*0.5,canvas.height];
|
||||
}
|
||||
|
||||
LiteGraph.Editor = Editor;
|
||||
1456
src/nodes/audio.js
1770
src/nodes/base.js
@@ -1,504 +0,0 @@
|
||||
//event related nodes
|
||||
(function(global) {
|
||||
var LiteGraph = global.LiteGraph;
|
||||
|
||||
//Show value inside the debug console
|
||||
function LogEvent() {
|
||||
this.size = [60, 30];
|
||||
this.addInput("event", LiteGraph.ACTION);
|
||||
}
|
||||
|
||||
LogEvent.title = "Log Event";
|
||||
LogEvent.desc = "Log event in console";
|
||||
|
||||
LogEvent.prototype.onAction = function(action, param, options) {
|
||||
console.log(action, param);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("events/log", LogEvent);
|
||||
|
||||
//convert to Event if the value is true
|
||||
function TriggerEvent() {
|
||||
this.size = [60, 30];
|
||||
this.addInput("if", "");
|
||||
this.addOutput("true", LiteGraph.EVENT);
|
||||
this.addOutput("change", LiteGraph.EVENT);
|
||||
this.addOutput("false", LiteGraph.EVENT);
|
||||
this.properties = { only_on_change: true };
|
||||
this.prev = 0;
|
||||
}
|
||||
|
||||
TriggerEvent.title = "TriggerEvent";
|
||||
TriggerEvent.desc = "Triggers event if input evaluates to true";
|
||||
|
||||
TriggerEvent.prototype.onExecute = function( param, options) {
|
||||
var v = this.getInputData(0);
|
||||
var changed = (v != this.prev);
|
||||
if(this.prev === 0)
|
||||
changed = false;
|
||||
var must_resend = (changed && this.properties.only_on_change) || (!changed && !this.properties.only_on_change);
|
||||
if(v && must_resend )
|
||||
this.triggerSlot(0, param, null, options);
|
||||
if(!v && must_resend)
|
||||
this.triggerSlot(2, param, null, options);
|
||||
if(changed)
|
||||
this.triggerSlot(1, param, null, options);
|
||||
this.prev = v;
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("events/trigger", TriggerEvent);
|
||||
|
||||
//Sequence of events
|
||||
function Sequence() {
|
||||
var that = this;
|
||||
this.addInput("", LiteGraph.ACTION);
|
||||
this.addInput("", LiteGraph.ACTION);
|
||||
this.addInput("", LiteGraph.ACTION);
|
||||
this.addOutput("", LiteGraph.EVENT);
|
||||
this.addOutput("", LiteGraph.EVENT);
|
||||
this.addOutput("", LiteGraph.EVENT);
|
||||
this.addWidget("button","+",null,function(){
|
||||
that.addInput("", LiteGraph.ACTION);
|
||||
that.addOutput("", LiteGraph.EVENT);
|
||||
});
|
||||
this.size = [90, 70];
|
||||
this.flags = { horizontal: true, render_box: false };
|
||||
}
|
||||
|
||||
Sequence.title = "Sequence";
|
||||
Sequence.desc = "Triggers a sequence of events when an event arrives";
|
||||
|
||||
Sequence.prototype.getTitle = function() {
|
||||
return "";
|
||||
};
|
||||
|
||||
Sequence.prototype.onAction = function(action, param, options) {
|
||||
if (this.outputs) {
|
||||
options = options || {};
|
||||
for (var i = 0; i < this.outputs.length; ++i) {
|
||||
var output = this.outputs[i];
|
||||
//needs more info about this...
|
||||
if( options.action_call ) // CREATE A NEW ID FOR THE ACTION
|
||||
options.action_call = options.action_call + "_seq_" + i;
|
||||
else
|
||||
options.action_call = this.id + "_" + (action ? action : "action")+"_seq_"+i+"_"+Math.floor(Math.random()*9999);
|
||||
this.triggerSlot(i, param, null, options);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("events/sequence", Sequence);
|
||||
|
||||
|
||||
//Sequencer for events
|
||||
function Stepper() {
|
||||
var that = this;
|
||||
this.properties = { index: 0 };
|
||||
this.addInput("index", "number");
|
||||
this.addInput("step", LiteGraph.ACTION);
|
||||
this.addInput("reset", LiteGraph.ACTION);
|
||||
this.addOutput("index", "number");
|
||||
this.addOutput("", LiteGraph.EVENT);
|
||||
this.addOutput("", LiteGraph.EVENT);
|
||||
this.addOutput("", LiteGraph.EVENT,{removable:true});
|
||||
this.addWidget("button","+",null,function(){
|
||||
that.addOutput("", LiteGraph.EVENT, {removable:true});
|
||||
});
|
||||
this.size = [120, 120];
|
||||
this.flags = { render_box: false };
|
||||
}
|
||||
|
||||
Stepper.title = "Stepper";
|
||||
Stepper.desc = "Trigger events sequentially when an tick arrives";
|
||||
|
||||
Stepper.prototype.onDrawBackground = function(ctx)
|
||||
{
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
var index = this.properties.index || 0;
|
||||
ctx.fillStyle = "#AFB";
|
||||
var w = this.size[0];
|
||||
var y = (index + 1)* LiteGraph.NODE_SLOT_HEIGHT + 4;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(w - 30, y);
|
||||
ctx.lineTo(w - 30, y + LiteGraph.NODE_SLOT_HEIGHT);
|
||||
ctx.lineTo(w - 15, y + LiteGraph.NODE_SLOT_HEIGHT * 0.5);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
Stepper.prototype.onExecute = function()
|
||||
{
|
||||
var index = this.getInputData(0);
|
||||
if(index != null)
|
||||
{
|
||||
index = Math.floor(index);
|
||||
index = clamp( index, 0, this.outputs ? (this.outputs.length - 2) : 0 );
|
||||
if( index != this.properties.index )
|
||||
{
|
||||
this.properties.index = index;
|
||||
this.triggerSlot( index+1 );
|
||||
}
|
||||
}
|
||||
|
||||
this.setOutputData(0, this.properties.index );
|
||||
}
|
||||
|
||||
Stepper.prototype.onAction = function(action, param) {
|
||||
if(action == "reset")
|
||||
this.properties.index = 0;
|
||||
else if(action == "step")
|
||||
{
|
||||
this.triggerSlot(this.properties.index+1, param);
|
||||
var n = this.outputs ? this.outputs.length - 1 : 0;
|
||||
this.properties.index = (this.properties.index + 1) % n;
|
||||
}
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("events/stepper", Stepper);
|
||||
|
||||
//Filter events
|
||||
function FilterEvent() {
|
||||
this.size = [60, 30];
|
||||
this.addInput("event", LiteGraph.ACTION);
|
||||
this.addOutput("event", LiteGraph.EVENT);
|
||||
this.properties = {
|
||||
equal_to: "",
|
||||
has_property: "",
|
||||
property_equal_to: ""
|
||||
};
|
||||
}
|
||||
|
||||
FilterEvent.title = "Filter Event";
|
||||
FilterEvent.desc = "Blocks events that do not match the filter";
|
||||
|
||||
FilterEvent.prototype.onAction = function(action, param, options) {
|
||||
if (param == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.properties.equal_to && this.properties.equal_to != param) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.properties.has_property) {
|
||||
var prop = param[this.properties.has_property];
|
||||
if (prop == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
this.properties.property_equal_to &&
|
||||
this.properties.property_equal_to != prop
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.triggerSlot(0, param, null, options);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("events/filter", FilterEvent);
|
||||
|
||||
|
||||
function EventBranch() {
|
||||
this.addInput("in", LiteGraph.ACTION);
|
||||
this.addInput("cond", "boolean");
|
||||
this.addOutput("true", LiteGraph.EVENT);
|
||||
this.addOutput("false", LiteGraph.EVENT);
|
||||
this.size = [120, 60];
|
||||
this._value = false;
|
||||
}
|
||||
|
||||
EventBranch.title = "Branch";
|
||||
EventBranch.desc = "If condition is true, outputs triggers true, otherwise false";
|
||||
|
||||
EventBranch.prototype.onExecute = function() {
|
||||
this._value = this.getInputData(1);
|
||||
}
|
||||
|
||||
EventBranch.prototype.onAction = function(action, param, options) {
|
||||
this._value = this.getInputData(1);
|
||||
this.triggerSlot(this._value ? 0 : 1, param, null, options);
|
||||
}
|
||||
|
||||
LiteGraph.registerNodeType("events/branch", EventBranch);
|
||||
|
||||
//Show value inside the debug console
|
||||
function EventCounter() {
|
||||
this.addInput("inc", LiteGraph.ACTION);
|
||||
this.addInput("dec", LiteGraph.ACTION);
|
||||
this.addInput("reset", LiteGraph.ACTION);
|
||||
this.addOutput("change", LiteGraph.EVENT);
|
||||
this.addOutput("num", "number");
|
||||
this.addProperty("doCountExecution", false, "boolean", {name: "Count Executions"});
|
||||
this.addWidget("toggle","Count Exec.",this.properties.doCountExecution,"doCountExecution");
|
||||
this.num = 0;
|
||||
}
|
||||
|
||||
EventCounter.title = "Counter";
|
||||
EventCounter.desc = "Counts events";
|
||||
|
||||
EventCounter.prototype.getTitle = function() {
|
||||
if (this.flags.collapsed) {
|
||||
return String(this.num);
|
||||
}
|
||||
return this.title;
|
||||
};
|
||||
|
||||
EventCounter.prototype.onAction = function(action, param, options) {
|
||||
var v = this.num;
|
||||
if (action == "inc") {
|
||||
this.num += 1;
|
||||
} else if (action == "dec") {
|
||||
this.num -= 1;
|
||||
} else if (action == "reset") {
|
||||
this.num = 0;
|
||||
}
|
||||
if (this.num != v) {
|
||||
this.trigger("change", this.num);
|
||||
}
|
||||
};
|
||||
|
||||
EventCounter.prototype.onDrawBackground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
ctx.fillStyle = "#AAA";
|
||||
ctx.font = "20px Arial";
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillText(this.num, this.size[0] * 0.5, this.size[1] * 0.5);
|
||||
};
|
||||
|
||||
EventCounter.prototype.onExecute = function() {
|
||||
if(this.properties.doCountExecution){
|
||||
this.num += 1;
|
||||
}
|
||||
this.setOutputData(1, this.num);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("events/counter", EventCounter);
|
||||
|
||||
//Show value inside the debug console
|
||||
function DelayEvent() {
|
||||
this.size = [60, 30];
|
||||
this.addProperty("time_in_ms", 1000);
|
||||
this.addInput("event", LiteGraph.ACTION);
|
||||
this.addOutput("on_time", LiteGraph.EVENT);
|
||||
|
||||
this._pending = [];
|
||||
}
|
||||
|
||||
DelayEvent.title = "Delay";
|
||||
DelayEvent.desc = "Delays one event";
|
||||
|
||||
DelayEvent.prototype.onAction = function(action, param, options) {
|
||||
var time = this.properties.time_in_ms;
|
||||
if (time <= 0) {
|
||||
this.trigger(null, param, options);
|
||||
} else {
|
||||
this._pending.push([time, param]);
|
||||
}
|
||||
};
|
||||
|
||||
DelayEvent.prototype.onExecute = function(param, options) {
|
||||
var dt = this.graph.elapsed_time * 1000; //in ms
|
||||
|
||||
if (this.isInputConnected(1)) {
|
||||
this.properties.time_in_ms = this.getInputData(1);
|
||||
}
|
||||
|
||||
for (var i = 0; i < this._pending.length; ++i) {
|
||||
var actionPass = this._pending[i];
|
||||
actionPass[0] -= dt;
|
||||
if (actionPass[0] > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//remove
|
||||
this._pending.splice(i, 1);
|
||||
--i;
|
||||
|
||||
//trigger
|
||||
this.trigger(null, actionPass[1], options);
|
||||
}
|
||||
};
|
||||
|
||||
DelayEvent.prototype.onGetInputs = function() {
|
||||
return [["event", LiteGraph.ACTION], ["time_in_ms", "number"]];
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("events/delay", DelayEvent);
|
||||
|
||||
//Show value inside the debug console
|
||||
function TimerEvent() {
|
||||
this.addProperty("interval", 1000);
|
||||
this.addProperty("event", "tick");
|
||||
this.addOutput("on_tick", LiteGraph.EVENT);
|
||||
this.time = 0;
|
||||
this.last_interval = 1000;
|
||||
this.triggered = false;
|
||||
}
|
||||
|
||||
TimerEvent.title = "Timer";
|
||||
TimerEvent.desc = "Sends an event every N milliseconds";
|
||||
|
||||
TimerEvent.prototype.onStart = function() {
|
||||
this.time = 0;
|
||||
};
|
||||
|
||||
TimerEvent.prototype.getTitle = function() {
|
||||
return "Timer: " + this.last_interval.toString() + "ms";
|
||||
};
|
||||
|
||||
TimerEvent.on_color = "#AAA";
|
||||
TimerEvent.off_color = "#222";
|
||||
|
||||
TimerEvent.prototype.onDrawBackground = function() {
|
||||
this.boxcolor = this.triggered
|
||||
? TimerEvent.on_color
|
||||
: TimerEvent.off_color;
|
||||
this.triggered = false;
|
||||
};
|
||||
|
||||
TimerEvent.prototype.onExecute = function() {
|
||||
var dt = this.graph.elapsed_time * 1000; //in ms
|
||||
|
||||
var trigger = this.time == 0;
|
||||
|
||||
this.time += dt;
|
||||
this.last_interval = Math.max(
|
||||
1,
|
||||
this.getInputOrProperty("interval") | 0
|
||||
);
|
||||
|
||||
if (
|
||||
!trigger &&
|
||||
(this.time < this.last_interval || isNaN(this.last_interval))
|
||||
) {
|
||||
if (this.inputs && this.inputs.length > 1 && this.inputs[1]) {
|
||||
this.setOutputData(1, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.triggered = true;
|
||||
this.time = this.time % this.last_interval;
|
||||
this.trigger("on_tick", this.properties.event);
|
||||
if (this.inputs && this.inputs.length > 1 && this.inputs[1]) {
|
||||
this.setOutputData(1, true);
|
||||
}
|
||||
};
|
||||
|
||||
TimerEvent.prototype.onGetInputs = function() {
|
||||
return [["interval", "number"]];
|
||||
};
|
||||
|
||||
TimerEvent.prototype.onGetOutputs = function() {
|
||||
return [["tick", "boolean"]];
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("events/timer", TimerEvent);
|
||||
|
||||
|
||||
|
||||
function SemaphoreEvent() {
|
||||
this.addInput("go", LiteGraph.ACTION );
|
||||
this.addInput("green", LiteGraph.ACTION );
|
||||
this.addInput("red", LiteGraph.ACTION );
|
||||
this.addOutput("continue", LiteGraph.EVENT );
|
||||
this.addOutput("blocked", LiteGraph.EVENT );
|
||||
this.addOutput("is_green", "boolean" );
|
||||
this._ready = false;
|
||||
this.properties = {};
|
||||
var that = this;
|
||||
this.addWidget("button","reset","",function(){
|
||||
that._ready = false;
|
||||
});
|
||||
}
|
||||
|
||||
SemaphoreEvent.title = "Semaphore Event";
|
||||
SemaphoreEvent.desc = "Until both events are not triggered, it doesnt continue.";
|
||||
|
||||
SemaphoreEvent.prototype.onExecute = function()
|
||||
{
|
||||
this.setOutputData(1,this._ready);
|
||||
this.boxcolor = this._ready ? "#9F9" : "#FA5";
|
||||
}
|
||||
|
||||
SemaphoreEvent.prototype.onAction = function(action, param) {
|
||||
if( action == "go" )
|
||||
this.triggerSlot( this._ready ? 0 : 1 );
|
||||
else if( action == "green" )
|
||||
this._ready = true;
|
||||
else if( action == "red" )
|
||||
this._ready = false;
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("events/semaphore", SemaphoreEvent);
|
||||
|
||||
function OnceEvent() {
|
||||
this.addInput("in", LiteGraph.ACTION );
|
||||
this.addInput("reset", LiteGraph.ACTION );
|
||||
this.addOutput("out", LiteGraph.EVENT );
|
||||
this._once = false;
|
||||
this.properties = {};
|
||||
var that = this;
|
||||
this.addWidget("button","reset","",function(){
|
||||
that._once = false;
|
||||
});
|
||||
}
|
||||
|
||||
OnceEvent.title = "Once";
|
||||
OnceEvent.desc = "Only passes an event once, then gets locked";
|
||||
|
||||
OnceEvent.prototype.onAction = function(action, param) {
|
||||
if( action == "in" && !this._once )
|
||||
{
|
||||
this._once = true;
|
||||
this.triggerSlot( 0, param );
|
||||
}
|
||||
else if( action == "reset" )
|
||||
this._once = false;
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("events/once", OnceEvent);
|
||||
|
||||
function DataStore() {
|
||||
this.addInput("data", 0);
|
||||
this.addInput("assign", LiteGraph.ACTION);
|
||||
this.addOutput("data", 0);
|
||||
this._last_value = null;
|
||||
this.properties = { data: null, serialize: true };
|
||||
var that = this;
|
||||
this.addWidget("button","store","",function(){
|
||||
that.properties.data = that._last_value;
|
||||
});
|
||||
}
|
||||
|
||||
DataStore.title = "Data Store";
|
||||
DataStore.desc = "Stores data and only changes when event is received";
|
||||
|
||||
DataStore.prototype.onExecute = function()
|
||||
{
|
||||
this._last_value = this.getInputData(0);
|
||||
this.setOutputData(0, this.properties.data );
|
||||
}
|
||||
|
||||
DataStore.prototype.onAction = function(action, param, options) {
|
||||
this.properties.data = this._last_value;
|
||||
};
|
||||
|
||||
DataStore.prototype.onSerialize = function(o)
|
||||
{
|
||||
if(o.data == null)
|
||||
return;
|
||||
if(this.properties.serialize == false || (o.data.constructor !== String && o.data.constructor !== Number && o.data.constructor !== Boolean && o.data.constructor !== Array && o.data.constructor !== Object ))
|
||||
o.data = null;
|
||||
}
|
||||
|
||||
LiteGraph.registerNodeType("basic/data_store", DataStore);
|
||||
|
||||
|
||||
|
||||
})(this);
|
||||
@@ -1,788 +0,0 @@
|
||||
(function(global) {
|
||||
var LiteGraph = global.LiteGraph;
|
||||
var LGraphTexture = global.LGraphTexture;
|
||||
|
||||
//Works with Litegl.js to create WebGL nodes
|
||||
if (typeof GL != "undefined") {
|
||||
// Texture Lens *****************************************
|
||||
function LGraphFXLens() {
|
||||
this.addInput("Texture", "Texture");
|
||||
this.addInput("Aberration", "number");
|
||||
this.addInput("Distortion", "number");
|
||||
this.addInput("Blur", "number");
|
||||
this.addOutput("Texture", "Texture");
|
||||
this.properties = {
|
||||
aberration: 1.0,
|
||||
distortion: 1.0,
|
||||
blur: 1.0,
|
||||
precision: LGraphTexture.DEFAULT
|
||||
};
|
||||
|
||||
if (!LGraphFXLens._shader) {
|
||||
LGraphFXLens._shader = new GL.Shader(
|
||||
GL.Shader.SCREEN_VERTEX_SHADER,
|
||||
LGraphFXLens.pixel_shader
|
||||
);
|
||||
LGraphFXLens._texture = new GL.Texture(3, 1, {
|
||||
format: gl.RGB,
|
||||
wrap: gl.CLAMP_TO_EDGE,
|
||||
magFilter: gl.LINEAR,
|
||||
minFilter: gl.LINEAR,
|
||||
pixel_data: [255, 0, 0, 0, 255, 0, 0, 0, 255]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
LGraphFXLens.title = "Lens";
|
||||
LGraphFXLens.desc = "Camera Lens distortion";
|
||||
LGraphFXLens.widgets_info = {
|
||||
precision: { widget: "combo", values: LGraphTexture.MODE_VALUES }
|
||||
};
|
||||
|
||||
LGraphFXLens.prototype.onExecute = function() {
|
||||
var tex = this.getInputData(0);
|
||||
if (this.properties.precision === LGraphTexture.PASS_THROUGH) {
|
||||
this.setOutputData(0, tex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tex) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._tex = LGraphTexture.getTargetTexture(
|
||||
tex,
|
||||
this._tex,
|
||||
this.properties.precision
|
||||
);
|
||||
|
||||
var aberration = this.properties.aberration;
|
||||
if (this.isInputConnected(1)) {
|
||||
aberration = this.getInputData(1);
|
||||
this.properties.aberration = aberration;
|
||||
}
|
||||
|
||||
var distortion = this.properties.distortion;
|
||||
if (this.isInputConnected(2)) {
|
||||
distortion = this.getInputData(2);
|
||||
this.properties.distortion = distortion;
|
||||
}
|
||||
|
||||
var blur = this.properties.blur;
|
||||
if (this.isInputConnected(3)) {
|
||||
blur = this.getInputData(3);
|
||||
this.properties.blur = blur;
|
||||
}
|
||||
|
||||
gl.disable(gl.BLEND);
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
var mesh = Mesh.getScreenQuad();
|
||||
var shader = LGraphFXLens._shader;
|
||||
//var camera = LS.Renderer._current_camera;
|
||||
|
||||
this._tex.drawTo(function() {
|
||||
tex.bind(0);
|
||||
shader
|
||||
.uniforms({
|
||||
u_texture: 0,
|
||||
u_aberration: aberration,
|
||||
u_distortion: distortion,
|
||||
u_blur: blur
|
||||
})
|
||||
.draw(mesh);
|
||||
});
|
||||
|
||||
this.setOutputData(0, this._tex);
|
||||
};
|
||||
|
||||
LGraphFXLens.pixel_shader =
|
||||
"precision highp float;\n\
|
||||
precision highp float;\n\
|
||||
varying vec2 v_coord;\n\
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform vec2 u_camera_planes;\n\
|
||||
uniform float u_aberration;\n\
|
||||
uniform float u_distortion;\n\
|
||||
uniform float u_blur;\n\
|
||||
\n\
|
||||
void main() {\n\
|
||||
vec2 coord = v_coord;\n\
|
||||
float dist = distance(vec2(0.5), coord);\n\
|
||||
vec2 dist_coord = coord - vec2(0.5);\n\
|
||||
float percent = 1.0 + ((0.5 - dist) / 0.5) * u_distortion;\n\
|
||||
dist_coord *= percent;\n\
|
||||
coord = dist_coord + vec2(0.5);\n\
|
||||
vec4 color = texture2D(u_texture,coord, u_blur * dist);\n\
|
||||
color.r = texture2D(u_texture,vec2(0.5) + dist_coord * (1.0+0.01*u_aberration), u_blur * dist ).r;\n\
|
||||
color.b = texture2D(u_texture,vec2(0.5) + dist_coord * (1.0-0.01*u_aberration), u_blur * dist ).b;\n\
|
||||
gl_FragColor = color;\n\
|
||||
}\n\
|
||||
";
|
||||
/*
|
||||
float normalized_tunable_sigmoid(float xs, float k)\n\
|
||||
{\n\
|
||||
xs = xs * 2.0 - 1.0;\n\
|
||||
float signx = sign(xs);\n\
|
||||
float absx = abs(xs);\n\
|
||||
return signx * ((-k - 1.0)*absx)/(2.0*(-2.0*k*absx+k-1.0)) + 0.5;\n\
|
||||
}\n\
|
||||
*/
|
||||
|
||||
LiteGraph.registerNodeType("fx/lens", LGraphFXLens);
|
||||
global.LGraphFXLens = LGraphFXLens;
|
||||
|
||||
/* not working yet
|
||||
function LGraphDepthOfField()
|
||||
{
|
||||
this.addInput("Color","Texture");
|
||||
this.addInput("Linear Depth","Texture");
|
||||
this.addInput("Camera","camera");
|
||||
this.addOutput("Texture","Texture");
|
||||
this.properties = { high_precision: false };
|
||||
}
|
||||
|
||||
LGraphDepthOfField.title = "Depth Of Field";
|
||||
LGraphDepthOfField.desc = "Applies a depth of field effect";
|
||||
|
||||
LGraphDepthOfField.prototype.onExecute = function()
|
||||
{
|
||||
var tex = this.getInputData(0);
|
||||
var depth = this.getInputData(1);
|
||||
var camera = this.getInputData(2);
|
||||
|
||||
if(!tex || !depth || !camera)
|
||||
{
|
||||
this.setOutputData(0, tex);
|
||||
return;
|
||||
}
|
||||
|
||||
var precision = gl.UNSIGNED_BYTE;
|
||||
if(this.properties.high_precision)
|
||||
precision = gl.half_float_ext ? gl.HALF_FLOAT_OES : gl.FLOAT;
|
||||
if(!this._temp_texture || this._temp_texture.type != precision ||
|
||||
this._temp_texture.width != tex.width || this._temp_texture.height != tex.height)
|
||||
this._temp_texture = new GL.Texture( tex.width, tex.height, { type: precision, format: gl.RGBA, filter: gl.LINEAR });
|
||||
|
||||
var shader = LGraphDepthOfField._shader = new GL.Shader( GL.Shader.SCREEN_VERTEX_SHADER, LGraphDepthOfField._pixel_shader );
|
||||
|
||||
var screen_mesh = Mesh.getScreenQuad();
|
||||
|
||||
gl.disable( gl.DEPTH_TEST );
|
||||
gl.disable( gl.BLEND );
|
||||
|
||||
var camera_position = camera.getEye();
|
||||
var focus_point = camera.getCenter();
|
||||
var distance = vec3.distance( camera_position, focus_point );
|
||||
var far = camera.far;
|
||||
var focus_range = distance * 0.5;
|
||||
|
||||
this._temp_texture.drawTo( function() {
|
||||
tex.bind(0);
|
||||
depth.bind(1);
|
||||
shader.uniforms({u_texture:0, u_depth_texture:1, u_resolution: [1/tex.width, 1/tex.height], u_far: far, u_focus_point: distance, u_focus_scale: focus_range }).draw(screen_mesh);
|
||||
});
|
||||
|
||||
this.setOutputData(0, this._temp_texture);
|
||||
}
|
||||
|
||||
//from http://tuxedolabs.blogspot.com.es/2018/05/bokeh-depth-of-field-in-single-pass.html
|
||||
LGraphDepthOfField._pixel_shader = "\n\
|
||||
precision highp float;\n\
|
||||
varying vec2 v_coord;\n\
|
||||
uniform sampler2D u_texture; //Image to be processed\n\
|
||||
uniform sampler2D u_depth_texture; //Linear depth, where 1.0 == far plane\n\
|
||||
uniform vec2 u_iresolution; //The size of a pixel: vec2(1.0/width, 1.0/height)\n\
|
||||
uniform float u_far; // Far plane\n\
|
||||
uniform float u_focus_point;\n\
|
||||
uniform float u_focus_scale;\n\
|
||||
\n\
|
||||
const float GOLDEN_ANGLE = 2.39996323;\n\
|
||||
const float MAX_BLUR_SIZE = 20.0;\n\
|
||||
const float RAD_SCALE = 0.5; // Smaller = nicer blur, larger = faster\n\
|
||||
\n\
|
||||
float getBlurSize(float depth, float focusPoint, float focusScale)\n\
|
||||
{\n\
|
||||
float coc = clamp((1.0 / focusPoint - 1.0 / depth)*focusScale, -1.0, 1.0);\n\
|
||||
return abs(coc) * MAX_BLUR_SIZE;\n\
|
||||
}\n\
|
||||
\n\
|
||||
vec3 depthOfField(vec2 texCoord, float focusPoint, float focusScale)\n\
|
||||
{\n\
|
||||
float centerDepth = texture2D(u_depth_texture, texCoord).r * u_far;\n\
|
||||
float centerSize = getBlurSize(centerDepth, focusPoint, focusScale);\n\
|
||||
vec3 color = texture2D(u_texture, v_coord).rgb;\n\
|
||||
float tot = 1.0;\n\
|
||||
\n\
|
||||
float radius = RAD_SCALE;\n\
|
||||
for (float ang = 0.0; ang < 100.0; ang += GOLDEN_ANGLE)\n\
|
||||
{\n\
|
||||
vec2 tc = texCoord + vec2(cos(ang), sin(ang)) * u_iresolution * radius;\n\
|
||||
\n\
|
||||
vec3 sampleColor = texture2D(u_texture, tc).rgb;\n\
|
||||
float sampleDepth = texture2D(u_depth_texture, tc).r * u_far;\n\
|
||||
float sampleSize = getBlurSize( sampleDepth, focusPoint, focusScale );\n\
|
||||
if (sampleDepth > centerDepth)\n\
|
||||
sampleSize = clamp(sampleSize, 0.0, centerSize*2.0);\n\
|
||||
\n\
|
||||
float m = smoothstep(radius-0.5, radius+0.5, sampleSize);\n\
|
||||
color += mix(color/tot, sampleColor, m);\n\
|
||||
tot += 1.0;\n\
|
||||
radius += RAD_SCALE/radius;\n\
|
||||
if(radius>=MAX_BLUR_SIZE)\n\
|
||||
return color / tot;\n\
|
||||
}\n\
|
||||
return color / tot;\n\
|
||||
}\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
gl_FragColor = vec4( depthOfField( v_coord, u_focus_point, u_focus_scale ), 1.0 );\n\
|
||||
//gl_FragColor = vec4( texture2D(u_depth_texture, v_coord).r );\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
LiteGraph.registerNodeType("fx/DOF", LGraphDepthOfField );
|
||||
global.LGraphDepthOfField = LGraphDepthOfField;
|
||||
*/
|
||||
|
||||
//*******************************************************
|
||||
|
||||
function LGraphFXBokeh() {
|
||||
this.addInput("Texture", "Texture");
|
||||
this.addInput("Blurred", "Texture");
|
||||
this.addInput("Mask", "Texture");
|
||||
this.addInput("Threshold", "number");
|
||||
this.addOutput("Texture", "Texture");
|
||||
this.properties = {
|
||||
shape: "",
|
||||
size: 10,
|
||||
alpha: 1.0,
|
||||
threshold: 1.0,
|
||||
high_precision: false
|
||||
};
|
||||
}
|
||||
|
||||
LGraphFXBokeh.title = "Bokeh";
|
||||
LGraphFXBokeh.desc = "applies an Bokeh effect";
|
||||
|
||||
LGraphFXBokeh.widgets_info = { shape: { widget: "texture" } };
|
||||
|
||||
LGraphFXBokeh.prototype.onExecute = function() {
|
||||
var tex = this.getInputData(0);
|
||||
var blurred_tex = this.getInputData(1);
|
||||
var mask_tex = this.getInputData(2);
|
||||
if (!tex || !mask_tex || !this.properties.shape) {
|
||||
this.setOutputData(0, tex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!blurred_tex) {
|
||||
blurred_tex = tex;
|
||||
}
|
||||
|
||||
var shape_tex = LGraphTexture.getTexture(this.properties.shape);
|
||||
if (!shape_tex) {
|
||||
return;
|
||||
}
|
||||
|
||||
var threshold = this.properties.threshold;
|
||||
if (this.isInputConnected(3)) {
|
||||
threshold = this.getInputData(3);
|
||||
this.properties.threshold = threshold;
|
||||
}
|
||||
|
||||
var precision = gl.UNSIGNED_BYTE;
|
||||
if (this.properties.high_precision) {
|
||||
precision = gl.half_float_ext ? gl.HALF_FLOAT_OES : gl.FLOAT;
|
||||
}
|
||||
if (
|
||||
!this._temp_texture ||
|
||||
this._temp_texture.type != precision ||
|
||||
this._temp_texture.width != tex.width ||
|
||||
this._temp_texture.height != tex.height
|
||||
) {
|
||||
this._temp_texture = new GL.Texture(tex.width, tex.height, {
|
||||
type: precision,
|
||||
format: gl.RGBA,
|
||||
filter: gl.LINEAR
|
||||
});
|
||||
}
|
||||
|
||||
//iterations
|
||||
var size = this.properties.size;
|
||||
|
||||
var first_shader = LGraphFXBokeh._first_shader;
|
||||
if (!first_shader) {
|
||||
first_shader = LGraphFXBokeh._first_shader = new GL.Shader(
|
||||
Shader.SCREEN_VERTEX_SHADER,
|
||||
LGraphFXBokeh._first_pixel_shader
|
||||
);
|
||||
}
|
||||
|
||||
var second_shader = LGraphFXBokeh._second_shader;
|
||||
if (!second_shader) {
|
||||
second_shader = LGraphFXBokeh._second_shader = new GL.Shader(
|
||||
LGraphFXBokeh._second_vertex_shader,
|
||||
LGraphFXBokeh._second_pixel_shader
|
||||
);
|
||||
}
|
||||
|
||||
var points_mesh = this._points_mesh;
|
||||
if (
|
||||
!points_mesh ||
|
||||
points_mesh._width != tex.width ||
|
||||
points_mesh._height != tex.height ||
|
||||
points_mesh._spacing != 2
|
||||
) {
|
||||
points_mesh = this.createPointsMesh(tex.width, tex.height, 2);
|
||||
}
|
||||
|
||||
var screen_mesh = Mesh.getScreenQuad();
|
||||
|
||||
var point_size = this.properties.size;
|
||||
var min_light = this.properties.min_light;
|
||||
var alpha = this.properties.alpha;
|
||||
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
gl.disable(gl.BLEND);
|
||||
|
||||
this._temp_texture.drawTo(function() {
|
||||
tex.bind(0);
|
||||
blurred_tex.bind(1);
|
||||
mask_tex.bind(2);
|
||||
first_shader
|
||||
.uniforms({
|
||||
u_texture: 0,
|
||||
u_texture_blur: 1,
|
||||
u_mask: 2,
|
||||
u_texsize: [tex.width, tex.height]
|
||||
})
|
||||
.draw(screen_mesh);
|
||||
});
|
||||
|
||||
this._temp_texture.drawTo(function() {
|
||||
//clear because we use blending
|
||||
//gl.clearColor(0.0,0.0,0.0,1.0);
|
||||
//gl.clear( gl.COLOR_BUFFER_BIT );
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendFunc(gl.ONE, gl.ONE);
|
||||
|
||||
tex.bind(0);
|
||||
shape_tex.bind(3);
|
||||
second_shader
|
||||
.uniforms({
|
||||
u_texture: 0,
|
||||
u_mask: 2,
|
||||
u_shape: 3,
|
||||
u_alpha: alpha,
|
||||
u_threshold: threshold,
|
||||
u_pointSize: point_size,
|
||||
u_itexsize: [1.0 / tex.width, 1.0 / tex.height]
|
||||
})
|
||||
.draw(points_mesh, gl.POINTS);
|
||||
});
|
||||
|
||||
this.setOutputData(0, this._temp_texture);
|
||||
};
|
||||
|
||||
LGraphFXBokeh.prototype.createPointsMesh = function(
|
||||
width,
|
||||
height,
|
||||
spacing
|
||||
) {
|
||||
var nwidth = Math.round(width / spacing);
|
||||
var nheight = Math.round(height / spacing);
|
||||
|
||||
var vertices = new Float32Array(nwidth * nheight * 2);
|
||||
|
||||
var ny = -1;
|
||||
var dx = (2 / width) * spacing;
|
||||
var dy = (2 / height) * spacing;
|
||||
for (var y = 0; y < nheight; ++y) {
|
||||
var nx = -1;
|
||||
for (var x = 0; x < nwidth; ++x) {
|
||||
var pos = y * nwidth * 2 + x * 2;
|
||||
vertices[pos] = nx;
|
||||
vertices[pos + 1] = ny;
|
||||
nx += dx;
|
||||
}
|
||||
ny += dy;
|
||||
}
|
||||
|
||||
this._points_mesh = GL.Mesh.load({ vertices2D: vertices });
|
||||
this._points_mesh._width = width;
|
||||
this._points_mesh._height = height;
|
||||
this._points_mesh._spacing = spacing;
|
||||
|
||||
return this._points_mesh;
|
||||
};
|
||||
|
||||
/*
|
||||
LGraphTextureBokeh._pixel_shader = "precision highp float;\n\
|
||||
varying vec2 a_coord;\n\
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform sampler2D u_shape;\n\
|
||||
\n\
|
||||
void main() {\n\
|
||||
vec4 color = texture2D( u_texture, gl_PointCoord );\n\
|
||||
color *= v_color * u_alpha;\n\
|
||||
gl_FragColor = color;\n\
|
||||
}\n";
|
||||
*/
|
||||
|
||||
LGraphFXBokeh._first_pixel_shader =
|
||||
"precision highp float;\n\
|
||||
precision highp float;\n\
|
||||
varying vec2 v_coord;\n\
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform sampler2D u_texture_blur;\n\
|
||||
uniform sampler2D u_mask;\n\
|
||||
\n\
|
||||
void main() {\n\
|
||||
vec4 color = texture2D(u_texture, v_coord);\n\
|
||||
vec4 blurred_color = texture2D(u_texture_blur, v_coord);\n\
|
||||
float mask = texture2D(u_mask, v_coord).x;\n\
|
||||
gl_FragColor = mix(color, blurred_color, mask);\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
LGraphFXBokeh._second_vertex_shader =
|
||||
"precision highp float;\n\
|
||||
attribute vec2 a_vertex2D;\n\
|
||||
varying vec4 v_color;\n\
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform sampler2D u_mask;\n\
|
||||
uniform vec2 u_itexsize;\n\
|
||||
uniform float u_pointSize;\n\
|
||||
uniform float u_threshold;\n\
|
||||
void main() {\n\
|
||||
vec2 coord = a_vertex2D * 0.5 + 0.5;\n\
|
||||
v_color = texture2D( u_texture, coord );\n\
|
||||
v_color += texture2D( u_texture, coord + vec2(u_itexsize.x, 0.0) );\n\
|
||||
v_color += texture2D( u_texture, coord + vec2(0.0, u_itexsize.y));\n\
|
||||
v_color += texture2D( u_texture, coord + u_itexsize);\n\
|
||||
v_color *= 0.25;\n\
|
||||
float mask = texture2D(u_mask, coord).x;\n\
|
||||
float luminance = length(v_color) * mask;\n\
|
||||
/*luminance /= (u_pointSize*u_pointSize)*0.01 */;\n\
|
||||
luminance -= u_threshold;\n\
|
||||
if(luminance < 0.0)\n\
|
||||
{\n\
|
||||
gl_Position.x = -100.0;\n\
|
||||
return;\n\
|
||||
}\n\
|
||||
gl_PointSize = u_pointSize;\n\
|
||||
gl_Position = vec4(a_vertex2D,0.0,1.0);\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
LGraphFXBokeh._second_pixel_shader =
|
||||
"precision highp float;\n\
|
||||
varying vec4 v_color;\n\
|
||||
uniform sampler2D u_shape;\n\
|
||||
uniform float u_alpha;\n\
|
||||
\n\
|
||||
void main() {\n\
|
||||
vec4 color = texture2D( u_shape, gl_PointCoord );\n\
|
||||
color *= v_color * u_alpha;\n\
|
||||
gl_FragColor = color;\n\
|
||||
}\n";
|
||||
|
||||
LiteGraph.registerNodeType("fx/bokeh", LGraphFXBokeh);
|
||||
global.LGraphFXBokeh = LGraphFXBokeh;
|
||||
|
||||
//************************************************
|
||||
|
||||
function LGraphFXGeneric() {
|
||||
this.addInput("Texture", "Texture");
|
||||
this.addInput("value1", "number");
|
||||
this.addInput("value2", "number");
|
||||
this.addOutput("Texture", "Texture");
|
||||
this.properties = {
|
||||
fx: "halftone",
|
||||
value1: 1,
|
||||
value2: 1,
|
||||
precision: LGraphTexture.DEFAULT
|
||||
};
|
||||
}
|
||||
|
||||
LGraphFXGeneric.title = "FX";
|
||||
LGraphFXGeneric.desc = "applies an FX from a list";
|
||||
|
||||
LGraphFXGeneric.widgets_info = {
|
||||
fx: {
|
||||
widget: "combo",
|
||||
values: ["halftone", "pixelate", "lowpalette", "noise", "gamma"]
|
||||
},
|
||||
precision: { widget: "combo", values: LGraphTexture.MODE_VALUES }
|
||||
};
|
||||
LGraphFXGeneric.shaders = {};
|
||||
|
||||
LGraphFXGeneric.prototype.onExecute = function() {
|
||||
if (!this.isOutputConnected(0)) {
|
||||
return;
|
||||
} //saves work
|
||||
|
||||
var tex = this.getInputData(0);
|
||||
if (this.properties.precision === LGraphTexture.PASS_THROUGH) {
|
||||
this.setOutputData(0, tex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tex) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._tex = LGraphTexture.getTargetTexture(
|
||||
tex,
|
||||
this._tex,
|
||||
this.properties.precision
|
||||
);
|
||||
|
||||
//iterations
|
||||
var value1 = this.properties.value1;
|
||||
if (this.isInputConnected(1)) {
|
||||
value1 = this.getInputData(1);
|
||||
this.properties.value1 = value1;
|
||||
}
|
||||
|
||||
var value2 = this.properties.value2;
|
||||
if (this.isInputConnected(2)) {
|
||||
value2 = this.getInputData(2);
|
||||
this.properties.value2 = value2;
|
||||
}
|
||||
|
||||
var fx = this.properties.fx;
|
||||
var shader = LGraphFXGeneric.shaders[fx];
|
||||
if (!shader) {
|
||||
var pixel_shader_code = LGraphFXGeneric["pixel_shader_" + fx];
|
||||
if (!pixel_shader_code) {
|
||||
return;
|
||||
}
|
||||
|
||||
shader = LGraphFXGeneric.shaders[fx] = new GL.Shader(
|
||||
Shader.SCREEN_VERTEX_SHADER,
|
||||
pixel_shader_code
|
||||
);
|
||||
}
|
||||
|
||||
gl.disable(gl.BLEND);
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
var mesh = Mesh.getScreenQuad();
|
||||
var camera = global.LS ? LS.Renderer._current_camera : null;
|
||||
var camera_planes;
|
||||
if (camera) {
|
||||
camera_planes = [
|
||||
LS.Renderer._current_camera.near,
|
||||
LS.Renderer._current_camera.far
|
||||
];
|
||||
} else {
|
||||
camera_planes = [1, 100];
|
||||
}
|
||||
|
||||
var noise = null;
|
||||
if (fx == "noise") {
|
||||
noise = LGraphTexture.getNoiseTexture();
|
||||
}
|
||||
|
||||
this._tex.drawTo(function() {
|
||||
tex.bind(0);
|
||||
if (fx == "noise") {
|
||||
noise.bind(1);
|
||||
}
|
||||
|
||||
shader
|
||||
.uniforms({
|
||||
u_texture: 0,
|
||||
u_noise: 1,
|
||||
u_size: [tex.width, tex.height],
|
||||
u_rand: [Math.random(), Math.random()],
|
||||
u_value1: value1,
|
||||
u_value2: value2,
|
||||
u_camera_planes: camera_planes
|
||||
})
|
||||
.draw(mesh);
|
||||
});
|
||||
|
||||
this.setOutputData(0, this._tex);
|
||||
};
|
||||
|
||||
LGraphFXGeneric.pixel_shader_halftone =
|
||||
"precision highp float;\n\
|
||||
varying vec2 v_coord;\n\
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform vec2 u_camera_planes;\n\
|
||||
uniform vec2 u_size;\n\
|
||||
uniform float u_value1;\n\
|
||||
uniform float u_value2;\n\
|
||||
\n\
|
||||
float pattern() {\n\
|
||||
float s = sin(u_value1 * 3.1415), c = cos(u_value1 * 3.1415);\n\
|
||||
vec2 tex = v_coord * u_size.xy;\n\
|
||||
vec2 point = vec2(\n\
|
||||
c * tex.x - s * tex.y ,\n\
|
||||
s * tex.x + c * tex.y \n\
|
||||
) * u_value2;\n\
|
||||
return (sin(point.x) * sin(point.y)) * 4.0;\n\
|
||||
}\n\
|
||||
void main() {\n\
|
||||
vec4 color = texture2D(u_texture, v_coord);\n\
|
||||
float average = (color.r + color.g + color.b) / 3.0;\n\
|
||||
gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);\n\
|
||||
}\n";
|
||||
|
||||
LGraphFXGeneric.pixel_shader_pixelate =
|
||||
"precision highp float;\n\
|
||||
varying vec2 v_coord;\n\
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform vec2 u_camera_planes;\n\
|
||||
uniform vec2 u_size;\n\
|
||||
uniform float u_value1;\n\
|
||||
uniform float u_value2;\n\
|
||||
\n\
|
||||
void main() {\n\
|
||||
vec2 coord = vec2( floor(v_coord.x * u_value1) / u_value1, floor(v_coord.y * u_value2) / u_value2 );\n\
|
||||
vec4 color = texture2D(u_texture, coord);\n\
|
||||
gl_FragColor = color;\n\
|
||||
}\n";
|
||||
|
||||
LGraphFXGeneric.pixel_shader_lowpalette =
|
||||
"precision highp float;\n\
|
||||
varying vec2 v_coord;\n\
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform vec2 u_camera_planes;\n\
|
||||
uniform vec2 u_size;\n\
|
||||
uniform float u_value1;\n\
|
||||
uniform float u_value2;\n\
|
||||
\n\
|
||||
void main() {\n\
|
||||
vec4 color = texture2D(u_texture, v_coord);\n\
|
||||
gl_FragColor = floor(color * u_value1) / u_value1;\n\
|
||||
}\n";
|
||||
|
||||
LGraphFXGeneric.pixel_shader_noise =
|
||||
"precision highp float;\n\
|
||||
varying vec2 v_coord;\n\
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform sampler2D u_noise;\n\
|
||||
uniform vec2 u_size;\n\
|
||||
uniform float u_value1;\n\
|
||||
uniform float u_value2;\n\
|
||||
uniform vec2 u_rand;\n\
|
||||
\n\
|
||||
void main() {\n\
|
||||
vec4 color = texture2D(u_texture, v_coord);\n\
|
||||
vec3 noise = texture2D(u_noise, v_coord * vec2(u_size.x / 512.0, u_size.y / 512.0) + u_rand).xyz - vec3(0.5);\n\
|
||||
gl_FragColor = vec4( color.xyz + noise * u_value1, color.a );\n\
|
||||
}\n";
|
||||
|
||||
LGraphFXGeneric.pixel_shader_gamma =
|
||||
"precision highp float;\n\
|
||||
varying vec2 v_coord;\n\
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform float u_value1;\n\
|
||||
\n\
|
||||
void main() {\n\
|
||||
vec4 color = texture2D(u_texture, v_coord);\n\
|
||||
float gamma = 1.0 / u_value1;\n\
|
||||
gl_FragColor = vec4( pow( color.xyz, vec3(gamma) ), color.a );\n\
|
||||
}\n";
|
||||
|
||||
LiteGraph.registerNodeType("fx/generic", LGraphFXGeneric);
|
||||
global.LGraphFXGeneric = LGraphFXGeneric;
|
||||
|
||||
// Vigneting ************************************
|
||||
|
||||
function LGraphFXVigneting() {
|
||||
this.addInput("Tex.", "Texture");
|
||||
this.addInput("intensity", "number");
|
||||
|
||||
this.addOutput("Texture", "Texture");
|
||||
this.properties = {
|
||||
intensity: 1,
|
||||
invert: false,
|
||||
precision: LGraphTexture.DEFAULT
|
||||
};
|
||||
|
||||
if (!LGraphFXVigneting._shader) {
|
||||
LGraphFXVigneting._shader = new GL.Shader(
|
||||
Shader.SCREEN_VERTEX_SHADER,
|
||||
LGraphFXVigneting.pixel_shader
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
LGraphFXVigneting.title = "Vigneting";
|
||||
LGraphFXVigneting.desc = "Vigneting";
|
||||
|
||||
LGraphFXVigneting.widgets_info = {
|
||||
precision: { widget: "combo", values: LGraphTexture.MODE_VALUES }
|
||||
};
|
||||
|
||||
LGraphFXVigneting.prototype.onExecute = function() {
|
||||
var tex = this.getInputData(0);
|
||||
|
||||
if (this.properties.precision === LGraphTexture.PASS_THROUGH) {
|
||||
this.setOutputData(0, tex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tex) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._tex = LGraphTexture.getTargetTexture(
|
||||
tex,
|
||||
this._tex,
|
||||
this.properties.precision
|
||||
);
|
||||
|
||||
var intensity = this.properties.intensity;
|
||||
if (this.isInputConnected(1)) {
|
||||
intensity = this.getInputData(1);
|
||||
this.properties.intensity = intensity;
|
||||
}
|
||||
|
||||
gl.disable(gl.BLEND);
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
|
||||
var mesh = Mesh.getScreenQuad();
|
||||
var shader = LGraphFXVigneting._shader;
|
||||
var invert = this.properties.invert;
|
||||
|
||||
this._tex.drawTo(function() {
|
||||
tex.bind(0);
|
||||
shader
|
||||
.uniforms({
|
||||
u_texture: 0,
|
||||
u_intensity: intensity,
|
||||
u_isize: [1 / tex.width, 1 / tex.height],
|
||||
u_invert: invert ? 1 : 0
|
||||
})
|
||||
.draw(mesh);
|
||||
});
|
||||
|
||||
this.setOutputData(0, this._tex);
|
||||
};
|
||||
|
||||
LGraphFXVigneting.pixel_shader =
|
||||
"precision highp float;\n\
|
||||
precision highp float;\n\
|
||||
varying vec2 v_coord;\n\
|
||||
uniform sampler2D u_texture;\n\
|
||||
uniform float u_intensity;\n\
|
||||
uniform int u_invert;\n\
|
||||
\n\
|
||||
void main() {\n\
|
||||
float luminance = 1.0 - length( v_coord - vec2(0.5) ) * 1.414;\n\
|
||||
vec4 color = texture2D(u_texture, v_coord);\n\
|
||||
if(u_invert == 1)\n\
|
||||
luminance = 1.0 - luminance;\n\
|
||||
luminance = mix(1.0, luminance, u_intensity);\n\
|
||||
gl_FragColor = vec4( luminance * color.xyz, color.a);\n\
|
||||
}\n\
|
||||
";
|
||||
|
||||
LiteGraph.registerNodeType("fx/vigneting", LGraphFXVigneting);
|
||||
global.LGraphFXVigneting = LGraphFXVigneting;
|
||||
}
|
||||
})(this);
|
||||
@@ -1,896 +0,0 @@
|
||||
(function(global) {
|
||||
var LiteGraph = global.LiteGraph;
|
||||
|
||||
function GraphicsPlot() {
|
||||
this.addInput("A", "Number");
|
||||
this.addInput("B", "Number");
|
||||
this.addInput("C", "Number");
|
||||
this.addInput("D", "Number");
|
||||
|
||||
this.values = [[], [], [], []];
|
||||
this.properties = { scale: 2 };
|
||||
}
|
||||
|
||||
GraphicsPlot.title = "Plot";
|
||||
GraphicsPlot.desc = "Plots data over time";
|
||||
GraphicsPlot.colors = ["#FFF", "#F99", "#9F9", "#99F"];
|
||||
|
||||
GraphicsPlot.prototype.onExecute = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
var size = this.size;
|
||||
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
var v = this.getInputData(i);
|
||||
if (v == null) {
|
||||
continue;
|
||||
}
|
||||
var values = this.values[i];
|
||||
values.push(v);
|
||||
if (values.length > size[0]) {
|
||||
values.shift();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
GraphicsPlot.prototype.onDrawBackground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
var size = this.size;
|
||||
|
||||
var scale = (0.5 * size[1]) / this.properties.scale;
|
||||
var colors = GraphicsPlot.colors;
|
||||
var offset = size[1] * 0.5;
|
||||
|
||||
ctx.fillStyle = "#000";
|
||||
ctx.fillRect(0, 0, size[0], size[1]);
|
||||
ctx.strokeStyle = "#555";
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, offset);
|
||||
ctx.lineTo(size[0], offset);
|
||||
ctx.stroke();
|
||||
|
||||
if (this.inputs) {
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
var values = this.values[i];
|
||||
if (!this.inputs[i] || !this.inputs[i].link) {
|
||||
continue;
|
||||
}
|
||||
ctx.strokeStyle = colors[i];
|
||||
ctx.beginPath();
|
||||
var v = values[0] * scale * -1 + offset;
|
||||
ctx.moveTo(0, clamp(v, 0, size[1]));
|
||||
for (var j = 1; j < values.length && j < size[0]; ++j) {
|
||||
var v = values[j] * scale * -1 + offset;
|
||||
ctx.lineTo(j, clamp(v, 0, size[1]));
|
||||
}
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("graphics/plot", GraphicsPlot);
|
||||
|
||||
function GraphicsImage() {
|
||||
this.addOutput("frame", "image");
|
||||
this.properties = { url: "" };
|
||||
}
|
||||
|
||||
GraphicsImage.title = "Image";
|
||||
GraphicsImage.desc = "Image loader";
|
||||
GraphicsImage.widgets = [{ name: "load", text: "Load", type: "button" }];
|
||||
|
||||
GraphicsImage.supported_extensions = ["jpg", "jpeg", "png", "gif"];
|
||||
|
||||
GraphicsImage.prototype.onAdded = function() {
|
||||
if (this.properties["url"] != "" && this.img == null) {
|
||||
this.loadImage(this.properties["url"]);
|
||||
}
|
||||
};
|
||||
|
||||
GraphicsImage.prototype.onDrawBackground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
if (this.img && this.size[0] > 5 && this.size[1] > 5 && this.img.width) {
|
||||
ctx.drawImage(this.img, 0, 0, this.size[0], this.size[1]);
|
||||
}
|
||||
};
|
||||
|
||||
GraphicsImage.prototype.onExecute = function() {
|
||||
if (!this.img) {
|
||||
this.boxcolor = "#000";
|
||||
}
|
||||
if (this.img && this.img.width) {
|
||||
this.setOutputData(0, this.img);
|
||||
} else {
|
||||
this.setOutputData(0, null);
|
||||
}
|
||||
if (this.img && this.img.dirty) {
|
||||
this.img.dirty = false;
|
||||
}
|
||||
};
|
||||
|
||||
GraphicsImage.prototype.onPropertyChanged = function(name, value) {
|
||||
this.properties[name] = value;
|
||||
if (name == "url" && value != "") {
|
||||
this.loadImage(value);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
GraphicsImage.prototype.loadImage = function(url, callback) {
|
||||
if (url == "") {
|
||||
this.img = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.img = document.createElement("img");
|
||||
|
||||
if (url.substr(0, 4) == "http" && LiteGraph.proxy) {
|
||||
url = LiteGraph.proxy + url.substr(url.indexOf(":") + 3);
|
||||
}
|
||||
|
||||
this.img.src = url;
|
||||
this.boxcolor = "#F95";
|
||||
var that = this;
|
||||
this.img.onload = function() {
|
||||
if (callback) {
|
||||
callback(this);
|
||||
}
|
||||
console.log( "Image loaded, size: " + that.img.width + "x" + that.img.height );
|
||||
this.dirty = true;
|
||||
that.boxcolor = "#9F9";
|
||||
that.setDirtyCanvas(true);
|
||||
};
|
||||
this.img.onerror = function() {
|
||||
console.log("error loading the image:" + url);
|
||||
}
|
||||
};
|
||||
|
||||
GraphicsImage.prototype.onWidget = function(e, widget) {
|
||||
if (widget.name == "load") {
|
||||
this.loadImage(this.properties["url"]);
|
||||
}
|
||||
};
|
||||
|
||||
GraphicsImage.prototype.onDropFile = function(file) {
|
||||
var that = this;
|
||||
if (this._url) {
|
||||
URL.revokeObjectURL(this._url);
|
||||
}
|
||||
this._url = URL.createObjectURL(file);
|
||||
this.properties.url = this._url;
|
||||
this.loadImage(this._url, function(img) {
|
||||
that.size[1] = (img.height / img.width) * that.size[0];
|
||||
});
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("graphics/image", GraphicsImage);
|
||||
|
||||
function ColorPalette() {
|
||||
this.addInput("f", "number");
|
||||
this.addOutput("Color", "color");
|
||||
this.properties = {
|
||||
colorA: "#444444",
|
||||
colorB: "#44AAFF",
|
||||
colorC: "#44FFAA",
|
||||
colorD: "#FFFFFF"
|
||||
};
|
||||
}
|
||||
|
||||
ColorPalette.title = "Palette";
|
||||
ColorPalette.desc = "Generates a color";
|
||||
|
||||
ColorPalette.prototype.onExecute = function() {
|
||||
var c = [];
|
||||
|
||||
if (this.properties.colorA != null) {
|
||||
c.push(hex2num(this.properties.colorA));
|
||||
}
|
||||
if (this.properties.colorB != null) {
|
||||
c.push(hex2num(this.properties.colorB));
|
||||
}
|
||||
if (this.properties.colorC != null) {
|
||||
c.push(hex2num(this.properties.colorC));
|
||||
}
|
||||
if (this.properties.colorD != null) {
|
||||
c.push(hex2num(this.properties.colorD));
|
||||
}
|
||||
|
||||
var f = this.getInputData(0);
|
||||
if (f == null) {
|
||||
f = 0.5;
|
||||
}
|
||||
if (f > 1.0) {
|
||||
f = 1.0;
|
||||
} else if (f < 0.0) {
|
||||
f = 0.0;
|
||||
}
|
||||
|
||||
if (c.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var result = [0, 0, 0];
|
||||
if (f == 0) {
|
||||
result = c[0];
|
||||
} else if (f == 1) {
|
||||
result = c[c.length - 1];
|
||||
} else {
|
||||
var pos = (c.length - 1) * f;
|
||||
var c1 = c[Math.floor(pos)];
|
||||
var c2 = c[Math.floor(pos) + 1];
|
||||
var t = pos - Math.floor(pos);
|
||||
result[0] = c1[0] * (1 - t) + c2[0] * t;
|
||||
result[1] = c1[1] * (1 - t) + c2[1] * t;
|
||||
result[2] = c1[2] * (1 - t) + c2[2] * t;
|
||||
}
|
||||
|
||||
/*
|
||||
c[0] = 1.0 - Math.abs( Math.sin( 0.1 * reModular.getTime() * Math.PI) );
|
||||
c[1] = Math.abs( Math.sin( 0.07 * reModular.getTime() * Math.PI) );
|
||||
c[2] = Math.abs( Math.sin( 0.01 * reModular.getTime() * Math.PI) );
|
||||
*/
|
||||
|
||||
for (var i=0; i < result.length; i++) {
|
||||
result[i] /= 255;
|
||||
}
|
||||
|
||||
this.boxcolor = colorToString(result);
|
||||
this.setOutputData(0, result);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("color/palette", ColorPalette);
|
||||
|
||||
function ImageFrame() {
|
||||
this.addInput("", "image,canvas");
|
||||
this.size = [200, 200];
|
||||
}
|
||||
|
||||
ImageFrame.title = "Frame";
|
||||
ImageFrame.desc = "Frame viewerew";
|
||||
ImageFrame.widgets = [
|
||||
{ name: "resize", text: "Resize box", type: "button" },
|
||||
{ name: "view", text: "View Image", type: "button" }
|
||||
];
|
||||
|
||||
ImageFrame.prototype.onDrawBackground = function(ctx) {
|
||||
if (this.frame && !this.flags.collapsed) {
|
||||
ctx.drawImage(this.frame, 0, 0, this.size[0], this.size[1]);
|
||||
}
|
||||
};
|
||||
|
||||
ImageFrame.prototype.onExecute = function() {
|
||||
this.frame = this.getInputData(0);
|
||||
this.setDirtyCanvas(true);
|
||||
};
|
||||
|
||||
ImageFrame.prototype.onWidget = function(e, widget) {
|
||||
if (widget.name == "resize" && this.frame) {
|
||||
var width = this.frame.width;
|
||||
var height = this.frame.height;
|
||||
|
||||
if (!width && this.frame.videoWidth != null) {
|
||||
width = this.frame.videoWidth;
|
||||
height = this.frame.videoHeight;
|
||||
}
|
||||
|
||||
if (width && height) {
|
||||
this.size = [width, height];
|
||||
}
|
||||
this.setDirtyCanvas(true, true);
|
||||
} else if (widget.name == "view") {
|
||||
this.show();
|
||||
}
|
||||
};
|
||||
|
||||
ImageFrame.prototype.show = function() {
|
||||
//var str = this.canvas.toDataURL("image/png");
|
||||
if (showElement && this.frame) {
|
||||
showElement(this.frame);
|
||||
}
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("graphics/frame", ImageFrame);
|
||||
|
||||
function ImageFade() {
|
||||
this.addInputs([
|
||||
["img1", "image"],
|
||||
["img2", "image"],
|
||||
["fade", "number"]
|
||||
]);
|
||||
this.addOutput("", "image");
|
||||
this.properties = { fade: 0.5, width: 512, height: 512 };
|
||||
}
|
||||
|
||||
ImageFade.title = "Image fade";
|
||||
ImageFade.desc = "Fades between images";
|
||||
ImageFade.widgets = [
|
||||
{ name: "resizeA", text: "Resize to A", type: "button" },
|
||||
{ name: "resizeB", text: "Resize to B", type: "button" }
|
||||
];
|
||||
|
||||
ImageFade.prototype.onAdded = function() {
|
||||
this.createCanvas();
|
||||
var ctx = this.canvas.getContext("2d");
|
||||
ctx.fillStyle = "#000";
|
||||
ctx.fillRect(0, 0, this.properties["width"], this.properties["height"]);
|
||||
};
|
||||
|
||||
ImageFade.prototype.createCanvas = function() {
|
||||
this.canvas = document.createElement("canvas");
|
||||
this.canvas.width = this.properties["width"];
|
||||
this.canvas.height = this.properties["height"];
|
||||
};
|
||||
|
||||
ImageFade.prototype.onExecute = function() {
|
||||
var ctx = this.canvas.getContext("2d");
|
||||
this.canvas.width = this.canvas.width;
|
||||
|
||||
var A = this.getInputData(0);
|
||||
if (A != null) {
|
||||
ctx.drawImage(A, 0, 0, this.canvas.width, this.canvas.height);
|
||||
}
|
||||
|
||||
var fade = this.getInputData(2);
|
||||
if (fade == null) {
|
||||
fade = this.properties["fade"];
|
||||
} else {
|
||||
this.properties["fade"] = fade;
|
||||
}
|
||||
|
||||
ctx.globalAlpha = fade;
|
||||
var B = this.getInputData(1);
|
||||
if (B != null) {
|
||||
ctx.drawImage(B, 0, 0, this.canvas.width, this.canvas.height);
|
||||
}
|
||||
ctx.globalAlpha = 1.0;
|
||||
|
||||
this.setOutputData(0, this.canvas);
|
||||
this.setDirtyCanvas(true);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("graphics/imagefade", ImageFade);
|
||||
|
||||
function ImageCrop() {
|
||||
this.addInput("", "image");
|
||||
this.addOutput("", "image");
|
||||
this.properties = { width: 256, height: 256, x: 0, y: 0, scale: 1.0 };
|
||||
this.size = [50, 20];
|
||||
}
|
||||
|
||||
ImageCrop.title = "Crop";
|
||||
ImageCrop.desc = "Crop Image";
|
||||
|
||||
ImageCrop.prototype.onAdded = function() {
|
||||
this.createCanvas();
|
||||
};
|
||||
|
||||
ImageCrop.prototype.createCanvas = function() {
|
||||
this.canvas = document.createElement("canvas");
|
||||
this.canvas.width = this.properties["width"];
|
||||
this.canvas.height = this.properties["height"];
|
||||
};
|
||||
|
||||
ImageCrop.prototype.onExecute = function() {
|
||||
var input = this.getInputData(0);
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (input.width) {
|
||||
var ctx = this.canvas.getContext("2d");
|
||||
|
||||
ctx.drawImage(
|
||||
input,
|
||||
-this.properties["x"],
|
||||
-this.properties["y"],
|
||||
input.width * this.properties["scale"],
|
||||
input.height * this.properties["scale"]
|
||||
);
|
||||
this.setOutputData(0, this.canvas);
|
||||
} else {
|
||||
this.setOutputData(0, null);
|
||||
}
|
||||
};
|
||||
|
||||
ImageCrop.prototype.onDrawBackground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
if (this.canvas) {
|
||||
ctx.drawImage(
|
||||
this.canvas,
|
||||
0,
|
||||
0,
|
||||
this.canvas.width,
|
||||
this.canvas.height,
|
||||
0,
|
||||
0,
|
||||
this.size[0],
|
||||
this.size[1]
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
ImageCrop.prototype.onPropertyChanged = function(name, value) {
|
||||
this.properties[name] = value;
|
||||
|
||||
if (name == "scale") {
|
||||
this.properties[name] = parseFloat(value);
|
||||
if (this.properties[name] == 0) {
|
||||
console.error("Error in scale");
|
||||
this.properties[name] = 1.0;
|
||||
}
|
||||
} else {
|
||||
this.properties[name] = parseInt(value);
|
||||
}
|
||||
|
||||
this.createCanvas();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("graphics/cropImage", ImageCrop);
|
||||
|
||||
//CANVAS stuff
|
||||
|
||||
function CanvasNode() {
|
||||
this.addInput("clear", LiteGraph.ACTION);
|
||||
this.addOutput("", "canvas");
|
||||
this.properties = { width: 512, height: 512, autoclear: true };
|
||||
|
||||
this.canvas = document.createElement("canvas");
|
||||
this.ctx = this.canvas.getContext("2d");
|
||||
}
|
||||
|
||||
CanvasNode.title = "Canvas";
|
||||
CanvasNode.desc = "Canvas to render stuff";
|
||||
|
||||
CanvasNode.prototype.onExecute = function() {
|
||||
var canvas = this.canvas;
|
||||
var w = this.properties.width | 0;
|
||||
var h = this.properties.height | 0;
|
||||
if (canvas.width != w) {
|
||||
canvas.width = w;
|
||||
}
|
||||
if (canvas.height != h) {
|
||||
canvas.height = h;
|
||||
}
|
||||
|
||||
if (this.properties.autoclear) {
|
||||
this.ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
this.setOutputData(0, canvas);
|
||||
};
|
||||
|
||||
CanvasNode.prototype.onAction = function(action, param) {
|
||||
if (action == "clear") {
|
||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
}
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("graphics/canvas", CanvasNode);
|
||||
|
||||
function DrawImageNode() {
|
||||
this.addInput("canvas", "canvas");
|
||||
this.addInput("img", "image,canvas");
|
||||
this.addInput("x", "number");
|
||||
this.addInput("y", "number");
|
||||
this.properties = { x: 0, y: 0, opacity: 1 };
|
||||
}
|
||||
|
||||
DrawImageNode.title = "DrawImage";
|
||||
DrawImageNode.desc = "Draws image into a canvas";
|
||||
|
||||
DrawImageNode.prototype.onExecute = function() {
|
||||
var canvas = this.getInputData(0);
|
||||
if (!canvas) {
|
||||
return;
|
||||
}
|
||||
|
||||
var img = this.getInputOrProperty("img");
|
||||
if (!img) {
|
||||
return;
|
||||
}
|
||||
|
||||
var x = this.getInputOrProperty("x");
|
||||
var y = this.getInputOrProperty("y");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(img, x, y);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("graphics/drawImage", DrawImageNode);
|
||||
|
||||
function DrawRectangleNode() {
|
||||
this.addInput("canvas", "canvas");
|
||||
this.addInput("x", "number");
|
||||
this.addInput("y", "number");
|
||||
this.addInput("w", "number");
|
||||
this.addInput("h", "number");
|
||||
this.properties = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 10,
|
||||
h: 10,
|
||||
color: "white",
|
||||
opacity: 1
|
||||
};
|
||||
}
|
||||
|
||||
DrawRectangleNode.title = "DrawRectangle";
|
||||
DrawRectangleNode.desc = "Draws rectangle in canvas";
|
||||
|
||||
DrawRectangleNode.prototype.onExecute = function() {
|
||||
var canvas = this.getInputData(0);
|
||||
if (!canvas) {
|
||||
return;
|
||||
}
|
||||
|
||||
var x = this.getInputOrProperty("x");
|
||||
var y = this.getInputOrProperty("y");
|
||||
var w = this.getInputOrProperty("w");
|
||||
var h = this.getInputOrProperty("h");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.fillRect(x, y, w, h);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("graphics/drawRectangle", DrawRectangleNode);
|
||||
|
||||
function ImageVideo() {
|
||||
this.addInput("t", "number");
|
||||
this.addOutputs([["frame", "image"], ["t", "number"], ["d", "number"]]);
|
||||
this.properties = { url: "", use_proxy: true };
|
||||
}
|
||||
|
||||
ImageVideo.title = "Video";
|
||||
ImageVideo.desc = "Video playback";
|
||||
ImageVideo.widgets = [
|
||||
{ name: "play", text: "PLAY", type: "minibutton" },
|
||||
{ name: "stop", text: "STOP", type: "minibutton" },
|
||||
{ name: "demo", text: "Demo video", type: "button" },
|
||||
{ name: "mute", text: "Mute video", type: "button" }
|
||||
];
|
||||
|
||||
ImageVideo.prototype.onExecute = function() {
|
||||
if (!this.properties.url) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.properties.url != this._video_url) {
|
||||
this.loadVideo(this.properties.url);
|
||||
}
|
||||
|
||||
if (!this._video || this._video.width == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var t = this.getInputData(0);
|
||||
if (t && t >= 0 && t <= 1.0) {
|
||||
this._video.currentTime = t * this._video.duration;
|
||||
this._video.pause();
|
||||
}
|
||||
|
||||
this._video.dirty = true;
|
||||
this.setOutputData(0, this._video);
|
||||
this.setOutputData(1, this._video.currentTime);
|
||||
this.setOutputData(2, this._video.duration);
|
||||
this.setDirtyCanvas(true);
|
||||
};
|
||||
|
||||
ImageVideo.prototype.onStart = function() {
|
||||
this.play();
|
||||
};
|
||||
|
||||
ImageVideo.prototype.onStop = function() {
|
||||
this.stop();
|
||||
};
|
||||
|
||||
ImageVideo.prototype.loadVideo = function(url) {
|
||||
this._video_url = url;
|
||||
|
||||
var pos = url.substr(0,10).indexOf(":");
|
||||
var protocol = "";
|
||||
if(pos != -1)
|
||||
protocol = url.substr(0,pos);
|
||||
|
||||
var host = "";
|
||||
if(protocol)
|
||||
{
|
||||
host = url.substr(0,url.indexOf("/",protocol.length + 3));
|
||||
host = host.substr(protocol.length+3);
|
||||
}
|
||||
|
||||
if (
|
||||
this.properties.use_proxy &&
|
||||
protocol &&
|
||||
LiteGraph.proxy &&
|
||||
host != location.host
|
||||
) {
|
||||
url = LiteGraph.proxy + url.substr(url.indexOf(":") + 3);
|
||||
}
|
||||
|
||||
this._video = document.createElement("video");
|
||||
this._video.src = url;
|
||||
this._video.type = "type=video/mp4";
|
||||
|
||||
this._video.muted = true;
|
||||
this._video.autoplay = true;
|
||||
|
||||
var that = this;
|
||||
this._video.addEventListener("loadedmetadata", function(e) {
|
||||
//onload
|
||||
console.log("Duration: " + this.duration + " seconds");
|
||||
console.log("Size: " + this.videoWidth + "," + this.videoHeight);
|
||||
that.setDirtyCanvas(true);
|
||||
this.width = this.videoWidth;
|
||||
this.height = this.videoHeight;
|
||||
});
|
||||
this._video.addEventListener("progress", function(e) {
|
||||
//onload
|
||||
console.log("video loading...");
|
||||
});
|
||||
this._video.addEventListener("error", function(e) {
|
||||
console.error("Error loading video: " + this.src);
|
||||
if (this.error) {
|
||||
switch (this.error.code) {
|
||||
case this.error.MEDIA_ERR_ABORTED:
|
||||
console.error("You stopped the video.");
|
||||
break;
|
||||
case this.error.MEDIA_ERR_NETWORK:
|
||||
console.error("Network error - please try again later.");
|
||||
break;
|
||||
case this.error.MEDIA_ERR_DECODE:
|
||||
console.error("Video is broken..");
|
||||
break;
|
||||
case this.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
|
||||
console.error("Sorry, your browser can't play this video.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this._video.addEventListener("ended", function(e) {
|
||||
console.log("Video Ended.");
|
||||
this.play(); //loop
|
||||
});
|
||||
|
||||
//document.body.appendChild(this.video);
|
||||
};
|
||||
|
||||
ImageVideo.prototype.onPropertyChanged = function(name, value) {
|
||||
this.properties[name] = value;
|
||||
if (name == "url" && value != "") {
|
||||
this.loadVideo(value);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
ImageVideo.prototype.play = function() {
|
||||
if (this._video && this._video.videoWidth ) { //is loaded
|
||||
this._video.play();
|
||||
}
|
||||
};
|
||||
|
||||
ImageVideo.prototype.playPause = function() {
|
||||
if (!this._video) {
|
||||
return;
|
||||
}
|
||||
if (this._video.paused) {
|
||||
this.play();
|
||||
} else {
|
||||
this.pause();
|
||||
}
|
||||
};
|
||||
|
||||
ImageVideo.prototype.stop = function() {
|
||||
if (!this._video) {
|
||||
return;
|
||||
}
|
||||
this._video.pause();
|
||||
this._video.currentTime = 0;
|
||||
};
|
||||
|
||||
ImageVideo.prototype.pause = function() {
|
||||
if (!this._video) {
|
||||
return;
|
||||
}
|
||||
console.log("Video paused");
|
||||
this._video.pause();
|
||||
};
|
||||
|
||||
ImageVideo.prototype.onWidget = function(e, widget) {
|
||||
/*
|
||||
if(widget.name == "demo")
|
||||
{
|
||||
this.loadVideo();
|
||||
}
|
||||
else if(widget.name == "play")
|
||||
{
|
||||
if(this._video)
|
||||
this.playPause();
|
||||
}
|
||||
if(widget.name == "stop")
|
||||
{
|
||||
this.stop();
|
||||
}
|
||||
else if(widget.name == "mute")
|
||||
{
|
||||
if(this._video)
|
||||
this._video.muted = !this._video.muted;
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("graphics/video", ImageVideo);
|
||||
|
||||
// Texture Webcam *****************************************
|
||||
function ImageWebcam() {
|
||||
this.addOutput("Webcam", "image");
|
||||
this.properties = { filterFacingMode: false, facingMode: "user" };
|
||||
this.boxcolor = "black";
|
||||
this.frame = 0;
|
||||
}
|
||||
|
||||
ImageWebcam.title = "Webcam";
|
||||
ImageWebcam.desc = "Webcam image";
|
||||
ImageWebcam.is_webcam_open = false;
|
||||
|
||||
ImageWebcam.prototype.openStream = function() {
|
||||
if (!navigator.mediaDevices.getUserMedia) {
|
||||
console.log('getUserMedia() is not supported in your browser, use chrome and enable WebRTC from about://flags');
|
||||
return;
|
||||
}
|
||||
|
||||
this._waiting_confirmation = true;
|
||||
|
||||
// Not showing vendor prefixes.
|
||||
var constraints = {
|
||||
audio: false,
|
||||
video: !this.properties.filterFacingMode ? true : { facingMode: this.properties.facingMode }
|
||||
};
|
||||
navigator.mediaDevices
|
||||
.getUserMedia(constraints)
|
||||
.then(this.streamReady.bind(this))
|
||||
.catch(onFailSoHard);
|
||||
|
||||
var that = this;
|
||||
function onFailSoHard(e) {
|
||||
console.log("Webcam rejected", e);
|
||||
that._webcam_stream = false;
|
||||
ImageWebcam.is_webcam_open = false;
|
||||
that.boxcolor = "red";
|
||||
that.trigger("stream_error");
|
||||
}
|
||||
};
|
||||
|
||||
ImageWebcam.prototype.closeStream = function() {
|
||||
if (this._webcam_stream) {
|
||||
var tracks = this._webcam_stream.getTracks();
|
||||
if (tracks.length) {
|
||||
for (var i = 0; i < tracks.length; ++i) {
|
||||
tracks[i].stop();
|
||||
}
|
||||
}
|
||||
ImageWebcam.is_webcam_open = false;
|
||||
this._webcam_stream = null;
|
||||
this._video = null;
|
||||
this.boxcolor = "black";
|
||||
this.trigger("stream_closed");
|
||||
}
|
||||
};
|
||||
|
||||
ImageWebcam.prototype.onPropertyChanged = function(name, value) {
|
||||
if (name == "facingMode") {
|
||||
this.properties.facingMode = value;
|
||||
this.closeStream();
|
||||
this.openStream();
|
||||
}
|
||||
};
|
||||
|
||||
ImageWebcam.prototype.onRemoved = function() {
|
||||
this.closeStream();
|
||||
};
|
||||
|
||||
ImageWebcam.prototype.streamReady = function(localMediaStream) {
|
||||
this._webcam_stream = localMediaStream;
|
||||
//this._waiting_confirmation = false;
|
||||
this.boxcolor = "green";
|
||||
|
||||
var video = this._video;
|
||||
if (!video) {
|
||||
video = document.createElement("video");
|
||||
video.autoplay = true;
|
||||
video.srcObject = localMediaStream;
|
||||
this._video = video;
|
||||
//document.body.appendChild( video ); //debug
|
||||
//when video info is loaded (size and so)
|
||||
video.onloadedmetadata = function(e) {
|
||||
// Ready to go. Do some stuff.
|
||||
console.log(e);
|
||||
ImageWebcam.is_webcam_open = true;
|
||||
};
|
||||
}
|
||||
|
||||
this.trigger("stream_ready", video);
|
||||
};
|
||||
|
||||
ImageWebcam.prototype.onExecute = function() {
|
||||
if (this._webcam_stream == null && !this._waiting_confirmation) {
|
||||
this.openStream();
|
||||
}
|
||||
|
||||
if (!this._video || !this._video.videoWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._video.frame = ++this.frame;
|
||||
this._video.width = this._video.videoWidth;
|
||||
this._video.height = this._video.videoHeight;
|
||||
this.setOutputData(0, this._video);
|
||||
for (var i = 1; i < this.outputs.length; ++i) {
|
||||
if (!this.outputs[i]) {
|
||||
continue;
|
||||
}
|
||||
switch (this.outputs[i].name) {
|
||||
case "width":
|
||||
this.setOutputData(i, this._video.videoWidth);
|
||||
break;
|
||||
case "height":
|
||||
this.setOutputData(i, this._video.videoHeight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ImageWebcam.prototype.getExtraMenuOptions = function(graphcanvas) {
|
||||
var that = this;
|
||||
var txt = !that.properties.show ? "Show Frame" : "Hide Frame";
|
||||
return [
|
||||
{
|
||||
content: txt,
|
||||
callback: function() {
|
||||
that.properties.show = !that.properties.show;
|
||||
}
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
ImageWebcam.prototype.onDrawBackground = function(ctx) {
|
||||
if (
|
||||
this.flags.collapsed ||
|
||||
this.size[1] <= 20 ||
|
||||
!this.properties.show
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._video) {
|
||||
return;
|
||||
}
|
||||
|
||||
//render to graph canvas
|
||||
ctx.save();
|
||||
ctx.drawImage(this._video, 0, 0, this.size[0], this.size[1]);
|
||||
ctx.restore();
|
||||
};
|
||||
|
||||
ImageWebcam.prototype.onGetOutputs = function() {
|
||||
return [
|
||||
["width", "number"],
|
||||
["height", "number"],
|
||||
["stream_ready", LiteGraph.EVENT],
|
||||
["stream_closed", LiteGraph.EVENT],
|
||||
["stream_error", LiteGraph.EVENT]
|
||||
];
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("graphics/webcam", ImageWebcam);
|
||||
})(this);
|
||||
@@ -1,354 +0,0 @@
|
||||
(function(global) {
|
||||
var LiteGraph = global.LiteGraph;
|
||||
|
||||
function GamepadInput() {
|
||||
this.addOutput("left_x_axis", "number");
|
||||
this.addOutput("left_y_axis", "number");
|
||||
this.addOutput("button_pressed", LiteGraph.EVENT);
|
||||
this.properties = { gamepad_index: 0, threshold: 0.1 };
|
||||
|
||||
this._left_axis = new Float32Array(2);
|
||||
this._right_axis = new Float32Array(2);
|
||||
this._triggers = new Float32Array(2);
|
||||
this._previous_buttons = new Uint8Array(17);
|
||||
this._current_buttons = new Uint8Array(17);
|
||||
}
|
||||
|
||||
GamepadInput.title = "Gamepad";
|
||||
GamepadInput.desc = "gets the input of the gamepad";
|
||||
|
||||
GamepadInput.CENTER = 0;
|
||||
GamepadInput.LEFT = 1;
|
||||
GamepadInput.RIGHT = 2;
|
||||
GamepadInput.UP = 4;
|
||||
GamepadInput.DOWN = 8;
|
||||
|
||||
GamepadInput.zero = new Float32Array(2);
|
||||
GamepadInput.buttons = [
|
||||
"a",
|
||||
"b",
|
||||
"x",
|
||||
"y",
|
||||
"lb",
|
||||
"rb",
|
||||
"lt",
|
||||
"rt",
|
||||
"back",
|
||||
"start",
|
||||
"ls",
|
||||
"rs",
|
||||
"home"
|
||||
];
|
||||
|
||||
GamepadInput.prototype.onExecute = function() {
|
||||
//get gamepad
|
||||
var gamepad = this.getGamepad();
|
||||
var threshold = this.properties.threshold || 0.0;
|
||||
|
||||
if (gamepad) {
|
||||
this._left_axis[0] =
|
||||
Math.abs(gamepad.xbox.axes["lx"]) > threshold
|
||||
? gamepad.xbox.axes["lx"]
|
||||
: 0;
|
||||
this._left_axis[1] =
|
||||
Math.abs(gamepad.xbox.axes["ly"]) > threshold
|
||||
? gamepad.xbox.axes["ly"]
|
||||
: 0;
|
||||
this._right_axis[0] =
|
||||
Math.abs(gamepad.xbox.axes["rx"]) > threshold
|
||||
? gamepad.xbox.axes["rx"]
|
||||
: 0;
|
||||
this._right_axis[1] =
|
||||
Math.abs(gamepad.xbox.axes["ry"]) > threshold
|
||||
? gamepad.xbox.axes["ry"]
|
||||
: 0;
|
||||
this._triggers[0] =
|
||||
Math.abs(gamepad.xbox.axes["ltrigger"]) > threshold
|
||||
? gamepad.xbox.axes["ltrigger"]
|
||||
: 0;
|
||||
this._triggers[1] =
|
||||
Math.abs(gamepad.xbox.axes["rtrigger"]) > threshold
|
||||
? gamepad.xbox.axes["rtrigger"]
|
||||
: 0;
|
||||
}
|
||||
|
||||
if (this.outputs) {
|
||||
for (var i = 0; i < this.outputs.length; i++) {
|
||||
var output = this.outputs[i];
|
||||
if (!output.links || !output.links.length) {
|
||||
continue;
|
||||
}
|
||||
var v = null;
|
||||
|
||||
if (gamepad) {
|
||||
switch (output.name) {
|
||||
case "left_axis":
|
||||
v = this._left_axis;
|
||||
break;
|
||||
case "right_axis":
|
||||
v = this._right_axis;
|
||||
break;
|
||||
case "left_x_axis":
|
||||
v = this._left_axis[0];
|
||||
break;
|
||||
case "left_y_axis":
|
||||
v = this._left_axis[1];
|
||||
break;
|
||||
case "right_x_axis":
|
||||
v = this._right_axis[0];
|
||||
break;
|
||||
case "right_y_axis":
|
||||
v = this._right_axis[1];
|
||||
break;
|
||||
case "trigger_left":
|
||||
v = this._triggers[0];
|
||||
break;
|
||||
case "trigger_right":
|
||||
v = this._triggers[1];
|
||||
break;
|
||||
case "a_button":
|
||||
v = gamepad.xbox.buttons["a"] ? 1 : 0;
|
||||
break;
|
||||
case "b_button":
|
||||
v = gamepad.xbox.buttons["b"] ? 1 : 0;
|
||||
break;
|
||||
case "x_button":
|
||||
v = gamepad.xbox.buttons["x"] ? 1 : 0;
|
||||
break;
|
||||
case "y_button":
|
||||
v = gamepad.xbox.buttons["y"] ? 1 : 0;
|
||||
break;
|
||||
case "lb_button":
|
||||
v = gamepad.xbox.buttons["lb"] ? 1 : 0;
|
||||
break;
|
||||
case "rb_button":
|
||||
v = gamepad.xbox.buttons["rb"] ? 1 : 0;
|
||||
break;
|
||||
case "ls_button":
|
||||
v = gamepad.xbox.buttons["ls"] ? 1 : 0;
|
||||
break;
|
||||
case "rs_button":
|
||||
v = gamepad.xbox.buttons["rs"] ? 1 : 0;
|
||||
break;
|
||||
case "hat_left":
|
||||
v = gamepad.xbox.hatmap & GamepadInput.LEFT;
|
||||
break;
|
||||
case "hat_right":
|
||||
v = gamepad.xbox.hatmap & GamepadInput.RIGHT;
|
||||
break;
|
||||
case "hat_up":
|
||||
v = gamepad.xbox.hatmap & GamepadInput.UP;
|
||||
break;
|
||||
case "hat_down":
|
||||
v = gamepad.xbox.hatmap & GamepadInput.DOWN;
|
||||
break;
|
||||
case "hat":
|
||||
v = gamepad.xbox.hatmap;
|
||||
break;
|
||||
case "start_button":
|
||||
v = gamepad.xbox.buttons["start"] ? 1 : 0;
|
||||
break;
|
||||
case "back_button":
|
||||
v = gamepad.xbox.buttons["back"] ? 1 : 0;
|
||||
break;
|
||||
case "button_pressed":
|
||||
for (
|
||||
var j = 0;
|
||||
j < this._current_buttons.length;
|
||||
++j
|
||||
) {
|
||||
if (
|
||||
this._current_buttons[j] &&
|
||||
!this._previous_buttons[j]
|
||||
) {
|
||||
this.triggerSlot(
|
||||
i,
|
||||
GamepadInput.buttons[j]
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
//if no gamepad is connected, output 0
|
||||
switch (output.name) {
|
||||
case "button_pressed":
|
||||
break;
|
||||
case "left_axis":
|
||||
case "right_axis":
|
||||
v = GamepadInput.zero;
|
||||
break;
|
||||
default:
|
||||
v = 0;
|
||||
}
|
||||
}
|
||||
this.setOutputData(i, v);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
GamepadInput.mapping = {a:0,b:1,x:2,y:3,lb:4,rb:5,lt:6,rt:7,back:8,start:9,ls:10,rs:11 };
|
||||
GamepadInput.mapping_array = ["a","b","x","y","lb","rb","lt","rt","back","start","ls","rs"];
|
||||
|
||||
GamepadInput.prototype.getGamepad = function() {
|
||||
var getGamepads =
|
||||
navigator.getGamepads ||
|
||||
navigator.webkitGetGamepads ||
|
||||
navigator.mozGetGamepads;
|
||||
if (!getGamepads) {
|
||||
return null;
|
||||
}
|
||||
var gamepads = getGamepads.call(navigator);
|
||||
var gamepad = null;
|
||||
|
||||
this._previous_buttons.set(this._current_buttons);
|
||||
|
||||
//pick the first connected
|
||||
for (var i = this.properties.gamepad_index; i < 4; i++) {
|
||||
if (!gamepads[i]) {
|
||||
continue;
|
||||
}
|
||||
gamepad = gamepads[i];
|
||||
|
||||
//xbox controller mapping
|
||||
var xbox = this.xbox_mapping;
|
||||
if (!xbox) {
|
||||
xbox = this.xbox_mapping = {
|
||||
axes: [],
|
||||
buttons: {},
|
||||
hat: "",
|
||||
hatmap: GamepadInput.CENTER
|
||||
};
|
||||
}
|
||||
|
||||
xbox.axes["lx"] = gamepad.axes[0];
|
||||
xbox.axes["ly"] = gamepad.axes[1];
|
||||
xbox.axes["rx"] = gamepad.axes[2];
|
||||
xbox.axes["ry"] = gamepad.axes[3];
|
||||
xbox.axes["ltrigger"] = gamepad.buttons[6].value;
|
||||
xbox.axes["rtrigger"] = gamepad.buttons[7].value;
|
||||
xbox.hat = "";
|
||||
xbox.hatmap = GamepadInput.CENTER;
|
||||
|
||||
for (var j = 0; j < gamepad.buttons.length; j++) {
|
||||
this._current_buttons[j] = gamepad.buttons[j].pressed;
|
||||
|
||||
if(j < 12)
|
||||
{
|
||||
xbox.buttons[ GamepadInput.mapping_array[j] ] = gamepad.buttons[j].pressed;
|
||||
if(gamepad.buttons[j].was_pressed)
|
||||
this.trigger( GamepadInput.mapping_array[j] + "_button_event" );
|
||||
}
|
||||
else //mapping of XBOX
|
||||
switch ( j ) //I use a switch to ensure that a player with another gamepad could play
|
||||
{
|
||||
case 12:
|
||||
if (gamepad.buttons[j].pressed) {
|
||||
xbox.hat += "up";
|
||||
xbox.hatmap |= GamepadInput.UP;
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
if (gamepad.buttons[j].pressed) {
|
||||
xbox.hat += "down";
|
||||
xbox.hatmap |= GamepadInput.DOWN;
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
if (gamepad.buttons[j].pressed) {
|
||||
xbox.hat += "left";
|
||||
xbox.hatmap |= GamepadInput.LEFT;
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
if (gamepad.buttons[j].pressed) {
|
||||
xbox.hat += "right";
|
||||
xbox.hatmap |= GamepadInput.RIGHT;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
xbox.buttons["home"] = gamepad.buttons[j].pressed;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
gamepad.xbox = xbox;
|
||||
return gamepad;
|
||||
}
|
||||
};
|
||||
|
||||
GamepadInput.prototype.onDrawBackground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
//render gamepad state?
|
||||
var la = this._left_axis;
|
||||
var ra = this._right_axis;
|
||||
ctx.strokeStyle = "#88A";
|
||||
ctx.strokeRect(
|
||||
(la[0] + 1) * 0.5 * this.size[0] - 4,
|
||||
(la[1] + 1) * 0.5 * this.size[1] - 4,
|
||||
8,
|
||||
8
|
||||
);
|
||||
ctx.strokeStyle = "#8A8";
|
||||
ctx.strokeRect(
|
||||
(ra[0] + 1) * 0.5 * this.size[0] - 4,
|
||||
(ra[1] + 1) * 0.5 * this.size[1] - 4,
|
||||
8,
|
||||
8
|
||||
);
|
||||
var h = this.size[1] / this._current_buttons.length;
|
||||
ctx.fillStyle = "#AEB";
|
||||
for (var i = 0; i < this._current_buttons.length; ++i) {
|
||||
if (this._current_buttons[i]) {
|
||||
ctx.fillRect(0, h * i, 6, h);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
GamepadInput.prototype.onGetOutputs = function() {
|
||||
return [
|
||||
["left_axis", "vec2"],
|
||||
["right_axis", "vec2"],
|
||||
["left_x_axis", "number"],
|
||||
["left_y_axis", "number"],
|
||||
["right_x_axis", "number"],
|
||||
["right_y_axis", "number"],
|
||||
["trigger_left", "number"],
|
||||
["trigger_right", "number"],
|
||||
["a_button", "number"],
|
||||
["b_button", "number"],
|
||||
["x_button", "number"],
|
||||
["y_button", "number"],
|
||||
["lb_button", "number"],
|
||||
["rb_button", "number"],
|
||||
["ls_button", "number"],
|
||||
["rs_button", "number"],
|
||||
["start_button", "number"],
|
||||
["back_button", "number"],
|
||||
["a_button_event", LiteGraph.EVENT ],
|
||||
["b_button_event", LiteGraph.EVENT ],
|
||||
["x_button_event", LiteGraph.EVENT ],
|
||||
["y_button_event", LiteGraph.EVENT ],
|
||||
["lb_button_event", LiteGraph.EVENT ],
|
||||
["rb_button_event", LiteGraph.EVENT ],
|
||||
["ls_button_event", LiteGraph.EVENT ],
|
||||
["rs_button_event", LiteGraph.EVENT ],
|
||||
["start_button_event", LiteGraph.EVENT ],
|
||||
["back_button_event", LiteGraph.EVENT ],
|
||||
["hat_left", "number"],
|
||||
["hat_right", "number"],
|
||||
["hat_up", "number"],
|
||||
["hat_down", "number"],
|
||||
["hat", "number"],
|
||||
["button_pressed", LiteGraph.EVENT]
|
||||
];
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("input/gamepad", GamepadInput);
|
||||
|
||||
})(this);
|
||||
@@ -1,798 +0,0 @@
|
||||
//widgets
|
||||
(function(global) {
|
||||
var LiteGraph = global.LiteGraph;
|
||||
|
||||
/* Button ****************/
|
||||
|
||||
function WidgetButton() {
|
||||
this.addOutput("", LiteGraph.EVENT);
|
||||
this.addOutput("", "boolean");
|
||||
this.addProperty("text", "click me");
|
||||
this.addProperty("font_size", 30);
|
||||
this.addProperty("message", "");
|
||||
this.size = [164, 84];
|
||||
this.clicked = false;
|
||||
}
|
||||
|
||||
WidgetButton.title = "Button";
|
||||
WidgetButton.desc = "Triggers an event";
|
||||
|
||||
WidgetButton.font = "Arial";
|
||||
WidgetButton.prototype.onDrawForeground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
var margin = 10;
|
||||
ctx.fillStyle = "black";
|
||||
ctx.fillRect(
|
||||
margin + 1,
|
||||
margin + 1,
|
||||
this.size[0] - margin * 2,
|
||||
this.size[1] - margin * 2
|
||||
);
|
||||
ctx.fillStyle = "#AAF";
|
||||
ctx.fillRect(
|
||||
margin - 1,
|
||||
margin - 1,
|
||||
this.size[0] - margin * 2,
|
||||
this.size[1] - margin * 2
|
||||
);
|
||||
ctx.fillStyle = this.clicked
|
||||
? "white"
|
||||
: this.mouseOver
|
||||
? "#668"
|
||||
: "#334";
|
||||
ctx.fillRect(
|
||||
margin,
|
||||
margin,
|
||||
this.size[0] - margin * 2,
|
||||
this.size[1] - margin * 2
|
||||
);
|
||||
|
||||
if (this.properties.text || this.properties.text === 0) {
|
||||
var font_size = this.properties.font_size || 30;
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillStyle = this.clicked ? "black" : "white";
|
||||
ctx.font = font_size + "px " + WidgetButton.font;
|
||||
ctx.fillText(
|
||||
this.properties.text,
|
||||
this.size[0] * 0.5,
|
||||
this.size[1] * 0.5 + font_size * 0.3
|
||||
);
|
||||
ctx.textAlign = "left";
|
||||
}
|
||||
};
|
||||
|
||||
WidgetButton.prototype.onMouseDown = function(e, local_pos) {
|
||||
if (
|
||||
local_pos[0] > 1 &&
|
||||
local_pos[1] > 1 &&
|
||||
local_pos[0] < this.size[0] - 2 &&
|
||||
local_pos[1] < this.size[1] - 2
|
||||
) {
|
||||
this.clicked = true;
|
||||
this.setOutputData(1, this.clicked);
|
||||
this.triggerSlot(0, this.properties.message);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
WidgetButton.prototype.onExecute = function() {
|
||||
this.setOutputData(1, this.clicked);
|
||||
};
|
||||
|
||||
WidgetButton.prototype.onMouseUp = function(e) {
|
||||
this.clicked = false;
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("widget/button", WidgetButton);
|
||||
|
||||
function WidgetToggle() {
|
||||
this.addInput("", "boolean");
|
||||
this.addInput("e", LiteGraph.ACTION);
|
||||
this.addOutput("v", "boolean");
|
||||
this.addOutput("e", LiteGraph.EVENT);
|
||||
this.properties = { font: "", value: false };
|
||||
this.size = [160, 44];
|
||||
}
|
||||
|
||||
WidgetToggle.title = "Toggle";
|
||||
WidgetToggle.desc = "Toggles between true or false";
|
||||
|
||||
WidgetToggle.prototype.onDrawForeground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
var size = this.size[1] * 0.5;
|
||||
var margin = 0.25;
|
||||
var h = this.size[1] * 0.8;
|
||||
ctx.font = this.properties.font || (size * 0.8).toFixed(0) + "px Arial";
|
||||
var w = ctx.measureText(this.title).width;
|
||||
var x = (this.size[0] - (w + size)) * 0.5;
|
||||
|
||||
ctx.fillStyle = "#AAA";
|
||||
ctx.fillRect(x, h - size, size, size);
|
||||
|
||||
ctx.fillStyle = this.properties.value ? "#AEF" : "#000";
|
||||
ctx.fillRect(
|
||||
x + size * margin,
|
||||
h - size + size * margin,
|
||||
size * (1 - margin * 2),
|
||||
size * (1 - margin * 2)
|
||||
);
|
||||
|
||||
ctx.textAlign = "left";
|
||||
ctx.fillStyle = "#AAA";
|
||||
ctx.fillText(this.title, size * 1.2 + x, h * 0.85);
|
||||
ctx.textAlign = "left";
|
||||
};
|
||||
|
||||
WidgetToggle.prototype.onAction = function(action) {
|
||||
this.properties.value = !this.properties.value;
|
||||
this.trigger("e", this.properties.value);
|
||||
};
|
||||
|
||||
WidgetToggle.prototype.onExecute = function() {
|
||||
var v = this.getInputData(0);
|
||||
if (v != null) {
|
||||
this.properties.value = v;
|
||||
}
|
||||
this.setOutputData(0, this.properties.value);
|
||||
};
|
||||
|
||||
WidgetToggle.prototype.onMouseDown = function(e, local_pos) {
|
||||
if (
|
||||
local_pos[0] > 1 &&
|
||||
local_pos[1] > 1 &&
|
||||
local_pos[0] < this.size[0] - 2 &&
|
||||
local_pos[1] < this.size[1] - 2
|
||||
) {
|
||||
this.properties.value = !this.properties.value;
|
||||
this.graph._version++;
|
||||
this.trigger("e", this.properties.value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("widget/toggle", WidgetToggle);
|
||||
|
||||
/* Number ****************/
|
||||
|
||||
function WidgetNumber() {
|
||||
this.addOutput("", "number");
|
||||
this.size = [80, 60];
|
||||
this.properties = { min: -1000, max: 1000, value: 1, step: 1 };
|
||||
this.old_y = -1;
|
||||
this._remainder = 0;
|
||||
this._precision = 0;
|
||||
this.mouse_captured = false;
|
||||
}
|
||||
|
||||
WidgetNumber.title = "Number";
|
||||
WidgetNumber.desc = "Widget to select number value";
|
||||
|
||||
WidgetNumber.pixels_threshold = 10;
|
||||
WidgetNumber.markers_color = "#666";
|
||||
|
||||
WidgetNumber.prototype.onDrawForeground = function(ctx) {
|
||||
var x = this.size[0] * 0.5;
|
||||
var h = this.size[1];
|
||||
if (h > 30) {
|
||||
ctx.fillStyle = WidgetNumber.markers_color;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, h * 0.1);
|
||||
ctx.lineTo(x + h * 0.1, h * 0.2);
|
||||
ctx.lineTo(x + h * -0.1, h * 0.2);
|
||||
ctx.fill();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, h * 0.9);
|
||||
ctx.lineTo(x + h * 0.1, h * 0.8);
|
||||
ctx.lineTo(x + h * -0.1, h * 0.8);
|
||||
ctx.fill();
|
||||
ctx.font = (h * 0.7).toFixed(1) + "px Arial";
|
||||
} else {
|
||||
ctx.font = (h * 0.8).toFixed(1) + "px Arial";
|
||||
}
|
||||
|
||||
ctx.textAlign = "center";
|
||||
ctx.font = (h * 0.7).toFixed(1) + "px Arial";
|
||||
ctx.fillStyle = "#EEE";
|
||||
ctx.fillText(
|
||||
this.properties.value.toFixed(this._precision),
|
||||
x,
|
||||
h * 0.75
|
||||
);
|
||||
};
|
||||
|
||||
WidgetNumber.prototype.onExecute = function() {
|
||||
this.setOutputData(0, this.properties.value);
|
||||
};
|
||||
|
||||
WidgetNumber.prototype.onPropertyChanged = function(name, value) {
|
||||
var t = (this.properties.step + "").split(".");
|
||||
this._precision = t.length > 1 ? t[1].length : 0;
|
||||
};
|
||||
|
||||
WidgetNumber.prototype.onMouseDown = function(e, pos) {
|
||||
if (pos[1] < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.old_y = e.canvasY;
|
||||
this.captureInput(true);
|
||||
this.mouse_captured = true;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
WidgetNumber.prototype.onMouseMove = function(e) {
|
||||
if (!this.mouse_captured) {
|
||||
return;
|
||||
}
|
||||
|
||||
var delta = this.old_y - e.canvasY;
|
||||
if (e.shiftKey) {
|
||||
delta *= 10;
|
||||
}
|
||||
if (e.metaKey || e.altKey) {
|
||||
delta *= 0.1;
|
||||
}
|
||||
this.old_y = e.canvasY;
|
||||
|
||||
var steps = this._remainder + delta / WidgetNumber.pixels_threshold;
|
||||
this._remainder = steps % 1;
|
||||
steps = steps | 0;
|
||||
|
||||
var v = clamp(
|
||||
this.properties.value + steps * this.properties.step,
|
||||
this.properties.min,
|
||||
this.properties.max
|
||||
);
|
||||
this.properties.value = v;
|
||||
this.graph._version++;
|
||||
this.setDirtyCanvas(true);
|
||||
};
|
||||
|
||||
WidgetNumber.prototype.onMouseUp = function(e, pos) {
|
||||
if (e.click_time < 200) {
|
||||
var steps = pos[1] > this.size[1] * 0.5 ? -1 : 1;
|
||||
this.properties.value = clamp(
|
||||
this.properties.value + steps * this.properties.step,
|
||||
this.properties.min,
|
||||
this.properties.max
|
||||
);
|
||||
this.graph._version++;
|
||||
this.setDirtyCanvas(true);
|
||||
}
|
||||
|
||||
if (this.mouse_captured) {
|
||||
this.mouse_captured = false;
|
||||
this.captureInput(false);
|
||||
}
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("widget/number", WidgetNumber);
|
||||
|
||||
|
||||
/* Combo ****************/
|
||||
|
||||
function WidgetCombo() {
|
||||
this.addOutput("", "string");
|
||||
this.addOutput("change", LiteGraph.EVENT);
|
||||
this.size = [80, 60];
|
||||
this.properties = { value: "A", values:"A;B;C" };
|
||||
this.old_y = -1;
|
||||
this.mouse_captured = false;
|
||||
this._values = this.properties.values.split(";");
|
||||
var that = this;
|
||||
this.widgets_up = true;
|
||||
this.widget = this.addWidget("combo","", this.properties.value, function(v){
|
||||
that.properties.value = v;
|
||||
that.triggerSlot(1, v);
|
||||
}, { property: "value", values: this._values } );
|
||||
}
|
||||
|
||||
WidgetCombo.title = "Combo";
|
||||
WidgetCombo.desc = "Widget to select from a list";
|
||||
|
||||
WidgetCombo.prototype.onExecute = function() {
|
||||
this.setOutputData( 0, this.properties.value );
|
||||
};
|
||||
|
||||
WidgetCombo.prototype.onPropertyChanged = function(name, value) {
|
||||
if(name == "values")
|
||||
{
|
||||
this._values = value.split(";");
|
||||
this.widget.options.values = this._values;
|
||||
}
|
||||
else if(name == "value")
|
||||
{
|
||||
this.widget.value = value;
|
||||
}
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("widget/combo", WidgetCombo);
|
||||
|
||||
|
||||
/* Knob ****************/
|
||||
|
||||
function WidgetKnob() {
|
||||
this.addOutput("", "number");
|
||||
this.size = [64, 84];
|
||||
this.properties = {
|
||||
min: 0,
|
||||
max: 1,
|
||||
value: 0.5,
|
||||
color: "#7AF",
|
||||
precision: 2
|
||||
};
|
||||
this.value = -1;
|
||||
}
|
||||
|
||||
WidgetKnob.title = "Knob";
|
||||
WidgetKnob.desc = "Circular controller";
|
||||
WidgetKnob.size = [80, 100];
|
||||
|
||||
WidgetKnob.prototype.onDrawForeground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.value == -1) {
|
||||
this.value =
|
||||
(this.properties.value - this.properties.min) /
|
||||
(this.properties.max - this.properties.min);
|
||||
}
|
||||
|
||||
var center_x = this.size[0] * 0.5;
|
||||
var center_y = this.size[1] * 0.5;
|
||||
var radius = Math.min(this.size[0], this.size[1]) * 0.5 - 5;
|
||||
var w = Math.floor(radius * 0.05);
|
||||
|
||||
ctx.globalAlpha = 1;
|
||||
ctx.save();
|
||||
ctx.translate(center_x, center_y);
|
||||
ctx.rotate(Math.PI * 0.75);
|
||||
|
||||
//bg
|
||||
ctx.fillStyle = "rgba(0,0,0,0.5)";
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, 0);
|
||||
ctx.arc(0, 0, radius, 0, Math.PI * 1.5);
|
||||
ctx.fill();
|
||||
|
||||
//value
|
||||
ctx.strokeStyle = "black";
|
||||
ctx.fillStyle = this.properties.color;
|
||||
ctx.lineWidth = 2;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, 0);
|
||||
ctx.arc(
|
||||
0,
|
||||
0,
|
||||
radius - 4,
|
||||
0,
|
||||
Math.PI * 1.5 * Math.max(0.01, this.value)
|
||||
);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
//ctx.stroke();
|
||||
ctx.lineWidth = 1;
|
||||
ctx.globalAlpha = 1;
|
||||
ctx.restore();
|
||||
|
||||
//inner
|
||||
ctx.fillStyle = "black";
|
||||
ctx.beginPath();
|
||||
ctx.arc(center_x, center_y, radius * 0.75, 0, Math.PI * 2, true);
|
||||
ctx.fill();
|
||||
|
||||
//miniball
|
||||
ctx.fillStyle = this.mouseOver ? "white" : this.properties.color;
|
||||
ctx.beginPath();
|
||||
var angle = this.value * Math.PI * 1.5 + Math.PI * 0.75;
|
||||
ctx.arc(
|
||||
center_x + Math.cos(angle) * radius * 0.65,
|
||||
center_y + Math.sin(angle) * radius * 0.65,
|
||||
radius * 0.05,
|
||||
0,
|
||||
Math.PI * 2,
|
||||
true
|
||||
);
|
||||
ctx.fill();
|
||||
|
||||
//text
|
||||
ctx.fillStyle = this.mouseOver ? "white" : "#AAA";
|
||||
ctx.font = Math.floor(radius * 0.5) + "px Arial";
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillText(
|
||||
this.properties.value.toFixed(this.properties.precision),
|
||||
center_x,
|
||||
center_y + radius * 0.15
|
||||
);
|
||||
};
|
||||
|
||||
WidgetKnob.prototype.onExecute = function() {
|
||||
this.setOutputData(0, this.properties.value);
|
||||
this.boxcolor = LiteGraph.colorToString([
|
||||
this.value,
|
||||
this.value,
|
||||
this.value
|
||||
]);
|
||||
};
|
||||
|
||||
WidgetKnob.prototype.onMouseDown = function(e) {
|
||||
this.center = [this.size[0] * 0.5, this.size[1] * 0.5 + 20];
|
||||
this.radius = this.size[0] * 0.5;
|
||||
if (
|
||||
e.canvasY - this.pos[1] < 20 ||
|
||||
LiteGraph.distance(
|
||||
[e.canvasX, e.canvasY],
|
||||
[this.pos[0] + this.center[0], this.pos[1] + this.center[1]]
|
||||
) > this.radius
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
this.oldmouse = [e.canvasX - this.pos[0], e.canvasY - this.pos[1]];
|
||||
this.captureInput(true);
|
||||
return true;
|
||||
};
|
||||
|
||||
WidgetKnob.prototype.onMouseMove = function(e) {
|
||||
if (!this.oldmouse) {
|
||||
return;
|
||||
}
|
||||
|
||||
var m = [e.canvasX - this.pos[0], e.canvasY - this.pos[1]];
|
||||
|
||||
var v = this.value;
|
||||
v -= (m[1] - this.oldmouse[1]) * 0.01;
|
||||
if (v > 1.0) {
|
||||
v = 1.0;
|
||||
} else if (v < 0.0) {
|
||||
v = 0.0;
|
||||
}
|
||||
this.value = v;
|
||||
this.properties.value =
|
||||
this.properties.min +
|
||||
(this.properties.max - this.properties.min) * this.value;
|
||||
this.oldmouse = m;
|
||||
this.setDirtyCanvas(true);
|
||||
};
|
||||
|
||||
WidgetKnob.prototype.onMouseUp = function(e) {
|
||||
if (this.oldmouse) {
|
||||
this.oldmouse = null;
|
||||
this.captureInput(false);
|
||||
}
|
||||
};
|
||||
|
||||
WidgetKnob.prototype.onPropertyChanged = function(name, value) {
|
||||
if (name == "min" || name == "max" || name == "value") {
|
||||
this.properties[name] = parseFloat(value);
|
||||
return true; //block
|
||||
}
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("widget/knob", WidgetKnob);
|
||||
|
||||
//Show value inside the debug console
|
||||
function WidgetSliderGUI() {
|
||||
this.addOutput("", "number");
|
||||
this.properties = {
|
||||
value: 0.5,
|
||||
min: 0,
|
||||
max: 1,
|
||||
text: "V"
|
||||
};
|
||||
var that = this;
|
||||
this.size = [140, 40];
|
||||
this.slider = this.addWidget(
|
||||
"slider",
|
||||
"V",
|
||||
this.properties.value,
|
||||
function(v) {
|
||||
that.properties.value = v;
|
||||
},
|
||||
this.properties
|
||||
);
|
||||
this.widgets_up = true;
|
||||
}
|
||||
|
||||
WidgetSliderGUI.title = "Inner Slider";
|
||||
|
||||
WidgetSliderGUI.prototype.onPropertyChanged = function(name, value) {
|
||||
if (name == "value") {
|
||||
this.slider.value = value;
|
||||
}
|
||||
};
|
||||
|
||||
WidgetSliderGUI.prototype.onExecute = function() {
|
||||
this.setOutputData(0, this.properties.value);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("widget/internal_slider", WidgetSliderGUI);
|
||||
|
||||
//Widget H SLIDER
|
||||
function WidgetHSlider() {
|
||||
this.size = [160, 26];
|
||||
this.addOutput("", "number");
|
||||
this.properties = { color: "#7AF", min: 0, max: 1, value: 0.5 };
|
||||
this.value = -1;
|
||||
}
|
||||
|
||||
WidgetHSlider.title = "H.Slider";
|
||||
WidgetHSlider.desc = "Linear slider controller";
|
||||
|
||||
WidgetHSlider.prototype.onDrawForeground = function(ctx) {
|
||||
if (this.value == -1) {
|
||||
this.value =
|
||||
(this.properties.value - this.properties.min) /
|
||||
(this.properties.max - this.properties.min);
|
||||
}
|
||||
|
||||
//border
|
||||
ctx.globalAlpha = 1;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.fillStyle = "#000";
|
||||
ctx.fillRect(2, 2, this.size[0] - 4, this.size[1] - 4);
|
||||
|
||||
ctx.fillStyle = this.properties.color;
|
||||
ctx.beginPath();
|
||||
ctx.rect(4, 4, (this.size[0] - 8) * this.value, this.size[1] - 8);
|
||||
ctx.fill();
|
||||
};
|
||||
|
||||
WidgetHSlider.prototype.onExecute = function() {
|
||||
this.properties.value =
|
||||
this.properties.min +
|
||||
(this.properties.max - this.properties.min) * this.value;
|
||||
this.setOutputData(0, this.properties.value);
|
||||
this.boxcolor = LiteGraph.colorToString([
|
||||
this.value,
|
||||
this.value,
|
||||
this.value
|
||||
]);
|
||||
};
|
||||
|
||||
WidgetHSlider.prototype.onMouseDown = function(e) {
|
||||
if (e.canvasY - this.pos[1] < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.oldmouse = [e.canvasX - this.pos[0], e.canvasY - this.pos[1]];
|
||||
this.captureInput(true);
|
||||
return true;
|
||||
};
|
||||
|
||||
WidgetHSlider.prototype.onMouseMove = function(e) {
|
||||
if (!this.oldmouse) {
|
||||
return;
|
||||
}
|
||||
|
||||
var m = [e.canvasX - this.pos[0], e.canvasY - this.pos[1]];
|
||||
|
||||
var v = this.value;
|
||||
var delta = m[0] - this.oldmouse[0];
|
||||
v += delta / this.size[0];
|
||||
if (v > 1.0) {
|
||||
v = 1.0;
|
||||
} else if (v < 0.0) {
|
||||
v = 0.0;
|
||||
}
|
||||
|
||||
this.value = v;
|
||||
|
||||
this.oldmouse = m;
|
||||
this.setDirtyCanvas(true);
|
||||
};
|
||||
|
||||
WidgetHSlider.prototype.onMouseUp = function(e) {
|
||||
this.oldmouse = null;
|
||||
this.captureInput(false);
|
||||
};
|
||||
|
||||
WidgetHSlider.prototype.onMouseLeave = function(e) {
|
||||
//this.oldmouse = null;
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("widget/hslider", WidgetHSlider);
|
||||
|
||||
function WidgetProgress() {
|
||||
this.size = [160, 26];
|
||||
this.addInput("", "number");
|
||||
this.properties = { min: 0, max: 1, value: 0, color: "#AAF" };
|
||||
}
|
||||
|
||||
WidgetProgress.title = "Progress";
|
||||
WidgetProgress.desc = "Shows data in linear progress";
|
||||
|
||||
WidgetProgress.prototype.onExecute = function() {
|
||||
var v = this.getInputData(0);
|
||||
if (v != undefined) {
|
||||
this.properties["value"] = v;
|
||||
}
|
||||
};
|
||||
|
||||
WidgetProgress.prototype.onDrawForeground = function(ctx) {
|
||||
//border
|
||||
ctx.lineWidth = 1;
|
||||
ctx.fillStyle = this.properties.color;
|
||||
var v =
|
||||
(this.properties.value - this.properties.min) /
|
||||
(this.properties.max - this.properties.min);
|
||||
v = Math.min(1, v);
|
||||
v = Math.max(0, v);
|
||||
ctx.fillRect(2, 2, (this.size[0] - 4) * v, this.size[1] - 4);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("widget/progress", WidgetProgress);
|
||||
|
||||
function WidgetText() {
|
||||
this.addInputs("", 0);
|
||||
this.properties = {
|
||||
value: "...",
|
||||
font: "Arial",
|
||||
fontsize: 18,
|
||||
color: "#AAA",
|
||||
align: "left",
|
||||
glowSize: 0,
|
||||
decimals: 1
|
||||
};
|
||||
}
|
||||
|
||||
WidgetText.title = "Text";
|
||||
WidgetText.desc = "Shows the input value";
|
||||
WidgetText.widgets = [
|
||||
{ name: "resize", text: "Resize box", type: "button" },
|
||||
{ name: "led_text", text: "LED", type: "minibutton" },
|
||||
{ name: "normal_text", text: "Normal", type: "minibutton" }
|
||||
];
|
||||
|
||||
WidgetText.prototype.onDrawForeground = function(ctx) {
|
||||
//ctx.fillStyle="#000";
|
||||
//ctx.fillRect(0,0,100,60);
|
||||
ctx.fillStyle = this.properties["color"];
|
||||
var v = this.properties["value"];
|
||||
|
||||
if (this.properties["glowSize"]) {
|
||||
ctx.shadowColor = this.properties.color;
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
ctx.shadowBlur = this.properties["glowSize"];
|
||||
} else {
|
||||
ctx.shadowColor = "transparent";
|
||||
}
|
||||
|
||||
var fontsize = this.properties["fontsize"];
|
||||
|
||||
ctx.textAlign = this.properties["align"];
|
||||
ctx.font = fontsize.toString() + "px " + this.properties["font"];
|
||||
this.str =
|
||||
typeof v == "number" ? v.toFixed(this.properties["decimals"]) : v;
|
||||
|
||||
if (typeof this.str == "string") {
|
||||
var lines = this.str.replace(/[\r\n]/g, "\\n").split("\\n");
|
||||
for (var i=0; i < lines.length; i++) {
|
||||
ctx.fillText(
|
||||
lines[i],
|
||||
this.properties["align"] == "left" ? 15 : this.size[0] - 15,
|
||||
fontsize * -0.15 + fontsize * (parseInt(i) + 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ctx.shadowColor = "transparent";
|
||||
this.last_ctx = ctx;
|
||||
ctx.textAlign = "left";
|
||||
};
|
||||
|
||||
WidgetText.prototype.onExecute = function() {
|
||||
var v = this.getInputData(0);
|
||||
if (v != null) {
|
||||
this.properties["value"] = v;
|
||||
}
|
||||
//this.setDirtyCanvas(true);
|
||||
};
|
||||
|
||||
WidgetText.prototype.resize = function() {
|
||||
if (!this.last_ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
var lines = this.str.split("\\n");
|
||||
this.last_ctx.font =
|
||||
this.properties["fontsize"] + "px " + this.properties["font"];
|
||||
var max = 0;
|
||||
for (var i=0; i < lines.length; i++) {
|
||||
var w = this.last_ctx.measureText(lines[i]).width;
|
||||
if (max < w) {
|
||||
max = w;
|
||||
}
|
||||
}
|
||||
this.size[0] = max + 20;
|
||||
this.size[1] = 4 + lines.length * this.properties["fontsize"];
|
||||
|
||||
this.setDirtyCanvas(true);
|
||||
};
|
||||
|
||||
WidgetText.prototype.onPropertyChanged = function(name, value) {
|
||||
this.properties[name] = value;
|
||||
this.str = typeof value == "number" ? value.toFixed(3) : value;
|
||||
//this.resize();
|
||||
return true;
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("widget/text", WidgetText);
|
||||
|
||||
function WidgetPanel() {
|
||||
this.size = [200, 100];
|
||||
this.properties = {
|
||||
borderColor: "#ffffff",
|
||||
bgcolorTop: "#f0f0f0",
|
||||
bgcolorBottom: "#e0e0e0",
|
||||
shadowSize: 2,
|
||||
borderRadius: 3
|
||||
};
|
||||
}
|
||||
|
||||
WidgetPanel.title = "Panel";
|
||||
WidgetPanel.desc = "Non interactive panel";
|
||||
WidgetPanel.widgets = [{ name: "update", text: "Update", type: "button" }];
|
||||
|
||||
WidgetPanel.prototype.createGradient = function(ctx) {
|
||||
if (
|
||||
this.properties["bgcolorTop"] == "" ||
|
||||
this.properties["bgcolorBottom"] == ""
|
||||
) {
|
||||
this.lineargradient = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
this.lineargradient = ctx.createLinearGradient(0, 0, 0, this.size[1]);
|
||||
this.lineargradient.addColorStop(0, this.properties["bgcolorTop"]);
|
||||
this.lineargradient.addColorStop(1, this.properties["bgcolorBottom"]);
|
||||
};
|
||||
|
||||
WidgetPanel.prototype.onDrawForeground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.lineargradient == null) {
|
||||
this.createGradient(ctx);
|
||||
}
|
||||
|
||||
if (!this.lineargradient) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeStyle = this.properties["borderColor"];
|
||||
//ctx.fillStyle = "#ebebeb";
|
||||
ctx.fillStyle = this.lineargradient;
|
||||
|
||||
if (this.properties["shadowSize"]) {
|
||||
ctx.shadowColor = "#000";
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
ctx.shadowBlur = this.properties["shadowSize"];
|
||||
} else {
|
||||
ctx.shadowColor = "transparent";
|
||||
}
|
||||
|
||||
ctx.roundRect(
|
||||
0,
|
||||
0,
|
||||
this.size[0] - 1,
|
||||
this.size[1] - 1,
|
||||
this.properties["shadowSize"]
|
||||
);
|
||||
ctx.fill();
|
||||
ctx.shadowColor = "transparent";
|
||||
ctx.stroke();
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("widget/panel", WidgetPanel);
|
||||
})(this);
|
||||
@@ -1,201 +0,0 @@
|
||||
(function(global) {
|
||||
var LiteGraph = global.LiteGraph;
|
||||
|
||||
function Selector() {
|
||||
this.addInput("sel", "number");
|
||||
this.addInput("A");
|
||||
this.addInput("B");
|
||||
this.addInput("C");
|
||||
this.addInput("D");
|
||||
this.addOutput("out");
|
||||
|
||||
this.selected = 0;
|
||||
}
|
||||
|
||||
Selector.title = "Selector";
|
||||
Selector.desc = "selects an output";
|
||||
|
||||
Selector.prototype.onDrawBackground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
ctx.fillStyle = "#AFB";
|
||||
var y = (this.selected + 1) * LiteGraph.NODE_SLOT_HEIGHT + 6;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(50, y);
|
||||
ctx.lineTo(50, y + LiteGraph.NODE_SLOT_HEIGHT);
|
||||
ctx.lineTo(34, y + LiteGraph.NODE_SLOT_HEIGHT * 0.5);
|
||||
ctx.fill();
|
||||
};
|
||||
|
||||
Selector.prototype.onExecute = function() {
|
||||
var sel = this.getInputData(0);
|
||||
if (sel == null || sel.constructor !== Number)
|
||||
sel = 0;
|
||||
this.selected = sel = Math.round(sel) % (this.inputs.length - 1);
|
||||
var v = this.getInputData(sel + 1);
|
||||
if (v !== undefined) {
|
||||
this.setOutputData(0, v);
|
||||
}
|
||||
};
|
||||
|
||||
Selector.prototype.onGetInputs = function() {
|
||||
return [["E", 0], ["F", 0], ["G", 0], ["H", 0]];
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("logic/selector", Selector);
|
||||
|
||||
function Sequence() {
|
||||
this.properties = {
|
||||
sequence: "A,B,C"
|
||||
};
|
||||
this.addInput("index", "number");
|
||||
this.addInput("seq");
|
||||
this.addOutput("out");
|
||||
|
||||
this.index = 0;
|
||||
this.values = this.properties.sequence.split(",");
|
||||
}
|
||||
|
||||
Sequence.title = "Sequence";
|
||||
Sequence.desc = "select one element from a sequence from a string";
|
||||
|
||||
Sequence.prototype.onPropertyChanged = function(name, value) {
|
||||
if (name == "sequence") {
|
||||
this.values = value.split(",");
|
||||
}
|
||||
};
|
||||
|
||||
Sequence.prototype.onExecute = function() {
|
||||
var seq = this.getInputData(1);
|
||||
if (seq && seq != this.current_sequence) {
|
||||
this.values = seq.split(",");
|
||||
this.current_sequence = seq;
|
||||
}
|
||||
var index = this.getInputData(0);
|
||||
if (index == null) {
|
||||
index = 0;
|
||||
}
|
||||
this.index = index = Math.round(index) % this.values.length;
|
||||
|
||||
this.setOutputData(0, this.values[index]);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("logic/sequence", Sequence);
|
||||
|
||||
|
||||
function logicAnd(){
|
||||
this.properties = { };
|
||||
this.addInput("a", "boolean");
|
||||
this.addInput("b", "boolean");
|
||||
this.addOutput("out", "boolean");
|
||||
}
|
||||
logicAnd.title = "AND";
|
||||
logicAnd.desc = "Return true if all inputs are true";
|
||||
logicAnd.prototype.onExecute = function() {
|
||||
var ret = true;
|
||||
for (var inX in this.inputs){
|
||||
if (!this.getInputData(inX)){
|
||||
var ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.setOutputData(0, ret);
|
||||
};
|
||||
logicAnd.prototype.onGetInputs = function() {
|
||||
return [
|
||||
["and", "boolean"]
|
||||
];
|
||||
};
|
||||
LiteGraph.registerNodeType("logic/AND", logicAnd);
|
||||
|
||||
|
||||
function logicOr(){
|
||||
this.properties = { };
|
||||
this.addInput("a", "boolean");
|
||||
this.addInput("b", "boolean");
|
||||
this.addOutput("out", "boolean");
|
||||
}
|
||||
logicOr.title = "OR";
|
||||
logicOr.desc = "Return true if at least one input is true";
|
||||
logicOr.prototype.onExecute = function() {
|
||||
var ret = false;
|
||||
for (var inX in this.inputs){
|
||||
if (this.getInputData(inX)){
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.setOutputData(0, ret);
|
||||
};
|
||||
logicOr.prototype.onGetInputs = function() {
|
||||
return [
|
||||
["or", "boolean"]
|
||||
];
|
||||
};
|
||||
LiteGraph.registerNodeType("logic/OR", logicOr);
|
||||
|
||||
|
||||
function logicNot(){
|
||||
this.properties = { };
|
||||
this.addInput("in", "boolean");
|
||||
this.addOutput("out", "boolean");
|
||||
}
|
||||
logicNot.title = "NOT";
|
||||
logicNot.desc = "Return the logical negation";
|
||||
logicNot.prototype.onExecute = function() {
|
||||
var ret = !this.getInputData(0);
|
||||
this.setOutputData(0, ret);
|
||||
};
|
||||
LiteGraph.registerNodeType("logic/NOT", logicNot);
|
||||
|
||||
|
||||
function logicCompare(){
|
||||
this.properties = { };
|
||||
this.addInput("a", "boolean");
|
||||
this.addInput("b", "boolean");
|
||||
this.addOutput("out", "boolean");
|
||||
}
|
||||
logicCompare.title = "bool == bool";
|
||||
logicCompare.desc = "Compare for logical equality";
|
||||
logicCompare.prototype.onExecute = function() {
|
||||
var last = null;
|
||||
var ret = true;
|
||||
for (var inX in this.inputs){
|
||||
if (last === null) last = this.getInputData(inX);
|
||||
else
|
||||
if (last != this.getInputData(inX)){
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.setOutputData(0, ret);
|
||||
};
|
||||
logicCompare.prototype.onGetInputs = function() {
|
||||
return [
|
||||
["bool", "boolean"]
|
||||
];
|
||||
};
|
||||
LiteGraph.registerNodeType("logic/CompareBool", logicCompare);
|
||||
|
||||
|
||||
function logicBranch(){
|
||||
this.properties = { };
|
||||
this.addInput("onTrigger", LiteGraph.ACTION);
|
||||
this.addInput("condition", "boolean");
|
||||
this.addOutput("true", LiteGraph.EVENT);
|
||||
this.addOutput("false", LiteGraph.EVENT);
|
||||
this.mode = LiteGraph.ON_TRIGGER;
|
||||
}
|
||||
logicBranch.title = "Branch";
|
||||
logicBranch.desc = "Branch execution on condition";
|
||||
logicBranch.prototype.onExecute = function(param, options) {
|
||||
var condtition = this.getInputData(1);
|
||||
if (condtition){
|
||||
this.triggerSlot(0);
|
||||
}else{
|
||||
this.triggerSlot(1);
|
||||
}
|
||||
};
|
||||
LiteGraph.registerNodeType("logic/IF", logicBranch);
|
||||
})(this);
|
||||
1333
src/nodes/math.js
@@ -1,573 +0,0 @@
|
||||
(function(global) {
|
||||
var LiteGraph = global.LiteGraph;
|
||||
|
||||
|
||||
function Math3DMat4()
|
||||
{
|
||||
this.addInput("T", "vec3");
|
||||
this.addInput("R", "vec3");
|
||||
this.addInput("S", "vec3");
|
||||
this.addOutput("mat4", "mat4");
|
||||
this.properties = {
|
||||
"T":[0,0,0],
|
||||
"R":[0,0,0],
|
||||
"S":[1,1,1],
|
||||
R_in_degrees: true
|
||||
};
|
||||
this._result = mat4.create();
|
||||
this._must_update = true;
|
||||
}
|
||||
|
||||
Math3DMat4.title = "mat4";
|
||||
Math3DMat4.temp_quat = new Float32Array([0,0,0,1]);
|
||||
Math3DMat4.temp_mat4 = new Float32Array(16);
|
||||
Math3DMat4.temp_vec3 = new Float32Array(3);
|
||||
|
||||
Math3DMat4.prototype.onPropertyChanged = function(name, value)
|
||||
{
|
||||
this._must_update = true;
|
||||
}
|
||||
|
||||
Math3DMat4.prototype.onExecute = function()
|
||||
{
|
||||
var M = this._result;
|
||||
var Q = Math3DMat4.temp_quat;
|
||||
var temp_mat4 = Math3DMat4.temp_mat4;
|
||||
var temp_vec3 = Math3DMat4.temp_vec3;
|
||||
|
||||
var T = this.getInputData(0);
|
||||
var R = this.getInputData(1);
|
||||
var S = this.getInputData(2);
|
||||
|
||||
if( this._must_update || T || R || S )
|
||||
{
|
||||
T = T || this.properties.T;
|
||||
R = R || this.properties.R;
|
||||
S = S || this.properties.S;
|
||||
mat4.identity( M );
|
||||
mat4.translate( M, M, T );
|
||||
if(this.properties.R_in_degrees)
|
||||
{
|
||||
temp_vec3.set( R );
|
||||
vec3.scale(temp_vec3,temp_vec3,DEG2RAD);
|
||||
quat.fromEuler( Q, temp_vec3 );
|
||||
}
|
||||
else
|
||||
quat.fromEuler( Q, R );
|
||||
mat4.fromQuat( temp_mat4, Q );
|
||||
mat4.multiply( M, M, temp_mat4 );
|
||||
mat4.scale( M, M, S );
|
||||
}
|
||||
|
||||
this.setOutputData(0, M);
|
||||
}
|
||||
|
||||
LiteGraph.registerNodeType("math3d/mat4", Math3DMat4);
|
||||
|
||||
//Math 3D operation
|
||||
function Math3DOperation() {
|
||||
this.addInput("A", "number,vec3");
|
||||
this.addInput("B", "number,vec3");
|
||||
this.addOutput("=", "number,vec3");
|
||||
this.addProperty("OP", "+", "enum", { values: Math3DOperation.values });
|
||||
this._result = vec3.create();
|
||||
}
|
||||
|
||||
Math3DOperation.values = ["+", "-", "*", "/", "%", "^", "max", "min","dot","cross"];
|
||||
|
||||
LiteGraph.registerSearchboxExtra("math3d/operation", "CROSS()", {
|
||||
properties: {"OP":"cross"},
|
||||
title: "CROSS()"
|
||||
});
|
||||
|
||||
LiteGraph.registerSearchboxExtra("math3d/operation", "DOT()", {
|
||||
properties: {"OP":"dot"},
|
||||
title: "DOT()"
|
||||
});
|
||||
|
||||
Math3DOperation.title = "Operation";
|
||||
Math3DOperation.desc = "Easy math 3D operators";
|
||||
Math3DOperation["@OP"] = {
|
||||
type: "enum",
|
||||
title: "operation",
|
||||
values: Math3DOperation.values
|
||||
};
|
||||
Math3DOperation.size = [100, 60];
|
||||
|
||||
Math3DOperation.prototype.getTitle = function() {
|
||||
if(this.properties.OP == "max" || this.properties.OP == "min" )
|
||||
return this.properties.OP + "(A,B)";
|
||||
return "A " + this.properties.OP + " B";
|
||||
};
|
||||
|
||||
Math3DOperation.prototype.onExecute = function() {
|
||||
var A = this.getInputData(0);
|
||||
var B = this.getInputData(1);
|
||||
if(A == null || B == null)
|
||||
return;
|
||||
if(A.constructor === Number)
|
||||
A = [A,A,A];
|
||||
if(B.constructor === Number)
|
||||
B = [B,B,B];
|
||||
|
||||
var result = this._result;
|
||||
switch (this.properties.OP) {
|
||||
case "+":
|
||||
result = vec3.add(result,A,B);
|
||||
break;
|
||||
case "-":
|
||||
result = vec3.sub(result,A,B);
|
||||
break;
|
||||
case "x":
|
||||
case "X":
|
||||
case "*":
|
||||
result = vec3.mul(result,A,B);
|
||||
break;
|
||||
case "/":
|
||||
result = vec3.div(result,A,B);
|
||||
break;
|
||||
case "%":
|
||||
result[0] = A[0]%B[0];
|
||||
result[1] = A[1]%B[1];
|
||||
result[2] = A[2]%B[2];
|
||||
break;
|
||||
case "^":
|
||||
result[0] = Math.pow(A[0],B[0]);
|
||||
result[1] = Math.pow(A[1],B[1]);
|
||||
result[2] = Math.pow(A[2],B[2]);
|
||||
break;
|
||||
case "max":
|
||||
result[0] = Math.max(A[0],B[0]);
|
||||
result[1] = Math.max(A[1],B[1]);
|
||||
result[2] = Math.max(A[2],B[2]);
|
||||
break;
|
||||
case "min":
|
||||
result[0] = Math.min(A[0],B[0]);
|
||||
result[1] = Math.min(A[1],B[1]);
|
||||
result[2] = Math.min(A[2],B[2]);
|
||||
case "dot":
|
||||
result = vec3.dot(A,B);
|
||||
break;
|
||||
case "cross":
|
||||
vec3.cross(result,A,B);
|
||||
break;
|
||||
default:
|
||||
console.warn("Unknown operation: " + this.properties.OP);
|
||||
}
|
||||
this.setOutputData(0, result);
|
||||
};
|
||||
|
||||
Math3DOperation.prototype.onDrawBackground = function(ctx) {
|
||||
if (this.flags.collapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.font = "40px Arial";
|
||||
ctx.fillStyle = "#666";
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillText(
|
||||
this.properties.OP,
|
||||
this.size[0] * 0.5,
|
||||
(this.size[1] + LiteGraph.NODE_TITLE_HEIGHT) * 0.5
|
||||
);
|
||||
ctx.textAlign = "left";
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/operation", Math3DOperation);
|
||||
|
||||
function Math3DVec3Scale() {
|
||||
this.addInput("in", "vec3");
|
||||
this.addInput("f", "number");
|
||||
this.addOutput("out", "vec3");
|
||||
this.properties = { f: 1 };
|
||||
this._data = new Float32Array(3);
|
||||
}
|
||||
|
||||
Math3DVec3Scale.title = "vec3_scale";
|
||||
Math3DVec3Scale.desc = "scales the components of a vec3";
|
||||
|
||||
Math3DVec3Scale.prototype.onExecute = function() {
|
||||
var v = this.getInputData(0);
|
||||
if (v == null) {
|
||||
return;
|
||||
}
|
||||
var f = this.getInputData(1);
|
||||
if (f == null) {
|
||||
f = this.properties.f;
|
||||
}
|
||||
|
||||
var data = this._data;
|
||||
data[0] = v[0] * f;
|
||||
data[1] = v[1] * f;
|
||||
data[2] = v[2] * f;
|
||||
this.setOutputData(0, data);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/vec3-scale", Math3DVec3Scale);
|
||||
|
||||
function Math3DVec3Length() {
|
||||
this.addInput("in", "vec3");
|
||||
this.addOutput("out", "number");
|
||||
}
|
||||
|
||||
Math3DVec3Length.title = "vec3_length";
|
||||
Math3DVec3Length.desc = "returns the module of a vector";
|
||||
|
||||
Math3DVec3Length.prototype.onExecute = function() {
|
||||
var v = this.getInputData(0);
|
||||
if (v == null) {
|
||||
return;
|
||||
}
|
||||
var dist = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
this.setOutputData(0, dist);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/vec3-length", Math3DVec3Length);
|
||||
|
||||
function Math3DVec3Normalize() {
|
||||
this.addInput("in", "vec3");
|
||||
this.addOutput("out", "vec3");
|
||||
this._data = new Float32Array(3);
|
||||
}
|
||||
|
||||
Math3DVec3Normalize.title = "vec3_normalize";
|
||||
Math3DVec3Normalize.desc = "returns the vector normalized";
|
||||
|
||||
Math3DVec3Normalize.prototype.onExecute = function() {
|
||||
var v = this.getInputData(0);
|
||||
if (v == null) {
|
||||
return;
|
||||
}
|
||||
var dist = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
var data = this._data;
|
||||
data[0] = v[0] / dist;
|
||||
data[1] = v[1] / dist;
|
||||
data[2] = v[2] / dist;
|
||||
|
||||
this.setOutputData(0, data);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/vec3-normalize", Math3DVec3Normalize);
|
||||
|
||||
function Math3DVec3Lerp() {
|
||||
this.addInput("A", "vec3");
|
||||
this.addInput("B", "vec3");
|
||||
this.addInput("f", "vec3");
|
||||
this.addOutput("out", "vec3");
|
||||
this.properties = { f: 0.5 };
|
||||
this._data = new Float32Array(3);
|
||||
}
|
||||
|
||||
Math3DVec3Lerp.title = "vec3_lerp";
|
||||
Math3DVec3Lerp.desc = "returns the interpolated vector";
|
||||
|
||||
Math3DVec3Lerp.prototype.onExecute = function() {
|
||||
var A = this.getInputData(0);
|
||||
if (A == null) {
|
||||
return;
|
||||
}
|
||||
var B = this.getInputData(1);
|
||||
if (B == null) {
|
||||
return;
|
||||
}
|
||||
var f = this.getInputOrProperty("f");
|
||||
|
||||
var data = this._data;
|
||||
data[0] = A[0] * (1 - f) + B[0] * f;
|
||||
data[1] = A[1] * (1 - f) + B[1] * f;
|
||||
data[2] = A[2] * (1 - f) + B[2] * f;
|
||||
|
||||
this.setOutputData(0, data);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/vec3-lerp", Math3DVec3Lerp);
|
||||
|
||||
function Math3DVec3Dot() {
|
||||
this.addInput("A", "vec3");
|
||||
this.addInput("B", "vec3");
|
||||
this.addOutput("out", "number");
|
||||
}
|
||||
|
||||
Math3DVec3Dot.title = "vec3_dot";
|
||||
Math3DVec3Dot.desc = "returns the dot product";
|
||||
|
||||
Math3DVec3Dot.prototype.onExecute = function() {
|
||||
var A = this.getInputData(0);
|
||||
if (A == null) {
|
||||
return;
|
||||
}
|
||||
var B = this.getInputData(1);
|
||||
if (B == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var dot = A[0] * B[0] + A[1] * B[1] + A[2] * B[2];
|
||||
this.setOutputData(0, dot);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/vec3-dot", Math3DVec3Dot);
|
||||
|
||||
//if glMatrix is installed...
|
||||
if (global.glMatrix) {
|
||||
function Math3DQuaternion() {
|
||||
this.addOutput("quat", "quat");
|
||||
this.properties = { x: 0, y: 0, z: 0, w: 1, normalize: false };
|
||||
this._value = quat.create();
|
||||
}
|
||||
|
||||
Math3DQuaternion.title = "Quaternion";
|
||||
Math3DQuaternion.desc = "quaternion";
|
||||
|
||||
Math3DQuaternion.prototype.onExecute = function() {
|
||||
this._value[0] = this.getInputOrProperty("x");
|
||||
this._value[1] = this.getInputOrProperty("y");
|
||||
this._value[2] = this.getInputOrProperty("z");
|
||||
this._value[3] = this.getInputOrProperty("w");
|
||||
if (this.properties.normalize) {
|
||||
quat.normalize(this._value, this._value);
|
||||
}
|
||||
this.setOutputData(0, this._value);
|
||||
};
|
||||
|
||||
Math3DQuaternion.prototype.onGetInputs = function() {
|
||||
return [
|
||||
["x", "number"],
|
||||
["y", "number"],
|
||||
["z", "number"],
|
||||
["w", "number"]
|
||||
];
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/quaternion", Math3DQuaternion);
|
||||
|
||||
function Math3DRotation() {
|
||||
this.addInputs([["degrees", "number"], ["axis", "vec3"]]);
|
||||
this.addOutput("quat", "quat");
|
||||
this.properties = { angle: 90.0, axis: vec3.fromValues(0, 1, 0) };
|
||||
|
||||
this._value = quat.create();
|
||||
}
|
||||
|
||||
Math3DRotation.title = "Rotation";
|
||||
Math3DRotation.desc = "quaternion rotation";
|
||||
|
||||
Math3DRotation.prototype.onExecute = function() {
|
||||
var angle = this.getInputData(0);
|
||||
if (angle == null) {
|
||||
angle = this.properties.angle;
|
||||
}
|
||||
var axis = this.getInputData(1);
|
||||
if (axis == null) {
|
||||
axis = this.properties.axis;
|
||||
}
|
||||
|
||||
var R = quat.setAxisAngle(this._value, axis, angle * 0.0174532925);
|
||||
this.setOutputData(0, R);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/rotation", Math3DRotation);
|
||||
|
||||
|
||||
function MathEulerToQuat() {
|
||||
this.addInput("euler", "vec3");
|
||||
this.addOutput("quat", "quat");
|
||||
this.properties = { euler:[0,0,0], use_yaw_pitch_roll: false };
|
||||
this._degs = vec3.create();
|
||||
this._value = quat.create();
|
||||
}
|
||||
|
||||
MathEulerToQuat.title = "Euler->Quat";
|
||||
MathEulerToQuat.desc = "Converts euler angles (in degrees) to quaternion";
|
||||
|
||||
MathEulerToQuat.prototype.onExecute = function() {
|
||||
var euler = this.getInputData(0);
|
||||
if (euler == null) {
|
||||
euler = this.properties.euler;
|
||||
}
|
||||
vec3.scale( this._degs, euler, DEG2RAD );
|
||||
if(this.properties.use_yaw_pitch_roll)
|
||||
this._degs = [this._degs[2],this._degs[0],this._degs[1]];
|
||||
var R = quat.fromEuler(this._value, this._degs);
|
||||
this.setOutputData(0, R);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/euler_to_quat", MathEulerToQuat);
|
||||
|
||||
function MathQuatToEuler() {
|
||||
this.addInput(["quat", "quat"]);
|
||||
this.addOutput("euler", "vec3");
|
||||
this._value = vec3.create();
|
||||
}
|
||||
|
||||
MathQuatToEuler.title = "Euler->Quat";
|
||||
MathQuatToEuler.desc = "Converts rotX,rotY,rotZ in degrees to quat";
|
||||
|
||||
MathQuatToEuler.prototype.onExecute = function() {
|
||||
var q = this.getInputData(0);
|
||||
if(!q)
|
||||
return;
|
||||
var R = quat.toEuler(this._value, q);
|
||||
vec3.scale( this._value, this._value, DEG2RAD );
|
||||
this.setOutputData(0, this._value);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/quat_to_euler", MathQuatToEuler);
|
||||
|
||||
|
||||
//Math3D rotate vec3
|
||||
function Math3DRotateVec3() {
|
||||
this.addInputs([["vec3", "vec3"], ["quat", "quat"]]);
|
||||
this.addOutput("result", "vec3");
|
||||
this.properties = { vec: [0, 0, 1] };
|
||||
}
|
||||
|
||||
Math3DRotateVec3.title = "Rot. Vec3";
|
||||
Math3DRotateVec3.desc = "rotate a point";
|
||||
|
||||
Math3DRotateVec3.prototype.onExecute = function() {
|
||||
var vec = this.getInputData(0);
|
||||
if (vec == null) {
|
||||
vec = this.properties.vec;
|
||||
}
|
||||
var quat = this.getInputData(1);
|
||||
if (quat == null) {
|
||||
this.setOutputData(vec);
|
||||
} else {
|
||||
this.setOutputData(
|
||||
0,
|
||||
vec3.transformQuat(vec3.create(), vec, quat)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/rotate_vec3", Math3DRotateVec3);
|
||||
|
||||
function Math3DMultQuat() {
|
||||
this.addInputs([["A", "quat"], ["B", "quat"]]);
|
||||
this.addOutput("A*B", "quat");
|
||||
|
||||
this._value = quat.create();
|
||||
}
|
||||
|
||||
Math3DMultQuat.title = "Mult. Quat";
|
||||
Math3DMultQuat.desc = "rotate quaternion";
|
||||
|
||||
Math3DMultQuat.prototype.onExecute = function() {
|
||||
var A = this.getInputData(0);
|
||||
if (A == null) {
|
||||
return;
|
||||
}
|
||||
var B = this.getInputData(1);
|
||||
if (B == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var R = quat.multiply(this._value, A, B);
|
||||
this.setOutputData(0, R);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/mult-quat", Math3DMultQuat);
|
||||
|
||||
function Math3DQuatSlerp() {
|
||||
this.addInputs([
|
||||
["A", "quat"],
|
||||
["B", "quat"],
|
||||
["factor", "number"]
|
||||
]);
|
||||
this.addOutput("slerp", "quat");
|
||||
this.addProperty("factor", 0.5);
|
||||
|
||||
this._value = quat.create();
|
||||
}
|
||||
|
||||
Math3DQuatSlerp.title = "Quat Slerp";
|
||||
Math3DQuatSlerp.desc = "quaternion spherical interpolation";
|
||||
|
||||
Math3DQuatSlerp.prototype.onExecute = function() {
|
||||
var A = this.getInputData(0);
|
||||
if (A == null) {
|
||||
return;
|
||||
}
|
||||
var B = this.getInputData(1);
|
||||
if (B == null) {
|
||||
return;
|
||||
}
|
||||
var factor = this.properties.factor;
|
||||
if (this.getInputData(2) != null) {
|
||||
factor = this.getInputData(2);
|
||||
}
|
||||
|
||||
var R = quat.slerp(this._value, A, B, factor);
|
||||
this.setOutputData(0, R);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/quat-slerp", Math3DQuatSlerp);
|
||||
|
||||
|
||||
//Math3D rotate vec3
|
||||
function Math3DRemapRange() {
|
||||
this.addInput("vec3", "vec3");
|
||||
this.addOutput("remap", "vec3");
|
||||
this.addOutput("clamped", "vec3");
|
||||
this.properties = { clamp: true, range_min: [-1, -1, 0], range_max: [1, 1, 0], target_min: [-1,-1,0], target_max:[1,1,0] };
|
||||
this._value = vec3.create();
|
||||
this._clamped = vec3.create();
|
||||
}
|
||||
|
||||
Math3DRemapRange.title = "Remap Range";
|
||||
Math3DRemapRange.desc = "remap a 3D range";
|
||||
|
||||
Math3DRemapRange.prototype.onExecute = function() {
|
||||
var vec = this.getInputData(0);
|
||||
if(vec)
|
||||
this._value.set(vec);
|
||||
var range_min = this.properties.range_min;
|
||||
var range_max = this.properties.range_max;
|
||||
var target_min = this.properties.target_min;
|
||||
var target_max = this.properties.target_max;
|
||||
|
||||
//swap to avoid errors
|
||||
/*
|
||||
if(range_min > range_max)
|
||||
{
|
||||
range_min = range_max;
|
||||
range_max = this.properties.range_min;
|
||||
}
|
||||
|
||||
if(target_min > target_max)
|
||||
{
|
||||
target_min = target_max;
|
||||
target_max = this.properties.target_min;
|
||||
}
|
||||
*/
|
||||
|
||||
for(var i = 0; i < 3; ++i)
|
||||
{
|
||||
var r = range_max[i] - range_min[i];
|
||||
this._clamped[i] = clamp( this._value[i], range_min[i], range_max[i] );
|
||||
if(r == 0)
|
||||
{
|
||||
this._value[i] = (target_min[i] + target_max[i]) * 0.5;
|
||||
continue;
|
||||
}
|
||||
|
||||
var n = (this._value[i] - range_min[i]) / r;
|
||||
if(this.properties.clamp)
|
||||
n = clamp(n,0,1);
|
||||
var t = target_max[i] - target_min[i];
|
||||
this._value[i] = target_min[i] + n * t;
|
||||
}
|
||||
|
||||
this.setOutputData(0,this._value);
|
||||
this.setOutputData(1,this._clamped);
|
||||
};
|
||||
|
||||
LiteGraph.registerNodeType("math3d/remap_range", Math3DRemapRange);
|
||||
|
||||
|
||||
|
||||
} //glMatrix
|
||||
else if (LiteGraph.debug)
|
||||
console.warn("No glmatrix found, some Math3D nodes may not work");
|
||||
|
||||
})(this);
|
||||