mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
Apply prettier to css, html, js, md, ts, and yml (#1249)
* Apply prettier to css, js, html, md, ts, and yml As a followup I will add prettier to the .pre-commit config. This patch is 100% generated by prettier. I used a forked version of prettier that understands the py-script tag. See https://github.com/hoodmane/pyscript-prettier-precommit for more info. * Apply old pre-commit * Revert some problems * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Revert some changes * More changes * Fix pre-commit * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
1
.github/workflows/build-unstable.yml
vendored
1
.github/workflows/build-unstable.yml
vendored
@@ -28,7 +28,6 @@ jobs:
|
|||||||
MINICONDA_PYTHON_VERSION: py38
|
MINICONDA_PYTHON_VERSION: py38
|
||||||
MINICONDA_VERSION: 4.11.0
|
MINICONDA_VERSION: 4.11.0
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
|||||||
1
.github/workflows/docs-release.yml
vendored
1
.github/workflows/docs-release.yml
vendored
@@ -13,7 +13,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
SPHINX_HTML_BASE_URL: https://docs.pyscript.net/
|
SPHINX_HTML_BASE_URL: https://docs.pyscript.net/
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
1
.github/workflows/docs-review.yml
vendored
1
.github/workflows/docs-review.yml
vendored
@@ -26,7 +26,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
SPHINX_HTML_BASE_URL: https://docs.pyscript.net/
|
SPHINX_HTML_BASE_URL: https://docs.pyscript.net/
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
1
.github/workflows/docs-unstable.yml
vendored
1
.github/workflows/docs-unstable.yml
vendored
@@ -16,7 +16,6 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
SPHINX_HTML_BASE_URL: https://docs.pyscript.net/
|
SPHINX_HTML_BASE_URL: https://docs.pyscript.net/
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
1
.github/workflows/prepare-release.yml
vendored
1
.github/workflows/prepare-release.yml
vendored
@@ -17,7 +17,6 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
|||||||
1
.github/workflows/sync-examples.yml
vendored
1
.github/workflows/sync-examples.yml
vendored
@@ -15,7 +15,6 @@ jobs:
|
|||||||
working-directory: examples
|
working-directory: examples
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
# Deploy to S3
|
# Deploy to S3
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|||||||
@@ -4,17 +4,17 @@ Thank you for wanting to contribute to the PyScript project!
|
|||||||
|
|
||||||
## Table of contents
|
## Table of contents
|
||||||
|
|
||||||
* [Code of Conduct](#code-of-conduct)
|
- [Code of Conduct](#code-of-conduct)
|
||||||
* [Contributing](#contributing)
|
- [Contributing](#contributing)
|
||||||
* [Reporting bugs](#reporting-bugs)
|
- [Reporting bugs](#reporting-bugs)
|
||||||
* [Reporting security issues](#reporting-security-issues)
|
- [Reporting security issues](#reporting-security-issues)
|
||||||
* [Asking questions](#asking-questions)
|
- [Asking questions](#asking-questions)
|
||||||
* [Setting up your local environment and developing](#setting-up-your-local-environment-and-developing)
|
- [Setting up your local environment and developing](#setting-up-your-local-environment-and-developing)
|
||||||
* [Places to start](#places-to-start)
|
- [Places to start](#places-to-start)
|
||||||
* [Setting up your local environment and developing](#setting-up-your-local-environment-and-developing)
|
- [Setting up your local environment and developing](#setting-up-your-local-environment-and-developing)
|
||||||
* [License terms for contributions](#license-terms-for-contributions)
|
- [License terms for contributions](#license-terms-for-contributions)
|
||||||
* [Becoming a maintainer](#becoming-a-maintainer)
|
- [Becoming a maintainer](#becoming-a-maintainer)
|
||||||
* [Trademarks](#trademarks)
|
- [Trademarks](#trademarks)
|
||||||
|
|
||||||
# Code of Conduct
|
# Code of Conduct
|
||||||
|
|
||||||
@@ -28,10 +28,10 @@ Bugs are tracked on the [project issues page](https://github.com/pyscript/pyscri
|
|||||||
|
|
||||||
## Creating useful issues
|
## Creating useful issues
|
||||||
|
|
||||||
* Use a clear and descriptive title.
|
- Use a clear and descriptive title.
|
||||||
* Describe the specific steps that reproduce the problem with as many details as possible so that someone can verify the issue.
|
- Describe the specific steps that reproduce the problem with as many details as possible so that someone can verify the issue.
|
||||||
* Describe the behavior you observed, and the behavior you had expected.
|
- Describe the behavior you observed, and the behavior you had expected.
|
||||||
* Include screenshots if they help make the issue clear.
|
- Include screenshots if they help make the issue clear.
|
||||||
|
|
||||||
## Reporting security issues
|
## Reporting security issues
|
||||||
|
|
||||||
@@ -45,10 +45,10 @@ If you have questions about the project, using PyScript, or anything else, pleas
|
|||||||
|
|
||||||
If you would like to contribute to PyScript, but you aren't sure where to begin, here are some suggestions.
|
If you would like to contribute to PyScript, but you aren't sure where to begin, here are some suggestions.
|
||||||
|
|
||||||
* **Read over the existing documentation.** Are there things missing, or could they be clearer? Make some changes/additions to those documents.
|
- **Read over the existing documentation.** Are there things missing, or could they be clearer? Make some changes/additions to those documents.
|
||||||
* **Review the open issues.** Are they clear? Can you reproduce them? You can add comments, clarifications, or additions to those issues. If you think you have an idea of how to address the issue, submit a fix!
|
- **Review the open issues.** Are they clear? Can you reproduce them? You can add comments, clarifications, or additions to those issues. If you think you have an idea of how to address the issue, submit a fix!
|
||||||
* **Look over the open pull requests.** Do you have comments or suggestions for the proposed changes? Add them.
|
- **Look over the open pull requests.** Do you have comments or suggestions for the proposed changes? Add them.
|
||||||
* **Check out the examples.** Is there a use case that would be good to have sample code for? Create an example for it.
|
- **Check out the examples.** Is there a use case that would be good to have sample code for? Create an example for it.
|
||||||
|
|
||||||
## Setting up your local environment and developing
|
## Setting up your local environment and developing
|
||||||
|
|
||||||
@@ -69,5 +69,6 @@ Contributors are invited to be maintainers of the project by demonstrating good
|
|||||||
The Project abides by the Organization's [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md).
|
The Project abides by the Organization's [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Part of MVG-0.1-beta.
|
Part of MVG-0.1-beta.
|
||||||
Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/).
|
Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/).
|
||||||
|
|||||||
@@ -41,5 +41,6 @@ Any names, trademarks, logos, or goodwill developed by and associated with the P
|
|||||||
Amendments to this governance policy may be made by affirmative vote of 2/3 of all Maintainers, with approval by the Organization's Steering Committee.
|
Amendments to this governance policy may be made by affirmative vote of 2/3 of all Maintainers, with approval by the Organization's Steering Committee.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Part of MVG-0.1-beta.
|
Part of MVG-0.1-beta.
|
||||||
Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/).
|
Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/).
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ This document lists the Maintainers of the Project. Maintainers may be added onc
|
|||||||
| Paul Everitt | --- |
|
| Paul Everitt | --- |
|
||||||
| Fabio Rosado | --- |
|
| Fabio Rosado | --- |
|
||||||
|
|
||||||
______________________________________________________________________
|
---
|
||||||
|
|
||||||
Part of MVG-0.1-beta.
|
Part of MVG-0.1-beta.
|
||||||
Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/).
|
Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/).
|
||||||
|
|||||||
23
README.md
23
README.md
@@ -11,21 +11,24 @@ To get started see the [getting started tutorial](docs/tutorials/getting-started
|
|||||||
For examples see [here](examples).
|
For examples see [here](examples).
|
||||||
|
|
||||||
### Longer Version
|
### Longer Version
|
||||||
|
|
||||||
PyScript is a meta project that aims to combine multiple open technologies into a framework that allows users to create sophisticated browser applications with Python. It integrates seamlessly with the way the DOM works in the browser and allows users to add Python logic in a way that feels natural both to web and Python developers.
|
PyScript is a meta project that aims to combine multiple open technologies into a framework that allows users to create sophisticated browser applications with Python. It integrates seamlessly with the way the DOM works in the browser and allows users to add Python logic in a way that feels natural both to web and Python developers.
|
||||||
|
|
||||||
## Try PyScript
|
## Try PyScript
|
||||||
|
|
||||||
To try PyScript, import the appropriate pyscript files into the ```<head>``` tag of your html page with:
|
To try PyScript, import the appropriate pyscript files into the `<head>` tag of your html page with:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
</head>
|
</head>
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then use PyScript components in your html page. PyScript currently implements the following elements:
|
You can then use PyScript components in your html page. PyScript currently implements the following elements:
|
||||||
|
|
||||||
* `<py-script>`: can be used to define python code that is executable within the web page. The element itself is not rendered to the page and is only used to add logic
|
- `<py-script>`: can be used to define python code that is executable within the web page. The element itself is not rendered to the page and is only used to add logic
|
||||||
* `<py-repl>`: creates a REPL component that is rendered to the page as a code editor and allows users to write executable code
|
- `<py-repl>`: creates a REPL component that is rendered to the page as a code editor and allows users to write executable code
|
||||||
|
|
||||||
Check out the [the examples directory](examples) folder for more examples on how to use it, all you need to do is open them in Chrome.
|
Check out the [the examples directory](examples) folder for more examples on how to use it, all you need to do is open them in Chrome.
|
||||||
|
|
||||||
@@ -37,16 +40,16 @@ Check out the [developing process](https://docs.pyscript.net/latest/development/
|
|||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
* [Official docs](https://docs.pyscript.net)
|
- [Official docs](https://docs.pyscript.net)
|
||||||
* [Discussion board](https://community.anaconda.cloud/c/tech-topics/pyscript)
|
- [Discussion board](https://community.anaconda.cloud/c/tech-topics/pyscript)
|
||||||
* [Home Page](https://pyscript.net/)
|
- [Home Page](https://pyscript.net/)
|
||||||
* [Blog Post](https://engineering.anaconda.com/2022/04/welcome-pyscript.html)
|
- [Blog Post](https://engineering.anaconda.com/2022/04/welcome-pyscript.html)
|
||||||
* [Discord Channel](https://discord.gg/BYB2kvyFwm)
|
- [Discord Channel](https://discord.gg/BYB2kvyFwm)
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
* This is an extremely experimental project, so expect things to break!
|
- This is an extremely experimental project, so expect things to break!
|
||||||
* PyScript has been only tested on Chrome at the moment.
|
- PyScript has been only tested on Chrome at the moment.
|
||||||
|
|
||||||
## Governance
|
## Governance
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
This page is meant for troubleshooting common problems with PyScript.
|
This page is meant for troubleshooting common problems with PyScript.
|
||||||
|
|
||||||
## Table of contents:
|
## Table of contents:
|
||||||
* [Make Setup](#make-setup)
|
|
||||||
|
- [Make Setup](#make-setup)
|
||||||
|
|
||||||
## Make setup
|
## Make setup
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Altair</title>
|
<title>Altair</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
<link rel="stylesheet" href="./assets/css/examples.css" />
|
<link rel="stylesheet" href="./assets/css/examples.css" />
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Altair</a>
|
<a class="title" href="" style="color: #f0ab3c">Altair</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Antigravity</title>
|
<title>Antigravity</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
<link rel="stylesheet" href="./assets/css/examples.css" />
|
<link rel="stylesheet" href="./assets/css/examples.css" />
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Antigravity</a>
|
<a class="title" href="" style="color: #f0ab3c">Antigravity</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<py-tutor modules="antigravity.py">
|
<py-tutor modules="antigravity.py">
|
||||||
|
|||||||
@@ -42,14 +42,15 @@ body {
|
|||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-html, .language-python {
|
.language-html,
|
||||||
|
.language-python {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
#view-code-button {
|
#view-code-button {
|
||||||
writing-mode: tb-rl;
|
writing-mode: tb-rl;
|
||||||
text-orientation: sideways-right;
|
text-orientation: sideways-right;
|
||||||
background-color: #1D1D22;
|
background-color: #1d1d22;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|||||||
@@ -16,9 +16,12 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card:hover, .card:hover a, .card:hover a:visited, .card:hover h2 {
|
.card:hover,
|
||||||
|
.card:hover a,
|
||||||
|
.card:hover a:visited,
|
||||||
|
.card:hover h2 {
|
||||||
background-color: var(--color-primary);
|
background-color: var(--color-primary);
|
||||||
color: #1D1D22
|
color: #1d1d22;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card a h2 {
|
.card a h2 {
|
||||||
@@ -46,7 +49,8 @@ a .card {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-content a, .card-content a:visited {
|
.card-content a,
|
||||||
|
.card-content a:visited {
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
@import "./variables.css";
|
@import "./variables.css";
|
||||||
@import "./reset.css";
|
@import "./reset.css";
|
||||||
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background: #2D2E35 url('https://assets.anaconda.com/production/Content/1650828148240.png?w=3240&auto=compress%2Cformat&fit=crop&dm=1650828161&s=c558dc55e0ed1f8419a892e842a5728f') repeat-x center bottom / 250px;
|
background: #2d2e35
|
||||||
|
url("https://assets.anaconda.com/production/Content/1650828148240.png?w=3240&auto=compress%2Cformat&fit=crop&dm=1650828161&s=c558dc55e0ed1f8419a892e842a5728f")
|
||||||
|
repeat-x center bottom / 250px;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
color: var(--text-color)
|
color: var(--text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
:root {
|
:root {
|
||||||
--color-primary: #FDA703;
|
--color-primary: #fda703;
|
||||||
--color-secondary: #1D1D22;
|
--color-secondary: #1d1d22;
|
||||||
--text-color: white;
|
--text-color: white;
|
||||||
--card-shadow: 0px 5px 11px 0px rgb(0 0 0 / 15%);
|
--card-shadow: 0px 5px 11px 0px rgb(0 0 0 / 15%);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -9,7 +9,8 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
Pyscript - FIRST ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
|
Pyscript - FIRST ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME LEVEL AS
|
||||||
|
LOOP Pyscript writing to console.log:
|
||||||
<py-script>
|
<py-script>
|
||||||
import js
|
import js
|
||||||
import asyncio
|
import asyncio
|
||||||
@@ -23,7 +24,8 @@
|
|||||||
</py-script>
|
</py-script>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Pyscript - SECOND ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
|
Pyscript - SECOND ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME LEVEL AS
|
||||||
|
LOOP Pyscript writing to console.log:
|
||||||
<py-script>
|
<py-script>
|
||||||
import js
|
import js
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -9,7 +9,8 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
Pyscript - FIRST ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
|
Pyscript - FIRST ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME LEVEL AS
|
||||||
|
LOOP Pyscript writing to console.log:
|
||||||
<py-script>
|
<py-script>
|
||||||
import js
|
import js
|
||||||
import asyncio
|
import asyncio
|
||||||
@@ -23,7 +24,8 @@
|
|||||||
</py-script>
|
</py-script>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Pyscript - SECOND ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
|
Pyscript - SECOND ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME LEVEL
|
||||||
|
AS LOOP Pyscript writing to console.log:
|
||||||
<py-script>
|
<py-script>
|
||||||
import js
|
import js
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -9,7 +9,8 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
Pyscript - FIRST ASYNC WITH NON-BLOCKING AWAIT AT ONE LEVEL LOWER THAN LOOP Pyscript writing to console.log:
|
Pyscript - FIRST ASYNC WITH NON-BLOCKING AWAIT AT ONE LEVEL LOWER THAN
|
||||||
|
LOOP Pyscript writing to console.log:
|
||||||
<py-script>
|
<py-script>
|
||||||
import js
|
import js
|
||||||
import asyncio
|
import asyncio
|
||||||
@@ -23,7 +24,8 @@
|
|||||||
</py-script>
|
</py-script>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Pyscript - SECOND ASYNC WITH NON-BLOCKING AWAIT AT ONE LEVEL LOWER THAN LOOP Pyscript writing to console.log:
|
Pyscript - SECOND ASYNC WITH NON-BLOCKING AWAIT AT ONE LEVEL LOWER THAN
|
||||||
|
LOOP Pyscript writing to console.log:
|
||||||
<py-script>
|
<py-script>
|
||||||
import js
|
import js
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -9,7 +9,8 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div>
|
||||||
Pyscript - FIRST ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
|
Pyscript - FIRST ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME LEVEL AS
|
||||||
|
LOOP Pyscript writing to console.log:
|
||||||
<py-script>
|
<py-script>
|
||||||
import js
|
import js
|
||||||
import asyncio
|
import asyncio
|
||||||
@@ -20,7 +21,8 @@
|
|||||||
</py-script>
|
</py-script>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Pyscript - SECOND ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
|
Pyscript - SECOND ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME LEVEL
|
||||||
|
AS LOOP Pyscript writing to console.log:
|
||||||
<py-script>
|
<py-script>
|
||||||
import js
|
import js
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
|
|||||||
@@ -1,12 +1,28 @@
|
|||||||
<html><head>
|
<html>
|
||||||
|
<head>
|
||||||
<title>Bokeh Example</title>
|
<title>Bokeh Example</title>
|
||||||
<meta charset="iso-8859-1">
|
<meta charset="iso-8859-1" />
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js"></script>
|
<script
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js"></script>
|
type="text/javascript"
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js"></script>
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js"
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js"></script>
|
></script>
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js"></script>
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js"
|
||||||
|
></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
Bokeh.set_log_level("info");
|
Bokeh.set_log_level("info");
|
||||||
@@ -17,12 +33,12 @@
|
|||||||
<link rel="stylesheet" href="./assets/css/examples.css" />
|
<link rel="stylesheet" href="./assets/css/examples.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Bokeh Example</a>
|
<a class="title" href="" style="color: #f0ab3c">Bokeh Example</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<py-tutor>
|
<py-tutor>
|
||||||
|
|||||||
@@ -1,12 +1,28 @@
|
|||||||
<html><head>
|
<html>
|
||||||
|
<head>
|
||||||
<title>Bokeh Example</title>
|
<title>Bokeh Example</title>
|
||||||
<meta charset="iso-8859-1">
|
<meta charset="iso-8859-1" />
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"></script>
|
<script
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js"></script>
|
type="text/javascript"
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"></script>
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"></script>
|
></script>
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js"></script>
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
<link rel="stylesheet" href="./assets/css/examples.css" />
|
<link rel="stylesheet" href="./assets/css/examples.css" />
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@@ -17,12 +33,12 @@
|
|||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Bokeh Example</a>
|
<a class="title" href="" style="color: #f0ab3c">Bokeh Example</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<py-tutor>
|
<py-tutor>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>d3: JavaScript & PyScript visualizations side-by-side</title>
|
<title>d3: JavaScript & PyScript visualizations side-by-side</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
@@ -25,15 +25,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Simple d3 visualization</a>
|
<a class="title" href="" style="color: #f0ab3c"
|
||||||
|
>Simple d3 visualization</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@@ -48,7 +49,14 @@
|
|||||||
</py-config>
|
</py-config>
|
||||||
</py-tutor>
|
</py-tutor>
|
||||||
<b>
|
<b>
|
||||||
Based on <i><a href="https://observablehq.com/@d3/learn-d3-shapes?collection=@d3/learn-d3>">Learn D3: Shapes</a></i> tutorial.
|
Based on
|
||||||
|
<i
|
||||||
|
><a
|
||||||
|
href="https://observablehq.com/@d3/learn-d3-shapes?collection=@d3/learn-d3>"
|
||||||
|
>Learn D3: Shapes</a
|
||||||
|
></i
|
||||||
|
>
|
||||||
|
tutorial.
|
||||||
</b>
|
</b>
|
||||||
<div style="display: flex; flex-direction: row">
|
<div style="display: flex; flex-direction: row">
|
||||||
<div>
|
<div>
|
||||||
@@ -68,7 +76,6 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
|
|
||||||
const fruits = [
|
const fruits = [
|
||||||
{ name: "🍊", count: 21 },
|
{ name: "🍊", count: 21 },
|
||||||
{ name: "🍇", count: 13 },
|
{ name: "🍇", count: 13 },
|
||||||
@@ -78,46 +85,49 @@
|
|||||||
{ name: "🍋", count: 2 },
|
{ name: "🍋", count: 2 },
|
||||||
{ name: "🍎", count: 1 },
|
{ name: "🍎", count: 1 },
|
||||||
{ name: "🍉", count: 1 },
|
{ name: "🍉", count: 1 },
|
||||||
]
|
];
|
||||||
|
|
||||||
const fn = (d) => d.count
|
const fn = (d) => d.count;
|
||||||
const data = d3.pie().value(fn)(fruits)
|
const data = d3.pie().value(fn)(fruits);
|
||||||
|
|
||||||
const arc = d3.arc()
|
const arc = d3
|
||||||
|
.arc()
|
||||||
.innerRadius(210)
|
.innerRadius(210)
|
||||||
.outerRadius(310)
|
.outerRadius(310)
|
||||||
.padRadius(300)
|
.padRadius(300)
|
||||||
.padAngle(2 / 300)
|
.padAngle(2 / 300)
|
||||||
.cornerRadius(8)
|
.cornerRadius(8);
|
||||||
|
|
||||||
const js = d3.select("#js")
|
const js = d3.select("#js");
|
||||||
js.select(".loading").remove()
|
js.select(".loading").remove();
|
||||||
|
|
||||||
const svg = js
|
const svg = js
|
||||||
.append("svg")
|
.append("svg")
|
||||||
.attr("viewBox", "-320 -320 640 640")
|
.attr("viewBox", "-320 -320 640 640")
|
||||||
.attr("width", "400")
|
.attr("width", "400")
|
||||||
.attr("height", "400")
|
.attr("height", "400");
|
||||||
|
|
||||||
for (const d of data) {
|
for (const d of data) {
|
||||||
svg.append("path")
|
svg.append("path").style("fill", "steelblue").attr("d", arc(d));
|
||||||
.style("fill", "steelblue")
|
|
||||||
.attr("d", arc(d))
|
|
||||||
|
|
||||||
const text = svg.append("text")
|
const text = svg
|
||||||
|
.append("text")
|
||||||
.style("fill", "white")
|
.style("fill", "white")
|
||||||
.attr("transform", `translate(${arc.centroid(d).join(",")})`)
|
.attr("transform", `translate(${arc.centroid(d).join(",")})`)
|
||||||
.attr("text-anchor", "middle")
|
.attr("text-anchor", "middle");
|
||||||
|
|
||||||
text.append("tspan")
|
text
|
||||||
|
.append("tspan")
|
||||||
.style("font-size", "24")
|
.style("font-size", "24")
|
||||||
.attr("x", "0").text(d.data.name)
|
.attr("x", "0")
|
||||||
|
.text(d.data.name);
|
||||||
|
|
||||||
text.append("tspan")
|
text
|
||||||
|
.append("tspan")
|
||||||
.style("font-size", "18")
|
.style("font-size", "18")
|
||||||
.attr("x", "0")
|
.attr("x", "0")
|
||||||
.attr("dy", "1.3em")
|
.attr("dy", "1.3em")
|
||||||
.text(d.value)
|
.text(d.value);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Folium</title>
|
<title>Folium</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
<link rel="stylesheet" href="./assets/css/examples.css" />
|
<link rel="stylesheet" href="./assets/css/examples.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Folium</a>
|
<a class="title" href="" style="color: #f0ab3c">Folium</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
@@ -63,7 +63,6 @@ folium.LayerControl().add_to(m)
|
|||||||
|
|
||||||
display(m, target="folium")
|
display(m, target="folium")
|
||||||
</py-script>
|
</py-script>
|
||||||
|
|
||||||
</py-tutor>
|
</py-tutor>
|
||||||
</section>
|
</section>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -13,12 +13,12 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Hello World</a>
|
<a class="title" href="" style="color: #f0ab3c">Hello World</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</py-config>
|
</py-config>
|
||||||
|
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
Hello world! <br>
|
Hello world! <br />
|
||||||
This is the current date and time, as computed by Python:
|
This is the current date and time, as computed by Python:
|
||||||
<py-script>
|
<py-script>
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -19,9 +19,7 @@
|
|||||||
<a href="./hello_world.html" target="_blank">
|
<a href="./hello_world.html" target="_blank">
|
||||||
<h2>Hello world</h2>
|
<h2>Hello world</h2>
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>A static demo of the <code><py-script></code> tag</p>
|
||||||
A static demo of the <code><py-script></code> tag
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -30,9 +28,7 @@
|
|||||||
<a href="./simple_clock.html" target="_blank">
|
<a href="./simple_clock.html" target="_blank">
|
||||||
<h2>Simple clock</h2>
|
<h2>Simple clock</h2>
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>A dynamic demo of the <code><py-script></code> tag</p>
|
||||||
A dynamic demo of the <code><py-script></code> tag
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -41,9 +37,7 @@
|
|||||||
<a href="./repl.html" target="_blank">
|
<a href="./repl.html" target="_blank">
|
||||||
<h2>REPL</h2>
|
<h2>REPL</h2>
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>A Python REPL (Read Eval Print Loop)</p>
|
||||||
A Python REPL (Read Eval Print Loop)
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -53,7 +47,8 @@
|
|||||||
<h2>REPL2</h2>
|
<h2>REPL2</h2>
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>
|
||||||
A Python REPL (Read Eval Print Loop) with slightly better formatting
|
A Python REPL (Read Eval Print Loop) with slightly better
|
||||||
|
formatting
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -63,9 +58,7 @@
|
|||||||
<a href="./todo.html" target="_blank">
|
<a href="./todo.html" target="_blank">
|
||||||
<h2>TODO App</h2>
|
<h2>TODO App</h2>
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>Simple TODO App</p>
|
||||||
Simple TODO App
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -74,9 +67,7 @@
|
|||||||
<a href="./todo-pylist.html" target="_blank">
|
<a href="./todo-pylist.html" target="_blank">
|
||||||
<h2>PyScript Native TODO App</h2>
|
<h2>PyScript Native TODO App</h2>
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>Simple TODO App using <code><py-list></code></p>
|
||||||
Simple TODO App using <code><py-list></code>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,7 +82,9 @@
|
|||||||
<h2>Matplotlib</h2>
|
<h2>Matplotlib</h2>
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>
|
||||||
Demonstrates rendering a <a href="https://matplotlib.org/" target="_blank">Matplotlib</a> figure as output of the py-script tag
|
Demonstrates rendering a
|
||||||
|
<a href="https://matplotlib.org/" target="_blank">Matplotlib</a>
|
||||||
|
figure as output of the py-script tag
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -99,12 +92,12 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<a href="./altair.html" target="_blank">
|
<a href="./altair.html" target="_blank">
|
||||||
<h2>
|
<h2>Altair</h2>
|
||||||
Altair
|
|
||||||
</h2>
|
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>
|
||||||
Demonstrates rendering a <a href="https://altair-viz.github.io/" target="_blank">Altair</a> plot as output of the py-script tag
|
Demonstrates rendering a
|
||||||
|
<a href="https://altair-viz.github.io/" target="_blank">Altair</a>
|
||||||
|
plot as output of the py-script tag
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -112,13 +105,15 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<a href="./folium.html" target="_blank">
|
<a href="./folium.html" target="_blank">
|
||||||
<h2>
|
<h2>Folium</h2>
|
||||||
Folium
|
|
||||||
</h2>
|
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>
|
||||||
Demonstrates rendering a
|
Demonstrates rendering a
|
||||||
<a href="https://python-visualization.github.io/folium/" target="_blank">Folium</a>
|
<a
|
||||||
|
href="https://python-visualization.github.io/folium/"
|
||||||
|
target="_blank"
|
||||||
|
>Folium</a
|
||||||
|
>
|
||||||
map as output of the py-script tag
|
map as output of the py-script tag
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -132,9 +127,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<a href="./d3.html" target="_blank">
|
<a href="./d3.html" target="_blank">
|
||||||
<h2>
|
<h2>Simple d3 visualization</h2>
|
||||||
Simple d3 visualization
|
|
||||||
</h2>
|
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>
|
||||||
Minimal <a href="https://d3js.org/" target="_blank">D3</a>
|
Minimal <a href="https://d3js.org/" target="_blank">D3</a>
|
||||||
@@ -146,12 +139,15 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<a href="./webgl/raycaster/index.html" target="_blank">
|
<a href="./webgl/raycaster/index.html" target="_blank">
|
||||||
<h2>
|
<h2>Webgl Icosahedron Example</h2>
|
||||||
Webgl Icosahedron Example
|
|
||||||
</h2>
|
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>
|
||||||
Demo showing how a Simple <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API" target="_blank">WebGL</a>
|
Demo showing how a Simple
|
||||||
|
<a
|
||||||
|
href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API"
|
||||||
|
target="_blank"
|
||||||
|
>WebGL</a
|
||||||
|
>
|
||||||
scene would work in the <code><py-script></code> tag
|
scene would work in the <code><py-script></code> tag
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -165,9 +161,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<a href="./bokeh.html" target="_blank">
|
<a href="./bokeh.html" target="_blank">
|
||||||
<h2>
|
<h2>Simple Static Bokeh Plot</h2>
|
||||||
Simple Static Bokeh Plot
|
|
||||||
</h2>
|
|
||||||
</a>
|
</a>
|
||||||
<p>
|
<p>
|
||||||
Minimal Bokeh demo demonstrating how to create a simple
|
Minimal Bokeh demo demonstrating how to create a simple
|
||||||
@@ -187,8 +181,8 @@
|
|||||||
<p>
|
<p>
|
||||||
Interactive demo using a
|
Interactive demo using a
|
||||||
<a href="https://bokeh.org/" target="_blank">Bokeh</a>
|
<a href="https://bokeh.org/" target="_blank">Bokeh</a>
|
||||||
slider widget to dynamically change a value in the page
|
slider widget to dynamically change a value in the page WARNING:
|
||||||
WARNING: This examples takes a little longer to load. So be patient :)
|
This examples takes a little longer to load. So be patient :)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -203,7 +197,8 @@
|
|||||||
<p>
|
<p>
|
||||||
Interactive KMeans Chart using
|
Interactive KMeans Chart using
|
||||||
<a href="https://panel.holoviz.org/" target="_blank">Panel</a>
|
<a href="https://panel.holoviz.org/" target="_blank">Panel</a>
|
||||||
WARNING: This examples takes a little longer to load. So be patient :)
|
WARNING: This examples takes a little longer to load. So be
|
||||||
|
patient :)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -218,7 +213,8 @@
|
|||||||
<p>
|
<p>
|
||||||
Interactive Streaming Table and Bokeh plot using
|
Interactive Streaming Table and Bokeh plot using
|
||||||
<a href="https://panel.holoviz.org/" target="_blank">Panel</a>
|
<a href="https://panel.holoviz.org/" target="_blank">Panel</a>
|
||||||
WARNING: This examples takes a little longer to load. So be patient :)
|
WARNING: This examples takes a little longer to load. So be
|
||||||
|
patient :)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -233,8 +229,8 @@
|
|||||||
<p>
|
<p>
|
||||||
Simple demo showing
|
Simple demo showing
|
||||||
<a href="https://panel.holoviz.org/" target="_blank">Panel</a>
|
<a href="https://panel.holoviz.org/" target="_blank">Panel</a>
|
||||||
widgets interacting with parts of the page
|
widgets interacting with parts of the page WARNING: This examples
|
||||||
WARNING: This examples takes a little longer to load. So be patient :)
|
takes a little longer to load. So be patient :)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -248,8 +244,10 @@
|
|||||||
</a>
|
</a>
|
||||||
<p>
|
<p>
|
||||||
Interactive application exploring the NYC Taxi dataset using
|
Interactive application exploring the NYC Taxi dataset using
|
||||||
<a href="https://panel.holoviz.org/" target="_blank">Panel</a> and <a href="https://deck.gl/" target="_blank">DeckGL</a>
|
<a href="https://panel.holoviz.org/" target="_blank">Panel</a> and
|
||||||
WARNING: This examples takes a little longer to load. So be patient :)
|
<a href="https://deck.gl/" target="_blank">DeckGL</a>
|
||||||
|
WARNING: This examples takes a little longer to load. So be
|
||||||
|
patient :)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -264,7 +262,10 @@
|
|||||||
<p>
|
<p>
|
||||||
Visualization of Mandelbrot and Julia sets with
|
Visualization of Mandelbrot and Julia sets with
|
||||||
<a href="https://numpy.org/" target="_blank">Numpy</a> and
|
<a href="https://numpy.org/" target="_blank">Numpy</a> and
|
||||||
<a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API" target="_blank">
|
<a
|
||||||
|
href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
HTML5 canvas
|
HTML5 canvas
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
html, body, ul, li {
|
html,
|
||||||
|
body,
|
||||||
|
ul,
|
||||||
|
li {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Bcoin = Mario.Bcoin = function(pos) {
|
var Bcoin = (Mario.Bcoin = function (pos) {
|
||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
sprite: level.bcoinSprite(),
|
sprite: level.bcoinSprite(),
|
||||||
hitbox: [0,0,16,16]
|
hitbox: [0, 0, 16, 16],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Mario.Util.inherits(Bcoin, Mario.Entity);
|
Mario.Util.inherits(Bcoin, Mario.Entity);
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@
|
|||||||
this.active = true;
|
this.active = true;
|
||||||
this.vel = -12;
|
this.vel = -12;
|
||||||
this.targetpos = this.pos[1] - 32;
|
this.targetpos = this.pos[1] - 32;
|
||||||
}
|
};
|
||||||
|
|
||||||
Bcoin.prototype.update = function (dt) {
|
Bcoin.prototype.update = function (dt) {
|
||||||
if (!this.active) return;
|
if (!this.active) return;
|
||||||
@@ -38,8 +37,7 @@
|
|||||||
this.vel += this.acc;
|
this.vel += this.acc;
|
||||||
this.pos[1] += this.vel;
|
this.pos[1] += this.vel;
|
||||||
this.sprite.update(dt);
|
this.sprite.update(dt);
|
||||||
}
|
};
|
||||||
|
|
||||||
Bcoin.prototype.checkCollisions = function() {;}
|
|
||||||
|
|
||||||
|
Bcoin.prototype.checkCollisions = function () {};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
//TODO: clean up the logic for sprite switching.
|
//TODO: clean up the logic for sprite switching.
|
||||||
//TODO: There's a weird bug with the collision logic. Look into it.
|
//TODO: There's a weird bug with the collision logic. Look into it.
|
||||||
|
|
||||||
var Block = Mario.Block = function(options) {
|
var Block = (Mario.Block = function (options) {
|
||||||
this.item = options.item;
|
this.item = options.item;
|
||||||
this.usedSprite = options.usedSprite;
|
this.usedSprite = options.usedSprite;
|
||||||
this.bounceSprite = options.bounceSprite;
|
this.bounceSprite = options.bounceSprite;
|
||||||
@@ -14,20 +13,21 @@
|
|||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: options.pos,
|
pos: options.pos,
|
||||||
sprite: options.sprite,
|
sprite: options.sprite,
|
||||||
hitbox: [0,0,16,16]
|
hitbox: [0, 0, 16, 16],
|
||||||
});
|
});
|
||||||
|
|
||||||
this.standing = true;
|
this.standing = true;
|
||||||
}
|
});
|
||||||
|
|
||||||
Mario.Util.inherits(Block, Mario.Floor);
|
Mario.Util.inherits(Block, Mario.Floor);
|
||||||
|
|
||||||
Block.prototype.break = function () {
|
Block.prototype.break = function () {
|
||||||
sounds.breakBlock.play();
|
sounds.breakBlock.play();
|
||||||
(new Mario.Rubble()).spawn(this.pos);
|
new Mario.Rubble().spawn(this.pos);
|
||||||
var x = this.pos[0] / 16, y = this.pos[1] / 16;
|
var x = this.pos[0] / 16,
|
||||||
|
y = this.pos[1] / 16;
|
||||||
delete level.blocks[y][x];
|
delete level.blocks[y][x];
|
||||||
}
|
};
|
||||||
|
|
||||||
Block.prototype.bonk = function (power) {
|
Block.prototype.bonk = function (power) {
|
||||||
sounds.bump.play();
|
sounds.bump.play();
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
this.vel[1] = -2;
|
this.vel[1] = -2;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Block.prototype.update = function (dt, gameTime) {
|
Block.prototype.update = function (dt, gameTime) {
|
||||||
if (!this.standing) {
|
if (!this.standing) {
|
||||||
@@ -68,7 +68,8 @@
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.sprite === this.usedSprite) {
|
if (this.sprite === this.usedSprite) {
|
||||||
var x = this.pos[0] / 16, y = this.pos[1] / 16;
|
var x = this.pos[0] / 16,
|
||||||
|
y = this.pos[1] / 16;
|
||||||
level.statics[y][x] = new Mario.Floor(this.pos, this.usedSprite);
|
level.statics[y][x] = new Mario.Floor(this.pos, this.usedSprite);
|
||||||
delete level.blocks[y][x];
|
delete level.blocks[y][x];
|
||||||
}
|
}
|
||||||
@@ -76,6 +77,5 @@
|
|||||||
|
|
||||||
this.pos[1] += this.vel[1];
|
this.pos[1] += this.vel[1];
|
||||||
this.sprite.update(dt, gameTime);
|
this.sprite.update(dt, gameTime);
|
||||||
}
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,47 +1,59 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Coin = Mario.Coin = function(pos, sprite) {
|
var Coin = (Mario.Coin = function (pos, sprite) {
|
||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
sprite: sprite,
|
sprite: sprite,
|
||||||
hitbox: [0,0,16,16]
|
hitbox: [0, 0, 16, 16],
|
||||||
|
});
|
||||||
|
this.idx = level.items.length;
|
||||||
});
|
});
|
||||||
this.idx = level.items.length
|
|
||||||
}
|
|
||||||
|
|
||||||
Mario.Util.inherits(Coin, Mario.Entity);
|
Mario.Util.inherits(Coin, Mario.Entity);
|
||||||
|
|
||||||
Coin.prototype.isPlayerCollided = function () {
|
Coin.prototype.isPlayerCollided = function () {
|
||||||
//the first two elements of the hitbox array are an offset, so let's do this now.
|
//the first two elements of the hitbox array are an offset, so let's do this now.
|
||||||
var hpos1 = [this.pos[0] + this.hitbox[0], this.pos[1] + this.hitbox[1]];
|
var hpos1 = [this.pos[0] + this.hitbox[0], this.pos[1] + this.hitbox[1]];
|
||||||
var hpos2 = [player.pos[0] + player.hitbox[0], player.pos[1] + player.hitbox[1]];
|
var hpos2 = [
|
||||||
|
player.pos[0] + player.hitbox[0],
|
||||||
|
player.pos[1] + player.hitbox[1],
|
||||||
|
];
|
||||||
|
|
||||||
//if the hitboxes actually overlap
|
//if the hitboxes actually overlap
|
||||||
if (!(hpos1[0] > hpos2[0]+player.hitbox[2] || (hpos1[0]+this.hitbox[2] < hpos2[0]))) {
|
if (
|
||||||
if (!(hpos1[1] > hpos2[1]+player.hitbox[3] || (hpos1[1]+this.hitbox[3] < hpos2[1]))) {
|
!(
|
||||||
|
hpos1[0] > hpos2[0] + player.hitbox[2] ||
|
||||||
|
hpos1[0] + this.hitbox[2] < hpos2[0]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
hpos1[1] > hpos2[1] + player.hitbox[3] ||
|
||||||
|
hpos1[1] + this.hitbox[3] < hpos2[1]
|
||||||
|
)
|
||||||
|
) {
|
||||||
this.collect();
|
this.collect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Coin.prototype.render = function (ctx, vX, vY) {
|
Coin.prototype.render = function (ctx, vX, vY) {
|
||||||
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
}
|
};
|
||||||
|
|
||||||
//money is not affected by gravity, you see.
|
//money is not affected by gravity, you see.
|
||||||
Coin.prototype.update = function (dt) {
|
Coin.prototype.update = function (dt) {
|
||||||
this.sprite.update(dt);
|
this.sprite.update(dt);
|
||||||
}
|
};
|
||||||
Coin.prototype.checkCollisions = function () {
|
Coin.prototype.checkCollisions = function () {
|
||||||
this.isPlayerCollided();
|
this.isPlayerCollided();
|
||||||
}
|
};
|
||||||
|
|
||||||
Coin.prototype.collect = function () {
|
Coin.prototype.collect = function () {
|
||||||
sounds.coin.currentTime = 0.05;
|
sounds.coin.currentTime = 0.05;
|
||||||
sounds.coin.play();
|
sounds.coin.play();
|
||||||
player.coins += 1;
|
player.coins += 1;
|
||||||
delete level.items[this.idx]
|
delete level.items[this.idx];
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Entity = Mario.Entity = function(options) {
|
var Entity = (Mario.Entity = function (options) {
|
||||||
this.vel = [0, 0];
|
this.vel = [0, 0];
|
||||||
this.acc = [0, 0];
|
this.acc = [0, 0];
|
||||||
this.standing = true;
|
this.standing = true;
|
||||||
@@ -10,11 +9,11 @@
|
|||||||
this.sprite = options.sprite;
|
this.sprite = options.sprite;
|
||||||
this.hitbox = options.hitbox;
|
this.hitbox = options.hitbox;
|
||||||
this.left = false;
|
this.left = false;
|
||||||
}
|
});
|
||||||
|
|
||||||
Entity.prototype.render = function (ctx, vX, vY) {
|
Entity.prototype.render = function (ctx, vX, vY) {
|
||||||
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY)
|
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
}
|
};
|
||||||
|
|
||||||
Entity.prototype.collideWall = function (wall) {
|
Entity.prototype.collideWall = function (wall) {
|
||||||
//the wall will always be a 16x16 block with hitbox = [0,0,16,16].
|
//the wall will always be a 16x16 block with hitbox = [0,0,16,16].
|
||||||
@@ -24,11 +23,12 @@
|
|||||||
this.vel[0] = Math.max(0, this.vel[0]);
|
this.vel[0] = Math.max(0, this.vel[0]);
|
||||||
this.acc[0] = Math.max(0, this.acc[0]);
|
this.acc[0] = Math.max(0, this.acc[0]);
|
||||||
} else {
|
} else {
|
||||||
this.pos[0] = wall.pos[0] + wall.hitbox[0] - this.hitbox[2] - this.hitbox[0];
|
this.pos[0] =
|
||||||
|
wall.pos[0] + wall.hitbox[0] - this.hitbox[2] - this.hitbox[0];
|
||||||
this.vel[0] = Math.min(0, this.vel[0]);
|
this.vel[0] = Math.min(0, this.vel[0]);
|
||||||
this.acc[0] = Math.min(0, this.acc[0]);
|
this.acc[0] = Math.min(0, this.acc[0]);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Entity.prototype.bump = function() {;}
|
Entity.prototype.bump = function () {};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Fireball = Mario.Fireball = function(pos) {
|
var Fireball = (Mario.Fireball = function (pos) {
|
||||||
this.hit = 0;
|
this.hit = 0;
|
||||||
this.standing = false;
|
this.standing = false;
|
||||||
|
|
||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
sprite: new Mario.Sprite('sprites/items.png', [96, 144], [8,8], 5, [0,1,2,3]),
|
sprite: new Mario.Sprite(
|
||||||
hitbox: [0,0,8,8]
|
"sprites/items.png",
|
||||||
|
[96, 144],
|
||||||
|
[8, 8],
|
||||||
|
5,
|
||||||
|
[0, 1, 2, 3],
|
||||||
|
),
|
||||||
|
hitbox: [0, 0, 8, 8],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Mario.Util.inherits(Fireball, Mario.Entity);
|
Mario.Util.inherits(Fireball, Mario.Entity);
|
||||||
|
|
||||||
@@ -25,14 +30,14 @@
|
|||||||
this.idx = 0;
|
this.idx = 0;
|
||||||
fireballs[0] = this;
|
fireballs[0] = this;
|
||||||
}
|
}
|
||||||
this.vel[0] = (left ? -5 : 5);
|
this.vel[0] = left ? -5 : 5;
|
||||||
this.standing = false;
|
this.standing = false;
|
||||||
this.vel[1] = 0;
|
this.vel[1] = 0;
|
||||||
}
|
};
|
||||||
|
|
||||||
Fireball.prototype.render = function (ctx, vX, vY) {
|
Fireball.prototype.render = function (ctx, vX, vY) {
|
||||||
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
}
|
};
|
||||||
|
|
||||||
Fireball.prototype.update = function (dt) {
|
Fireball.prototype.update = function (dt) {
|
||||||
if (this.hit == 1) {
|
if (this.hit == 1) {
|
||||||
@@ -67,11 +72,11 @@
|
|||||||
this.hit = 1;
|
this.hit = 1;
|
||||||
}
|
}
|
||||||
this.sprite.update(dt);
|
this.sprite.update(dt);
|
||||||
}
|
};
|
||||||
|
|
||||||
Fireball.prototype.collideWall = function () {
|
Fireball.prototype.collideWall = function () {
|
||||||
if (!this.hit) this.hit = 1;
|
if (!this.hit) this.hit = 1;
|
||||||
}
|
};
|
||||||
|
|
||||||
Fireball.prototype.checkCollisions = function () {
|
Fireball.prototype.checkCollisions = function () {
|
||||||
if (this.hit) return;
|
if (this.hit) return;
|
||||||
@@ -100,13 +105,14 @@
|
|||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
level.enemies.forEach(function (enemy) {
|
level.enemies.forEach(function (enemy) {
|
||||||
if (enemy.flipping || enemy.pos[0] - vX > 336){ //stop checking once we get to far away dudes.
|
if (enemy.flipping || enemy.pos[0] - vX > 336) {
|
||||||
|
//stop checking once we get to far away dudes.
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
that.isCollideWith(enemy);
|
that.isCollideWith(enemy);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
Fireball.prototype.isCollideWith = function (ent) {
|
Fireball.prototype.isCollideWith = function (ent) {
|
||||||
//the first two elements of the hitbox array are an offset, so let's do this now.
|
//the first two elements of the hitbox array are an offset, so let's do this now.
|
||||||
@@ -114,13 +120,23 @@
|
|||||||
var hpos2 = [ent.pos[0] + ent.hitbox[0], ent.pos[1] + ent.hitbox[1]];
|
var hpos2 = [ent.pos[0] + ent.hitbox[0], ent.pos[1] + ent.hitbox[1]];
|
||||||
|
|
||||||
//if the hitboxes actually overlap
|
//if the hitboxes actually overlap
|
||||||
if (!(hpos1[0] > hpos2[0]+ent.hitbox[2] || (hpos1[0]+this.hitbox[2] < hpos2[0]))) {
|
if (
|
||||||
if (!(hpos1[1] > hpos2[1]+ent.hitbox[3] || (hpos1[1]+this.hitbox[3] < hpos2[1]))) {
|
!(
|
||||||
|
hpos1[0] > hpos2[0] + ent.hitbox[2] ||
|
||||||
|
hpos1[0] + this.hitbox[2] < hpos2[0]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
hpos1[1] > hpos2[1] + ent.hitbox[3] ||
|
||||||
|
hpos1[1] + this.hitbox[3] < hpos2[1]
|
||||||
|
)
|
||||||
|
) {
|
||||||
this.hit = 1;
|
this.hit = 1;
|
||||||
ent.bump();
|
ent.bump();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Fireball.prototype.bump = function() {;}
|
Fireball.prototype.bump = function () {};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Fireflower = Mario.Fireflower = function(pos) {
|
var Fireflower = (Mario.Fireflower = function (pos) {
|
||||||
this.spawning = false;
|
this.spawning = false;
|
||||||
this.waiting = 0;
|
this.waiting = 0;
|
||||||
|
|
||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
sprite: level.fireFlowerSprite,
|
sprite: level.fireFlowerSprite,
|
||||||
hitbox: [0,0,16,16]
|
hitbox: [0, 0, 16, 16],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Mario.Util.inherits(Fireflower, Mario.Entity);
|
Mario.Util.inherits(Fireflower, Mario.Entity);
|
||||||
|
|
||||||
Fireflower.prototype.render = function (ctx, vX, vY) {
|
Fireflower.prototype.render = function (ctx, vX, vY) {
|
||||||
if (this.spawning > 1) return;
|
if (this.spawning > 1) return;
|
||||||
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
}
|
};
|
||||||
|
|
||||||
Fireflower.prototype.spawn = function () {
|
Fireflower.prototype.spawn = function () {
|
||||||
sounds.itemAppear.play();
|
sounds.itemAppear.play();
|
||||||
@@ -28,12 +27,12 @@
|
|||||||
this.targetpos = [];
|
this.targetpos = [];
|
||||||
this.targetpos[0] = this.pos[0];
|
this.targetpos[0] = this.pos[0];
|
||||||
this.targetpos[1] = this.pos[1] - 16;
|
this.targetpos[1] = this.pos[1] - 16;
|
||||||
}
|
};
|
||||||
|
|
||||||
Fireflower.prototype.update = function (dt) {
|
Fireflower.prototype.update = function (dt) {
|
||||||
if (this.spawning > 1) {
|
if (this.spawning > 1) {
|
||||||
this.spawning -= 1;
|
this.spawning -= 1;
|
||||||
if (this.spawning == 1) this.vel[1] = -.5;
|
if (this.spawning == 1) this.vel[1] = -0.5;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.spawning) {
|
if (this.spawning) {
|
||||||
@@ -48,27 +47,41 @@
|
|||||||
this.pos[0] += this.vel[0];
|
this.pos[0] += this.vel[0];
|
||||||
this.pos[1] += this.vel[1];
|
this.pos[1] += this.vel[1];
|
||||||
this.sprite.update(dt);
|
this.sprite.update(dt);
|
||||||
}
|
};
|
||||||
|
|
||||||
Fireflower.prototype.checkCollisions = function () {
|
Fireflower.prototype.checkCollisions = function () {
|
||||||
if (this.spawning) {return;}
|
if (this.spawning) {
|
||||||
this.isPlayerCollided();
|
return;
|
||||||
}
|
}
|
||||||
|
this.isPlayerCollided();
|
||||||
|
};
|
||||||
|
|
||||||
Fireflower.prototype.isPlayerCollided = function () {
|
Fireflower.prototype.isPlayerCollided = function () {
|
||||||
//the first two elements of the hitbox array are an offset, so let's do this now.
|
//the first two elements of the hitbox array are an offset, so let's do this now.
|
||||||
var hpos1 = [this.pos[0] + this.hitbox[0], this.pos[1] + this.hitbox[1]];
|
var hpos1 = [this.pos[0] + this.hitbox[0], this.pos[1] + this.hitbox[1]];
|
||||||
var hpos2 = [player.pos[0] + player.hitbox[0], player.pos[1] + player.hitbox[1]];
|
var hpos2 = [
|
||||||
|
player.pos[0] + player.hitbox[0],
|
||||||
|
player.pos[1] + player.hitbox[1],
|
||||||
|
];
|
||||||
|
|
||||||
//if the hitboxes actually overlap
|
//if the hitboxes actually overlap
|
||||||
if (!(hpos1[0] > hpos2[0]+player.hitbox[2] || (hpos1[0]+this.hitbox[2] < hpos2[0]))) {
|
if (
|
||||||
if (!(hpos1[1] > hpos2[1]+player.hitbox[3] || (hpos1[1]+this.hitbox[3] < hpos2[1]))) {
|
!(
|
||||||
|
hpos1[0] > hpos2[0] + player.hitbox[2] ||
|
||||||
|
hpos1[0] + this.hitbox[2] < hpos2[0]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
hpos1[1] > hpos2[1] + player.hitbox[3] ||
|
||||||
|
hpos1[1] + this.hitbox[3] < hpos2[1]
|
||||||
|
)
|
||||||
|
) {
|
||||||
player.powerUp(this.idx);
|
player.powerUp(this.idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
//This should never be called, but just in case.
|
//This should never be called, but just in case.
|
||||||
Fireflower.prototype.bump = function() {;}
|
Fireflower.prototype.bump = function () {};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
Flag = Mario.Flag = function (pos) {
|
Flag = Mario.Flag = function (pos) {
|
||||||
//afaik flags always have the same height and Y-position
|
//afaik flags always have the same height and Y-position
|
||||||
@@ -8,10 +7,9 @@
|
|||||||
this.hitbox = [0, 0, 0, 0];
|
this.hitbox = [0, 0, 0, 0];
|
||||||
this.vel = [0, 0];
|
this.vel = [0, 0];
|
||||||
this.acc = [0, 0];
|
this.acc = [0, 0];
|
||||||
}
|
};
|
||||||
|
|
||||||
Flag.prototype.collideWall = function() {;
|
Flag.prototype.collideWall = function () {};
|
||||||
}
|
|
||||||
|
|
||||||
Flag.prototype.update = function (dt) {
|
Flag.prototype.update = function (dt) {
|
||||||
if (!this.done && this.pos[1] >= 170) {
|
if (!this.done && this.pos[1] >= 170) {
|
||||||
@@ -21,11 +19,11 @@
|
|||||||
this.done = true;
|
this.done = true;
|
||||||
}
|
}
|
||||||
this.pos[1] += this.vel[1];
|
this.pos[1] += this.vel[1];
|
||||||
}
|
};
|
||||||
|
|
||||||
Flag.prototype.checkCollisions = function () {
|
Flag.prototype.checkCollisions = function () {
|
||||||
this.isPlayerCollided();
|
this.isPlayerCollided();
|
||||||
}
|
};
|
||||||
|
|
||||||
Flag.prototype.isPlayerCollided = function () {
|
Flag.prototype.isPlayerCollided = function () {
|
||||||
if (this.hit) return;
|
if (this.hit) return;
|
||||||
@@ -39,9 +37,9 @@
|
|||||||
player.flag();
|
player.flag();
|
||||||
this.vel = [0, 2];
|
this.vel = [0, 2];
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Flag.prototype.render = function () {
|
Flag.prototype.render = function () {
|
||||||
level.flagpoleSprites[2].render(ctx, this.pos[0] - 8, this.pos[1], vX, vY);
|
level.flagpoleSprites[2].render(ctx, this.pos[0] - 8, this.pos[1], vX, vY);
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,41 +1,60 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Floor = Mario.Floor = function(pos, sprite) {
|
|
||||||
|
|
||||||
|
var Floor = (Mario.Floor = function (pos, sprite) {
|
||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
sprite: sprite,
|
sprite: sprite,
|
||||||
hitbox: [0,0,16,16]
|
hitbox: [0, 0, 16, 16],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Mario.Util.inherits(Floor, Mario.Entity);
|
Mario.Util.inherits(Floor, Mario.Entity);
|
||||||
|
|
||||||
Floor.prototype.isCollideWith = function (ent) {
|
Floor.prototype.isCollideWith = function (ent) {
|
||||||
//the first two elements of the hitbox array are an offset, so let's do this now.
|
//the first two elements of the hitbox array are an offset, so let's do this now.
|
||||||
var hpos1 = [Math.floor(this.pos[0] + this.hitbox[0]), Math.floor(this.pos[1] + this.hitbox[1])];
|
var hpos1 = [
|
||||||
var hpos2 = [Math.floor(ent.pos[0] + ent.hitbox[0]), Math.floor(ent.pos[1] + ent.hitbox[1])];
|
Math.floor(this.pos[0] + this.hitbox[0]),
|
||||||
|
Math.floor(this.pos[1] + this.hitbox[1]),
|
||||||
|
];
|
||||||
|
var hpos2 = [
|
||||||
|
Math.floor(ent.pos[0] + ent.hitbox[0]),
|
||||||
|
Math.floor(ent.pos[1] + ent.hitbox[1]),
|
||||||
|
];
|
||||||
|
|
||||||
//if the hitboxes actually overlap
|
//if the hitboxes actually overlap
|
||||||
if (!(hpos1[0] > hpos2[0]+ent.hitbox[2] || (hpos1[0]+this.hitbox[2] < hpos2[0]))) {
|
if (
|
||||||
if (!(hpos1[1] > hpos2[1]+ent.hitbox[3] || (hpos1[1]+this.hitbox[3] < hpos2[1]))) {
|
!(
|
||||||
|
hpos1[0] > hpos2[0] + ent.hitbox[2] ||
|
||||||
|
hpos1[0] + this.hitbox[2] < hpos2[0]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
hpos1[1] > hpos2[1] + ent.hitbox[3] ||
|
||||||
|
hpos1[1] + this.hitbox[3] < hpos2[1]
|
||||||
|
)
|
||||||
|
) {
|
||||||
if (!this.standing) {
|
if (!this.standing) {
|
||||||
ent.bump();
|
ent.bump();
|
||||||
} else {
|
} else {
|
||||||
//if the entity is over the block, it's basically floor
|
//if the entity is over the block, it's basically floor
|
||||||
var center = hpos2[0] + ent.hitbox[2] / 2;
|
var center = hpos2[0] + ent.hitbox[2] / 2;
|
||||||
if (Math.abs(hpos2[1] + ent.hitbox[3] - hpos1[1]) <= ent.vel[1]) {
|
if (Math.abs(hpos2[1] + ent.hitbox[3] - hpos1[1]) <= ent.vel[1]) {
|
||||||
if (level.statics[(this.pos[1] / 16) - 1][this.pos[0] / 16]) {return};
|
if (level.statics[this.pos[1] / 16 - 1][this.pos[0] / 16]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
ent.vel[1] = 0;
|
ent.vel[1] = 0;
|
||||||
ent.pos[1] = hpos1[1] - ent.hitbox[3] - ent.hitbox[1];
|
ent.pos[1] = hpos1[1] - ent.hitbox[3] - ent.hitbox[1];
|
||||||
ent.standing = true;
|
ent.standing = true;
|
||||||
if (ent instanceof Mario.Player) {
|
if (ent instanceof Mario.Player) {
|
||||||
ent.jumping = 0;
|
ent.jumping = 0;
|
||||||
}
|
}
|
||||||
} else if (Math.abs(hpos2[1] - hpos1[1] - this.hitbox[3]) > ent.vel[1] &&
|
} else if (
|
||||||
center + 2 >= hpos1[0] && center - 2 <= hpos1[0] + this.hitbox[2]) {
|
Math.abs(hpos2[1] - hpos1[1] - this.hitbox[3]) > ent.vel[1] &&
|
||||||
|
center + 2 >= hpos1[0] &&
|
||||||
|
center - 2 <= hpos1[0] + this.hitbox[2]
|
||||||
|
) {
|
||||||
//ent is under the block.
|
//ent is under the block.
|
||||||
ent.vel[1] = 0;
|
ent.vel[1] = 0;
|
||||||
ent.pos[1] = hpos1[1] + this.hitbox[3];
|
ent.pos[1] = hpos1[1] + this.hitbox[3];
|
||||||
@@ -50,7 +69,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Floor.prototype.bonk = function() {;}
|
Floor.prototype.bonk = function () {};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
var requestAnimFrame = (function () {
|
var requestAnimFrame = (function () {
|
||||||
return window.requestAnimationFrame ||
|
return (
|
||||||
|
window.requestAnimationFrame ||
|
||||||
window.webkitRequestAnimationFrame ||
|
window.webkitRequestAnimationFrame ||
|
||||||
window.mozRequestAnimationFrame ||
|
window.mozRequestAnimationFrame ||
|
||||||
window.oRequestAnimationFrame ||
|
window.oRequestAnimationFrame ||
|
||||||
window.msRequestAnimationFrame ||
|
window.msRequestAnimationFrame ||
|
||||||
function (callback) {
|
function (callback) {
|
||||||
window.setTimeout(callback, 1000 / 60);
|
window.setTimeout(callback, 1000 / 60);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
//create the canvas
|
//create the canvas
|
||||||
var canvas = document.createElement("canvas");
|
var canvas = document.createElement("canvas");
|
||||||
var ctx = canvas.getContext('2d');
|
var ctx = canvas.getContext("2d");
|
||||||
var updateables = [];
|
var updateables = [];
|
||||||
var fireballs = [];
|
var fireballs = [];
|
||||||
var player = new Mario.Player([0, 0]);
|
var player = new Mario.Player([0, 0]);
|
||||||
@@ -34,12 +36,12 @@ var vX = 0,
|
|||||||
|
|
||||||
//load our images
|
//load our images
|
||||||
resources.load([
|
resources.load([
|
||||||
'sprites/player.png',
|
"sprites/player.png",
|
||||||
'sprites/enemy.png',
|
"sprites/enemy.png",
|
||||||
'sprites/tiles.png',
|
"sprites/tiles.png",
|
||||||
'sprites/playerl.png',
|
"sprites/playerl.png",
|
||||||
'sprites/items.png',
|
"sprites/items.png",
|
||||||
'sprites/enemyr.png',
|
"sprites/enemyr.png",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
resources.onReady(init);
|
resources.onReady(init);
|
||||||
@@ -51,24 +53,24 @@ var music;
|
|||||||
var lastTime;
|
var lastTime;
|
||||||
function init() {
|
function init() {
|
||||||
music = {
|
music = {
|
||||||
overworld: new Audio('sounds/aboveground_bgm.ogg'),
|
overworld: new Audio("sounds/aboveground_bgm.ogg"),
|
||||||
underground: new Audio('sounds/underground_bgm.ogg'),
|
underground: new Audio("sounds/underground_bgm.ogg"),
|
||||||
clear: new Audio('sounds/stage_clear.wav'),
|
clear: new Audio("sounds/stage_clear.wav"),
|
||||||
death: new Audio('sounds/mariodie.wav')
|
death: new Audio("sounds/mariodie.wav"),
|
||||||
};
|
};
|
||||||
sounds = {
|
sounds = {
|
||||||
smallJump: new Audio('sounds/jump-small.wav'),
|
smallJump: new Audio("sounds/jump-small.wav"),
|
||||||
bigJump: new Audio('sounds/jump-super.wav'),
|
bigJump: new Audio("sounds/jump-super.wav"),
|
||||||
breakBlock: new Audio('sounds/breakblock.wav'),
|
breakBlock: new Audio("sounds/breakblock.wav"),
|
||||||
bump: new Audio('sounds/bump.wav'),
|
bump: new Audio("sounds/bump.wav"),
|
||||||
coin: new Audio('sounds/coin.wav'),
|
coin: new Audio("sounds/coin.wav"),
|
||||||
fireball: new Audio('sounds/fireball.wav'),
|
fireball: new Audio("sounds/fireball.wav"),
|
||||||
flagpole: new Audio('sounds/flagpole.wav'),
|
flagpole: new Audio("sounds/flagpole.wav"),
|
||||||
kick: new Audio('sounds/kick.wav'),
|
kick: new Audio("sounds/kick.wav"),
|
||||||
pipe: new Audio('sounds/pipe.wav'),
|
pipe: new Audio("sounds/pipe.wav"),
|
||||||
itemAppear: new Audio('sounds/itemAppear.wav'),
|
itemAppear: new Audio("sounds/itemAppear.wav"),
|
||||||
powerup: new Audio('sounds/powerup.wav'),
|
powerup: new Audio("sounds/powerup.wav"),
|
||||||
stomp: new Audio('sounds/stomp.wav')
|
stomp: new Audio("sounds/stomp.wav"),
|
||||||
};
|
};
|
||||||
Mario.oneone();
|
Mario.oneone();
|
||||||
lastTime = Date.now();
|
lastTime = Date.now();
|
||||||
@@ -101,28 +103,29 @@ function update(dt) {
|
|||||||
function handleInput(dt) {
|
function handleInput(dt) {
|
||||||
if (player.piping || player.dying || player.noInput) return; //don't accept input
|
if (player.piping || player.dying || player.noInput) return; //don't accept input
|
||||||
|
|
||||||
if (input.isDown('RUN')){
|
if (input.isDown("RUN")) {
|
||||||
player.run();
|
player.run();
|
||||||
} else {
|
} else {
|
||||||
player.noRun();
|
player.noRun();
|
||||||
}
|
}
|
||||||
if (input.isDown('JUMP')) {
|
if (input.isDown("JUMP")) {
|
||||||
player.jump();
|
player.jump();
|
||||||
} else {
|
} else {
|
||||||
//we need this to handle the timing for how long you hold it
|
//we need this to handle the timing for how long you hold it
|
||||||
player.noJump();
|
player.noJump();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.isDown('DOWN')) {
|
if (input.isDown("DOWN")) {
|
||||||
player.crouch();
|
player.crouch();
|
||||||
} else {
|
} else {
|
||||||
player.noCrouch();
|
player.noCrouch();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.isDown('LEFT')) { // 'd' or left arrow
|
if (input.isDown("LEFT")) {
|
||||||
|
// 'd' or left arrow
|
||||||
player.moveLeft();
|
player.moveLeft();
|
||||||
}
|
} else if (input.isDown("RIGHT")) {
|
||||||
else if (input.isDown('RIGHT')) { // 'k' or right arrow
|
// 'k' or right arrow
|
||||||
player.moveRight();
|
player.moveRight();
|
||||||
} else {
|
} else {
|
||||||
player.noWalk();
|
player.noWalk();
|
||||||
@@ -138,13 +141,14 @@ function updateEntities(dt, gameTime) {
|
|||||||
|
|
||||||
//This should stop the jump when he switches sides on the flag.
|
//This should stop the jump when he switches sides on the flag.
|
||||||
if (player.exiting) {
|
if (player.exiting) {
|
||||||
if (player.pos[0] > vX + 96)
|
if (player.pos[0] > vX + 96) vX = player.pos[0] - 96;
|
||||||
vX = player.pos[0] - 96
|
|
||||||
} else if (level.scrolling && player.pos[0] > vX + 80) {
|
} else if (level.scrolling && player.pos[0] > vX + 80) {
|
||||||
vX = player.pos[0] - 80;
|
vX = player.pos[0] - 80;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.powering.length !== 0 || player.dying) { return; }
|
if (player.powering.length !== 0 || player.dying) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
level.items.forEach(function (ent) {
|
level.items.forEach(function (ent) {
|
||||||
ent.update(dt);
|
ent.update(dt);
|
||||||
});
|
});
|
||||||
@@ -163,7 +167,9 @@ function updateEntities(dt, gameTime) {
|
|||||||
|
|
||||||
//scan for collisions
|
//scan for collisions
|
||||||
function checkCollisions() {
|
function checkCollisions() {
|
||||||
if (player.powering.length !== 0 || player.dying) { return; }
|
if (player.powering.length !== 0 || player.dying) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
player.checkCollisions();
|
player.checkCollisions();
|
||||||
|
|
||||||
//Apparently for each will just skip indices where things were deleted.
|
//Apparently for each will just skip indices where things were deleted.
|
||||||
@@ -206,11 +212,9 @@ function render() {
|
|||||||
renderEntity(enemy);
|
renderEntity(enemy);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fireballs.forEach(function (fireball) {
|
fireballs.forEach(function (fireball) {
|
||||||
renderEntity(fireball);
|
renderEntity(fireball);
|
||||||
})
|
});
|
||||||
|
|
||||||
//then we draw every static object.
|
//then we draw every static object.
|
||||||
for (var i = 0; i < 15; i++) {
|
for (var i = 0; i < 15; i++) {
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
//TODO: On console the hitbox is smaller. Measure it and edit this.
|
//TODO: On console the hitbox is smaller. Measure it and edit this.
|
||||||
|
|
||||||
var Goomba = Mario.Goomba = function(pos, sprite) {
|
var Goomba = (Mario.Goomba = function (pos, sprite) {
|
||||||
this.dying = false;
|
this.dying = false;
|
||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
sprite: sprite,
|
sprite: sprite,
|
||||||
hitbox: [0,0,16,16]
|
hitbox: [0, 0, 16, 16],
|
||||||
});
|
});
|
||||||
this.vel[0] = -0.5;
|
this.vel[0] = -0.5;
|
||||||
this.idx = level.enemies.length;
|
this.idx = level.enemies.length;
|
||||||
};
|
});
|
||||||
|
|
||||||
Goomba.prototype.render = function (ctx, vX, vY) {
|
Goomba.prototype.render = function (ctx, vX, vY) {
|
||||||
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
};
|
};
|
||||||
|
|
||||||
Goomba.prototype.update = function (dt, vX) {
|
Goomba.prototype.update = function (dt, vX) {
|
||||||
if (this.pos[0] - vX > 336) { //if we're too far away, do nothing.
|
if (this.pos[0] - vX > 336) {
|
||||||
|
//if we're too far away, do nothing.
|
||||||
return;
|
return;
|
||||||
} else if (this.pos[0] - vX < -32) {
|
} else if (this.pos[0] - vX < -32) {
|
||||||
delete level.enemies[this.idx];
|
delete level.enemies[this.idx];
|
||||||
@@ -71,9 +71,11 @@
|
|||||||
}
|
}
|
||||||
var that = this;
|
var that = this;
|
||||||
level.enemies.forEach(function (enemy) {
|
level.enemies.forEach(function (enemy) {
|
||||||
if (enemy === that) { //don't check collisions with ourselves.
|
if (enemy === that) {
|
||||||
|
//don't check collisions with ourselves.
|
||||||
return;
|
return;
|
||||||
} else if (enemy.pos[0] - vX > 336){ //stop checking once we get to far away dudes.
|
} else if (enemy.pos[0] - vX > 336) {
|
||||||
|
//stop checking once we get to far away dudes.
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
that.isCollideWith(enemy);
|
that.isCollideWith(enemy);
|
||||||
@@ -92,14 +94,27 @@
|
|||||||
var hpos2 = [ent.pos[0] + ent.hitbox[0], ent.pos[1] + ent.hitbox[1]];
|
var hpos2 = [ent.pos[0] + ent.hitbox[0], ent.pos[1] + ent.hitbox[1]];
|
||||||
|
|
||||||
//if the hitboxes actually overlap
|
//if the hitboxes actually overlap
|
||||||
if (!(hpos1[0] > hpos2[0]+ent.hitbox[2] || (hpos1[0]+this.hitbox[2] < hpos2[0]))) {
|
if (
|
||||||
if (!(hpos1[1] > hpos2[1]+ent.hitbox[3] || (hpos1[1]+this.hitbox[3] < hpos2[1]))) {
|
!(
|
||||||
if (ent instanceof Mario.Player) { //if we hit the player
|
hpos1[0] > hpos2[0] + ent.hitbox[2] ||
|
||||||
if (ent.vel[1] > 0) { //then the goomba dies
|
hpos1[0] + this.hitbox[2] < hpos2[0]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
hpos1[1] > hpos2[1] + ent.hitbox[3] ||
|
||||||
|
hpos1[1] + this.hitbox[3] < hpos2[1]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (ent instanceof Mario.Player) {
|
||||||
|
//if we hit the player
|
||||||
|
if (ent.vel[1] > 0) {
|
||||||
|
//then the goomba dies
|
||||||
this.stomp();
|
this.stomp();
|
||||||
} else if (ent.starTime) {
|
} else if (ent.starTime) {
|
||||||
this.bump();
|
this.bump();
|
||||||
} else { //or the player gets hit
|
} else {
|
||||||
|
//or the player gets hit
|
||||||
ent.damage();
|
ent.damage();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -120,7 +135,7 @@
|
|||||||
|
|
||||||
Goomba.prototype.bump = function () {
|
Goomba.prototype.bump = function () {
|
||||||
sounds.kick.play();
|
sounds.kick.play();
|
||||||
this.sprite.img = 'sprites/enemyr.png';
|
this.sprite.img = "sprites/enemyr.png";
|
||||||
this.flipping = true;
|
this.flipping = true;
|
||||||
this.pos[1] -= 1;
|
this.pos[1] -= 1;
|
||||||
this.vel[0] = 0;
|
this.vel[0] = 0;
|
||||||
|
|||||||
@@ -7,19 +7,26 @@
|
|||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 32:
|
case 32:
|
||||||
key = 'SPACE'; break;
|
key = "SPACE";
|
||||||
|
break;
|
||||||
case 37:
|
case 37:
|
||||||
key = 'LEFT'; break;
|
key = "LEFT";
|
||||||
|
break;
|
||||||
case 38:
|
case 38:
|
||||||
key = 'UP'; break;
|
key = "UP";
|
||||||
|
break;
|
||||||
case 39:
|
case 39:
|
||||||
key = 'RIGHT'; break;
|
key = "RIGHT";
|
||||||
|
break;
|
||||||
case 40:
|
case 40:
|
||||||
key = 'DOWN'; break;
|
key = "DOWN";
|
||||||
|
break;
|
||||||
case 88:
|
case 88:
|
||||||
key = 'JUMP'; break;
|
key = "JUMP";
|
||||||
|
break;
|
||||||
case 90:
|
case 90:
|
||||||
key = 'RUN'; break;
|
key = "RUN";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
key = String.fromCharCode(code);
|
key = String.fromCharCode(code);
|
||||||
}
|
}
|
||||||
@@ -27,15 +34,15 @@
|
|||||||
pressedKeys[key] = status;
|
pressedKeys[key] = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('keydown', function(e) {
|
document.addEventListener("keydown", function (e) {
|
||||||
setKey(e, true);
|
setKey(e, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener('keyup', function(e) {
|
document.addEventListener("keyup", function (e) {
|
||||||
setKey(e, false);
|
setKey(e, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('blur', function() {
|
window.addEventListener("blur", function () {
|
||||||
pressedKeys = {};
|
pressedKeys = {};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -44,11 +51,11 @@
|
|||||||
return pressedKeys[key.toUpperCase()];
|
return pressedKeys[key.toUpperCase()];
|
||||||
},
|
},
|
||||||
reset: function () {
|
reset: function () {
|
||||||
pressedKeys['RUN'] = false;
|
pressedKeys["RUN"] = false;
|
||||||
pressedKeys['LEFT'] = false;
|
pressedKeys["LEFT"] = false;
|
||||||
pressedKeys['RIGHT'] = false;
|
pressedKeys["RIGHT"] = false;
|
||||||
pressedKeys['DOWN'] = false;
|
pressedKeys["DOWN"] = false;
|
||||||
pressedKeys['JUMP'] = false;
|
pressedKeys["JUMP"] = false;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Koopa = Mario.Koopa = function(pos, sprite, para) {
|
var Koopa = (Mario.Koopa = function (pos, sprite, para) {
|
||||||
this.dying = false;
|
this.dying = false;
|
||||||
this.shell = false;
|
this.shell = false;
|
||||||
|
|
||||||
@@ -14,11 +13,11 @@
|
|||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
sprite: sprite,
|
sprite: sprite,
|
||||||
hitbox: [2,8,12,24]
|
hitbox: [2, 8, 12, 24],
|
||||||
});
|
});
|
||||||
this.vel[0] = -0.5;
|
this.vel[0] = -0.5;
|
||||||
this.idx = level.enemies.length;
|
this.idx = level.enemies.length;
|
||||||
};
|
});
|
||||||
|
|
||||||
Koopa.prototype.render = function (ctx, vX, vY) {
|
Koopa.prototype.render = function (ctx, vX, vY) {
|
||||||
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
@@ -31,16 +30,17 @@
|
|||||||
this.turn = false;
|
this.turn = false;
|
||||||
}
|
}
|
||||||
if (this.vel[0] != 0) {
|
if (this.vel[0] != 0) {
|
||||||
this.left = (this.vel[0] < 0);
|
this.left = this.vel[0] < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.left) {
|
if (this.left) {
|
||||||
this.sprite.img = 'sprites/enemy.png';
|
this.sprite.img = "sprites/enemy.png";
|
||||||
} else {
|
} else {
|
||||||
this.sprite.img = 'sprites/enemyr.png';
|
this.sprite.img = "sprites/enemyr.png";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.pos[0] - vX > 336) { //if we're too far away, do nothing.
|
if (this.pos[0] - vX > 336) {
|
||||||
|
//if we're too far away, do nothing.
|
||||||
return;
|
return;
|
||||||
} else if (this.pos[0] - vX < -32) {
|
} else if (this.pos[0] - vX < -32) {
|
||||||
delete level.enemies[this.idx];
|
delete level.enemies[this.idx];
|
||||||
@@ -61,9 +61,9 @@
|
|||||||
}
|
}
|
||||||
if (this.shell == 0) {
|
if (this.shell == 0) {
|
||||||
this.sprite = level.koopaSprite();
|
this.sprite = level.koopaSprite();
|
||||||
this.hitbox = [2,8,12,24]
|
this.hitbox = [2, 8, 12, 24];
|
||||||
if (this.left) {
|
if (this.left) {
|
||||||
this.sprite.img = 'sprites/enemyr.png';
|
this.sprite.img = "sprites/enemyr.png";
|
||||||
this.vel[0] = 0.5;
|
this.vel[0] = 0.5;
|
||||||
this.left = false;
|
this.left = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -122,9 +122,11 @@
|
|||||||
}
|
}
|
||||||
var that = this;
|
var that = this;
|
||||||
level.enemies.forEach(function (enemy) {
|
level.enemies.forEach(function (enemy) {
|
||||||
if (enemy === that) { //don't check collisions with ourselves.
|
if (enemy === that) {
|
||||||
|
//don't check collisions with ourselves.
|
||||||
return;
|
return;
|
||||||
} else if (enemy.pos[0] - vX > 336){ //stop checking once we get to far away dudes.
|
} else if (enemy.pos[0] - vX > 336) {
|
||||||
|
//stop checking once we get to far away dudes.
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
that.isCollideWith(enemy);
|
that.isCollideWith(enemy);
|
||||||
@@ -143,8 +145,18 @@
|
|||||||
var hpos2 = [ent.pos[0] + ent.hitbox[0], ent.pos[1] + ent.hitbox[1]];
|
var hpos2 = [ent.pos[0] + ent.hitbox[0], ent.pos[1] + ent.hitbox[1]];
|
||||||
|
|
||||||
//if the hitboxes actually overlap
|
//if the hitboxes actually overlap
|
||||||
if (!(hpos1[0] > hpos2[0]+ent.hitbox[2] || (hpos1[0]+this.hitbox[2] < hpos2[0]))) {
|
if (
|
||||||
if (!(hpos1[1] > hpos2[1]+ent.hitbox[3] || (hpos1[1]+this.hitbox[3] < hpos2[1]))) {
|
!(
|
||||||
|
hpos1[0] > hpos2[0] + ent.hitbox[2] ||
|
||||||
|
hpos1[0] + this.hitbox[2] < hpos2[0]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
hpos1[1] > hpos2[1] + ent.hitbox[3] ||
|
||||||
|
hpos1[1] + this.hitbox[3] < hpos2[1]
|
||||||
|
)
|
||||||
|
) {
|
||||||
if (ent instanceof Mario.Player) {
|
if (ent instanceof Mario.Player) {
|
||||||
if (ent.vel[1] > 0) {
|
if (ent.vel[1] > 0) {
|
||||||
player.bounce = true;
|
player.bounce = true;
|
||||||
@@ -152,7 +164,8 @@
|
|||||||
if (this.shell) {
|
if (this.shell) {
|
||||||
sounds.kick.play();
|
sounds.kick.play();
|
||||||
if (this.vel[0] === 0) {
|
if (this.vel[0] === 0) {
|
||||||
if (ent.left) { //I'm pretty sure this isn't the real logic.
|
if (ent.left) {
|
||||||
|
//I'm pretty sure this isn't the real logic.
|
||||||
this.vel[0] = -4;
|
this.vel[0] = -4;
|
||||||
} else {
|
} else {
|
||||||
this.vel[0] = 4;
|
this.vel[0] = 4;
|
||||||
@@ -162,13 +175,15 @@
|
|||||||
this.vel[0] = 0;
|
this.vel[0] = 0;
|
||||||
} else ent.damage();
|
} else ent.damage();
|
||||||
}
|
}
|
||||||
} else if (ent.vel[1] > 0) { //then we get BOPPED.
|
} else if (ent.vel[1] > 0) {
|
||||||
|
//then we get BOPPED.
|
||||||
this.stomp();
|
this.stomp();
|
||||||
} else { //or the player gets hit
|
} else {
|
||||||
|
//or the player gets hit
|
||||||
ent.damage();
|
ent.damage();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.shell && (ent instanceof Mario.Goomba)) {
|
if (this.shell && ent instanceof Mario.Goomba) {
|
||||||
ent.bump();
|
ent.bump();
|
||||||
} else this.collideWall();
|
} else this.collideWall();
|
||||||
}
|
}
|
||||||
@@ -194,7 +209,6 @@
|
|||||||
this.vel = [0, 0];
|
this.vel = [0, 0];
|
||||||
this.pos[1] += 16;
|
this.pos[1] += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Koopa.prototype.bump = function () {
|
Koopa.prototype.bump = function () {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var oneone = Mario.oneone = function() {
|
var oneone = (Mario.oneone = function () {
|
||||||
//The things that need to be passed in are basically just dependent on what
|
//The things that need to be passed in are basically just dependent on what
|
||||||
//tileset we're in, so it makes more sense to just make one variable for that, so
|
//tileset we're in, so it makes more sense to just make one variable for that, so
|
||||||
//TODO: put as much of this in the Level object definition as possible.
|
//TODO: put as much of this in the Level object definition as possible.
|
||||||
@@ -9,62 +9,134 @@ var oneone = Mario.oneone = function() {
|
|||||||
scrolling: true,
|
scrolling: true,
|
||||||
invincibility: [144, 192, 240],
|
invincibility: [144, 192, 240],
|
||||||
exit: 204,
|
exit: 204,
|
||||||
floorSprite: new Mario.Sprite('sprites/tiles.png', [0,0],[16,16],0),
|
floorSprite: new Mario.Sprite("sprites/tiles.png", [0, 0], [16, 16], 0),
|
||||||
cloudSprite: new Mario.Sprite('sprites/tiles.png', [0,320],[48,32],0),
|
cloudSprite: new Mario.Sprite("sprites/tiles.png", [0, 320], [48, 32], 0),
|
||||||
wallSprite: new Mario.Sprite('sprites/tiles.png', [0, 16],[16,16],0),
|
wallSprite: new Mario.Sprite("sprites/tiles.png", [0, 16], [16, 16], 0),
|
||||||
brickSprite: new Mario.Sprite('sprites/tiles.png', [16, 0], [16,16], 0),
|
brickSprite: new Mario.Sprite("sprites/tiles.png", [16, 0], [16, 16], 0),
|
||||||
brickBounceSprite: new Mario.Sprite('sprites/tiles.png',[32,0],[16,16],0),
|
brickBounceSprite: new Mario.Sprite(
|
||||||
|
"sprites/tiles.png",
|
||||||
|
[32, 0],
|
||||||
|
[16, 16],
|
||||||
|
0,
|
||||||
|
),
|
||||||
rubbleSprite: function () {
|
rubbleSprite: function () {
|
||||||
return new Mario.Sprite('sprites/items.png', [64,0], [8,8], 3, [0,1])
|
return new Mario.Sprite("sprites/items.png", [64, 0], [8, 8], 3, [0, 1]);
|
||||||
},
|
},
|
||||||
ublockSprite: new Mario.Sprite('sprites/tiles.png', [48, 0], [16,16],0),
|
ublockSprite: new Mario.Sprite("sprites/tiles.png", [48, 0], [16, 16], 0),
|
||||||
superShroomSprite: new Mario.Sprite('sprites/items.png', [0,0], [16,16], 0),
|
superShroomSprite: new Mario.Sprite(
|
||||||
fireFlowerSprite: new Mario.Sprite('sprites/items.png', [0,32], [16,16], 20, [0,1,2,3]),
|
"sprites/items.png",
|
||||||
starSprite: new Mario.Sprite('sprites/items.png', [0,48], [16,16], 20, [0,1,2,3]),
|
[0, 0],
|
||||||
pipeLEndSprite: new Mario.Sprite('sprites/tiles.png', [0, 128], [16,16], 0),
|
[16, 16],
|
||||||
pipeREndSprite: new Mario.Sprite('sprites/tiles.png', [16, 128], [16,16], 0),
|
0,
|
||||||
pipeLMidSprite: new Mario.Sprite('sprites/tiles.png', [0, 144], [16,16], 0),
|
),
|
||||||
pipeRMidSprite: new Mario.Sprite('sprites/tiles.png', [16, 144], [16,16], 0),
|
fireFlowerSprite: new Mario.Sprite(
|
||||||
|
"sprites/items.png",
|
||||||
|
[0, 32],
|
||||||
|
[16, 16],
|
||||||
|
20,
|
||||||
|
[0, 1, 2, 3],
|
||||||
|
),
|
||||||
|
starSprite: new Mario.Sprite(
|
||||||
|
"sprites/items.png",
|
||||||
|
[0, 48],
|
||||||
|
[16, 16],
|
||||||
|
20,
|
||||||
|
[0, 1, 2, 3],
|
||||||
|
),
|
||||||
|
pipeLEndSprite: new Mario.Sprite(
|
||||||
|
"sprites/tiles.png",
|
||||||
|
[0, 128],
|
||||||
|
[16, 16],
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
pipeREndSprite: new Mario.Sprite(
|
||||||
|
"sprites/tiles.png",
|
||||||
|
[16, 128],
|
||||||
|
[16, 16],
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
pipeLMidSprite: new Mario.Sprite(
|
||||||
|
"sprites/tiles.png",
|
||||||
|
[0, 144],
|
||||||
|
[16, 16],
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
pipeRMidSprite: new Mario.Sprite(
|
||||||
|
"sprites/tiles.png",
|
||||||
|
[16, 144],
|
||||||
|
[16, 16],
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
|
||||||
pipeUpMid: new Mario.Sprite('sprites/tiles.png', [0, 144], [32,16], 0),
|
pipeUpMid: new Mario.Sprite("sprites/tiles.png", [0, 144], [32, 16], 0),
|
||||||
pipeSideMid: new Mario.Sprite('sprites/tiles.png', [48, 128], [16,32], 0),
|
pipeSideMid: new Mario.Sprite("sprites/tiles.png", [48, 128], [16, 32], 0),
|
||||||
pipeLeft: new Mario.Sprite('sprites/tiles.png', [32, 128], [16,32], 0),
|
pipeLeft: new Mario.Sprite("sprites/tiles.png", [32, 128], [16, 32], 0),
|
||||||
pipeTop: new Mario.Sprite('sprites/tiles.png', [0, 128], [32,16], 0),
|
pipeTop: new Mario.Sprite("sprites/tiles.png", [0, 128], [32, 16], 0),
|
||||||
qblockSprite: new Mario.Sprite('sprites/tiles.png', [384, 0], [16,16], 8, [0,0,0,0,1,2,1]),
|
qblockSprite: new Mario.Sprite(
|
||||||
|
"sprites/tiles.png",
|
||||||
|
[384, 0],
|
||||||
|
[16, 16],
|
||||||
|
8,
|
||||||
|
[0, 0, 0, 0, 1, 2, 1],
|
||||||
|
),
|
||||||
bcoinSprite: function () {
|
bcoinSprite: function () {
|
||||||
return new Mario.Sprite('sprites/items.png', [0,112],[16,16], 20,[0,1,2,3]);
|
return new Mario.Sprite(
|
||||||
|
"sprites/items.png",
|
||||||
|
[0, 112],
|
||||||
|
[16, 16],
|
||||||
|
20,
|
||||||
|
[0, 1, 2, 3],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
cloudSprites: [
|
cloudSprites: [
|
||||||
new Mario.Sprite('sprites/tiles.png', [0,320],[16,32],0),
|
new Mario.Sprite("sprites/tiles.png", [0, 320], [16, 32], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [16,320],[16,32],0),
|
new Mario.Sprite("sprites/tiles.png", [16, 320], [16, 32], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [32,320],[16,32],0)
|
new Mario.Sprite("sprites/tiles.png", [32, 320], [16, 32], 0),
|
||||||
],
|
],
|
||||||
hillSprites: [
|
hillSprites: [
|
||||||
new Mario.Sprite('sprites/tiles.png', [128,128],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [128, 128], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [144,128],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [144, 128], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [160,128],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [160, 128], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [128,144],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [128, 144], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [144,144],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [144, 144], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [160,144],[16,16],0)
|
new Mario.Sprite("sprites/tiles.png", [160, 144], [16, 16], 0),
|
||||||
],
|
],
|
||||||
bushSprite: new Mario.Sprite('sprites/tiles.png', [176, 144], [48, 16], 0),
|
bushSprite: new Mario.Sprite("sprites/tiles.png", [176, 144], [48, 16], 0),
|
||||||
bushSprites: [
|
bushSprites: [
|
||||||
new Mario.Sprite('sprites/tiles.png', [176,144], [16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [176, 144], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [192,144], [16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [192, 144], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [208,144], [16,16],0)],
|
new Mario.Sprite("sprites/tiles.png", [208, 144], [16, 16], 0),
|
||||||
|
],
|
||||||
goombaSprite: function () {
|
goombaSprite: function () {
|
||||||
return new Mario.Sprite('sprites/enemy.png', [0, 16], [16,16], 3, [0,1]);
|
return new Mario.Sprite(
|
||||||
|
"sprites/enemy.png",
|
||||||
|
[0, 16],
|
||||||
|
[16, 16],
|
||||||
|
3,
|
||||||
|
[0, 1],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
koopaSprite: function () {
|
koopaSprite: function () {
|
||||||
return new Mario.Sprite('sprites/enemy.png', [96,0], [16,32], 2, [0,1]);
|
return new Mario.Sprite(
|
||||||
|
"sprites/enemy.png",
|
||||||
|
[96, 0],
|
||||||
|
[16, 32],
|
||||||
|
2,
|
||||||
|
[0, 1],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
flagPoleSprites: [
|
flagPoleSprites: [
|
||||||
new Mario.Sprite('sprites/tiles.png', [256, 128], [16,16], 0),
|
new Mario.Sprite("sprites/tiles.png", [256, 128], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [256, 144], [16,16], 0),
|
new Mario.Sprite("sprites/tiles.png", [256, 144], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/items.png', [128, 32], [16,16], 0)
|
new Mario.Sprite("sprites/items.png", [128, 32], [16, 16], 0),
|
||||||
]
|
],
|
||||||
});
|
});
|
||||||
ground = [[0,69],[71,86],[89,153],[155,212]];
|
ground = [
|
||||||
|
[0, 69],
|
||||||
|
[71, 86],
|
||||||
|
[89, 153],
|
||||||
|
[155, 212],
|
||||||
|
];
|
||||||
player.pos[0] = level.playerPos[0];
|
player.pos[0] = level.playerPos[0];
|
||||||
player.pos[1] = level.playerPos[1];
|
player.pos[1] = level.playerPos[1];
|
||||||
vX = 0;
|
vX = 0;
|
||||||
@@ -75,22 +147,41 @@ var oneone = Mario.oneone = function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//build scenery
|
//build scenery
|
||||||
clouds = [[7,3],[19, 2],[56, 3],[67, 2],[87, 2],[103, 2],[152, 3],[163, 2],[200, 3]];
|
clouds = [
|
||||||
|
[7, 3],
|
||||||
|
[19, 2],
|
||||||
|
[56, 3],
|
||||||
|
[67, 2],
|
||||||
|
[87, 2],
|
||||||
|
[103, 2],
|
||||||
|
[152, 3],
|
||||||
|
[163, 2],
|
||||||
|
[200, 3],
|
||||||
|
];
|
||||||
clouds.forEach(function (cloud) {
|
clouds.forEach(function (cloud) {
|
||||||
level.putCloud(cloud[0], cloud[1]);
|
level.putCloud(cloud[0], cloud[1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
twoClouds = [[36,2],[132,2],[180,2]];
|
twoClouds = [
|
||||||
|
[36, 2],
|
||||||
|
[132, 2],
|
||||||
|
[180, 2],
|
||||||
|
];
|
||||||
twoClouds.forEach(function (cloud) {
|
twoClouds.forEach(function (cloud) {
|
||||||
level.putTwoCloud(cloud[0], cloud[1]);
|
level.putTwoCloud(cloud[0], cloud[1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
threeClouds = [[27,3],[75,3],[123,3],[171,3]];
|
threeClouds = [
|
||||||
|
[27, 3],
|
||||||
|
[75, 3],
|
||||||
|
[123, 3],
|
||||||
|
[171, 3],
|
||||||
|
];
|
||||||
threeClouds.forEach(function (cloud) {
|
threeClouds.forEach(function (cloud) {
|
||||||
level.putThreeCloud(cloud[0], cloud[1]);
|
level.putThreeCloud(cloud[0], cloud[1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
bHills = [0,48,96,144,192]
|
bHills = [0, 48, 96, 144, 192];
|
||||||
bHills.forEach(function (hill) {
|
bHills.forEach(function (hill) {
|
||||||
level.putBigHill(hill, 12);
|
level.putBigHill(hill, 12);
|
||||||
});
|
});
|
||||||
@@ -216,4 +307,4 @@ var oneone = Mario.oneone = function() {
|
|||||||
music.underground.pause();
|
music.underground.pause();
|
||||||
// music.overworld.currentTime = 0;
|
// music.overworld.currentTime = 0;
|
||||||
music.overworld.play();
|
music.overworld.play();
|
||||||
};
|
});
|
||||||
|
|||||||
@@ -1,35 +1,65 @@
|
|||||||
var oneonetunnel = Mario.oneonetunnel = function() {
|
var oneonetunnel = (Mario.oneonetunnel = function () {
|
||||||
level = new Mario.Level({
|
level = new Mario.Level({
|
||||||
playerPos: [40, 16],
|
playerPos: [40, 16],
|
||||||
loader: Mario.oneonetunnel,
|
loader: Mario.oneonetunnel,
|
||||||
background: "#000000",
|
background: "#000000",
|
||||||
scrolling: false,
|
scrolling: false,
|
||||||
coinSprite: function () {
|
coinSprite: function () {
|
||||||
return new Mario.Sprite('sprites/items.png', [0,96],[16,16], 6,[0,0,0,0,1,2,1]);
|
return new Mario.Sprite(
|
||||||
|
"sprites/items.png",
|
||||||
|
[0, 96],
|
||||||
|
[16, 16],
|
||||||
|
6,
|
||||||
|
[0, 0, 0, 0, 1, 2, 1],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
floorSprite: new Mario.Sprite('sprites/tiles.png', [0,32],[16,16],0),
|
floorSprite: new Mario.Sprite("sprites/tiles.png", [0, 32], [16, 16], 0),
|
||||||
wallSprite: new Mario.Sprite('sprites/tiles.png', [32, 32],[16,16],0),
|
wallSprite: new Mario.Sprite("sprites/tiles.png", [32, 32], [16, 16], 0),
|
||||||
brickSprite: new Mario.Sprite('sprites/tiles.png', [16, 0], [16,16], 0),
|
brickSprite: new Mario.Sprite("sprites/tiles.png", [16, 0], [16, 16], 0),
|
||||||
brickBounceSprite: new Mario.Sprite('sprites/tiles.png',[32,0],[16,16],0),
|
brickBounceSprite: new Mario.Sprite(
|
||||||
ublockSprite: new Mario.Sprite('sprites/tiles.png', [48, 0], [16,16],0),
|
"sprites/tiles.png",
|
||||||
pipeLMidSprite: new Mario.Sprite('sprites/tiles.png', [0, 144], [16,16], 0),
|
[32, 0],
|
||||||
pipeRMidSprite: new Mario.Sprite('sprites/tiles.png', [16, 144], [16,16], 0),
|
[16, 16],
|
||||||
pipeLEndSprite: new Mario.Sprite('sprites/tiles.png', [0, 128], [16,16], 0),
|
0,
|
||||||
pipeREndSprite: new Mario.Sprite('sprites/tiles.png', [16, 128], [16,16], 0),
|
),
|
||||||
pipeUpMid: new Mario.Sprite('sprites/tiles.png', [0, 144], [32,16], 0),
|
ublockSprite: new Mario.Sprite("sprites/tiles.png", [48, 0], [16, 16], 0),
|
||||||
pipeSideMid: new Mario.Sprite('sprites/tiles.png', [48, 128], [16,32], 0),
|
pipeLMidSprite: new Mario.Sprite(
|
||||||
pipeLeft: new Mario.Sprite('sprites/tiles.png', [32, 128], [16,32], 0),
|
"sprites/tiles.png",
|
||||||
pipeTop: new Mario.Sprite('sprites/tiles.png', [0, 128], [32,16], 0),
|
[0, 144],
|
||||||
|
[16, 16],
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
pipeRMidSprite: new Mario.Sprite(
|
||||||
|
"sprites/tiles.png",
|
||||||
|
[16, 144],
|
||||||
|
[16, 16],
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
pipeLEndSprite: new Mario.Sprite(
|
||||||
|
"sprites/tiles.png",
|
||||||
|
[0, 128],
|
||||||
|
[16, 16],
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
pipeREndSprite: new Mario.Sprite(
|
||||||
|
"sprites/tiles.png",
|
||||||
|
[16, 128],
|
||||||
|
[16, 16],
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
pipeUpMid: new Mario.Sprite("sprites/tiles.png", [0, 144], [32, 16], 0),
|
||||||
|
pipeSideMid: new Mario.Sprite("sprites/tiles.png", [48, 128], [16, 32], 0),
|
||||||
|
pipeLeft: new Mario.Sprite("sprites/tiles.png", [32, 128], [16, 32], 0),
|
||||||
|
pipeTop: new Mario.Sprite("sprites/tiles.png", [0, 128], [32, 16], 0),
|
||||||
|
|
||||||
LPipeSprites: [
|
LPipeSprites: [
|
||||||
new Mario.Sprite('sprites/tiles.png', [32,128],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [32, 128], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [32,144],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [32, 144], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [48,128],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [48, 128], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [48,144],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [48, 144], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [64,128],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [64, 128], [16, 16], 0),
|
||||||
new Mario.Sprite('sprites/tiles.png', [64,144],[16,16],0),
|
new Mario.Sprite("sprites/tiles.png", [64, 144], [16, 16], 0),
|
||||||
]
|
],
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
player.pos[0] = level.playerPos[0];
|
player.pos[0] = level.playerPos[0];
|
||||||
@@ -43,9 +73,27 @@ var oneonetunnel = Mario.oneonetunnel = function() {
|
|||||||
level.putWall(loc, 3, 1);
|
level.putWall(loc, 3, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
coins = [[5,5], [6,5], [7,5], [8,5], [9,5],
|
coins = [
|
||||||
[4,7], [5,7], [6,7], [7,7], [8,7], [9,7], [10,7],
|
[5, 5],
|
||||||
[4,9], [5,9], [6,9], [7,9], [8,9], [9,9], [10,9]];
|
[6, 5],
|
||||||
|
[7, 5],
|
||||||
|
[8, 5],
|
||||||
|
[9, 5],
|
||||||
|
[4, 7],
|
||||||
|
[5, 7],
|
||||||
|
[6, 7],
|
||||||
|
[7, 7],
|
||||||
|
[8, 7],
|
||||||
|
[9, 7],
|
||||||
|
[10, 7],
|
||||||
|
[4, 9],
|
||||||
|
[5, 9],
|
||||||
|
[6, 9],
|
||||||
|
[7, 9],
|
||||||
|
[8, 9],
|
||||||
|
[9, 9],
|
||||||
|
[10, 9],
|
||||||
|
];
|
||||||
coins.forEach(function (pos) {
|
coins.forEach(function (pos) {
|
||||||
level.putCoin(pos[0], pos[1]);
|
level.putCoin(pos[0], pos[1]);
|
||||||
});
|
});
|
||||||
@@ -53,8 +101,8 @@ var oneonetunnel = Mario.oneonetunnel = function() {
|
|||||||
//level.putLeftPipe(13,11);
|
//level.putLeftPipe(13,11);
|
||||||
level.putRealPipe(13, 11, 3, "RIGHT", function () {
|
level.putRealPipe(13, 11, 3, "RIGHT", function () {
|
||||||
Mario.oneone.call();
|
Mario.oneone.call();
|
||||||
player.pos = [2616, 177]
|
player.pos = [2616, 177];
|
||||||
player.pipe("UP", function() {;});
|
player.pipe("UP", function () {});
|
||||||
});
|
});
|
||||||
|
|
||||||
level.putPipe(15, 13, 13);
|
level.putPipe(15, 13, 13);
|
||||||
@@ -62,4 +110,4 @@ var oneonetunnel = Mario.oneonetunnel = function() {
|
|||||||
music.overworld.pause();
|
music.overworld.pause();
|
||||||
music.underground.currentTime = 0;
|
music.underground.currentTime = 0;
|
||||||
music.underground.play();
|
music.underground.play();
|
||||||
};
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var Level = Mario.Level = function(options) {
|
var Level = (Mario.Level = function (options) {
|
||||||
this.playerPos = options.playerPos;
|
this.playerPos = options.playerPos;
|
||||||
this.scrolling = options.scrolling;
|
this.scrolling = options.scrolling;
|
||||||
this.loader = options.loader;
|
this.loader = options.loader;
|
||||||
@@ -55,8 +55,7 @@
|
|||||||
this.scenery[i] = [];
|
this.scenery[i] = [];
|
||||||
this.blocks[i] = [];
|
this.blocks[i] = [];
|
||||||
}
|
}
|
||||||
|
});
|
||||||
};
|
|
||||||
|
|
||||||
Level.prototype.putFloor = function (start, end) {
|
Level.prototype.putFloor = function (start, end) {
|
||||||
for (var i = start; i < end; i++) {
|
for (var i = start; i < end; i++) {
|
||||||
@@ -70,7 +69,9 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
Level.prototype.putKoopa = function (x, y) {
|
Level.prototype.putKoopa = function (x, y) {
|
||||||
this.enemies.push(new Mario.Koopa([16*x, 16*y], this.koopaSprite(), false));
|
this.enemies.push(
|
||||||
|
new Mario.Koopa([16 * x, 16 * y], this.koopaSprite(), false),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Level.prototype.putWall = function (x, y, height) {
|
Level.prototype.putWall = function (x, y, height) {
|
||||||
@@ -83,30 +84,57 @@
|
|||||||
Level.prototype.putPipe = function (x, y, height) {
|
Level.prototype.putPipe = function (x, y, height) {
|
||||||
for (var i = y - height; i < y; i++) {
|
for (var i = y - height; i < y; i++) {
|
||||||
if (i === y - height) {
|
if (i === y - height) {
|
||||||
this.statics[i][x] = new Mario.Floor([16*x, 16*i], this.pipeLEndSprite);
|
this.statics[i][x] = new Mario.Floor(
|
||||||
this.statics[i][x+1] = new Mario.Floor([16*x+16, 16*i], this.pipeREndSprite);
|
[16 * x, 16 * i],
|
||||||
|
this.pipeLEndSprite,
|
||||||
|
);
|
||||||
|
this.statics[i][x + 1] = new Mario.Floor(
|
||||||
|
[16 * x + 16, 16 * i],
|
||||||
|
this.pipeREndSprite,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.statics[i][x] = new Mario.Floor([16*x, 16*i], this.pipeLMidSprite);
|
this.statics[i][x] = new Mario.Floor(
|
||||||
this.statics[i][x+1] = new Mario.Floor([16*x+16, 16*i], this.pipeRMidSprite);
|
[16 * x, 16 * i],
|
||||||
|
this.pipeLMidSprite,
|
||||||
|
);
|
||||||
|
this.statics[i][x + 1] = new Mario.Floor(
|
||||||
|
[16 * x + 16, 16 * i],
|
||||||
|
this.pipeRMidSprite,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//sometimes, pipes don't go straight up and down.
|
//sometimes, pipes don't go straight up and down.
|
||||||
Level.prototype.putLeftPipe = function (x, y) {
|
Level.prototype.putLeftPipe = function (x, y) {
|
||||||
this.statics[y][x] = new Mario.Floor([16*x, 16*y], this.LPipeSprites[0]);
|
this.statics[y][x] = new Mario.Floor(
|
||||||
this.statics[y+1][x] = new Mario.Floor([16*x,16*(y+1)], this.LPipeSprites[1]);
|
[16 * x, 16 * y],
|
||||||
this.statics[y][x+1] = new Mario.Floor([16*(x+1),16*y], this.LPipeSprites[2]);
|
this.LPipeSprites[0],
|
||||||
this.statics[y+1][x+1] = new Mario.Floor([16*(x+1),16*(y+1)], this.LPipeSprites[3]);
|
);
|
||||||
this.statics[y][x+2] = new Mario.Floor([16*(x+2),16*y], this.LPipeSprites[4]);
|
this.statics[y + 1][x] = new Mario.Floor(
|
||||||
this.statics[y+1][x+2] = new Mario.Floor([16*(x+2),16*(y+1)], this.LPipeSprites[5]);
|
[16 * x, 16 * (y + 1)],
|
||||||
|
this.LPipeSprites[1],
|
||||||
|
);
|
||||||
|
this.statics[y][x + 1] = new Mario.Floor(
|
||||||
|
[16 * (x + 1), 16 * y],
|
||||||
|
this.LPipeSprites[2],
|
||||||
|
);
|
||||||
|
this.statics[y + 1][x + 1] = new Mario.Floor(
|
||||||
|
[16 * (x + 1), 16 * (y + 1)],
|
||||||
|
this.LPipeSprites[3],
|
||||||
|
);
|
||||||
|
this.statics[y][x + 2] = new Mario.Floor(
|
||||||
|
[16 * (x + 2), 16 * y],
|
||||||
|
this.LPipeSprites[4],
|
||||||
|
);
|
||||||
|
this.statics[y + 1][x + 2] = new Mario.Floor(
|
||||||
|
[16 * (x + 2), 16 * (y + 1)],
|
||||||
|
this.LPipeSprites[5],
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Level.prototype.putCoin = function (x, y) {
|
Level.prototype.putCoin = function (x, y) {
|
||||||
this.items.push(new Mario.Coin(
|
this.items.push(new Mario.Coin([x * 16, y * 16], this.coinSprite()));
|
||||||
[x*16, y*16],
|
|
||||||
this.coinSprite()
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Level.prototype.putCloud = function (x, y) {
|
Level.prototype.putCloud = function (x, y) {
|
||||||
@@ -118,7 +146,7 @@
|
|||||||
pos: [x * 16, y * 16],
|
pos: [x * 16, y * 16],
|
||||||
item: item,
|
item: item,
|
||||||
sprite: this.qblockSprite,
|
sprite: this.qblockSprite,
|
||||||
usedSprite: this.ublockSprite
|
usedSprite: this.ublockSprite,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -129,20 +157,33 @@
|
|||||||
sprite: this.brickSprite,
|
sprite: this.brickSprite,
|
||||||
bounceSprite: this.brickBounceSprite,
|
bounceSprite: this.brickBounceSprite,
|
||||||
usedSprite: this.ublockSprite,
|
usedSprite: this.ublockSprite,
|
||||||
breakable: !item
|
breakable: !item,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Level.prototype.putBigHill = function (x, y) {
|
Level.prototype.putBigHill = function (x, y) {
|
||||||
var px = x*16, py = y*16;
|
var px = x * 16,
|
||||||
|
py = y * 16;
|
||||||
this.scenery[y][x] = new Mario.Prop([px, py], this.hillSprites[0]);
|
this.scenery[y][x] = new Mario.Prop([px, py], this.hillSprites[0]);
|
||||||
this.scenery[y][x + 1] = new Mario.Prop([px + 16, py], this.hillSprites[3]);
|
this.scenery[y][x + 1] = new Mario.Prop([px + 16, py], this.hillSprites[3]);
|
||||||
this.scenery[y-1][x+1] = new Mario.Prop([px+16, py-16], this.hillSprites[0]);
|
this.scenery[y - 1][x + 1] = new Mario.Prop(
|
||||||
|
[px + 16, py - 16],
|
||||||
|
this.hillSprites[0],
|
||||||
|
);
|
||||||
this.scenery[y][x + 2] = new Mario.Prop([px + 32, py], this.hillSprites[4]);
|
this.scenery[y][x + 2] = new Mario.Prop([px + 32, py], this.hillSprites[4]);
|
||||||
this.scenery[y-1][x+2] = new Mario.Prop([px+32, py-16], this.hillSprites[3]);
|
this.scenery[y - 1][x + 2] = new Mario.Prop(
|
||||||
this.scenery[y-2][x+2] = new Mario.Prop([px+32, py-32], this.hillSprites[1]);
|
[px + 32, py - 16],
|
||||||
|
this.hillSprites[3],
|
||||||
|
);
|
||||||
|
this.scenery[y - 2][x + 2] = new Mario.Prop(
|
||||||
|
[px + 32, py - 32],
|
||||||
|
this.hillSprites[1],
|
||||||
|
);
|
||||||
this.scenery[y][x + 3] = new Mario.Prop([px + 48, py], this.hillSprites[5]);
|
this.scenery[y][x + 3] = new Mario.Prop([px + 48, py], this.hillSprites[5]);
|
||||||
this.scenery[y-1][x+3] = new Mario.Prop([px+48, py-16], this.hillSprites[2]);
|
this.scenery[y - 1][x + 3] = new Mario.Prop(
|
||||||
|
[px + 48, py - 16],
|
||||||
|
this.hillSprites[2],
|
||||||
|
);
|
||||||
this.scenery[y][x + 4] = new Mario.Prop([px + 64, py], this.hillSprites[2]);
|
this.scenery[y][x + 4] = new Mario.Prop([px + 64, py], this.hillSprites[2]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -170,10 +211,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
Level.prototype.putSmallHill = function (x, y) {
|
Level.prototype.putSmallHill = function (x, y) {
|
||||||
var px = x*16, py = y*16;
|
var px = x * 16,
|
||||||
|
py = y * 16;
|
||||||
this.scenery[y][x] = new Mario.Prop([px, py], this.hillSprites[0]);
|
this.scenery[y][x] = new Mario.Prop([px, py], this.hillSprites[0]);
|
||||||
this.scenery[y][x + 1] = new Mario.Prop([px + 16, py], this.hillSprites[3]);
|
this.scenery[y][x + 1] = new Mario.Prop([px + 16, py], this.hillSprites[3]);
|
||||||
this.scenery[y-1][x+1] = new Mario.Prop([px+16, py-16], this.hillSprites[1]);
|
this.scenery[y - 1][x + 1] = new Mario.Prop(
|
||||||
|
[px + 16, py - 16],
|
||||||
|
this.hillSprites[1],
|
||||||
|
);
|
||||||
this.scenery[y][x + 2] = new Mario.Prop([px + 32, py], this.hillSprites[2]);
|
this.scenery[y][x + 2] = new Mario.Prop([px + 32, py], this.hillSprites[2]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -181,38 +226,70 @@
|
|||||||
px = x * 16;
|
px = x * 16;
|
||||||
py = y * 16;
|
py = y * 16;
|
||||||
this.scenery[y][x] = new Mario.Prop([px, py], this.cloudSprites[0]);
|
this.scenery[y][x] = new Mario.Prop([px, py], this.cloudSprites[0]);
|
||||||
this.scenery[y][x+1] = new Mario.Prop([px+16, py], this.cloudSprites[1]);
|
this.scenery[y][x + 1] = new Mario.Prop(
|
||||||
this.scenery[y][x+2] = new Mario.Prop([px+32, py], this.cloudSprites[1]);
|
[px + 16, py],
|
||||||
this.scenery[y][x+3] = new Mario.Prop([px+48, py], this.cloudSprites[2]);
|
this.cloudSprites[1],
|
||||||
|
);
|
||||||
|
this.scenery[y][x + 2] = new Mario.Prop(
|
||||||
|
[px + 32, py],
|
||||||
|
this.cloudSprites[1],
|
||||||
|
);
|
||||||
|
this.scenery[y][x + 3] = new Mario.Prop(
|
||||||
|
[px + 48, py],
|
||||||
|
this.cloudSprites[2],
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Level.prototype.putThreeCloud = function (x, y) {
|
Level.prototype.putThreeCloud = function (x, y) {
|
||||||
px = x * 16;
|
px = x * 16;
|
||||||
py = y * 16;
|
py = y * 16;
|
||||||
this.scenery[y][x] = new Mario.Prop([px, py], this.cloudSprites[0]);
|
this.scenery[y][x] = new Mario.Prop([px, py], this.cloudSprites[0]);
|
||||||
this.scenery[y][x+1] = new Mario.Prop([px+16, py], this.cloudSprites[1]);
|
this.scenery[y][x + 1] = new Mario.Prop(
|
||||||
this.scenery[y][x+2] = new Mario.Prop([px+32, py], this.cloudSprites[1]);
|
[px + 16, py],
|
||||||
this.scenery[y][x+3] = new Mario.Prop([px+48, py], this.cloudSprites[1]);
|
this.cloudSprites[1],
|
||||||
this.scenery[y][x+4] = new Mario.Prop([px+64, py], this.cloudSprites[2]);
|
);
|
||||||
|
this.scenery[y][x + 2] = new Mario.Prop(
|
||||||
|
[px + 32, py],
|
||||||
|
this.cloudSprites[1],
|
||||||
|
);
|
||||||
|
this.scenery[y][x + 3] = new Mario.Prop(
|
||||||
|
[px + 48, py],
|
||||||
|
this.cloudSprites[1],
|
||||||
|
);
|
||||||
|
this.scenery[y][x + 4] = new Mario.Prop(
|
||||||
|
[px + 64, py],
|
||||||
|
this.cloudSprites[2],
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Level.prototype.putRealPipe = function(x, y, length, direction, destination) {
|
Level.prototype.putRealPipe = function (
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
length,
|
||||||
|
direction,
|
||||||
|
destination,
|
||||||
|
) {
|
||||||
px = x * 16;
|
px = x * 16;
|
||||||
py = y * 16;
|
py = y * 16;
|
||||||
this.pipes.push(new Mario.Pipe({
|
this.pipes.push(
|
||||||
|
new Mario.Pipe({
|
||||||
pos: [px, py],
|
pos: [px, py],
|
||||||
length: length,
|
length: length,
|
||||||
direction: direction,
|
direction: direction,
|
||||||
destination: destination
|
destination: destination,
|
||||||
}));
|
}),
|
||||||
}
|
);
|
||||||
|
};
|
||||||
|
|
||||||
Level.prototype.putFlagpole = function (x) {
|
Level.prototype.putFlagpole = function (x) {
|
||||||
this.statics[12][x] = new Mario.Floor([16 * x, 192], this.wallSprite);
|
this.statics[12][x] = new Mario.Floor([16 * x, 192], this.wallSprite);
|
||||||
for (i = 3; i < 12; i++) {
|
for (i = 3; i < 12; i++) {
|
||||||
this.scenery[i][x] = new Mario.Prop([16*x, 16*i], this.flagpoleSprites[1])
|
this.scenery[i][x] = new Mario.Prop(
|
||||||
|
[16 * x, 16 * i],
|
||||||
|
this.flagpoleSprites[1],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
this.scenery[2][x] = new Mario.Prop([16 * x, 32], this.flagpoleSprites[0]);
|
this.scenery[2][x] = new Mario.Prop([16 * x, 32], this.flagpoleSprites[0]);
|
||||||
this.items.push(new Mario.Flag(16 * x));
|
this.items.push(new Mario.Flag(16 * x));
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,29 +1,28 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Mushroom = Mario.Mushroom = function(pos) {
|
var Mushroom = (Mario.Mushroom = function (pos) {
|
||||||
this.spawning = false;
|
this.spawning = false;
|
||||||
this.waiting = 0;
|
this.waiting = 0;
|
||||||
|
|
||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
sprite: level.superShroomSprite,
|
sprite: level.superShroomSprite,
|
||||||
hitbox: [0,0,16,16]
|
hitbox: [0, 0, 16, 16],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Mario.Util.inherits(Mushroom, Mario.Entity);
|
Mario.Util.inherits(Mushroom, Mario.Entity);
|
||||||
|
|
||||||
Mushroom.prototype.render = function (ctx, vX, vY) {
|
Mushroom.prototype.render = function (ctx, vX, vY) {
|
||||||
if (this.spawning > 1) return;
|
if (this.spawning > 1) return;
|
||||||
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
}
|
};
|
||||||
|
|
||||||
Mushroom.prototype.spawn = function () {
|
Mushroom.prototype.spawn = function () {
|
||||||
if (player.power > 0) {
|
if (player.power > 0) {
|
||||||
//replace this with a fire flower
|
//replace this with a fire flower
|
||||||
var ff = new Mario.Fireflower(this.pos)
|
var ff = new Mario.Fireflower(this.pos);
|
||||||
ff.spawn();
|
ff.spawn();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -34,12 +33,12 @@
|
|||||||
this.targetpos = [];
|
this.targetpos = [];
|
||||||
this.targetpos[0] = this.pos[0];
|
this.targetpos[0] = this.pos[0];
|
||||||
this.targetpos[1] = this.pos[1] - 16;
|
this.targetpos[1] = this.pos[1] - 16;
|
||||||
}
|
};
|
||||||
|
|
||||||
Mushroom.prototype.update = function (dt) {
|
Mushroom.prototype.update = function (dt) {
|
||||||
if (this.spawning > 1) {
|
if (this.spawning > 1) {
|
||||||
this.spawning -= 1;
|
this.spawning -= 1;
|
||||||
if (this.spawning == 1) this.vel[1] = -.5;
|
if (this.spawning == 1) this.vel[1] = -0.5;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.spawning) {
|
if (this.spawning) {
|
||||||
@@ -62,11 +61,11 @@
|
|||||||
this.pos[1] += this.vel[1];
|
this.pos[1] += this.vel[1];
|
||||||
this.sprite.update(dt);
|
this.sprite.update(dt);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Mushroom.prototype.collideWall = function () {
|
Mushroom.prototype.collideWall = function () {
|
||||||
this.vel[0] = -this.vel[0];
|
this.vel[0] = -this.vel[0];
|
||||||
}
|
};
|
||||||
|
|
||||||
Mushroom.prototype.checkCollisions = function () {
|
Mushroom.prototype.checkCollisions = function () {
|
||||||
if (this.spawning) {
|
if (this.spawning) {
|
||||||
@@ -95,24 +94,36 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.isPlayerCollided();
|
this.isPlayerCollided();
|
||||||
}
|
};
|
||||||
|
|
||||||
//we have access to player everywhere, so let's just do this.
|
//we have access to player everywhere, so let's just do this.
|
||||||
Mushroom.prototype.isPlayerCollided = function () {
|
Mushroom.prototype.isPlayerCollided = function () {
|
||||||
//the first two elements of the hitbox array are an offset, so let's do this now.
|
//the first two elements of the hitbox array are an offset, so let's do this now.
|
||||||
var hpos1 = [this.pos[0] + this.hitbox[0], this.pos[1] + this.hitbox[1]];
|
var hpos1 = [this.pos[0] + this.hitbox[0], this.pos[1] + this.hitbox[1]];
|
||||||
var hpos2 = [player.pos[0] + player.hitbox[0], player.pos[1] + player.hitbox[1]];
|
var hpos2 = [
|
||||||
|
player.pos[0] + player.hitbox[0],
|
||||||
|
player.pos[1] + player.hitbox[1],
|
||||||
|
];
|
||||||
|
|
||||||
//if the hitboxes actually overlap
|
//if the hitboxes actually overlap
|
||||||
if (!(hpos1[0] > hpos2[0]+player.hitbox[2] || (hpos1[0]+this.hitbox[2] < hpos2[0]))) {
|
if (
|
||||||
if (!(hpos1[1] > hpos2[1]+player.hitbox[3] || (hpos1[1]+this.hitbox[3] < hpos2[1]))) {
|
!(
|
||||||
|
hpos1[0] > hpos2[0] + player.hitbox[2] ||
|
||||||
|
hpos1[0] + this.hitbox[2] < hpos2[0]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
hpos1[1] > hpos2[1] + player.hitbox[3] ||
|
||||||
|
hpos1[1] + this.hitbox[3] < hpos2[1]
|
||||||
|
)
|
||||||
|
) {
|
||||||
player.powerUp(this.idx);
|
player.powerUp(this.idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Mushroom.prototype.bump = function () {
|
Mushroom.prototype.bump = function () {
|
||||||
this.vel[1] = -2;
|
this.vel[1] = -2;
|
||||||
}
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
|
|
||||||
//there are too many possible configurations of pipe to capture in a reasonable
|
//there are too many possible configurations of pipe to capture in a reasonable
|
||||||
//set of simple variables. Joints, etc. are just too much.
|
//set of simple variables. Joints, etc. are just too much.
|
||||||
//To that end, the pipe class handles simple pipes, and we'll put together
|
//To that end, the pipe class handles simple pipes, and we'll put together
|
||||||
//anything more complex with individual props. OK? OK.
|
//anything more complex with individual props. OK? OK.
|
||||||
Pipe = Mario.Pipe = function (options) {
|
Pipe = Mario.Pipe = function (options) {
|
||||||
this.pos = options.pos
|
this.pos = options.pos;
|
||||||
|
|
||||||
//NOTE: direction is the direction you move INTO the pipe.
|
//NOTE: direction is the direction you move INTO the pipe.
|
||||||
this.direction = options.direction
|
this.direction = options.direction;
|
||||||
this.destination = options.destination
|
this.destination = options.destination;
|
||||||
this.length = options.length;
|
this.length = options.length;
|
||||||
|
|
||||||
if (this.direction === "UP" || this.direction === "DOWN") {
|
if (this.direction === "UP" || this.direction === "DOWN") {
|
||||||
@@ -24,7 +22,7 @@
|
|||||||
this.midsection = level.pipeSideMid;
|
this.midsection = level.pipeSideMid;
|
||||||
this.endsection = level.pipeLeft;
|
this.endsection = level.pipeLeft;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Pipe.prototype.checkPipe = function () {
|
Pipe.prototype.checkPipe = function () {
|
||||||
if (this.destination === undefined || !input.isDown(this.direction)) return;
|
if (this.destination === undefined || !input.isDown(this.direction)) return;
|
||||||
@@ -33,32 +31,44 @@
|
|||||||
var x = Math.floor(player.pos[0]);
|
var x = Math.floor(player.pos[0]);
|
||||||
var y = Math.floor(player.pos[1]);
|
var y = Math.floor(player.pos[1]);
|
||||||
switch (this.direction) {
|
switch (this.direction) {
|
||||||
case 'RIGHT': if (x === this.pos[0]-16 &&
|
case "RIGHT":
|
||||||
|
if (
|
||||||
|
x === this.pos[0] - 16 &&
|
||||||
y >= this.pos[1] &&
|
y >= this.pos[1] &&
|
||||||
y+h <= this.pos[1]+32) {
|
y + h <= this.pos[1] + 32
|
||||||
player.pipe(this.direction, this.destination)
|
) {
|
||||||
|
player.pipe(this.direction, this.destination);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'LEFT': if (x === this.pos[0]+16*this.length &&
|
case "LEFT":
|
||||||
|
if (
|
||||||
|
x === this.pos[0] + 16 * this.length &&
|
||||||
y >= this.pos[1] &&
|
y >= this.pos[1] &&
|
||||||
y+h <= this.pos[1]+32) {
|
y + h <= this.pos[1] + 32
|
||||||
player.pipe(this.direction, this.destination)
|
) {
|
||||||
|
player.pipe(this.direction, this.destination);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'UP': if (y === this.pos[1] + 16*this.length &&
|
case "UP":
|
||||||
|
if (
|
||||||
|
y === this.pos[1] + 16 * this.length &&
|
||||||
x >= this.pos[0] &&
|
x >= this.pos[0] &&
|
||||||
x+16 <= this.pos[0]+32) {
|
x + 16 <= this.pos[0] + 32
|
||||||
player.pipe(this.direction, this.destination)
|
) {
|
||||||
|
player.pipe(this.direction, this.destination);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'DOWN': if (y+h === this.pos[1] &&
|
case "DOWN":
|
||||||
|
if (
|
||||||
|
y + h === this.pos[1] &&
|
||||||
x >= this.pos[0] &&
|
x >= this.pos[0] &&
|
||||||
x+16 <= this.pos[0]+32) {
|
x + 16 <= this.pos[0] + 32
|
||||||
|
) {
|
||||||
player.pipe(this.direction, this.destination);
|
player.pipe(this.direction, this.destination);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
//Note to self: next time, decide on a convention for which thing checks for collisions
|
//Note to self: next time, decide on a convention for which thing checks for collisions
|
||||||
//and stick to it. This is a pain.
|
//and stick to it. This is a pain.
|
||||||
@@ -73,25 +83,40 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
fireballs.forEach(function (ent) {
|
fireballs.forEach(function (ent) {
|
||||||
that.isCollideWith(ent)
|
that.isCollideWith(ent);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!player.piping) this.isCollideWith(player);
|
if (!player.piping) this.isCollideWith(player);
|
||||||
}
|
};
|
||||||
|
|
||||||
Pipe.prototype.isCollideWith = function (ent) {
|
Pipe.prototype.isCollideWith = function (ent) {
|
||||||
//long story short: because we scan every item, and and one 'rubble' item is four things with separate positions
|
//long story short: because we scan every item, and and one 'rubble' item is four things with separate positions
|
||||||
//we'll crash without this line as soon as we destroy a block. OOPS.
|
//we'll crash without this line as soon as we destroy a block. OOPS.
|
||||||
if (ent.pos === undefined) return;
|
if (ent.pos === undefined) return;
|
||||||
|
|
||||||
|
|
||||||
//the first two elements of the hitbox array are an offset, so let's do this now.
|
//the first two elements of the hitbox array are an offset, so let's do this now.
|
||||||
var hpos1 = [Math.floor(this.pos[0] + this.hitbox[0]), Math.floor(this.pos[1] + this.hitbox[1])];
|
var hpos1 = [
|
||||||
var hpos2 = [Math.floor(ent.pos[0] + ent.hitbox[0]), Math.floor(ent.pos[1] + ent.hitbox[1])];
|
Math.floor(this.pos[0] + this.hitbox[0]),
|
||||||
|
Math.floor(this.pos[1] + this.hitbox[1]),
|
||||||
|
];
|
||||||
|
var hpos2 = [
|
||||||
|
Math.floor(ent.pos[0] + ent.hitbox[0]),
|
||||||
|
Math.floor(ent.pos[1] + ent.hitbox[1]),
|
||||||
|
];
|
||||||
|
|
||||||
//if the hitboxes actually overlap
|
//if the hitboxes actually overlap
|
||||||
if (!(hpos1[0] > hpos2[0]+ent.hitbox[2] || (hpos1[0]+this.hitbox[2] < hpos2[0]))) {
|
if (
|
||||||
if (!(hpos1[1] > hpos2[1]+ent.hitbox[3] || (hpos1[1]+this.hitbox[3] < hpos2[1]))) {
|
!(
|
||||||
|
hpos1[0] > hpos2[0] + ent.hitbox[2] ||
|
||||||
|
hpos1[0] + this.hitbox[2] < hpos2[0]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
hpos1[1] > hpos2[1] + ent.hitbox[3] ||
|
||||||
|
hpos1[1] + this.hitbox[3] < hpos2[1]
|
||||||
|
)
|
||||||
|
) {
|
||||||
//if the entity is over the block, it's basically floor
|
//if the entity is over the block, it's basically floor
|
||||||
var center = hpos2[0] + ent.hitbox[2] / 2;
|
var center = hpos2[0] + ent.hitbox[2] / 2;
|
||||||
if (Math.abs(hpos2[1] + ent.hitbox[3] - hpos1[1]) <= ent.vel[1]) {
|
if (Math.abs(hpos2[1] + ent.hitbox[3] - hpos1[1]) <= ent.vel[1]) {
|
||||||
@@ -101,8 +126,11 @@
|
|||||||
if (ent instanceof Mario.Player) {
|
if (ent instanceof Mario.Player) {
|
||||||
ent.jumping = 0;
|
ent.jumping = 0;
|
||||||
}
|
}
|
||||||
} else if (Math.abs(hpos2[1] - hpos1[1] - this.hitbox[3]) > ent.vel[1] &&
|
} else if (
|
||||||
center + 2 >= hpos1[0] && center - 2 <= hpos1[0] + this.hitbox[2]) {
|
Math.abs(hpos2[1] - hpos1[1] - this.hitbox[3]) > ent.vel[1] &&
|
||||||
|
center + 2 >= hpos1[0] &&
|
||||||
|
center - 2 <= hpos1[0] + this.hitbox[2]
|
||||||
|
) {
|
||||||
//ent is under the block.
|
//ent is under the block.
|
||||||
ent.vel[1] = 0;
|
ent.vel[1] = 0;
|
||||||
ent.pos[1] = hpos1[1] + this.hitbox[3];
|
ent.pos[1] = hpos1[1] + this.hitbox[3];
|
||||||
@@ -115,14 +143,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
//we COULD try to write some shenanigans so that the check gets put into the
|
//we COULD try to write some shenanigans so that the check gets put into the
|
||||||
//collision code, but there won't ever be more than a handful of pipes in a level
|
//collision code, but there won't ever be more than a handful of pipes in a level
|
||||||
//so the performance hit of scanning all of them is miniscule.
|
//so the performance hit of scanning all of them is miniscule.
|
||||||
Pipe.prototype.update = function (dt) {
|
Pipe.prototype.update = function (dt) {
|
||||||
if (this.destination) this.checkPipe();
|
if (this.destination) this.checkPipe();
|
||||||
}
|
};
|
||||||
|
|
||||||
//http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array
|
//http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array
|
||||||
//I honestly have no idea if javascript does this, but I feel like it makes sense
|
//I honestly have no idea if javascript does this, but I feel like it makes sense
|
||||||
@@ -134,27 +162,63 @@
|
|||||||
case "DOWN":
|
case "DOWN":
|
||||||
this.endsection.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
this.endsection.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
for (var i = 1; i < this.length; i++) {
|
for (var i = 1; i < this.length; i++) {
|
||||||
this.midsection.render(ctx, this.pos[0], this.pos[1]+i*16, vX, vY)
|
this.midsection.render(
|
||||||
|
ctx,
|
||||||
|
this.pos[0],
|
||||||
|
this.pos[1] + i * 16,
|
||||||
|
vX,
|
||||||
|
vY,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "UP":
|
case "UP":
|
||||||
this.endsection.render(ctx, this.pos[0], this.pos[1]+16*(this.length-1), vX, vY)
|
this.endsection.render(
|
||||||
|
ctx,
|
||||||
|
this.pos[0],
|
||||||
|
this.pos[1] + 16 * (this.length - 1),
|
||||||
|
vX,
|
||||||
|
vY,
|
||||||
|
);
|
||||||
for (var i = 0; i < this.length - 1; i++) {
|
for (var i = 0; i < this.length - 1; i++) {
|
||||||
this.midsection.render(ctx, this.pos[0], this.pos[1]+i*16, vX, vY)
|
this.midsection.render(
|
||||||
|
ctx,
|
||||||
|
this.pos[0],
|
||||||
|
this.pos[1] + i * 16,
|
||||||
|
vX,
|
||||||
|
vY,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "RIGHT":
|
case "RIGHT":
|
||||||
this.endsection.render(ctx, this.pos[0], this.pos[1], vX, vY)
|
this.endsection.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
for (var i = 1; i < this.length; i++) {
|
for (var i = 1; i < this.length; i++) {
|
||||||
this.midsection.render(ctx, this.pos[0]+16*i, this.pos[1], vX, vY)
|
this.midsection.render(
|
||||||
|
ctx,
|
||||||
|
this.pos[0] + 16 * i,
|
||||||
|
this.pos[1],
|
||||||
|
vX,
|
||||||
|
vY,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "LEFT":
|
case "LEFT":
|
||||||
this.endsection.render(ctx, this.pos[0]+16*(this.length-1), this.pos[1], vX, vY)
|
this.endsection.render(
|
||||||
|
ctx,
|
||||||
|
this.pos[0] + 16 * (this.length - 1),
|
||||||
|
this.pos[1],
|
||||||
|
vX,
|
||||||
|
vY,
|
||||||
|
);
|
||||||
for (var i = 0; i < this.legth - 1; i++) {
|
for (var i = 0; i < this.legth - 1; i++) {
|
||||||
this.midsection.render(ctx, this.pos[0], this.pos[1]+i*16, vX, vY)
|
this.midsection.render(
|
||||||
|
ctx,
|
||||||
|
this.pos[0],
|
||||||
|
this.pos[1] + i * 16,
|
||||||
|
vX,
|
||||||
|
vY,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Player = Mario.Player = function(pos) {
|
var Player = (Mario.Player = function (pos) {
|
||||||
//I know, I know, there are a lot of variables tracking Mario's state.
|
//I know, I know, there are a lot of variables tracking Mario's state.
|
||||||
//Maybe these can be consolidated some way? We'll see once they're all in.
|
//Maybe these can be consolidated some way? We'll see once they're all in.
|
||||||
this.power = 0;
|
this.power = 0;
|
||||||
@@ -20,10 +19,10 @@
|
|||||||
|
|
||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
sprite: new Mario.Sprite('sprites/player.png', [80,32],[16,16],0),
|
sprite: new Mario.Sprite("sprites/player.png", [80, 32], [16, 16], 0),
|
||||||
hitbox: [0,0,16,16]
|
hitbox: [0, 0, 16, 16],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
Mario.Util.inherits(Player, Mario.Entity);
|
Mario.Util.inherits(Player, Mario.Entity);
|
||||||
|
|
||||||
@@ -33,7 +32,7 @@
|
|||||||
this.shoot();
|
this.shoot();
|
||||||
}
|
}
|
||||||
this.runheld = true;
|
this.runheld = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
Player.prototype.shoot = function () {
|
Player.prototype.shoot = function () {
|
||||||
if (this.fireballs >= 2) return; //Projectile limit!
|
if (this.fireballs >= 2) return; //Projectile limit!
|
||||||
@@ -41,13 +40,13 @@
|
|||||||
var fb = new Mario.Fireball([this.pos[0] + 8, this.pos[1]]); //I hate you, Javascript.
|
var fb = new Mario.Fireball([this.pos[0] + 8, this.pos[1]]); //I hate you, Javascript.
|
||||||
fb.spawn(this.left);
|
fb.spawn(this.left);
|
||||||
this.shooting = 2;
|
this.shooting = 2;
|
||||||
}
|
};
|
||||||
|
|
||||||
Player.prototype.noRun = function () {
|
Player.prototype.noRun = function () {
|
||||||
this.maxSpeed = 1.5;
|
this.maxSpeed = 1.5;
|
||||||
this.moveAcc = 0.07;
|
this.moveAcc = 0.07;
|
||||||
this.runheld = false;
|
this.runheld = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
Player.prototype.moveRight = function () {
|
Player.prototype.moveRight = function () {
|
||||||
//we're on the ground
|
//we're on the ground
|
||||||
@@ -84,7 +83,6 @@
|
|||||||
this.vel[0] = 0;
|
this.vel[0] = 0;
|
||||||
this.acc[0] = 0;
|
this.acc[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Player.prototype.crouch = function () {
|
Player.prototype.crouch = function () {
|
||||||
@@ -94,11 +92,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.standing) this.crouching = true;
|
if (this.standing) this.crouching = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
Player.prototype.noCrouch = function () {
|
Player.prototype.noCrouch = function () {
|
||||||
this.crouching = false;
|
this.crouching = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
Player.prototype.jump = function () {
|
Player.prototype.jump = function () {
|
||||||
if (this.vel[1] > 0) {
|
if (this.vel[1] > 0) {
|
||||||
@@ -136,8 +134,7 @@
|
|||||||
|
|
||||||
if (this.starTime) {
|
if (this.starTime) {
|
||||||
var index;
|
var index;
|
||||||
if (this.starTime > 60)
|
if (this.starTime > 60) index = Math.floor(this.starTime / 2) % 3;
|
||||||
index = Math.floor(this.starTime / 2) % 3;
|
|
||||||
else index = Math.floor(this.starTime / 8) % 3;
|
else index = Math.floor(this.starTime / 8) % 3;
|
||||||
|
|
||||||
this.sprite.pos[1] = level.invincibility[index];
|
this.sprite.pos[1] = level.invincibility[index];
|
||||||
@@ -147,9 +144,15 @@
|
|||||||
this.starTime -= 1;
|
this.starTime -= 1;
|
||||||
if (this.starTime == 0) {
|
if (this.starTime == 0) {
|
||||||
switch (this.power) {
|
switch (this.power) {
|
||||||
case 0: this.sprite.pos[1] = 32; break;
|
case 0:
|
||||||
case 1: this.sprite.pos[1] = 0; break;
|
this.sprite.pos[1] = 32;
|
||||||
case 2: this.sprite.pos[1] = 96; break;
|
break;
|
||||||
|
case 1:
|
||||||
|
this.sprite.pos[1] = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.sprite.pos[1] = 96;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,7 +176,10 @@
|
|||||||
} else {
|
} else {
|
||||||
this.sprite.speed = Math.abs(this.vel[0]) * 8;
|
this.sprite.speed = Math.abs(this.vel[0]) * 8;
|
||||||
}
|
}
|
||||||
} else if ((this.vel[0] > 0 && this.left) || (this.vel[0] < 0 && !this.left)){
|
} else if (
|
||||||
|
(this.vel[0] > 0 && this.left) ||
|
||||||
|
(this.vel[0] < 0 && !this.left)
|
||||||
|
) {
|
||||||
this.sprite.pos[0] = 144;
|
this.sprite.pos[0] = 144;
|
||||||
this.sprite.speed = 0;
|
this.sprite.speed = 0;
|
||||||
}
|
}
|
||||||
@@ -196,9 +202,9 @@
|
|||||||
|
|
||||||
//which way are we facing?
|
//which way are we facing?
|
||||||
if (this.left) {
|
if (this.left) {
|
||||||
this.sprite.img = 'sprites/playerl.png';
|
this.sprite.img = "sprites/playerl.png";
|
||||||
} else {
|
} else {
|
||||||
this.sprite.img = 'sprites/player.png';
|
this.sprite.img = "sprites/player.png";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -238,7 +244,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Math.abs(this.vel[0]) > this.maxSpeed) {
|
if (Math.abs(this.vel[0]) > this.maxSpeed) {
|
||||||
this.vel[0] -= 0.05 * this.vel[0] / Math.abs(this.vel[0]);
|
this.vel[0] -= (0.05 * this.vel[0]) / Math.abs(this.vel[0]);
|
||||||
this.acc[0] = 0;
|
this.acc[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,9 +258,8 @@
|
|||||||
level.loader.call();
|
level.loader.call();
|
||||||
input.reset();
|
input.reset();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
this.acc[1] = 0.25;
|
||||||
this.acc[1] = 0.25
|
|
||||||
if (this.pos[1] > 240) {
|
if (this.pos[1] > 240) {
|
||||||
this.die();
|
this.die();
|
||||||
}
|
}
|
||||||
@@ -262,7 +267,7 @@
|
|||||||
|
|
||||||
if (this.piping) {
|
if (this.piping) {
|
||||||
this.acc = [0, 0];
|
this.acc = [0, 0];
|
||||||
var pos = [Math.round(this.pos[0]), Math.round(this.pos[1])]
|
var pos = [Math.round(this.pos[0]), Math.round(this.pos[1])];
|
||||||
if (pos[0] === this.targetPos[0] && pos[1] === this.targetPos[1]) {
|
if (pos[0] === this.targetPos[0] && pos[1] === this.targetPos[1]) {
|
||||||
this.piping = false;
|
this.piping = false;
|
||||||
this.pipeLoc.call();
|
this.pipeLoc.call();
|
||||||
@@ -318,7 +323,9 @@
|
|||||||
for (var i = 0; i < h; i++) {
|
for (var i = 0; i < h; i++) {
|
||||||
if (baseY + i < 0 || baseY + i >= 15) continue;
|
if (baseY + i < 0 || baseY + i >= 15) continue;
|
||||||
for (var j = 0; j < w; j++) {
|
for (var j = 0; j < w; j++) {
|
||||||
if (baseY < 0) { i++;}
|
if (baseY < 0) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
if (level.statics[baseY + i][baseX + j]) {
|
if (level.statics[baseY + i][baseX + j]) {
|
||||||
level.statics[baseY + i][baseX + j].isCollideWith(this);
|
level.statics[baseY + i][baseX + j].isCollideWith(this);
|
||||||
}
|
}
|
||||||
@@ -331,23 +338,41 @@
|
|||||||
|
|
||||||
Player.prototype.powerUp = function (idx) {
|
Player.prototype.powerUp = function (idx) {
|
||||||
sounds.powerup.play();
|
sounds.powerup.play();
|
||||||
this.powering = [0,5,2,5,1,5,2,5,1,5,2,5,3,5,1,5,2,5,3,5,1,5,4];
|
this.powering = [
|
||||||
|
0, 5, 2, 5, 1, 5, 2, 5, 1, 5, 2, 5, 3, 5, 1, 5, 2, 5, 3, 5, 1, 5, 4,
|
||||||
|
];
|
||||||
this.touchedItem = idx;
|
this.touchedItem = idx;
|
||||||
|
|
||||||
if (this.power === 0) {
|
if (this.power === 0) {
|
||||||
this.sprite.pos[0] = 80;
|
this.sprite.pos[0] = 80;
|
||||||
var newy = this.sprite.pos[1] - 32;
|
var newy = this.sprite.pos[1] - 32;
|
||||||
this.powerSprites = [[80, newy+32], [80, newy+32], [320, newy], [80, newy], [128, newy]];
|
this.powerSprites = [
|
||||||
this.powerSizes = [[16,16],[16,16],[16,32],[16,32],[16,32]];
|
[80, newy + 32],
|
||||||
|
[80, newy + 32],
|
||||||
|
[320, newy],
|
||||||
|
[80, newy],
|
||||||
|
[128, newy],
|
||||||
|
];
|
||||||
|
this.powerSizes = [
|
||||||
|
[16, 16],
|
||||||
|
[16, 16],
|
||||||
|
[16, 32],
|
||||||
|
[16, 32],
|
||||||
|
[16, 32],
|
||||||
|
];
|
||||||
this.shift = [0, 16, -16, 0, -16];
|
this.shift = [0, 16, -16, 0, -16];
|
||||||
this.power = 1;
|
this.power = 1;
|
||||||
this.hitbox = [0, 0, 16, 32];
|
this.hitbox = [0, 0, 16, 32];
|
||||||
} else if (this.power == 1) {
|
} else if (this.power == 1) {
|
||||||
var curx = this.sprite.pos[0];
|
var curx = this.sprite.pos[0];
|
||||||
this.powerSprites = [[curx, 96], [curx, level.invincibility[0]],
|
this.powerSprites = [
|
||||||
[curx, level.invincibility[1]], [curx, level.invincibility[2]],
|
[curx, 96],
|
||||||
[curx, 96]];
|
[curx, level.invincibility[0]],
|
||||||
this.powerSizes[[16,32],[16,32],[16,32],[16,32],[16,32]];
|
[curx, level.invincibility[1]],
|
||||||
|
[curx, level.invincibility[2]],
|
||||||
|
[curx, 96],
|
||||||
|
];
|
||||||
|
this.powerSizes[([16, 32], [16, 32], [16, 32], [16, 32], [16, 32])];
|
||||||
this.shift = [0, 0, 0, 0, 0];
|
this.shift = [0, 0, 0, 0, 0];
|
||||||
this.power = 2;
|
this.power = 2;
|
||||||
} else {
|
} else {
|
||||||
@@ -358,15 +383,29 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
Player.prototype.damage = function () {
|
Player.prototype.damage = function () {
|
||||||
if (this.power === 0) { //if you're already small, you dead!
|
if (this.power === 0) {
|
||||||
|
//if you're already small, you dead!
|
||||||
this.die();
|
this.die();
|
||||||
} else { //otherwise, you get turned into small mario
|
} else {
|
||||||
|
//otherwise, you get turned into small mario
|
||||||
sounds.pipe.play();
|
sounds.pipe.play();
|
||||||
this.powering = [0,5,1,5,2,5,1,5,2,5,1,5,2,5,1,5,2,5,1,5,2,5,3];
|
this.powering = [
|
||||||
|
0, 5, 1, 5, 2, 5, 1, 5, 2, 5, 1, 5, 2, 5, 1, 5, 2, 5, 1, 5, 2, 5, 3,
|
||||||
|
];
|
||||||
this.shift = [0, 16, -16, 16];
|
this.shift = [0, 16, -16, 16];
|
||||||
this.sprite.pos = [160, 0];
|
this.sprite.pos = [160, 0];
|
||||||
this.powerSprites = [[160,0], [240, 32], [240, 0], [160, 32]];
|
this.powerSprites = [
|
||||||
this.powerSizes = [[16, 32], [16,16], [16,32], [16,16]];
|
[160, 0],
|
||||||
|
[240, 32],
|
||||||
|
[240, 0],
|
||||||
|
[160, 32],
|
||||||
|
];
|
||||||
|
this.powerSizes = [
|
||||||
|
[16, 32],
|
||||||
|
[16, 16],
|
||||||
|
[16, 32],
|
||||||
|
[16, 16],
|
||||||
|
];
|
||||||
this.invincibility = 120;
|
this.invincibility = 120;
|
||||||
this.power = 0;
|
this.power = 0;
|
||||||
this.hitbox = [0, 0, 16, 16];
|
this.hitbox = [0, 0, 16, 16];
|
||||||
@@ -390,7 +429,8 @@
|
|||||||
this.waiting = 0.5;
|
this.waiting = 0.5;
|
||||||
this.dying = 2;
|
this.dying = 2;
|
||||||
|
|
||||||
if (this.pos[1] < 240) { //falling into a pit doesn't do the animation.
|
if (this.pos[1] < 240) {
|
||||||
|
//falling into a pit doesn't do the animation.
|
||||||
this.targetPos = [this.pos[0], this.pos[1] - 128];
|
this.targetPos = [this.pos[0], this.pos[1] - 128];
|
||||||
this.vel = [0, -5];
|
this.vel = [0, -5];
|
||||||
} else {
|
} else {
|
||||||
@@ -402,7 +442,7 @@
|
|||||||
Player.prototype.star = function (idx) {
|
Player.prototype.star = function (idx) {
|
||||||
delete level.items[idx];
|
delete level.items[idx];
|
||||||
this.starTime = 660;
|
this.starTime = 660;
|
||||||
}
|
};
|
||||||
|
|
||||||
Player.prototype.pipe = function (direction, destination) {
|
Player.prototype.pipe = function (direction, destination) {
|
||||||
sounds.pipe.play();
|
sounds.pipe.play();
|
||||||
@@ -411,29 +451,41 @@
|
|||||||
switch (direction) {
|
switch (direction) {
|
||||||
case "LEFT":
|
case "LEFT":
|
||||||
this.vel = [-1, 0];
|
this.vel = [-1, 0];
|
||||||
this.targetPos = [Math.round(this.pos[0]-16), Math.round(this.pos[1])]
|
this.targetPos = [
|
||||||
|
Math.round(this.pos[0] - 16),
|
||||||
|
Math.round(this.pos[1]),
|
||||||
|
];
|
||||||
break;
|
break;
|
||||||
case "RIGHT":
|
case "RIGHT":
|
||||||
this.vel = [1, 0];
|
this.vel = [1, 0];
|
||||||
this.targetPos = [Math.round(this.pos[0]+16), Math.round(this.pos[1])]
|
this.targetPos = [
|
||||||
|
Math.round(this.pos[0] + 16),
|
||||||
|
Math.round(this.pos[1]),
|
||||||
|
];
|
||||||
break;
|
break;
|
||||||
case "DOWN":
|
case "DOWN":
|
||||||
this.vel = [0, 1];
|
this.vel = [0, 1];
|
||||||
this.targetPos = [Math.round(this.pos[0]), Math.round(this.pos[1]+this.hitbox[3])]
|
this.targetPos = [
|
||||||
|
Math.round(this.pos[0]),
|
||||||
|
Math.round(this.pos[1] + this.hitbox[3]),
|
||||||
|
];
|
||||||
break;
|
break;
|
||||||
case "UP":
|
case "UP":
|
||||||
this.vel = [0, -1];
|
this.vel = [0, -1];
|
||||||
this.targetPos = [Math.round(this.pos[0]), Math.round(this.pos[1]-this.hitbox[3])]
|
this.targetPos = [
|
||||||
|
Math.round(this.pos[0]),
|
||||||
|
Math.round(this.pos[1] - this.hitbox[3]),
|
||||||
|
];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Player.prototype.flag = function () {
|
Player.prototype.flag = function () {
|
||||||
this.noInput = true;
|
this.noInput = true;
|
||||||
this.flagging = true;
|
this.flagging = true;
|
||||||
this.vel = [0, 2];
|
this.vel = [0, 2];
|
||||||
this.acc = [0, 0];
|
this.acc = [0, 0];
|
||||||
}
|
};
|
||||||
|
|
||||||
Player.prototype.exit = function () {
|
Player.prototype.exit = function () {
|
||||||
this.pos[0] += 16;
|
this.pos[0] += 16;
|
||||||
@@ -442,5 +494,5 @@
|
|||||||
this.setAnimation();
|
this.setAnimation();
|
||||||
this.waiting = 1;
|
this.waiting = 1;
|
||||||
this.exiting = true;
|
this.exiting = true;
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
//props do even less than entities, so they don't need to inherit really
|
//props do even less than entities, so they don't need to inherit really
|
||||||
var Prop = Mario.Prop = function(pos, sprite) {
|
var Prop = (Mario.Prop = function (pos, sprite) {
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
this.sprite = sprite;
|
this.sprite = sprite;
|
||||||
}
|
});
|
||||||
|
|
||||||
//but we will be using the same Render, more or less.
|
//but we will be using the same Render, more or less.
|
||||||
Prop.prototype.render = function (ctx, vX, vY) {
|
Prop.prototype.render = function (ctx, vX, vY) {
|
||||||
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -10,8 +10,7 @@
|
|||||||
urlOrArr.forEach(function (url) {
|
urlOrArr.forEach(function (url) {
|
||||||
_load(url);
|
_load(url);
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_load(urlOrArr);
|
_load(urlOrArr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,14 +18,15 @@
|
|||||||
function _load(url) {
|
function _load(url) {
|
||||||
if (resourceCache[url]) {
|
if (resourceCache[url]) {
|
||||||
return resourceCache[url];
|
return resourceCache[url];
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
var img = new Image();
|
var img = new Image();
|
||||||
img.onload = function () {
|
img.onload = function () {
|
||||||
resourceCache[url] = img;
|
resourceCache[url] = img;
|
||||||
|
|
||||||
if (isReady()) {
|
if (isReady()) {
|
||||||
readyCallbacks.forEach(function(func) { func(); });
|
readyCallbacks.forEach(function (func) {
|
||||||
|
func();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
resourceCache[url] = false;
|
resourceCache[url] = false;
|
||||||
@@ -41,8 +41,7 @@
|
|||||||
function isReady() {
|
function isReady() {
|
||||||
var ready = true;
|
var ready = true;
|
||||||
for (var k in resourceCache) {
|
for (var k in resourceCache) {
|
||||||
if(resourceCache.hasOwnProperty(k) &&
|
if (resourceCache.hasOwnProperty(k) && !resourceCache[k]) {
|
||||||
!resourceCache[k]) {
|
|
||||||
ready = false;
|
ready = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,6 +56,6 @@
|
|||||||
load: load,
|
load: load,
|
||||||
get: get,
|
get: get,
|
||||||
onReady: onReady,
|
onReady: onReady,
|
||||||
isReady: isReady
|
isReady: isReady,
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
//TODO: make each rubble an entity, use that render and write in Entity.update
|
//TODO: make each rubble an entity, use that render and write in Entity.update
|
||||||
var Rubble = Mario.Rubble = function() {
|
var Rubble = (Mario.Rubble = function () {
|
||||||
this.sprites = [];
|
this.sprites = [];
|
||||||
this.poss = [];
|
this.poss = [];
|
||||||
this.vels = [];
|
this.vels = [];
|
||||||
}
|
});
|
||||||
|
|
||||||
Rubble.prototype.spawn = function (pos) {
|
Rubble.prototype.spawn = function (pos) {
|
||||||
this.idx = level.items.length;
|
this.idx = level.items.length;
|
||||||
@@ -24,12 +23,12 @@
|
|||||||
this.vels[1] = [1.25, -5];
|
this.vels[1] = [1.25, -5];
|
||||||
this.vels[2] = [-1.25, -3];
|
this.vels[2] = [-1.25, -3];
|
||||||
this.vels[3] = [1.25, -3];
|
this.vels[3] = [1.25, -3];
|
||||||
}
|
};
|
||||||
|
|
||||||
Rubble.prototype.update = function (dt) {
|
Rubble.prototype.update = function (dt) {
|
||||||
for (var i = 0; i < 4; i++) {
|
for (var i = 0; i < 4; i++) {
|
||||||
if (this.sprites[i] === undefined) continue;
|
if (this.sprites[i] === undefined) continue;
|
||||||
this.vels[i][1] += .3;
|
this.vels[i][1] += 0.3;
|
||||||
this.poss[i][0] += this.vels[i][0];
|
this.poss[i][0] += this.vels[i][0];
|
||||||
this.poss[i][1] += this.vels[i][1];
|
this.poss[i][1] += this.vels[i][1];
|
||||||
this.sprites[i].update(dt);
|
this.sprites[i].update(dt);
|
||||||
@@ -37,19 +36,23 @@
|
|||||||
delete this.sprites[i];
|
delete this.sprites[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.sprites.every(function (el) {return !el})) {
|
if (
|
||||||
|
this.sprites.every(function (el) {
|
||||||
|
return !el;
|
||||||
|
})
|
||||||
|
) {
|
||||||
delete level.items[this.idx];
|
delete level.items[this.idx];
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
//You might argue that things that can't collide are more like scenery
|
//You might argue that things that can't collide are more like scenery
|
||||||
//but these move and need to be deleted, and i'd rather deal with the 1d array.
|
//but these move and need to be deleted, and i'd rather deal with the 1d array.
|
||||||
Rubble.prototype.checkCollisions = function() {;}
|
Rubble.prototype.checkCollisions = function () {};
|
||||||
|
|
||||||
Rubble.prototype.render = function () {
|
Rubble.prototype.render = function () {
|
||||||
for (var i = 0; i < 4; i++) {
|
for (var i = 0; i < 4; i++) {
|
||||||
if (this.sprites[i] === undefined) continue;
|
if (this.sprites[i] === undefined) continue;
|
||||||
this.sprites[i].render(ctx, this.poss[i][0], this.poss[i][1], vX, vY);
|
this.sprites[i].render(ctx, this.poss[i][0], this.poss[i][1], vX, vY);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Sprite = Mario.Sprite = function(img, pos, size, speed, frames, once) {
|
var Sprite = (Mario.Sprite = function (img, pos, size, speed, frames, once) {
|
||||||
this.pos = pos;
|
this.pos = pos;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.speed = speed;
|
this.speed = speed;
|
||||||
@@ -10,17 +9,17 @@
|
|||||||
this.img = img;
|
this.img = img;
|
||||||
this.once = once;
|
this.once = once;
|
||||||
this.frames = frames;
|
this.frames = frames;
|
||||||
}
|
});
|
||||||
|
|
||||||
Sprite.prototype.update = function (dt, gameTime) {
|
Sprite.prototype.update = function (dt, gameTime) {
|
||||||
if (gameTime && gameTime == this.lastUpdated) return;
|
if (gameTime && gameTime == this.lastUpdated) return;
|
||||||
this._index += this.speed * dt;
|
this._index += this.speed * dt;
|
||||||
if (gameTime) this.lastUpdated = gameTime;
|
if (gameTime) this.lastUpdated = gameTime;
|
||||||
}
|
};
|
||||||
|
|
||||||
Sprite.prototype.setFrame = function (frame) {
|
Sprite.prototype.setFrame = function (frame) {
|
||||||
this._index = frame;
|
this._index = frame;
|
||||||
}
|
};
|
||||||
|
|
||||||
Sprite.prototype.render = function (ctx, posx, posy, vX, vY) {
|
Sprite.prototype.render = function (ctx, posx, posy, vX, vY) {
|
||||||
var frame;
|
var frame;
|
||||||
@@ -42,6 +41,16 @@
|
|||||||
var y = this.pos[1];
|
var y = this.pos[1];
|
||||||
|
|
||||||
x += frame * this.size[0];
|
x += frame * this.size[0];
|
||||||
ctx.drawImage(resources.get(this.img), x + (1/3),y + (1/3), this.size[0] - (2/3), this.size[1] - (2/3), Math.round(posx - vX), Math.round(posy - vY), this.size[0],this.size[1]);
|
ctx.drawImage(
|
||||||
}
|
resources.get(this.img),
|
||||||
|
x + 1 / 3,
|
||||||
|
y + 1 / 3,
|
||||||
|
this.size[0] - 2 / 3,
|
||||||
|
this.size[1] - 2 / 3,
|
||||||
|
Math.round(posx - vX),
|
||||||
|
Math.round(posy - vY),
|
||||||
|
this.size[0],
|
||||||
|
this.size[1],
|
||||||
|
);
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined')
|
if (typeof Mario === "undefined") window.Mario = {};
|
||||||
window.Mario = {};
|
|
||||||
|
|
||||||
var Star = Mario.Star = function(pos) {
|
var Star = (Mario.Star = function (pos) {
|
||||||
this.spawning = false;
|
this.spawning = false;
|
||||||
this.waiting = 0;
|
this.waiting = 0;
|
||||||
|
|
||||||
Mario.Entity.call(this, {
|
Mario.Entity.call(this, {
|
||||||
pos: pos,
|
pos: pos,
|
||||||
sprite: level.starSprite,
|
sprite: level.starSprite,
|
||||||
hitbox: [0,0,16,16]
|
hitbox: [0, 0, 16, 16],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Mario.Util.inherits(Star, Mario.Entity);
|
Mario.Util.inherits(Star, Mario.Entity);
|
||||||
|
|
||||||
Star.prototype.render = function (ctx, vX, vY) {
|
Star.prototype.render = function (ctx, vX, vY) {
|
||||||
if (this.spawning > 1) return;
|
if (this.spawning > 1) return;
|
||||||
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
|
||||||
}
|
};
|
||||||
|
|
||||||
Star.prototype.spawn = function () {
|
Star.prototype.spawn = function () {
|
||||||
this.idx = level.items.length;
|
this.idx = level.items.length;
|
||||||
@@ -27,12 +26,12 @@
|
|||||||
this.targetpos = [];
|
this.targetpos = [];
|
||||||
this.targetpos[0] = this.pos[0];
|
this.targetpos[0] = this.pos[0];
|
||||||
this.targetpos[1] = this.pos[1] - 16;
|
this.targetpos[1] = this.pos[1] - 16;
|
||||||
}
|
};
|
||||||
|
|
||||||
Star.prototype.update = function (dt) {
|
Star.prototype.update = function (dt) {
|
||||||
if (this.spawning > 1) {
|
if (this.spawning > 1) {
|
||||||
this.spawning -= 1;
|
this.spawning -= 1;
|
||||||
if (this.spawning == 1) this.vel[1] = -.5;
|
if (this.spawning == 1) this.vel[1] = -0.5;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.spawning) {
|
if (this.spawning) {
|
||||||
@@ -60,11 +59,11 @@
|
|||||||
this.pos[1] += this.vel[1];
|
this.pos[1] += this.vel[1];
|
||||||
this.sprite.update(dt);
|
this.sprite.update(dt);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Star.prototype.collideWall = function () {
|
Star.prototype.collideWall = function () {
|
||||||
this.vel[0] = -this.vel[0];
|
this.vel[0] = -this.vel[0];
|
||||||
}
|
};
|
||||||
|
|
||||||
Star.prototype.checkCollisions = function () {
|
Star.prototype.checkCollisions = function () {
|
||||||
if (this.spawning) {
|
if (this.spawning) {
|
||||||
@@ -93,24 +92,36 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.isPlayerCollided();
|
this.isPlayerCollided();
|
||||||
}
|
};
|
||||||
|
|
||||||
//we have access to player everywhere, so let's just do this.
|
//we have access to player everywhere, so let's just do this.
|
||||||
Star.prototype.isPlayerCollided = function () {
|
Star.prototype.isPlayerCollided = function () {
|
||||||
//the first two elements of the hitbox array are an offset, so let's do this now.
|
//the first two elements of the hitbox array are an offset, so let's do this now.
|
||||||
var hpos1 = [this.pos[0] + this.hitbox[0], this.pos[1] + this.hitbox[1]];
|
var hpos1 = [this.pos[0] + this.hitbox[0], this.pos[1] + this.hitbox[1]];
|
||||||
var hpos2 = [player.pos[0] + player.hitbox[0], player.pos[1] + player.hitbox[1]];
|
var hpos2 = [
|
||||||
|
player.pos[0] + player.hitbox[0],
|
||||||
|
player.pos[1] + player.hitbox[1],
|
||||||
|
];
|
||||||
|
|
||||||
//if the hitboxes actually overlap
|
//if the hitboxes actually overlap
|
||||||
if (!(hpos1[0] > hpos2[0]+player.hitbox[2] || (hpos1[0]+this.hitbox[2] < hpos2[0]))) {
|
if (
|
||||||
if (!(hpos1[1] > hpos2[1]+player.hitbox[3] || (hpos1[1]+this.hitbox[3] < hpos2[1]))) {
|
!(
|
||||||
|
hpos1[0] > hpos2[0] + player.hitbox[2] ||
|
||||||
|
hpos1[0] + this.hitbox[2] < hpos2[0]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
hpos1[1] > hpos2[1] + player.hitbox[3] ||
|
||||||
|
hpos1[1] + this.hitbox[3] < hpos2[1]
|
||||||
|
)
|
||||||
|
) {
|
||||||
player.star(this.idx);
|
player.star(this.idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
Star.prototype.bump = function () {
|
Star.prototype.bump = function () {
|
||||||
this.vel[1] = -2;
|
this.vel[1] = -2;
|
||||||
}
|
};
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
(function () {
|
(function () {
|
||||||
if (typeof Mario === 'undefined') {
|
if (typeof Mario === "undefined") {
|
||||||
window.Mario = {};
|
window.Mario = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
var Util = Mario.Util = {};
|
var Util = (Mario.Util = {});
|
||||||
|
|
||||||
Util.inherits = function (subclass, superclass) {
|
Util.inherits = function (subclass, superclass) {
|
||||||
function Surrogate() {};
|
function Surrogate() {}
|
||||||
|
|
||||||
Surrogate.prototype = superclass.prototype;
|
Surrogate.prototype = superclass.prototype;
|
||||||
subclass.prototype = new Surrogate();
|
subclass.prototype = new Surrogate();
|
||||||
}
|
};
|
||||||
})()
|
})();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Matplotlib</title>
|
<title>Matplotlib</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
<link rel="stylesheet" href="./assets/css/examples.css" />
|
<link rel="stylesheet" href="./assets/css/examples.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Matplotlib</a>
|
<a class="title" href="" style="color: #f0ab3c">Matplotlib</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
|
|
||||||
@@ -9,7 +8,6 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<py-tutor>
|
<py-tutor>
|
||||||
<py-config>
|
<py-config>
|
||||||
packages = [
|
packages = [
|
||||||
@@ -53,7 +51,9 @@ message = np.array([1.0, 0.0, 0.0, 0.0])
|
|||||||
print(f"message: {message}")
|
print(f"message: {message}")
|
||||||
</py-script>
|
</py-script>
|
||||||
</pre>
|
</pre>
|
||||||
<p>Try out message passing below by doing any one of the following steps:</p>
|
<p>
|
||||||
|
Try out message passing below by doing any one of the following steps:
|
||||||
|
</p>
|
||||||
<pre><code>message @ adj_mat</code></pre>
|
<pre><code>message @ adj_mat</code></pre>
|
||||||
<pre><code>message @ adj_mat @ adj_mat</code></pre>
|
<pre><code>message @ adj_mat @ adj_mat</code></pre>
|
||||||
<pre><code>message @ adj_mat @ adj_mat @ adj_mat</code></pre>
|
<pre><code>message @ adj_mat @ adj_mat @ adj_mat</code></pre>
|
||||||
@@ -62,5 +62,4 @@ print(f"message: {message}")
|
|||||||
</div>
|
</div>
|
||||||
</py-tutor>
|
</py-tutor>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,19 +1,31 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
|
|
||||||
<title>micrograd</title>
|
<title>micrograd</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
|
<link
|
||||||
|
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
|
||||||
|
rel="stylesheet"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body style="padding-top: 20px; padding-right: 20px; padding-bottom: 20px; padding-left: 20px">
|
<body
|
||||||
<h1>Micrograd - A tiny Autograd engine (with a bite! :))</h1><br>
|
style="
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
padding-left: 20px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<h1>Micrograd - A tiny Autograd engine (with a bite! :))</h1>
|
||||||
|
<br />
|
||||||
|
|
||||||
<py-config>
|
<py-config>
|
||||||
packages = [
|
packages = [
|
||||||
@@ -25,167 +37,150 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<a href="https://github.com/karpathy/micrograd">Micrograd</a> is a tiny Autograd engine created
|
<a href="https://github.com/karpathy/micrograd">Micrograd</a> is a tiny
|
||||||
by <a href="https://twitter.com/karpathy">Andrej Karpathy</a>. This app recreates the
|
Autograd engine created by
|
||||||
<a href="https://github.com/karpathy/micrograd/blob/master/demo.ipynb">demo</a>
|
<a href="https://twitter.com/karpathy">Andrej Karpathy</a>. This app
|
||||||
he prepared for this package using pyscript to train a basic model, written in Python, natively in
|
recreates the
|
||||||
the browser. <br>
|
<a href="https://github.com/karpathy/micrograd/blob/master/demo.ipynb"
|
||||||
|
>demo</a
|
||||||
|
>
|
||||||
|
he prepared for this package using pyscript to train a basic model,
|
||||||
|
written in Python, natively in the browser. <br />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
You may run each Python REPL cell interactively by pressing (Shift + Enter) or (Ctrl + Enter).
|
You may run each Python REPL cell interactively by pressing (Shift +
|
||||||
You can also modify the code directly as you wish. If you want to run all the code at once,
|
Enter) or (Ctrl + Enter). You can also modify the code directly as you
|
||||||
not each cell individually, you may instead click the 'Run All' button. Training the model
|
wish. If you want to run all the code at once, not each cell
|
||||||
takes between 1-2 min if you decide to 'Run All' at once. 'Run All' is your only option if
|
individually, you may instead click the 'Run All' button. Training the
|
||||||
you are running this on a mobile device where you cannot press (Shift + Enter). After the
|
model takes between 1-2 min if you decide to 'Run All' at once. 'Run
|
||||||
model is trained, a plot image should be displayed depicting the model's ability to
|
All' is your only option if you are running this on a mobile device
|
||||||
classify the data. <br>
|
where you cannot press (Shift + Enter). After the model is trained, a
|
||||||
|
plot image should be displayed depicting the model's ability to classify
|
||||||
|
the data. <br />
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Currently the <code>></code> symbol is being imported incorrectly as <code>&gt;</code> into the REPL's.
|
Currently the <code>></code> symbol is being imported incorrectly as
|
||||||
In this app the <code>></code> symbol has been replaced with <code>().__gt__()</code> so you can run the code
|
<code>&gt;</code> into the REPL's. In this app the
|
||||||
without issue. Ex: instead of <code>a > b</code>, you will see <code>(a).__gt__(b)</code> instead. <br>
|
<code>></code> symbol has been replaced with
|
||||||
|
<code>().__gt__()</code> so you can run the code without issue. Ex:
|
||||||
|
instead of <code>a > b</code>, you will see
|
||||||
|
<code>(a).__gt__(b)</code> instead. <br />
|
||||||
</p>
|
</p>
|
||||||
<py-script>import js; js.document.getElementById('python-status').innerHTML = 'Python is now ready. You may proceed.'</py-script>
|
<py-script>
|
||||||
|
import js; js.document.getElementById('python-status').innerHTML = 'Python is now ready. You may proceed.'
|
||||||
|
</py-script>
|
||||||
<div id="python-status">Python is currently starting. Please wait...</div>
|
<div id="python-status">Python is currently starting. Please wait...</div>
|
||||||
<button id="run-all-button" class="btn btn-primary" type="submit" py-onClick="run_all_micrograd_demo()">Run All</button><br>
|
<button
|
||||||
|
id="run-all-button"
|
||||||
|
class="btn btn-primary"
|
||||||
|
type="submit"
|
||||||
|
py-onClick="run_all_micrograd_demo()"
|
||||||
|
>
|
||||||
|
Run All</button
|
||||||
|
><br />
|
||||||
<py-script src="/micrograd_ai.py"></py-script>
|
<py-script src="/micrograd_ai.py"></py-script>
|
||||||
<div id="micrograd-run-all-print-div"></div><br>
|
<div id="micrograd-run-all-print-div"></div>
|
||||||
|
<br />
|
||||||
<div id="micrograd-run-all-fig1-div"></div>
|
<div id="micrograd-run-all-fig1-div"></div>
|
||||||
<div id="micrograd-run-all-fig2-div"></div><br>
|
<div id="micrograd-run-all-fig2-div"></div>
|
||||||
|
<br />
|
||||||
</div>
|
</div>
|
||||||
<py-repl auto-generate="false">
|
<py-repl auto-generate="false">
|
||||||
import random
|
import random import numpy as np import matplotlib.pyplot as plt </py-repl
|
||||||
import numpy as np
|
><br />
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
</py-repl><br>
|
|
||||||
<py-repl auto-generate="false">
|
<py-repl auto-generate="false">
|
||||||
from micrograd.engine import Value
|
from micrograd.engine import Value from micrograd.nn import Neuron, Layer,
|
||||||
from micrograd.nn import Neuron, Layer, MLP
|
MLP </py-repl
|
||||||
</py-repl><br>
|
><br />
|
||||||
<py-repl auto-generate="true">
|
<py-repl auto-generate="true">
|
||||||
np.random.seed(1337)
|
np.random.seed(1337) random.seed(1337) </py-repl
|
||||||
random.seed(1337)
|
><br />
|
||||||
</py-repl><br>
|
|
||||||
<py-repl auto-generate="true">
|
<py-repl auto-generate="true">
|
||||||
#An adaptation of sklearn's make_moons function https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_moons.html
|
#An adaptation of sklearn's make_moons function
|
||||||
def make_moons(n_samples=100, noise=None):
|
https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_moons.html
|
||||||
n_samples_out, n_samples_in = n_samples, n_samples
|
def make_moons(n_samples=100, noise=None): n_samples_out, n_samples_in =
|
||||||
|
n_samples, n_samples outer_circ_x = np.cos(np.linspace(0, np.pi,
|
||||||
outer_circ_x = np.cos(np.linspace(0, np.pi, n_samples_out))
|
n_samples_out)) outer_circ_y = np.sin(np.linspace(0, np.pi,
|
||||||
outer_circ_y = np.sin(np.linspace(0, np.pi, n_samples_out))
|
n_samples_out)) inner_circ_x = 1 - np.cos(np.linspace(0, np.pi,
|
||||||
inner_circ_x = 1 - np.cos(np.linspace(0, np.pi, n_samples_in))
|
n_samples_in)) inner_circ_y = 1 - np.sin(np.linspace(0, np.pi,
|
||||||
inner_circ_y = 1 - np.sin(np.linspace(0, np.pi, n_samples_in)) - 0.5
|
n_samples_in)) - 0.5 X = np.vstack([np.append(outer_circ_x, inner_circ_x),
|
||||||
|
np.append(outer_circ_y, inner_circ_y)]).T y =
|
||||||
X = np.vstack([np.append(outer_circ_x, inner_circ_x), np.append(outer_circ_y, inner_circ_y)]).T
|
np.hstack([np.zeros(n_samples_out, dtype=np.intp), np.ones(n_samples_in,
|
||||||
y = np.hstack([np.zeros(n_samples_out, dtype=np.intp), np.ones(n_samples_in, dtype=np.intp)])
|
dtype=np.intp)]) if noise is not None: X += np.random.normal(loc=0.0,
|
||||||
if noise is not None: X += np.random.normal(loc=0.0, scale=noise, size=X.shape)
|
scale=noise, size=X.shape) return X, y X, y = make_moons(n_samples=100,
|
||||||
return X, y
|
noise=0.1) </py-repl
|
||||||
X, y = make_moons(n_samples=100, noise=0.1)
|
><br />
|
||||||
</py-repl><br>
|
|
||||||
<py-repl auto-generate="true">
|
<py-repl auto-generate="true">
|
||||||
y = y*2 - 1 # make y be -1 or 1
|
y = y*2 - 1 # make y be -1 or 1 # visualize in 2D
|
||||||
# visualize in 2D
|
plt.figure(figsize=(5,5)) plt.scatter(X[:,0], X[:,1], c=y, s=20,
|
||||||
plt.figure(figsize=(5,5))
|
cmap='jet') plt </py-repl
|
||||||
plt.scatter(X[:,0], X[:,1], c=y, s=20, cmap='jet')
|
><br />
|
||||||
plt
|
|
||||||
</py-repl><br>
|
|
||||||
<py-repl auto-generate="true">
|
<py-repl auto-generate="true">
|
||||||
model = MLP(2, [16, 16, 1]) # 2-layer neural network
|
model = MLP(2, [16, 16, 1]) # 2-layer neural network print(model)
|
||||||
print(model)
|
print("number of parameters", len(model.parameters())) </py-repl
|
||||||
print("number of parameters", len(model.parameters()))
|
><br />
|
||||||
</py-repl><br>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
Line 24 has been changed from: <br>
|
Line 24 has been changed from: <br />
|
||||||
<code>accuracy = [(yi > 0) == (scorei.data > 0) for yi, scorei in zip(yb, scores)]</code><br>
|
<code
|
||||||
to: <br>
|
>accuracy = [(yi > 0) == (scorei.data > 0) for yi, scorei in
|
||||||
<code>accuracy = [((yi).__gt__(0)) == ((scorei.data).__gt__(0)) for yi, scorei in zip(yb, scores)]</code><br>
|
zip(yb, scores)]</code
|
||||||
|
><br />
|
||||||
|
to: <br />
|
||||||
|
<code
|
||||||
|
>accuracy = [((yi).__gt__(0)) == ((scorei.data).__gt__(0)) for yi,
|
||||||
|
scorei in zip(yb, scores)]</code
|
||||||
|
><br />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<py-repl auto-generate="true">
|
<py-repl auto-generate="true">
|
||||||
# loss function
|
# loss function def loss(batch_size=None): # inline DataLoader :) if
|
||||||
def loss(batch_size=None):
|
batch_size is None: Xb, yb = X, y else: ri =
|
||||||
|
np.random.permutation(X.shape[0])[:batch_size] Xb, yb = X[ri], y[ri]
|
||||||
# inline DataLoader :)
|
inputs = [list(map(Value, xrow)) for xrow in Xb] # forward the model to
|
||||||
if batch_size is None:
|
get scores scores = list(map(model, inputs)) # svm "max-margin" loss
|
||||||
Xb, yb = X, y
|
|
||||||
else:
|
|
||||||
ri = np.random.permutation(X.shape[0])[:batch_size]
|
|
||||||
Xb, yb = X[ri], y[ri]
|
|
||||||
inputs = [list(map(Value, xrow)) for xrow in Xb]
|
|
||||||
|
|
||||||
# forward the model to get scores
|
|
||||||
scores = list(map(model, inputs))
|
|
||||||
|
|
||||||
# svm "max-margin" loss
|
|
||||||
losses = [(1 + -yi*scorei).relu() for yi, scorei in zip(yb, scores)]
|
losses = [(1 + -yi*scorei).relu() for yi, scorei in zip(yb, scores)]
|
||||||
data_loss = sum(losses) * (1.0 / len(losses))
|
data_loss = sum(losses) * (1.0 / len(losses)) # L2 regularization alpha =
|
||||||
# L2 regularization
|
1e-4 reg_loss = alpha * sum((p*p for p in model.parameters())) total_loss
|
||||||
alpha = 1e-4
|
= data_loss + reg_loss # also get accuracy accuracy = [((yi).__gt__(0)) ==
|
||||||
reg_loss = alpha * sum((p*p for p in model.parameters()))
|
((scorei.data).__gt__(0)) for yi, scorei in zip(yb, scores)] return
|
||||||
total_loss = data_loss + reg_loss
|
total_loss, sum(accuracy) / len(accuracy) total_loss, acc = loss()
|
||||||
|
print(total_loss, acc) </py-repl
|
||||||
# also get accuracy
|
><br />
|
||||||
accuracy = [((yi).__gt__(0)) == ((scorei.data).__gt__(0)) for yi, scorei in zip(yb, scores)]
|
|
||||||
return total_loss, sum(accuracy) / len(accuracy)
|
|
||||||
|
|
||||||
total_loss, acc = loss()
|
|
||||||
print(total_loss, acc)
|
|
||||||
</py-repl><br>
|
|
||||||
<py-repl auto-generate="true">
|
<py-repl auto-generate="true">
|
||||||
# optimization
|
# optimization for k in range(20): #was 100. Accuracy can be further
|
||||||
for k in range(20): #was 100. Accuracy can be further improved w/ more epochs (to 100%).
|
improved w/ more epochs (to 100%). # forward total_loss, acc = loss() #
|
||||||
|
backward model.zero_grad() total_loss.backward() # update (sgd)
|
||||||
# forward
|
learning_rate = 1.0 - 0.9*k/100 for p in model.parameters(): p.data -=
|
||||||
total_loss, acc = loss()
|
learning_rate * p.grad if k % 1 == 0: print(f"step {k} loss
|
||||||
|
{total_loss.data}, accuracy {acc*100}%") </py-repl
|
||||||
# backward
|
><br />
|
||||||
model.zero_grad()
|
|
||||||
total_loss.backward()
|
|
||||||
|
|
||||||
# update (sgd)
|
|
||||||
learning_rate = 1.0 - 0.9*k/100
|
|
||||||
for p in model.parameters():
|
|
||||||
p.data -= learning_rate * p.grad
|
|
||||||
|
|
||||||
if k % 1 == 0:
|
|
||||||
print(f"step {k} loss {total_loss.data}, accuracy {acc*100}%")
|
|
||||||
</py-repl><br>
|
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
Please wait for the training loop above to complete. It will not print out stats until it
|
Please wait for the training loop above to complete. It will not print
|
||||||
has completely finished. This typically takes 1-2 min. <br><br>
|
out stats until it has completely finished. This typically takes 1-2
|
||||||
|
min. <br /><br />
|
||||||
|
|
||||||
Line 9 has been changed from: <br>
|
Line 9 has been changed from: <br />
|
||||||
<code>Z = np.array([s.data > 0 for s in scores])</code><br>
|
<code>Z = np.array([s.data > 0 for s in scores])</code><br />
|
||||||
to: <br>
|
to: <br />
|
||||||
<code>Z = np.array([(s.data).__gt__(0) for s in scores])</code><br>
|
<code>Z = np.array([(s.data).__gt__(0) for s in scores])</code><br />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<py-repl auto-generate="true">
|
<py-repl auto-generate="true">
|
||||||
h = 0.25
|
h = 0.25 x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max
|
||||||
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
|
= X[:, 1].min() - 1, X[:, 1].max() + 1 xx, yy =
|
||||||
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
|
np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) Xmesh
|
||||||
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
|
= np.c_[xx.ravel(), yy.ravel()] inputs = [list(map(Value, xrow)) for xrow
|
||||||
np.arange(y_min, y_max, h))
|
in Xmesh] scores = list(map(model, inputs)) Z =
|
||||||
Xmesh = np.c_[xx.ravel(), yy.ravel()]
|
np.array([(s.data).__gt__(0) for s in scores]) Z = Z.reshape(xx.shape) fig
|
||||||
inputs = [list(map(Value, xrow)) for xrow in Xmesh]
|
= plt.figure() plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral, alpha=0.8)
|
||||||
scores = list(map(model, inputs))
|
|
||||||
Z = np.array([(s.data).__gt__(0) for s in scores])
|
|
||||||
Z = Z.reshape(xx.shape)
|
|
||||||
|
|
||||||
fig = plt.figure()
|
|
||||||
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral, alpha=0.8)
|
|
||||||
plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)
|
plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)
|
||||||
plt.xlim(xx.min(), xx.max())
|
plt.xlim(xx.min(), xx.max()) plt.ylim(yy.min(), yy.max()) plt </py-repl
|
||||||
plt.ylim(yy.min(), yy.max())
|
><br />
|
||||||
plt
|
<py-repl auto-generate="true"> 1+1 </py-repl><br />
|
||||||
</py-repl><br>
|
|
||||||
<py-repl auto-generate="true">
|
|
||||||
1+1
|
|
||||||
</py-repl><br>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
<!-- Adapted by Mat Miller -->
|
<!-- Adapted by Mat Miller -->
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Visualization of Mandelbrot, Julia and Newton sets with NumPy and HTML5 canvas</title>
|
<title>
|
||||||
<meta charset="utf-8">
|
Visualization of Mandelbrot, Julia and Newton sets with NumPy and HTML5
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
canvas
|
||||||
|
</title>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
<link rel="stylesheet" href="./assets/css/examples.css" />
|
<link rel="stylesheet" href="./assets/css/examples.css" />
|
||||||
@@ -27,19 +30,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Fractals with NumPy and canvas</a>
|
<a class="title" href="" style="color: #f0ab3c"
|
||||||
|
>Fractals with NumPy and canvas</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
<div style="display: flex; flex-direction: column; gap: 1em; width: 600px">
|
<div
|
||||||
|
style="display: flex; flex-direction: column; gap: 1em; width: 600px"
|
||||||
|
>
|
||||||
<div id="mandelbrot">
|
<div id="mandelbrot">
|
||||||
<div style="text-align: center">Mandelbrot set</div>
|
<div style="text-align: center">Mandelbrot set</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -57,25 +63,63 @@
|
|||||||
<div id="newton">
|
<div id="newton">
|
||||||
<div style="text-align: center">Newton set</div>
|
<div style="text-align: center">Newton set</div>
|
||||||
<fieldset style="display: flex; flex-direction: row; gap: 1em">
|
<fieldset style="display: flex; flex-direction: row; gap: 1em">
|
||||||
<div><span style="white-space: pre">p(z) = </span><input id="poly" type="text" value="z**3 - 2*z + 2"></div>
|
<div>
|
||||||
<div><span style="white-space: pre">a = </span><input id="coef" type="text" value="1" style="width: 40px"></div>
|
<span style="white-space: pre">p(z) = </span
|
||||||
|
><input id="poly" type="text" value="z**3 - 2*z + 2" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span style="white-space: pre">a = </span
|
||||||
|
><input id="coef" type="text" value="1" style="width: 40px" />
|
||||||
|
</div>
|
||||||
<div style="display: flex; flex-direction: row">
|
<div style="display: flex; flex-direction: row">
|
||||||
<span style="white-space: pre">x = [</span>
|
<span style="white-space: pre">x = [</span>
|
||||||
<input id="x0" type="text" value="-2.5" style="width: 80px; text-align: right">
|
<input
|
||||||
|
id="x0"
|
||||||
|
type="text"
|
||||||
|
value="-2.5"
|
||||||
|
style="width: 80px; text-align: right"
|
||||||
|
/>
|
||||||
<span style="white-space: pre">, </span>
|
<span style="white-space: pre">, </span>
|
||||||
<input id="x1" type="text" value="2.5" style="width: 80px; text-align: right">
|
<input
|
||||||
|
id="x1"
|
||||||
|
type="text"
|
||||||
|
value="2.5"
|
||||||
|
style="width: 80px; text-align: right"
|
||||||
|
/>
|
||||||
<span style="white-space: pre">]</span>
|
<span style="white-space: pre">]</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: row">
|
<div style="display: flex; flex-direction: row">
|
||||||
<span style="white-space: pre">y = [</span>
|
<span style="white-space: pre">y = [</span>
|
||||||
<input id="y0" type="text" value="-5.0" style="width: 80px; text-align: right">
|
<input
|
||||||
|
id="y0"
|
||||||
|
type="text"
|
||||||
|
value="-5.0"
|
||||||
|
style="width: 80px; text-align: right"
|
||||||
|
/>
|
||||||
<span style="white-space: pre">, </span>
|
<span style="white-space: pre">, </span>
|
||||||
<input id="y1" type="text" value="5.0" style="width: 80px; text-align: right">
|
<input
|
||||||
|
id="y1"
|
||||||
|
type="text"
|
||||||
|
value="5.0"
|
||||||
|
style="width: 80px; text-align: right"
|
||||||
|
/>
|
||||||
<span style="white-space: pre">]</span>
|
<span style="white-space: pre">]</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: row; gap: 1em">
|
<div style="display: flex; flex-direction: row; gap: 1em">
|
||||||
<div style="white-space: pre"><input type="radio" id="conv" name="type" value="convergence" checked> convergence</div>
|
<div style="white-space: pre">
|
||||||
<div style="white-space: pre"><input type="radio" id="iter" name="type" value="iterations"> iterations</div>
|
<input
|
||||||
|
type="radio"
|
||||||
|
id="conv"
|
||||||
|
name="type"
|
||||||
|
value="convergence"
|
||||||
|
checked
|
||||||
|
/>
|
||||||
|
convergence
|
||||||
|
</div>
|
||||||
|
<div style="white-space: pre">
|
||||||
|
<input type="radio" id="iter" name="type" value="iterations" />
|
||||||
|
iterations
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title id="header-title"></title>
|
<title id="header-title"></title>
|
||||||
@@ -12,12 +12,12 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" id="page-title" href="" style="color: #f0ab3c;"></a>
|
<a class="title" id="page-title" href="" style="color: #f0ab3c"></a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
@@ -26,20 +26,24 @@
|
|||||||
|
|
||||||
<div id="pandas-source">
|
<div id="pandas-source">
|
||||||
<h3>Data Source</h3>
|
<h3>Data Source</h3>
|
||||||
<input type="text" id="txt-url" class="py-input" size="70">
|
<input type="text" id="txt-url" class="py-input" size="70" />
|
||||||
<button type="submit" id="btn-load" class="py-button" py-click="loadFromURL()">Load CSV</button>
|
<button
|
||||||
|
type="submit"
|
||||||
|
id="btn-load"
|
||||||
|
class="py-button"
|
||||||
|
py-click="loadFromURL()"
|
||||||
|
>
|
||||||
|
Load CSV
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="pandas-repl" hidden>
|
<div id="pandas-repl" hidden>
|
||||||
<h3>Python REPL</h3>
|
<h3>Python REPL</h3>
|
||||||
<py-repl id="pandas-repl-inner" output="pandas-output-inner">
|
<py-repl id="pandas-repl-inner" output="pandas-output-inner">
|
||||||
# Hit SHIFT + ENTER to execute example code
|
# Hit SHIFT + ENTER to execute example code # Get all closed airports in
|
||||||
|
Great Britain df2 = df.query("type == 'closed' & iso_country == 'GB'")
|
||||||
# Get all closed airports in Great Britain
|
|
||||||
df2 = df.query("type == 'closed' & iso_country == 'GB'")
|
|
||||||
df2
|
df2
|
||||||
</py-repl>
|
</py-repl>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="pandas-output" hidden>
|
<div id="pandas-output" hidden>
|
||||||
|
|||||||
@@ -1,23 +1,35 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Panel Example</title>
|
<title>Panel Example</title>
|
||||||
<meta charset="iso-8859-1">
|
<meta charset="iso-8859-1" />
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"></script>
|
<script
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"></script>
|
type="text/javascript"
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"></script>
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@holoviz/panel@0.14.1/dist/panel.min.js"></script>
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/@holoviz/panel@0.14.1/dist/panel.min.js"
|
||||||
|
></script>
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
<link rel="stylesheet" href="./assets/css/examples.css" />
|
<link rel="stylesheet" href="./assets/css/examples.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Panel Example</a>
|
<a class="title" href="" style="color: #f0ab3c">Panel Example</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
|
|||||||
@@ -1,34 +1,88 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||||
<meta name="theme-color" content="#0072b5">
|
<meta name="theme-color" content="#0072b5" />
|
||||||
<meta name="name" content="PyScript/Panel DeckGL Demo">
|
<meta name="name" content="PyScript/Panel DeckGL Demo" />
|
||||||
|
|
||||||
<title>PyScript/Panel DeckGL Demo</title>
|
<title>PyScript/Panel DeckGL Demo</title>
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" type="text/css" />
|
<link
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/widgets.css" type="text/css" />
|
rel="stylesheet"
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/markdown.css" type="text/css" />
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/widgets.css"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/markdown.css"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
|
||||||
<script type="text/javascript" src="https://unpkg.com/h3-js@3.7.2/dist/h3-js.umd.js"></script>
|
<script
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/deck.gl@8.6.7/dist.min.js"></script>
|
type="text/javascript"
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@deck.gl/json@8.6.7/dist.min.js"></script>
|
src="https://unpkg.com/h3-js@3.7.2/dist/h3-js.umd.js"
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@loaders.gl/csv@3.1.7/dist/dist.min.js"></script>
|
></script>
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@loaders.gl/json@3.1.7/dist/dist.min.js"></script>
|
<script
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@3.1.7/dist/dist.min.js"></script>
|
type="text/javascript"
|
||||||
<script type="text/javascript" src="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.js"></script>
|
src="https://cdn.jsdelivr.net/npm/deck.gl@8.6.7/dist.min.js"
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"></script>
|
></script>
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"></script>
|
<script
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"></script>
|
type="text/javascript"
|
||||||
<script type="text/javascript" src="https://unpkg.com/@holoviz/panel@0.13.1/dist/panel.js"></script>
|
src="https://cdn.jsdelivr.net/npm/@deck.gl/json@8.6.7/dist.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/@loaders.gl/csv@3.1.7/dist/dist.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/@loaders.gl/json@3.1.7/dist/dist.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/@loaders.gl/3d-tiles@3.1.7/dist/dist.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://unpkg.com/@holoviz/panel@0.13.1/dist/panel.js"
|
||||||
|
></script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
|
<link
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/bootstraptemplate/bootstrap.css">
|
rel="stylesheet"
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/defaulttheme/default.css">
|
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/bootstraptemplate/bootstrap.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/defaulttheme/default.css"
|
||||||
|
/>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
@@ -44,12 +98,14 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Panel DeckGL NYC Taxi Demo</a>
|
<a class="title" href="" style="color: #f0ab3c"
|
||||||
|
>Panel DeckGL NYC Taxi Demo</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
@@ -221,6 +277,5 @@
|
|||||||
</py-script>
|
</py-script>
|
||||||
</py-tutor>
|
</py-tutor>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,34 +1,79 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||||
<meta name="theme-color" content="#000000">
|
<meta name="theme-color" content="#000000" />
|
||||||
<meta name="name" content="PyScript/Panel KMeans Demo">
|
<meta name="name" content="PyScript/Panel KMeans Demo" />
|
||||||
|
|
||||||
<title>Pyscript/Panel KMeans Demo</title>
|
<title>Pyscript/Panel KMeans Demo</title>
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" type="text/css" />
|
<link
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/widgets.css" type="text/css" />
|
rel="stylesheet"
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/markdown.css" type="text/css" />
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/widgets.css"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/markdown.css"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@5"></script>
|
<script
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
|
type="text/javascript"
|
||||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
|
src="https://cdn.jsdelivr.net/npm/vega@5"
|
||||||
<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.9.3/dist/js/tabulator.js"></script>
|
></script>
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"></script>
|
<script
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"></script>
|
type="text/javascript"
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"></script>
|
src="https://cdn.jsdelivr.net/npm/vega-lite@5"
|
||||||
<script type="text/javascript" src="https://unpkg.com/@holoviz/panel@0.13.1/dist/panel.min.js"></script>
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/vega-embed@6"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://unpkg.com/tabulator-tables@4.9.3/dist/js/tabulator.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://unpkg.com/@holoviz/panel@0.13.1/dist/panel.min.js"
|
||||||
|
></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
Bokeh.set_log_level("info");
|
Bokeh.set_log_level("info");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
|
<link
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/bootstraptemplate/bootstrap.css">
|
rel="stylesheet"
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/defaulttheme/default.css">
|
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/bootstraptemplate/bootstrap.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/defaulttheme/default.css"
|
||||||
|
/>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#sidebar {
|
#sidebar {
|
||||||
@@ -45,12 +90,14 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Panel KMeans Clustering Demo</a>
|
<a class="title" href="" style="color: #f0ab3c"
|
||||||
|
>Panel KMeans Clustering Demo</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
@@ -163,11 +210,15 @@
|
|||||||
</section>
|
</section>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('#sidebarCollapse').on('click', function () {
|
$("#sidebarCollapse").on("click", function () {
|
||||||
$('#sidebar').toggleClass('active')
|
$("#sidebar").toggleClass("active");
|
||||||
$(this).toggleClass('active')
|
$(this).toggleClass("active");
|
||||||
var interval = setInterval(function () { window.dispatchEvent(new Event('resize')); }, 10);
|
var interval = setInterval(function () {
|
||||||
setTimeout(function () { clearInterval(interval) }, 210)
|
window.dispatchEvent(new Event("resize"));
|
||||||
|
}, 10);
|
||||||
|
setTimeout(function () {
|
||||||
|
clearInterval(interval);
|
||||||
|
}, 210);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,31 +1,67 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||||
<meta name="theme-color" content="#000000">
|
<meta name="theme-color" content="#000000" />
|
||||||
<meta name="name" content="PyScript/Panel Streaming Demo">
|
<meta name="name" content="PyScript/Panel Streaming Demo" />
|
||||||
|
|
||||||
<title>PyScript/Panel Streaming Demo</title>
|
<title>PyScript/Panel Streaming Demo</title>
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.ico">
|
<link rel="icon" type="image/x-icon" href="./favicon.ico" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" type="text/css" />
|
<link
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/widgets.css" type="text/css" />
|
rel="stylesheet"
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/markdown.css" type="text/css" />
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/widgets.css"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/css/markdown.css"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
|
||||||
<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.9.3/dist/js/tabulator.js"></script>
|
<script
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"></script>
|
type="text/javascript"
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"></script>
|
src="https://unpkg.com/tabulator-tables@4.9.3/dist/js/tabulator.js"
|
||||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"></script>
|
></script>
|
||||||
<script type="text/javascript" src="https://unpkg.com/@holoviz/panel@0.13.1/dist/panel.min.js"></script>
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"
|
||||||
|
></script>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://unpkg.com/@holoviz/panel@0.13.1/dist/panel.min.js"
|
||||||
|
></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
Bokeh.set_log_level("info");
|
Bokeh.set_log_level("info");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css">
|
<link
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/bootstraptemplate/bootstrap.css">
|
rel="stylesheet"
|
||||||
<link rel="stylesheet" href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/defaulttheme/default.css">
|
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/bootstraptemplate/bootstrap.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://unpkg.com/@holoviz/panel@0.13.1/dist/bundled/defaulttheme/default.css"
|
||||||
|
/>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
@@ -36,12 +72,12 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Panel Streaming Demo</a>
|
<a class="title" href="" style="color: #f0ab3c">Panel Streaming Demo</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#output > div {
|
#output > div {
|
||||||
font-family: 'monospace';
|
font-family: "monospace";
|
||||||
background-color: #e5e5e5;
|
background-color: #e5e5e5;
|
||||||
border: 1px solid lightgray;
|
border: 1px solid lightgray;
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -13,18 +13,18 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">PyScript REPL</a>
|
<a class="title" href="" style="color: #f0ab3c">PyScript REPL</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
<h1><b>PyScript REPL</b></h1>
|
<h1><b>PyScript REPL</b></h1>
|
||||||
Tip: press Shift-ENTER to evaluate a cell
|
Tip: press Shift-ENTER to evaluate a cell
|
||||||
<br>
|
<br />
|
||||||
<py-tutor modules="antigravity.py">
|
<py-tutor modules="antigravity.py">
|
||||||
<py-config>
|
<py-config>
|
||||||
plugins = [
|
plugins = [
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
[[fetch]]
|
[[fetch]]
|
||||||
files = ["./antigravity.py"]
|
files = ["./antigravity.py"]
|
||||||
</py-config>
|
</py-config>
|
||||||
<div style="margin-right: 3rem;">
|
<div style="margin-right: 3rem">
|
||||||
<py-repl id="my-repl" auto-generate="true"> </py-repl>
|
<py-repl id="my-repl" auto-generate="true"> </py-repl>
|
||||||
</div>
|
</div>
|
||||||
</py-tutor>
|
</py-tutor>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -14,12 +14,12 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Custom REPL</a>
|
<a class="title" href="" style="color: #f0ab3c">Custom REPL</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
[[fetch]]
|
[[fetch]]
|
||||||
files = ["./utils.py", "./antigravity.py"]
|
files = ["./utils.py", "./antigravity.py"]
|
||||||
</py-config>
|
</py-config>
|
||||||
<div style="margin-right: 3rem;">
|
<div style="margin-right: 3rem">
|
||||||
<py-repl id="my-repl" auto-generate="true"> </py-repl>
|
<py-repl id="my-repl" auto-generate="true"> </py-repl>
|
||||||
<div id="output" class="p-4"></div>
|
<div id="output" class="p-4"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,29 +1,42 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8'>
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<title>PyScript — Simple Bioinformatics Example</title>
|
<title>PyScript — Simple Bioinformatics Example</title>
|
||||||
<link rel="icon" type="image/x-icon" href="./favicon.png">
|
<link rel="icon" type="image/x-icon" href="./favicon.png" />
|
||||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<link rel='stylesheet' type='text/css' media='screen' href='https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css'>
|
<link
|
||||||
<link rel="icon" type="image/png" href="https://user-images.githubusercontent.com/49681382/166738771-d0c26557-426c-4688-9641-8db5e6b08348.png" />
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
media="screen"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="https://user-images.githubusercontent.com/49681382/166738771-d0c26557-426c-4688-9641-8db5e6b08348.png"
|
||||||
|
/>
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<section class="hero is-primary is-small">
|
<section class="hero is-primary is-small">
|
||||||
<div class="hero-body">
|
<div class="hero-body">
|
||||||
<p class="title is-3">PyScript — Simple Bioinformatics Example <span class="tag is-white">v.1</span></p>
|
<p class="title is-3">
|
||||||
|
PyScript — Simple Bioinformatics Example
|
||||||
|
<span class="tag is-white">v.1</span>
|
||||||
|
</p>
|
||||||
<p class="subtitle is-6">
|
<p class="subtitle is-6">
|
||||||
Demonstrates the simple use of <a href="https://pyscript.net/" target="_blank"><code>PyScript</code></a>
|
Demonstrates the simple use of
|
||||||
|
<a href="https://pyscript.net/" target="_blank"
|
||||||
|
><code>PyScript</code></a
|
||||||
|
>
|
||||||
in <strong>Bioinformatics/Computational Biology</strong> fields!
|
in <strong>Bioinformatics/Computational Biology</strong> fields!
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- Main Content -->
|
||||||
<div class="container is-white is-fluid" style="margin-top: 45px">
|
<div class="container is-white is-fluid" style="margin-top: 45px">
|
||||||
<p class="title is-3">🧬 DNA Sequence Tool</p>
|
<p class="title is-3">🧬 DNA Sequence Tool</p>
|
||||||
@@ -32,7 +45,11 @@
|
|||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Input DNA Sequence</label>
|
<label class="label">Input DNA Sequence</label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<textarea class="textarea" placeholder="GATTACA" id="dna_seq"></textarea>
|
<textarea
|
||||||
|
class="textarea"
|
||||||
|
placeholder="GATTACA"
|
||||||
|
id="dna_seq"
|
||||||
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -43,35 +60,62 @@
|
|||||||
<div class="select is-fullwidth">
|
<div class="select is-fullwidth">
|
||||||
<select name="operation" id="operation">
|
<select name="operation" id="operation">
|
||||||
<option value="Reverse">Compute the reverse counterpart</option>
|
<option value="Reverse">Compute the reverse counterpart</option>
|
||||||
<option value="Complement">Compute the complement counterpart</option>
|
<option value="Complement">
|
||||||
<option value="ReverseComplement">Compute the reverse complement counterpart</option>
|
Compute the complement counterpart
|
||||||
|
</option>
|
||||||
|
<option value="ReverseComplement">
|
||||||
|
Compute the reverse complement counterpart
|
||||||
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<button id="run" type="button" class="button is-primary" py-onClick="run()">Run!</button>
|
<button
|
||||||
<button id="clear" type="button" class="button is-danger" py-onClick="clear()">Clear</button>
|
id="run"
|
||||||
|
type="button"
|
||||||
|
class="button is-primary"
|
||||||
|
py-onClick="run()"
|
||||||
|
>
|
||||||
|
Run!
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
id="clear"
|
||||||
|
type="button"
|
||||||
|
class="button is-danger"
|
||||||
|
py-onClick="clear()"
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr />
|
||||||
|
|
||||||
<!--- DNA Sequence Output -->
|
<!--- DNA Sequence Output -->
|
||||||
<label class="label">Output for the <code id="operation_name_output">given operation</code></label>
|
<label class="label"
|
||||||
|
>Output for the
|
||||||
|
<code id="operation_name_output">given operation</code></label
|
||||||
|
>
|
||||||
<div id="output"></div>
|
<div id="output"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br><br>
|
<br /><br />
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="content has-text-centered">
|
<div class="content has-text-centered">
|
||||||
<p>
|
<p>
|
||||||
Developed by <a href="mailto:furkanmtorun@gmail.com"><strong>Furkan M. Torun (@furkanmtorun)</strong></a>
|
Developed by
|
||||||
<br>
|
<a href="mailto:furkanmtorun@gmail.com"
|
||||||
|
><strong>Furkan M. Torun (@furkanmtorun)</strong></a
|
||||||
|
>
|
||||||
|
<br />
|
||||||
<a href="https://github.com/furkanmtorun">GitHub</a>
|
<a href="https://github.com/furkanmtorun">GitHub</a>
|
||||||
| <a href="https://scholar.google.com/citations?user=d5ZyOZ4AAAAJ">Google Scholar</a>
|
|
|
||||||
| <a href="https://twitter.com/furkanmtorun">Twitter</a>
|
<a href="https://scholar.google.com/citations?user=d5ZyOZ4AAAAJ"
|
||||||
| <a href="https://www.linkedin.com/in/furkanmtorun/">LinkedIn</a>
|
>Google Scholar</a
|
||||||
|
>
|
||||||
|
| <a href="https://twitter.com/furkanmtorun">Twitter</a> |
|
||||||
|
<a href="https://www.linkedin.com/in/furkanmtorun/">LinkedIn</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -124,6 +168,5 @@ def run(*args, **kwargs):
|
|||||||
else:
|
else:
|
||||||
output.write("Invalid DNA sequence entered")
|
output.write("Invalid DNA sequence entered")
|
||||||
</py-script>
|
</py-script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -14,12 +14,12 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Simple Clock</a>
|
<a class="title" href="" style="color: #f0ab3c">Simple Clock</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -13,18 +13,24 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Pyscript Native TODO App</a>
|
<a class="title" href="" style="color: #f0ab3c"
|
||||||
|
>Pyscript Native TODO App</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
<h1>To Do List</h1>
|
<h1>To Do List</h1>
|
||||||
<py-tutor modules="utils.py;pylist.py">
|
<py-tutor modules="utils.py;pylist.py">
|
||||||
<py-register-widget src="./pylist.py" name="py-list" klass="PyList"></py-register-widget>
|
<py-register-widget
|
||||||
|
src="./pylist.py"
|
||||||
|
name="py-list"
|
||||||
|
klass="PyList"
|
||||||
|
></py-register-widget>
|
||||||
|
|
||||||
<py-config>
|
<py-config>
|
||||||
plugins = [
|
plugins = [
|
||||||
@@ -62,11 +68,12 @@
|
|||||||
"keypress",
|
"keypress",
|
||||||
handle_keypress
|
handle_keypress
|
||||||
)
|
)
|
||||||
|
|
||||||
</py-script>
|
</py-script>
|
||||||
<div class="py-box">
|
<div class="py-box">
|
||||||
<input id="new-task-content" />
|
<input id="new-task-content" />
|
||||||
<button py-click="add_task()" id="new-task-btn" class="py-button">Add Task!</button>
|
<button py-click="add_task()" id="new-task-btn" class="py-button">
|
||||||
|
Add Task!
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<py-list id="myList"></py-list>
|
<py-list id="myList"></py-list>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -14,12 +14,12 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar" style="background-color: #000000;">
|
<nav class="navbar" style="background-color: #000000">
|
||||||
<div class="app-header">
|
<div class="app-header">
|
||||||
<a href="/">
|
<a href="/">
|
||||||
<img src="./logo.png" class="logo">
|
<img src="./logo.png" class="logo" />
|
||||||
</a>
|
</a>
|
||||||
<a class="title" href="" style="color: #f0ab3c;">Todo App</a>
|
<a class="title" href="" style="color: #f0ab3c">Todo App</a>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<section class="pyscript">
|
<section class="pyscript">
|
||||||
@@ -36,24 +36,35 @@
|
|||||||
</py-tutor>
|
</py-tutor>
|
||||||
<main>
|
<main>
|
||||||
<section>
|
<section>
|
||||||
|
|
||||||
<div class="text-center w-full mb-8">
|
<div class="text-center w-full mb-8">
|
||||||
<h1 class="text-3xl font-bold text-gray-800 uppercase tracking-tight">To Do List</h1>
|
<h1
|
||||||
|
class="text-3xl font-bold text-gray-800 uppercase tracking-tight"
|
||||||
|
>
|
||||||
|
To Do List
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input id="new-task-content" class="py-input" type="text">
|
<input id="new-task-content" class="py-input" type="text" />
|
||||||
<button id="new-task-btn" class="py-button" type="submit" py-click="add_task()">
|
<button
|
||||||
|
id="new-task-btn"
|
||||||
|
class="py-button"
|
||||||
|
type="submit"
|
||||||
|
py-click="add_task()"
|
||||||
|
>
|
||||||
Add task
|
Add task
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<py-list id="myList"></py-list>
|
<py-list id="myList"></py-list>
|
||||||
<div id="list-tasks-container" class="flex flex-col-reverse mt-4"></div>
|
<div
|
||||||
|
id="list-tasks-container"
|
||||||
|
class="flex flex-col-reverse mt-4"
|
||||||
|
></div>
|
||||||
|
|
||||||
<template id="task-template">
|
<template id="task-template">
|
||||||
<section class="task py-li-element">
|
<section class="task py-li-element">
|
||||||
<label for="flex items-center p-2 ">
|
<label for="flex items-center p-2 ">
|
||||||
<input class="mr-2" type="checkbox">
|
<input class="mr-2" type="checkbox" />
|
||||||
<p class="m-0 inline"></p>
|
<p class="m-0 inline"></p>
|
||||||
</label>
|
</label>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||||
|
/>
|
||||||
<title>Freedom Units</title>
|
<title>Freedom Units</title>
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="/static/logo-32.png" />
|
<link rel="icon" type="image/png" href="/static/logo-32.png" />
|
||||||
@@ -10,23 +13,28 @@
|
|||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
|
|
||||||
|
<link
|
||||||
<link rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
|
href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
|
||||||
integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N"
|
integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N"
|
||||||
crossorigin="anonymous">
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/css/briefcase.css">
|
<link rel="stylesheet" href="/static/css/briefcase.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app-placeholder"></div>
|
<div id="app-placeholder"></div>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"
|
<script
|
||||||
|
src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"
|
||||||
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
|
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
|
||||||
crossorigin="anonymous"></script>
|
crossorigin="anonymous"
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"
|
></script>
|
||||||
|
<script
|
||||||
|
src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"
|
||||||
integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct"
|
integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct"
|
||||||
crossorigin="anonymous"></script>
|
crossorigin="anonymous"
|
||||||
|
></script>
|
||||||
|
|
||||||
<py-config>
|
<py-config>
|
||||||
name = "Freedom Units"
|
name = "Freedom Units"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
/* Unset the overly generic pyscript .label style */
|
/* Unset the overly generic pyscript .label style */
|
||||||
#app-placeholder .label {
|
#app-placeholder .label {
|
||||||
margin-top: inherit;
|
margin-top: inherit;
|
||||||
@@ -9,7 +8,6 @@
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
margin-top: inherit;
|
margin-top: inherit;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<title>Raycaster</title>
|
<title>Raycaster</title>
|
||||||
<link rel="icon" type="image/png" href="../favicon.png" />
|
<link rel="icon" type="image/png" href="../favicon.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<link rel="stylesheet" href="./style.css">
|
<link rel="stylesheet" href="./style.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container-fluid fixed-top header disable-selection">
|
<div class="container-fluid fixed-top header disable-selection">
|
||||||
@@ -13,14 +13,13 @@
|
|||||||
<div class="col"></div>
|
<div class="col"></div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col"></div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col"></div>
|
<div class="col"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/0.147.0/three.min.js'></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.147.0/three.min.js"></script>
|
||||||
|
|
||||||
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
|
||||||
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
|
||||||
@@ -188,7 +187,6 @@ async def main():
|
|||||||
await asyncio.sleep(0.02)
|
await asyncio.sleep(0.02)
|
||||||
|
|
||||||
asyncio.ensure_future(main())
|
asyncio.ensure_future(main())
|
||||||
|
|
||||||
</py-script>
|
</py-script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ canvas {
|
|||||||
.header {
|
.header {
|
||||||
/*top:45%;*/
|
/*top:45%;*/
|
||||||
top: 45%;
|
top: 45%;
|
||||||
color: #DDDDDD;
|
color: #dddddd;
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
bottom: 3%;
|
bottom: 3%;
|
||||||
@@ -25,7 +25,9 @@ canvas {
|
|||||||
border-radius: 30px;
|
border-radius: 30px;
|
||||||
padding: 10px 30px;
|
padding: 10px 30px;
|
||||||
}
|
}
|
||||||
a, a:hover, a:visited {
|
a,
|
||||||
|
a:hover,
|
||||||
|
a:visited {
|
||||||
color: red;
|
color: red;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
@@ -37,7 +39,7 @@ a, a:hover, a:visited {
|
|||||||
-webkit-touch-callout: none; /* Disable Android and iOS callouts*/
|
-webkit-touch-callout: none; /* Disable Android and iOS callouts*/
|
||||||
}
|
}
|
||||||
h1::after {
|
h1::after {
|
||||||
content: ' V 2.0';
|
content: " V 2.0";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 3px;
|
top: 3px;
|
||||||
@@ -45,7 +47,7 @@ h1::after {
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
h2::after {
|
h2::after {
|
||||||
content: '2';
|
content: "2";
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 14px;
|
top: 14px;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
module.exports = "";
|
module.exports = '';
|
||||||
|
|||||||
@@ -13,4 +13,4 @@
|
|||||||
console.warn(`.py files that are not explicitly mocked in \
|
console.warn(`.py files that are not explicitly mocked in \
|
||||||
jest.config.js and /__mocks__/ are mocked as empty strings`);
|
jest.config.js and /__mocks__/ are mocked as empty strings`);
|
||||||
|
|
||||||
module.exports = "";
|
module.exports = '';
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ module.exports = {
|
|||||||
url: 'http://localhost',
|
url: 'http://localhost',
|
||||||
},
|
},
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
'^.*?pyscript\.py$': '<rootDir>/__mocks__/_pyscript.js',
|
'^.*?pyscript.py$': '<rootDir>/__mocks__/_pyscript.js',
|
||||||
'^[./a-zA-Z0-9$_-]+\\.py$': '<rootDir>/__mocks__/fileMock.js',
|
'^[./a-zA-Z0-9$_-]+\\.py$': '<rootDir>/__mocks__/fileMock.js',
|
||||||
'\\.(css)$': '<rootDir>/__mocks__/cssMock.js',
|
'\\.(css)$': '<rootDir>/__mocks__/cssMock.js',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<link rel="stylesheet" href="https://unpkg.com/mvp.css@1.12/mvp.css">
|
<link rel="stylesheet" href="https://unpkg.com/mvp.css@1.12/mvp.css" />
|
||||||
<link rel="stylesheet" href="pyscript.css">
|
<link rel="stylesheet" href="pyscript.css" />
|
||||||
<script defer src="pyscript.min.js"></script>
|
<script defer src="pyscript.min.js"></script>
|
||||||
<title>PyScript</title>
|
<title>PyScript</title>
|
||||||
</head>
|
</head>
|
||||||
@@ -28,7 +27,8 @@
|
|||||||
</py-script>
|
</py-script>
|
||||||
|
|
||||||
<h2>Example</h2>
|
<h2>Example</h2>
|
||||||
<pre style="padding:1em;border:1px solid #000000;"><!DOCTYPE html>
|
<pre style="padding: 1em; border: 1px solid #000000">
|
||||||
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@@ -47,8 +47,8 @@ now = datetime.now()
|
|||||||
now.strftime("%m/%d/%Y, %H:%M:%S")
|
now.strftime("%m/%d/%Y, %H:%M:%S")
|
||||||
</py-script>
|
</py-script>
|
||||||
</body>
|
</body>
|
||||||
</html></pre>
|
</html></pre
|
||||||
|
>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
import commonjs from "@rollup/plugin-commonjs";
|
import commonjs from '@rollup/plugin-commonjs';
|
||||||
import resolve from "@rollup/plugin-node-resolve";
|
import resolve from '@rollup/plugin-node-resolve';
|
||||||
import { terser } from "rollup-plugin-terser";
|
import { terser } from 'rollup-plugin-terser';
|
||||||
import legacy from '@rollup/plugin-legacy';
|
import legacy from '@rollup/plugin-legacy';
|
||||||
import typescript from "@rollup/plugin-typescript";
|
import typescript from '@rollup/plugin-typescript';
|
||||||
import css from "rollup-plugin-css-only";
|
import css from 'rollup-plugin-css-only';
|
||||||
import serve from "rollup-plugin-serve";
|
import serve from 'rollup-plugin-serve';
|
||||||
import { string } from "rollup-plugin-string";
|
import { string } from 'rollup-plugin-string';
|
||||||
import copy from 'rollup-plugin-copy'
|
import copy from 'rollup-plugin-copy';
|
||||||
|
|
||||||
const production = !process.env.ROLLUP_WATCH || (process.env.NODE_ENV === "production");
|
const production = !process.env.ROLLUP_WATCH || process.env.NODE_ENV === 'production';
|
||||||
|
|
||||||
const copy_targets = {
|
const copy_targets = {
|
||||||
targets: [
|
targets: [
|
||||||
{ src: 'public/index.html', dest: 'build' },
|
{ src: 'public/index.html', dest: 'build' },
|
||||||
{ src: 'src/plugins/*', dest: 'build/plugins' }
|
{ src: 'src/plugins/*', dest: 'build/plugins' },
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
|
|
||||||
if (!production) {
|
if (!production) {
|
||||||
copy_targets.targets.push({ src: 'build/*', dest: 'examples/build' })
|
copy_targets.targets.push({ src: 'build/*', dest: 'examples/build' });
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
input: "src/main.ts",
|
input: 'src/main.ts',
|
||||||
output: [
|
output: [
|
||||||
{
|
{
|
||||||
file: "build/pyscript.js",
|
file: 'build/pyscript.js',
|
||||||
format: "iife",
|
format: 'iife',
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
inlineDynamicImports: true,
|
inlineDynamicImports: true,
|
||||||
name: "pyscript",
|
name: 'pyscript',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
file: "build/pyscript.min.js",
|
file: 'build/pyscript.min.js',
|
||||||
format: "iife",
|
format: 'iife',
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
inlineDynamicImports: true,
|
inlineDynamicImports: true,
|
||||||
name: "pyscript",
|
name: 'pyscript',
|
||||||
plugins: [terser()],
|
plugins: [terser()],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
plugins: [
|
plugins: [
|
||||||
css({ output: "pyscript.css" }),
|
css({ output: 'pyscript.css' }),
|
||||||
// Bundle all the Python files into the output file
|
// Bundle all the Python files into the output file
|
||||||
string({
|
string({
|
||||||
include: "./src/**/*.py",
|
include: './src/**/*.py',
|
||||||
}),
|
}),
|
||||||
legacy({ 'src/toml.js': 'toml' }),
|
legacy({ 'src/toml.js': 'toml' }),
|
||||||
resolve({
|
resolve({
|
||||||
@@ -58,10 +58,11 @@ export default {
|
|||||||
// This will make sure that examples will always get the latest build folder
|
// This will make sure that examples will always get the latest build folder
|
||||||
copy(copy_targets),
|
copy(copy_targets),
|
||||||
// production && terser(),
|
// production && terser(),
|
||||||
!production && serve({
|
!production &&
|
||||||
|
serve({
|
||||||
port: 8080,
|
port: 8080,
|
||||||
contentBase: 'examples'}
|
contentBase: 'examples',
|
||||||
)
|
}),
|
||||||
],
|
],
|
||||||
watch: {
|
watch: {
|
||||||
clearScreen: false,
|
clearScreen: false,
|
||||||
|
|||||||
@@ -36,9 +36,14 @@ export function make_PyScript(interpreter: InterpreterClient, app: PyScriptApp)
|
|||||||
|
|
||||||
app.plugins.beforePyScriptExec({ interpreter: interpreter, src: pySrc, pyScriptTag: this });
|
app.plugins.beforePyScriptExec({ interpreter: interpreter, src: pySrc, pyScriptTag: this });
|
||||||
const result = (await pyExec(interpreter, pySrc, this)).result;
|
const result = (await pyExec(interpreter, pySrc, this)).result;
|
||||||
app.plugins.afterPyScriptExec({interpreter: interpreter, src: pySrc, pyScriptTag: this, result: result});
|
app.plugins.afterPyScriptExec({
|
||||||
|
interpreter: interpreter,
|
||||||
|
src: pySrc,
|
||||||
|
pyScriptTag: this,
|
||||||
|
result: result,
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
releaseLock()
|
releaseLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,8 +204,7 @@ function createElementsWithEventListeners(interpreter: InterpreterClient, pyAttr
|
|||||||
void (async () => {
|
void (async () => {
|
||||||
try {
|
try {
|
||||||
await interpreter.run(handlerCode);
|
await interpreter.run(handlerCode);
|
||||||
}
|
} catch (err) {
|
||||||
catch (err) {
|
|
||||||
displayPyException(err, el.parentElement);
|
displayPyException(err, el.parentElement);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -12,50 +12,48 @@ The convention is:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export enum ErrorCode {
|
export enum ErrorCode {
|
||||||
GENERIC = "PY0000", // Use this only for development then change to a more specific error code
|
GENERIC = 'PY0000', // Use this only for development then change to a more specific error code
|
||||||
FETCH_ERROR = "PY0001",
|
FETCH_ERROR = 'PY0001',
|
||||||
FETCH_NAME_ERROR = "PY0002",
|
FETCH_NAME_ERROR = 'PY0002',
|
||||||
// Currently these are created depending on error code received from fetching
|
// Currently these are created depending on error code received from fetching
|
||||||
FETCH_UNAUTHORIZED_ERROR = "PY0401",
|
FETCH_UNAUTHORIZED_ERROR = 'PY0401',
|
||||||
FETCH_FORBIDDEN_ERROR = "PY0403",
|
FETCH_FORBIDDEN_ERROR = 'PY0403',
|
||||||
FETCH_NOT_FOUND_ERROR = "PY0404",
|
FETCH_NOT_FOUND_ERROR = 'PY0404',
|
||||||
FETCH_SERVER_ERROR = "PY0500",
|
FETCH_SERVER_ERROR = 'PY0500',
|
||||||
FETCH_UNAVAILABLE_ERROR = "PY0503",
|
FETCH_UNAVAILABLE_ERROR = 'PY0503',
|
||||||
BAD_CONFIG = "PY1000",
|
BAD_CONFIG = 'PY1000',
|
||||||
MICROPIP_INSTALL_ERROR = "PY1001",
|
MICROPIP_INSTALL_ERROR = 'PY1001',
|
||||||
BAD_PLUGIN_FILE_EXTENSION = "PY2000",
|
BAD_PLUGIN_FILE_EXTENSION = 'PY2000',
|
||||||
NO_DEFAULT_EXPORT = "PY2001",
|
NO_DEFAULT_EXPORT = 'PY2001',
|
||||||
TOP_LEVEL_AWAIT = "PY9000"
|
TOP_LEVEL_AWAIT = 'PY9000',
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UserError extends Error {
|
export class UserError extends Error {
|
||||||
messageType: MessageType;
|
messageType: MessageType;
|
||||||
errorCode: ErrorCode;
|
errorCode: ErrorCode;
|
||||||
|
|
||||||
constructor(errorCode: ErrorCode, message: string, t: MessageType = "text") {
|
constructor(errorCode: ErrorCode, message: string, t: MessageType = 'text') {
|
||||||
super(message);
|
super(message);
|
||||||
this.errorCode = errorCode;
|
this.errorCode = errorCode;
|
||||||
this.name = "UserError";
|
this.name = 'UserError';
|
||||||
this.messageType = t;
|
this.messageType = t;
|
||||||
this.message = `(${errorCode}): ${message}`;
|
this.message = `(${errorCode}): ${message}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class FetchError extends UserError {
|
export class FetchError extends UserError {
|
||||||
errorCode: ErrorCode;
|
errorCode: ErrorCode;
|
||||||
constructor(errorCode: ErrorCode, message: string) {
|
constructor(errorCode: ErrorCode, message: string) {
|
||||||
super(errorCode, message)
|
super(errorCode, message);
|
||||||
this.name = "FetchError";
|
this.name = 'FetchError';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class InstallError extends UserError {
|
export class InstallError extends UserError {
|
||||||
errorCode: ErrorCode;
|
errorCode: ErrorCode;
|
||||||
constructor(errorCode: ErrorCode, message: string) {
|
constructor(errorCode: ErrorCode, message: string) {
|
||||||
super(errorCode, message)
|
super(errorCode, message);
|
||||||
this.name = "InstallError";
|
this.name = 'InstallError';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ InterpreterClient class is responsible to request code execution
|
|||||||
(among other things) from a `RemoteInterpreter`
|
(among other things) from a `RemoteInterpreter`
|
||||||
*/
|
*/
|
||||||
export class InterpreterClient extends Object {
|
export class InterpreterClient extends Object {
|
||||||
|
|
||||||
_remote: RemoteInterpreter;
|
_remote: RemoteInterpreter;
|
||||||
config: AppConfig;
|
config: AppConfig;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ export class PyScriptApp {
|
|||||||
logger.info('importing pyscript');
|
logger.info('importing pyscript');
|
||||||
|
|
||||||
// Save and load pyscript.py from FS
|
// Save and load pyscript.py from FS
|
||||||
interpreter._remote.interface.FS.mkdirTree("/home/pyodide/pyscript");
|
interpreter._remote.interface.FS.mkdirTree('/home/pyodide/pyscript');
|
||||||
interpreter._remote.interface.FS.writeFile('pyscript/__init__.py', pyscript);
|
interpreter._remote.interface.FS.writeFile('pyscript/__init__.py', pyscript);
|
||||||
//Refresh the module cache so Python consistently finds pyscript module
|
//Refresh the module cache so Python consistently finds pyscript module
|
||||||
interpreter._remote.invalidate_module_path_cache();
|
interpreter._remote.invalidate_module_path_cache();
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export class Plugin {
|
|||||||
* @param options.src {string} The Python source code to be evaluated
|
* @param options.src {string} The Python source code to be evaluated
|
||||||
* @param options.pyScriptTag The <py-script> HTML tag that originated the evaluation
|
* @param options.pyScriptTag The <py-script> HTML tag that originated the evaluation
|
||||||
*/
|
*/
|
||||||
beforePyScriptExec(options: {interpreter: InterpreterClient, src: string, pyScriptTag: PyScriptTag}) {}
|
beforePyScriptExec(options: { interpreter: InterpreterClient; src: string; pyScriptTag: PyScriptTag }) {}
|
||||||
|
|
||||||
/** The Python in a <py-script> has just been evaluated, but control
|
/** The Python in a <py-script> has just been evaluated, but control
|
||||||
* has not been ceded back to the JavaScript event loop yet
|
* has not been ceded back to the JavaScript event loop yet
|
||||||
@@ -58,7 +58,12 @@ export class Plugin {
|
|||||||
* @param options.pyScriptTag The <py-script> HTML tag that originated the evaluation
|
* @param options.pyScriptTag The <py-script> HTML tag that originated the evaluation
|
||||||
* @param options.result The returned result of evaluating the Python (if any)
|
* @param options.result The returned result of evaluating the Python (if any)
|
||||||
*/
|
*/
|
||||||
afterPyScriptExec(options: {interpreter: InterpreterClient, src: string, pyScriptTag: PyScriptTag, result: any}) {}
|
afterPyScriptExec(options: {
|
||||||
|
interpreter: InterpreterClient;
|
||||||
|
src: string;
|
||||||
|
pyScriptTag: PyScriptTag;
|
||||||
|
result: any;
|
||||||
|
}) {}
|
||||||
|
|
||||||
/** Startup complete. The interpreter is initialized and ready, user
|
/** Startup complete. The interpreter is initialized and ready, user
|
||||||
* scripts have been executed: the main initialization logic ends here and
|
* scripts have been executed: the main initialization logic ends here and
|
||||||
@@ -122,13 +127,13 @@ export class PluginManager {
|
|||||||
for (const p of this._pythonPlugins) p.afterStartup?.(interpreter);
|
for (const p of this._pythonPlugins) p.afterStartup?.(interpreter);
|
||||||
}
|
}
|
||||||
|
|
||||||
beforePyScriptExec(options: {interpreter: InterpreterClient, src: string, pyScriptTag: PyScriptTag}) {
|
beforePyScriptExec(options: { interpreter: InterpreterClient; src: string; pyScriptTag: PyScriptTag }) {
|
||||||
for (const p of this._plugins) p.beforePyScriptExec?.(options);
|
for (const p of this._plugins) p.beforePyScriptExec?.(options);
|
||||||
|
|
||||||
for (const p of this._pythonPlugins) p.beforePyScriptExec?.callKwargs(options);
|
for (const p of this._pythonPlugins) p.beforePyScriptExec?.callKwargs(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
afterPyScriptExec(options: {interpreter: InterpreterClient, src: string, pyScriptTag: PyScriptTag, result: any}) {
|
afterPyScriptExec(options: { interpreter: InterpreterClient; src: string; pyScriptTag: PyScriptTag; result: any }) {
|
||||||
for (const p of this._plugins) p.afterPyScriptExec?.(options);
|
for (const p of this._plugins) p.afterPyScriptExec?.(options);
|
||||||
|
|
||||||
for (const p of this._pythonPlugins) p.afterPyScriptExec?.callKwargs(options);
|
for (const p of this._pythonPlugins) p.afterPyScriptExec?.callKwargs(options);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { joinPaths } from '../utils';
|
import { joinPaths } from '../utils';
|
||||||
import { FetchConfig } from "../pyconfig";
|
import { FetchConfig } from '../pyconfig';
|
||||||
import { UserError, ErrorCode } from '../exceptions';
|
import { UserError, ErrorCode } from '../exceptions';
|
||||||
|
|
||||||
export function calculatePaths(fetch_cfg: FetchConfig[]) {
|
export function calculatePaths(fetch_cfg: FetchConfig[]) {
|
||||||
@@ -10,14 +10,9 @@ export function calculatePaths(fetch_cfg: FetchConfig[]) {
|
|||||||
const to_folder = each_fetch_cfg.to_folder || '.';
|
const to_folder = each_fetch_cfg.to_folder || '.';
|
||||||
const to_file = each_fetch_cfg.to_file;
|
const to_file = each_fetch_cfg.to_file;
|
||||||
const files = each_fetch_cfg.files;
|
const files = each_fetch_cfg.files;
|
||||||
if (files !== undefined)
|
if (files !== undefined) {
|
||||||
{
|
if (to_file !== undefined) {
|
||||||
if (to_file !== undefined)
|
throw new UserError(ErrorCode.BAD_CONFIG, `Cannot use 'to_file' and 'files' parameters together!`);
|
||||||
{
|
|
||||||
throw new UserError(
|
|
||||||
ErrorCode.BAD_CONFIG,
|
|
||||||
`Cannot use 'to_file' and 'files' parameters together!`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
for (const each_f of files) {
|
for (const each_f of files) {
|
||||||
const each_fetch_path = joinPaths([from, each_f]);
|
const each_fetch_path = joinPaths([from, each_f]);
|
||||||
@@ -31,10 +26,9 @@ export function calculatePaths(fetch_cfg: FetchConfig[]) {
|
|||||||
if (filename === '') {
|
if (filename === '') {
|
||||||
throw new UserError(
|
throw new UserError(
|
||||||
ErrorCode.BAD_CONFIG,
|
ErrorCode.BAD_CONFIG,
|
||||||
`Couldn't determine the filename from the path ${from}, please supply 'to_file' parameter.`
|
`Couldn't determine the filename from the path ${from}, please supply 'to_file' parameter.`,
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
paths.push(joinPaths([to_folder, filename]));
|
paths.push(joinPaths([to_folder, filename]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Plugin } from "../plugin";
|
import { Plugin } from '../plugin';
|
||||||
import { TargetedStdio, StdioMultiplexer } from "../stdio";
|
import { TargetedStdio, StdioMultiplexer } from '../stdio';
|
||||||
import { make_PyScript } from "../components/pyscript";
|
import { make_PyScript } from '../components/pyscript';
|
||||||
import { InterpreterClient } from "../interpreter_client";
|
import { InterpreterClient } from '../interpreter_client';
|
||||||
|
|
||||||
type PyScriptTag = InstanceType<ReturnType<typeof make_PyScript>>;
|
type PyScriptTag = InstanceType<ReturnType<typeof make_PyScript>>;
|
||||||
|
|
||||||
@@ -17,8 +17,8 @@ export class StdioDirector extends Plugin {
|
|||||||
_stdioMultiplexer: StdioMultiplexer;
|
_stdioMultiplexer: StdioMultiplexer;
|
||||||
|
|
||||||
constructor(stdio: StdioMultiplexer) {
|
constructor(stdio: StdioMultiplexer) {
|
||||||
super()
|
super();
|
||||||
this._stdioMultiplexer = stdio
|
this._stdioMultiplexer = stdio;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prior to a <py-script> tag being evaluated, if that tag itself has
|
/** Prior to a <py-script> tag being evaluated, if that tag itself has
|
||||||
@@ -27,30 +27,35 @@ export class StdioDirector extends Plugin {
|
|||||||
* with that ID for the duration of the evaluation.
|
* with that ID for the duration of the evaluation.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
beforePyScriptExec(options: {interpreter: InterpreterClient, src: string, pyScriptTag: PyScriptTag}): void {
|
beforePyScriptExec(options: { interpreter: InterpreterClient; src: string; pyScriptTag: PyScriptTag }): void {
|
||||||
if (options.pyScriptTag.hasAttribute("output")){
|
if (options.pyScriptTag.hasAttribute('output')) {
|
||||||
const targeted_io = new TargetedStdio(options.pyScriptTag, "output", true, true)
|
const targeted_io = new TargetedStdio(options.pyScriptTag, 'output', true, true);
|
||||||
options.pyScriptTag.stdout_manager = targeted_io
|
options.pyScriptTag.stdout_manager = targeted_io;
|
||||||
this._stdioMultiplexer.addListener(targeted_io)
|
this._stdioMultiplexer.addListener(targeted_io);
|
||||||
}
|
}
|
||||||
if (options.pyScriptTag.hasAttribute("stderr")){
|
if (options.pyScriptTag.hasAttribute('stderr')) {
|
||||||
const targeted_io = new TargetedStdio(options.pyScriptTag, "stderr", false, true)
|
const targeted_io = new TargetedStdio(options.pyScriptTag, 'stderr', false, true);
|
||||||
options.pyScriptTag.stderr_manager = targeted_io
|
options.pyScriptTag.stderr_manager = targeted_io;
|
||||||
this._stdioMultiplexer.addListener(targeted_io)
|
this._stdioMultiplexer.addListener(targeted_io);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** After a <py-script> tag is evaluated, if that tag has a 'stdout_manager'
|
/** After a <py-script> tag is evaluated, if that tag has a 'stdout_manager'
|
||||||
* (presumably TargetedStdio, or some other future IO handler), it is removed.
|
* (presumably TargetedStdio, or some other future IO handler), it is removed.
|
||||||
*/
|
*/
|
||||||
afterPyScriptExec(options: {interpreter: InterpreterClient, src: string, pyScriptTag: PyScriptTag, result: any}): void {
|
afterPyScriptExec(options: {
|
||||||
|
interpreter: InterpreterClient;
|
||||||
|
src: string;
|
||||||
|
pyScriptTag: PyScriptTag;
|
||||||
|
result: any;
|
||||||
|
}): void {
|
||||||
if (options.pyScriptTag.stdout_manager != null) {
|
if (options.pyScriptTag.stdout_manager != null) {
|
||||||
this._stdioMultiplexer.removeListener(options.pyScriptTag.stdout_manager)
|
this._stdioMultiplexer.removeListener(options.pyScriptTag.stdout_manager);
|
||||||
options.pyScriptTag.stdout_manager = null
|
options.pyScriptTag.stdout_manager = null;
|
||||||
}
|
}
|
||||||
if (options.pyScriptTag.stderr_manager != null) {
|
if (options.pyScriptTag.stderr_manager != null) {
|
||||||
this._stdioMultiplexer.removeListener(options.pyScriptTag.stderr_manager)
|
this._stdioMultiplexer.removeListener(options.pyScriptTag.stderr_manager);
|
||||||
options.pyScriptTag.stderr_manager = null
|
options.pyScriptTag.stderr_manager = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export async function pyExec(interpreter: InterpreterClient, pysrc: string, outE
|
|||||||
'\nSee https://docs.pyscript.net/latest/guides/asyncio.html for more information.',
|
'\nSee https://docs.pyscript.net/latest/guides/asyncio.html for more information.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (await interpreter.run(pysrc));
|
return await interpreter.run(pysrc);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// XXX: currently we display exceptions in the same position as
|
// XXX: currently we display exceptions in the same position as
|
||||||
// the output. But we probably need a better way to do that,
|
// the output. But we probably need a better way to do that,
|
||||||
|
|||||||
@@ -37,9 +37,7 @@ export class RemoteInterpreter extends Object {
|
|||||||
// TODO: Remove this once `runtimes` is removed!
|
// TODO: Remove this once `runtimes` is removed!
|
||||||
interpreter: InterpreterInterface;
|
interpreter: InterpreterInterface;
|
||||||
|
|
||||||
constructor(
|
constructor(src = 'https://cdn.jsdelivr.net/pyodide/v0.22.1/full/pyodide.js') {
|
||||||
src = 'https://cdn.jsdelivr.net/pyodide/v0.22.1/full/pyodide.js'
|
|
||||||
) {
|
|
||||||
super();
|
super();
|
||||||
this.src = src;
|
this.src = src;
|
||||||
}
|
}
|
||||||
@@ -87,7 +85,7 @@ export class RemoteInterpreter extends Object {
|
|||||||
await this.loadPackage('micropip');
|
await this.loadPackage('micropip');
|
||||||
}
|
}
|
||||||
logger.info('pyodide loaded and initialized');
|
logger.info('pyodide loaded and initialized');
|
||||||
await this.run('print("Python initialization complete")')
|
await this.run('print("Python initialization complete")');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
@@ -134,10 +132,12 @@ export class RemoteInterpreter extends Object {
|
|||||||
// for which the signature of `loadPackage` accepts the above params as args i.e.
|
// for which the signature of `loadPackage` accepts the above params as args i.e.
|
||||||
// the call uses `logger.info.bind(logger), logger.info.bind(logger)`.
|
// the call uses `logger.info.bind(logger), logger.info.bind(logger)`.
|
||||||
const pyodide_version = (await this.run("import sys; sys.modules['pyodide'].__version__")).result.toString();
|
const pyodide_version = (await this.run("import sys; sys.modules['pyodide'].__version__")).result.toString();
|
||||||
if (pyodide_version.startsWith("0.22")) {
|
if (pyodide_version.startsWith('0.22')) {
|
||||||
await this.interface.loadPackage(names, { messageCallback: logger.info.bind(logger), errorCallback: logger.info.bind(logger) });
|
await this.interface.loadPackage(names, {
|
||||||
}
|
messageCallback: logger.info.bind(logger),
|
||||||
else {
|
errorCallback: logger.info.bind(logger),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
await this.interface.loadPackage(names, logger.info.bind(logger), logger.info.bind(logger));
|
await this.interface.loadPackage(names, logger.info.bind(logger), logger.info.bind(logger));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { createSingularWarning, escape } from "./utils";
|
import { createSingularWarning, escape } from './utils';
|
||||||
|
|
||||||
export interface Stdio {
|
export interface Stdio {
|
||||||
stdout_writeline: (msg: string) => void;
|
stdout_writeline: (msg: string) => void;
|
||||||
@@ -43,7 +43,6 @@ export class CaptureStdio implements Stdio {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class TargetedStdio implements Stdio {
|
export class TargetedStdio implements Stdio {
|
||||||
|
|
||||||
source_element: HTMLElement;
|
source_element: HTMLElement;
|
||||||
source_attribute: string;
|
source_attribute: string;
|
||||||
capture_stdout: boolean;
|
capture_stdout: boolean;
|
||||||
@@ -67,30 +66,31 @@ export class TargetedStdio implements Stdio{
|
|||||||
* @param msg The output to be written
|
* @param msg The output to be written
|
||||||
*/
|
*/
|
||||||
writeline_by_attribute(msg: string) {
|
writeline_by_attribute(msg: string) {
|
||||||
const target_id = this.source_element.getAttribute(this.source_attribute)
|
const target_id = this.source_element.getAttribute(this.source_attribute);
|
||||||
const target = document.getElementById(target_id)
|
const target = document.getElementById(target_id);
|
||||||
if (target === null) { // No matching ID
|
if (target === null) {
|
||||||
createSingularWarning(`${this.source_attribute} = "${target_id}" does not match the id of any element on the page.`)
|
// No matching ID
|
||||||
|
createSingularWarning(
|
||||||
|
`${this.source_attribute} = "${target_id}" does not match the id of any element on the page.`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
msg = escape(msg).replace('\n', '<br>');
|
||||||
|
if (!msg.endsWith('<br/>') && !msg.endsWith('<br>')) {
|
||||||
|
msg = msg + '<br>';
|
||||||
}
|
}
|
||||||
else {
|
target.innerHTML += msg;
|
||||||
msg = escape(msg).replace("\n", "<br>")
|
|
||||||
if (!msg.endsWith("<br/>") && !msg.endsWith("<br>")){
|
|
||||||
msg = msg + "<br>"
|
|
||||||
}
|
|
||||||
target.innerHTML += msg
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout_writeline(msg: string) {
|
stdout_writeline(msg: string) {
|
||||||
if (this.capture_stdout) {
|
if (this.capture_stdout) {
|
||||||
this.writeline_by_attribute(msg)
|
this.writeline_by_attribute(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stderr_writeline(msg: string) {
|
stderr_writeline(msg: string) {
|
||||||
if (this.capture_stderr) {
|
if (this.capture_stderr) {
|
||||||
this.writeline_by_attribute(msg)
|
this.writeline_by_attribute(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,9 +109,9 @@ export class StdioMultiplexer implements Stdio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeListener(obj: Stdio) {
|
removeListener(obj: Stdio) {
|
||||||
const index = this._listeners.indexOf(obj)
|
const index = this._listeners.indexOf(obj);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
this._listeners.splice(index, 1)
|
this._listeners.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +1,35 @@
|
|||||||
/* py-config - not a component */
|
/* py-config - not a component */
|
||||||
py-config {
|
py-config {
|
||||||
display: none
|
display: none;
|
||||||
}
|
}
|
||||||
/* py-{el} - components not defined */
|
/* py-{el} - components not defined */
|
||||||
py-script:not(:defined) {
|
py-script:not(:defined) {
|
||||||
display: none
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
py-repl:not(:defined) {
|
py-repl:not(:defined) {
|
||||||
display: none
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
py-title:not(:defined) {
|
py-title:not(:defined) {
|
||||||
display: none
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
py-inputbox:not(:defined) {
|
py-inputbox:not(:defined) {
|
||||||
display: none
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
py-button:not(:defined) {
|
py-button:not(:defined) {
|
||||||
display: none
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
py-box:not(:defined) {
|
py-box:not(:defined) {
|
||||||
display: none
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
|
||||||
|
Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ html {
|
|||||||
/* Pop-up second layer end */
|
/* Pop-up second layer end */
|
||||||
.alert-banner {
|
.alert-banner {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: .5rem 1.5rem .5rem .5rem;
|
padding: 0.5rem 1.5rem 0.5rem 0.5rem;
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +120,7 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.py-error {
|
.py-error {
|
||||||
background-color: #FFE9E8;
|
background-color: #ffe9e8;
|
||||||
border: solid;
|
border: solid;
|
||||||
border-color: #f0625f;
|
border-color: #f0625f;
|
||||||
color: #9d041c;
|
color: #9d041c;
|
||||||
@@ -137,13 +138,13 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.alert-banner.py-warning > #alert-close-button {
|
.alert-banner.py-warning > #alert-close-button {
|
||||||
color: #794700
|
color: #794700;
|
||||||
}
|
}
|
||||||
|
|
||||||
#alert-close-button {
|
#alert-close-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: .5rem;
|
right: 0.5rem;
|
||||||
top: .5rem;
|
top: 0.5rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
@@ -168,10 +169,7 @@ border: none;
|
|||||||
border-color: rgba(209, 213, 219, var(--tw-border-opacity));
|
border-color: rgba(209, 213, 219, var(--tw-border-opacity));
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
position: relative;
|
position: relative;
|
||||||
--tw-ring-inset: var(--tw-empty,
|
--tw-ring-inset: var(--tw-empty, /*!*/ /*!*/);
|
||||||
/*!*/
|
|
||||||
/*!*/
|
|
||||||
);
|
|
||||||
--tw-ring-offset-width: 0px;
|
--tw-ring-offset-width: 0px;
|
||||||
--tw-ring-offset-color: #fff;
|
--tw-ring-offset-color: #fff;
|
||||||
--tw-ring-color: rgba(59, 130, 246, 0.5);
|
--tw-ring-color: rgba(59, 130, 246, 0.5);
|
||||||
@@ -183,7 +181,7 @@ border: none;
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: rgb(209, 213, 219)
|
border-color: rgb(209, 213, 219);
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-box:hover button {
|
.editor-box:hover button {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { _createAlertBanner } from "./exceptions"
|
import { _createAlertBanner } from './exceptions';
|
||||||
|
|
||||||
export function addClasses(element: HTMLElement, classes: string[]) {
|
export function addClasses(element: HTMLElement, classes: string[]) {
|
||||||
for (const entry of classes) {
|
for (const entry of classes) {
|
||||||
@@ -129,7 +129,7 @@ export function createLock() {
|
|||||||
async function acquireLock() {
|
async function acquireLock() {
|
||||||
const old_lock = _lock;
|
const old_lock = _lock;
|
||||||
let releaseLock: () => void;
|
let releaseLock: () => void;
|
||||||
_lock = new Promise((resolve) => (releaseLock = resolve));
|
_lock = new Promise(resolve => (releaseLock = resolve));
|
||||||
await old_lock;
|
await old_lock;
|
||||||
return releaseLock;
|
return releaseLock;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,121 +1,117 @@
|
|||||||
import { expect, it, jest, describe, afterEach } from "@jest/globals"
|
import { expect, it, jest, describe, afterEach } from '@jest/globals';
|
||||||
import { _createAlertBanner, UserError, FetchError, ErrorCode } from "../../src/exceptions"
|
import { _createAlertBanner, UserError, FetchError, ErrorCode } from '../../src/exceptions';
|
||||||
|
|
||||||
describe("Test _createAlertBanner", () => {
|
describe('Test _createAlertBanner', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
// Ensure we always have a clean body
|
// Ensure we always have a clean body
|
||||||
document.body.innerHTML = `<div>Hello World</div>`;
|
document.body.innerHTML = `<div>Hello World</div>`;
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
it("error level shouldn't contain close button", async () => {
|
it("error level shouldn't contain close button", async () => {
|
||||||
_createAlertBanner("Something went wrong!", "error");
|
_createAlertBanner('Something went wrong!', 'error');
|
||||||
|
|
||||||
const banner = document.getElementsByClassName("alert-banner");
|
const banner = document.getElementsByClassName('alert-banner');
|
||||||
const closeButton = document.getElementById("alert-close-button");
|
const closeButton = document.getElementById('alert-close-button');
|
||||||
expect(banner.length).toBe(1);
|
expect(banner.length).toBe(1);
|
||||||
expect(banner[0].innerHTML).toBe("Something went wrong!");
|
expect(banner[0].innerHTML).toBe('Something went wrong!');
|
||||||
expect(closeButton).toBeNull();
|
expect(closeButton).toBeNull();
|
||||||
})
|
});
|
||||||
|
|
||||||
it("warning level should contain close button", async () => {
|
it('warning level should contain close button', async () => {
|
||||||
_createAlertBanner("This is a warning", "warning");
|
_createAlertBanner('This is a warning', 'warning');
|
||||||
|
|
||||||
const banner = document.getElementsByClassName("alert-banner");
|
const banner = document.getElementsByClassName('alert-banner');
|
||||||
const closeButton = document.getElementById("alert-close-button");
|
const closeButton = document.getElementById('alert-close-button');
|
||||||
expect(banner.length).toBe(1);
|
expect(banner.length).toBe(1);
|
||||||
expect(banner[0].innerHTML).toContain("This is a warning");
|
expect(banner[0].innerHTML).toContain('This is a warning');
|
||||||
expect(closeButton).not.toBeNull();
|
expect(closeButton).not.toBeNull();
|
||||||
})
|
});
|
||||||
|
|
||||||
it("error level banner should log to console", async () => {
|
it('error level banner should log to console', async () => {
|
||||||
const logSpy = jest.spyOn(console, "error");
|
const logSpy = jest.spyOn(console, 'error');
|
||||||
|
|
||||||
_createAlertBanner("Something went wrong!");
|
_createAlertBanner('Something went wrong!');
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith("Something went wrong!");
|
expect(logSpy).toHaveBeenCalledWith('Something went wrong!');
|
||||||
|
});
|
||||||
|
|
||||||
})
|
it('warning level banner should log to console', async () => {
|
||||||
|
const logSpy = jest.spyOn(console, 'warn');
|
||||||
|
|
||||||
it("warning level banner should log to console", async () => {
|
_createAlertBanner('This warning', 'warning');
|
||||||
const logSpy = jest.spyOn(console, "warn");
|
|
||||||
|
|
||||||
_createAlertBanner("This warning", "warning");
|
expect(logSpy).toHaveBeenCalledWith('This warning');
|
||||||
|
});
|
||||||
|
|
||||||
expect(logSpy).toHaveBeenCalledWith("This warning");
|
it('close button should remove element from page', async () => {
|
||||||
})
|
let banner = document.getElementsByClassName('alert-banner');
|
||||||
|
|
||||||
it("close button should remove element from page", async () => {
|
|
||||||
let banner = document.getElementsByClassName("alert-banner");
|
|
||||||
expect(banner.length).toBe(0);
|
expect(banner.length).toBe(0);
|
||||||
|
|
||||||
_createAlertBanner("Warning!", "warning");
|
_createAlertBanner('Warning!', 'warning');
|
||||||
|
|
||||||
// Just a sanity check
|
// Just a sanity check
|
||||||
banner = document.getElementsByClassName("alert-banner");
|
banner = document.getElementsByClassName('alert-banner');
|
||||||
expect(banner.length).toBe(1);
|
expect(banner.length).toBe(1);
|
||||||
|
|
||||||
const closeButton = document.getElementById("alert-close-button");
|
const closeButton = document.getElementById('alert-close-button');
|
||||||
if (closeButton) {
|
if (closeButton) {
|
||||||
closeButton.click();
|
closeButton.click();
|
||||||
// Confirm that clicking the close button, removes the element
|
// Confirm that clicking the close button, removes the element
|
||||||
banner = document.getElementsByClassName("alert-banner");
|
banner = document.getElementsByClassName('alert-banner');
|
||||||
expect(banner.length).toBe(0);
|
expect(banner.length).toBe(0);
|
||||||
} else {
|
} else {
|
||||||
fail("Unable to find close button on the page, but should exist");
|
fail('Unable to find close button on the page, but should exist');
|
||||||
}
|
}
|
||||||
|
});
|
||||||
})
|
|
||||||
|
|
||||||
it("toggling logging off on error alert shouldn't log to console", async () => {
|
it("toggling logging off on error alert shouldn't log to console", async () => {
|
||||||
const errorLogSpy = jest.spyOn(console, "error");
|
const errorLogSpy = jest.spyOn(console, 'error');
|
||||||
|
|
||||||
_createAlertBanner("Test error", "error", "text", false);
|
_createAlertBanner('Test error', 'error', 'text', false);
|
||||||
expect(errorLogSpy).not.toHaveBeenCalledWith("Test error");
|
expect(errorLogSpy).not.toHaveBeenCalledWith('Test error');
|
||||||
})
|
});
|
||||||
|
|
||||||
it("toggling logging off on warning alert shouldn't log to console", async () => {
|
it("toggling logging off on warning alert shouldn't log to console", async () => {
|
||||||
const warnLogSpy = jest.spyOn(console, "warn");
|
const warnLogSpy = jest.spyOn(console, 'warn');
|
||||||
_createAlertBanner("Test warning", "warning", "text", false);
|
_createAlertBanner('Test warning', 'warning', 'text', false);
|
||||||
expect(warnLogSpy).not.toHaveBeenCalledWith("Test warning");
|
expect(warnLogSpy).not.toHaveBeenCalledWith('Test warning');
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
it('_createAlertbanner messageType text writes message to content', async () => {
|
it('_createAlertbanner messageType text writes message to content', async () => {
|
||||||
let banner = document.getElementsByClassName("alert-banner");
|
let banner = document.getElementsByClassName('alert-banner');
|
||||||
expect(banner.length).toBe(0);
|
expect(banner.length).toBe(0);
|
||||||
|
|
||||||
const message = '<p>Test message</p>'
|
const message = '<p>Test message</p>';
|
||||||
_createAlertBanner(message, 'error', 'text');
|
_createAlertBanner(message, 'error', 'text');
|
||||||
banner = document.getElementsByClassName("alert-banner");
|
banner = document.getElementsByClassName('alert-banner');
|
||||||
|
|
||||||
expect(banner.length).toBe(1);
|
expect(banner.length).toBe(1);
|
||||||
expect(banner[0].innerHTML).toBe("<p>Test message</p>");
|
expect(banner[0].innerHTML).toBe('<p>Test message</p>');
|
||||||
expect(banner[0].textContent).toBe(message);
|
expect(banner[0].textContent).toBe(message);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('_createAlertbanner messageType html writes message to innerHTML', async () => {
|
it('_createAlertbanner messageType html writes message to innerHTML', async () => {
|
||||||
let banner = document.getElementsByClassName("alert-banner");
|
let banner = document.getElementsByClassName('alert-banner');
|
||||||
expect(banner.length).toBe(0);
|
expect(banner.length).toBe(0);
|
||||||
|
|
||||||
const message = '<p>Test message</p>';
|
const message = '<p>Test message</p>';
|
||||||
_createAlertBanner(message, 'error', 'html');
|
_createAlertBanner(message, 'error', 'html');
|
||||||
banner = document.getElementsByClassName("alert-banner");
|
banner = document.getElementsByClassName('alert-banner');
|
||||||
|
|
||||||
expect(banner.length).toBe(1);
|
expect(banner.length).toBe(1);
|
||||||
expect(banner[0].innerHTML).toBe(message);
|
expect(banner[0].innerHTML).toBe(message);
|
||||||
expect(banner[0].textContent).toBe("Test message");
|
expect(banner[0].textContent).toBe('Test message');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
describe("Test Exceptions", () => {
|
describe('Test Exceptions', () => {
|
||||||
it('UserError contains errorCode and shows in message', async () => {
|
it('UserError contains errorCode and shows in message', async () => {
|
||||||
const errorCode = ErrorCode.BAD_CONFIG;
|
const errorCode = ErrorCode.BAD_CONFIG;
|
||||||
const message = 'Test error';
|
const message = 'Test error';
|
||||||
const userError = new UserError(ErrorCode.BAD_CONFIG, message);
|
const userError = new UserError(ErrorCode.BAD_CONFIG, message);
|
||||||
expect(userError.errorCode).toBe(errorCode);
|
expect(userError.errorCode).toBe(errorCode);
|
||||||
expect(userError.message).toBe(`(${errorCode}): ${message}`);
|
expect(userError.message).toBe(`(${errorCode}): ${message}`);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('FetchError contains errorCode and shows in message', async () => {
|
it('FetchError contains errorCode and shows in message', async () => {
|
||||||
const errorCode = ErrorCode.FETCH_NOT_FOUND_ERROR;
|
const errorCode = ErrorCode.FETCH_NOT_FOUND_ERROR;
|
||||||
@@ -123,5 +119,5 @@ describe("Test Exceptions", () => {
|
|||||||
const fetchError = new FetchError(errorCode, message);
|
const fetchError = new FetchError(errorCode, message);
|
||||||
expect(fetchError.errorCode).toBe(errorCode);
|
expect(fetchError.errorCode).toBe(errorCode);
|
||||||
expect(fetchError.message).toBe(`(${errorCode}): ${message}`);
|
expect(fetchError.message).toBe(`(${errorCode}): ${message}`);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -1,99 +1,95 @@
|
|||||||
import { describe, it, expect, jest } from '@jest/globals'
|
import { describe, it, expect, jest } from '@jest/globals';
|
||||||
import { FetchError, ErrorCode } from "../../src/exceptions"
|
import { FetchError, ErrorCode } from '../../src/exceptions';
|
||||||
import { robustFetch } from "../../src/fetch"
|
import { robustFetch } from '../../src/fetch';
|
||||||
import { Response } from 'node-fetch';
|
import { Response } from 'node-fetch';
|
||||||
|
|
||||||
describe("robustFetch", () => {
|
describe('robustFetch', () => {
|
||||||
|
it('should return a response object', async () => {
|
||||||
|
global.fetch = jest.fn(() => Promise.resolve(new Response((status = '200'), 'Hello World')));
|
||||||
|
|
||||||
it("should return a response object", async () => {
|
const response = await robustFetch('https://pyscript.net');
|
||||||
global.fetch = jest.fn(() => (Promise.resolve(new Response(status="200", "Hello World"))));
|
|
||||||
|
|
||||||
const response = await robustFetch("https://pyscript.net");
|
|
||||||
expect(response).toBeInstanceOf(Response);
|
expect(response).toBeInstanceOf(Response);
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('receiving a 404 when fetching should throw FetchError with the right errorCode', async () => {
|
it('receiving a 404 when fetching should throw FetchError with the right errorCode', async () => {
|
||||||
global.fetch = jest.fn(() => (Promise.resolve(new Response("Not Found", {status: 404}))));
|
global.fetch = jest.fn(() => Promise.resolve(new Response('Not Found', { status: 404 })));
|
||||||
|
|
||||||
const url = "https://pyscript.net/non-existent-page"
|
const url = 'https://pyscript.net/non-existent-page';
|
||||||
const expectedError = new FetchError(
|
const expectedError = new FetchError(
|
||||||
ErrorCode.FETCH_NOT_FOUND_ERROR,
|
ErrorCode.FETCH_NOT_FOUND_ERROR,
|
||||||
`Fetching from URL ${url} failed with error 404 (Not Found). ` +
|
`Fetching from URL ${url} failed with error 404 (Not Found). ` + `Are your filename and path correct?`,
|
||||||
`Are your filename and path correct?`
|
);
|
||||||
)
|
|
||||||
|
|
||||||
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('receiving a 401 when fetching should throw FetchError with the right errorCode', async () => {
|
it('receiving a 401 when fetching should throw FetchError with the right errorCode', async () => {
|
||||||
global.fetch = jest.fn(() => (Promise.resolve(new Response("", {status: 401}))));
|
global.fetch = jest.fn(() => Promise.resolve(new Response('', { status: 401 })));
|
||||||
|
|
||||||
const url = "https://pyscript.net/protected-page"
|
const url = 'https://pyscript.net/protected-page';
|
||||||
const expectedError = new FetchError(
|
const expectedError = new FetchError(
|
||||||
ErrorCode.FETCH_UNAUTHORIZED_ERROR,
|
ErrorCode.FETCH_UNAUTHORIZED_ERROR,
|
||||||
`Fetching from URL ${url} failed with error 401 (Unauthorized). ` +
|
`Fetching from URL ${url} failed with error 401 (Unauthorized). ` + `Are your filename and path correct?`,
|
||||||
`Are your filename and path correct?`
|
);
|
||||||
)
|
|
||||||
|
|
||||||
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('receiving a 403 when fetching should throw FetchError with the right errorCode', async () => {
|
it('receiving a 403 when fetching should throw FetchError with the right errorCode', async () => {
|
||||||
global.fetch = jest.fn(() => (Promise.resolve(new Response("", {status: 403}))));
|
global.fetch = jest.fn(() => Promise.resolve(new Response('', { status: 403 })));
|
||||||
|
|
||||||
const url = "https://pyscript.net/secret-page"
|
const url = 'https://pyscript.net/secret-page';
|
||||||
const expectedError = new FetchError(
|
const expectedError = new FetchError(
|
||||||
ErrorCode.FETCH_FORBIDDEN_ERROR,
|
ErrorCode.FETCH_FORBIDDEN_ERROR,
|
||||||
`Fetching from URL ${url} failed with error 403 (Forbidden). ` +
|
`Fetching from URL ${url} failed with error 403 (Forbidden). ` + `Are your filename and path correct?`,
|
||||||
`Are your filename and path correct?`
|
);
|
||||||
)
|
|
||||||
|
|
||||||
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('receiving a 500 when fetching should throw FetchError with the right errorCode', async () => {
|
it('receiving a 500 when fetching should throw FetchError with the right errorCode', async () => {
|
||||||
global.fetch = jest.fn(() => (Promise.resolve(new Response("Not Found", {status: 500}))));
|
global.fetch = jest.fn(() => Promise.resolve(new Response('Not Found', { status: 500 })));
|
||||||
|
|
||||||
const url = "https://pyscript.net/protected-page"
|
const url = 'https://pyscript.net/protected-page';
|
||||||
const expectedError = new FetchError(
|
const expectedError = new FetchError(
|
||||||
ErrorCode.FETCH_SERVER_ERROR,
|
ErrorCode.FETCH_SERVER_ERROR,
|
||||||
`Fetching from URL ${url} failed with error 500 (Internal Server Error). ` +
|
`Fetching from URL ${url} failed with error 500 (Internal Server Error). ` +
|
||||||
`Are your filename and path correct?`
|
`Are your filename and path correct?`,
|
||||||
)
|
);
|
||||||
|
|
||||||
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('receiving a 503 when fetching should throw FetchError with the right errorCode', async () => {
|
it('receiving a 503 when fetching should throw FetchError with the right errorCode', async () => {
|
||||||
global.fetch = jest.fn(() => (Promise.resolve(new Response("Not Found", {status: 503}))));
|
global.fetch = jest.fn(() => Promise.resolve(new Response('Not Found', { status: 503 })));
|
||||||
|
|
||||||
const url = "https://pyscript.net/protected-page"
|
const url = 'https://pyscript.net/protected-page';
|
||||||
const expectedError = new FetchError(
|
const expectedError = new FetchError(
|
||||||
ErrorCode.FETCH_UNAVAILABLE_ERROR,
|
ErrorCode.FETCH_UNAVAILABLE_ERROR,
|
||||||
`Fetching from URL ${url} failed with error 503 (Service Unavailable). ` +
|
`Fetching from URL ${url} failed with error 503 (Service Unavailable). ` +
|
||||||
`Are your filename and path correct?`
|
`Are your filename and path correct?`,
|
||||||
)
|
);
|
||||||
|
|
||||||
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('handle TypeError when using a bad url', async () => {
|
it('handle TypeError when using a bad url', async () => {
|
||||||
global.fetch = jest.fn(() => (Promise.reject(new TypeError("Failed to fetch"))));
|
global.fetch = jest.fn(() => Promise.reject(new TypeError('Failed to fetch')));
|
||||||
|
|
||||||
const url = "https://pyscript.net/protected-page"
|
const url = 'https://pyscript.net/protected-page';
|
||||||
const expectedError = new FetchError(
|
const expectedError = new FetchError(
|
||||||
ErrorCode.FETCH_ERROR,
|
ErrorCode.FETCH_ERROR,
|
||||||
`Fetching from URL ${url} failed with error 'Failed to fetch'. Are your filename and path correct?`
|
`Fetching from URL ${url} failed with error 'Failed to fetch'. Are your filename and path correct?`,
|
||||||
)
|
);
|
||||||
|
|
||||||
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
||||||
})
|
});
|
||||||
|
|
||||||
it('handle failed to fetch when using local file', async () => {
|
it('handle failed to fetch when using local file', async () => {
|
||||||
global.fetch = jest.fn(() => (Promise.reject(new TypeError("Failed to fetch"))));
|
global.fetch = jest.fn(() => Promise.reject(new TypeError('Failed to fetch')));
|
||||||
|
|
||||||
const url = "./my-awesome-pyscript.py"
|
const url = './my-awesome-pyscript.py';
|
||||||
|
|
||||||
const expectedError = new FetchError(
|
const expectedError = new FetchError(
|
||||||
ErrorCode.FETCH_ERROR,
|
ErrorCode.FETCH_ERROR,
|
||||||
@@ -103,9 +99,9 @@ describe("robustFetch", () => {
|
|||||||
you must use a webserver to serve the additional files.
|
you must use a webserver to serve the additional files.
|
||||||
See <a style="text-decoration: underline;" href="https://github.com/pyscript/pyscript/issues/257#issuecomment-1119595062">this reference</a>
|
See <a style="text-decoration: underline;" href="https://github.com/pyscript/pyscript/issues/257#issuecomment-1119595062">this reference</a>
|
||||||
on starting a simple webserver with Python.
|
on starting a simple webserver with Python.
|
||||||
`
|
`,
|
||||||
)
|
);
|
||||||
|
|
||||||
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
expect(() => robustFetch(url)).rejects.toThrow(expectedError);
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,49 +1,55 @@
|
|||||||
import { calculatePaths } from "../../src/plugins/fetch";
|
import { calculatePaths } from '../../src/plugins/fetch';
|
||||||
import { FetchConfig } from "../../src/pyconfig";
|
import { FetchConfig } from '../../src/pyconfig';
|
||||||
|
|
||||||
describe("CalculateFetchPaths", () => {
|
describe('CalculateFetchPaths', () => {
|
||||||
it("should calculate paths when only from is provided", () => {
|
it('should calculate paths when only from is provided', () => {
|
||||||
const fetch_cfg: FetchConfig[] = [{from: "http://a.com/data.csv" }];
|
const fetch_cfg: FetchConfig[] = [{ from: 'http://a.com/data.csv' }];
|
||||||
const [paths, fetchPaths] = calculatePaths(fetch_cfg);
|
const [paths, fetchPaths] = calculatePaths(fetch_cfg);
|
||||||
expect(paths).toStrictEqual(["./data.csv"]);
|
expect(paths).toStrictEqual(['./data.csv']);
|
||||||
expect(fetchPaths).toStrictEqual(["http://a.com/data.csv"]);
|
expect(fetchPaths).toStrictEqual(['http://a.com/data.csv']);
|
||||||
})
|
});
|
||||||
|
|
||||||
it("should calculate paths when only files is provided", () => {
|
it('should calculate paths when only files is provided', () => {
|
||||||
const fetch_cfg: FetchConfig[] = [{files: ["foo/__init__.py", "foo/mod.py"] }];
|
const fetch_cfg: FetchConfig[] = [{ files: ['foo/__init__.py', 'foo/mod.py'] }];
|
||||||
const [paths, fetchPaths] = calculatePaths(fetch_cfg);
|
const [paths, fetchPaths] = calculatePaths(fetch_cfg);
|
||||||
expect(paths).toStrictEqual(["./foo/__init__.py", "./foo/mod.py"]);
|
expect(paths).toStrictEqual(['./foo/__init__.py', './foo/mod.py']);
|
||||||
expect(fetchPaths).toStrictEqual(["foo/__init__.py", "foo/mod.py"]);
|
expect(fetchPaths).toStrictEqual(['foo/__init__.py', 'foo/mod.py']);
|
||||||
})
|
});
|
||||||
|
|
||||||
it("should calculate paths when files and to_folder is provided", () => {
|
it('should calculate paths when files and to_folder is provided', () => {
|
||||||
const fetch_cfg: FetchConfig[] = [{files: ["foo/__init__.py", "foo/mod.py"], to_folder: "/my/lib/"}];
|
const fetch_cfg: FetchConfig[] = [{ files: ['foo/__init__.py', 'foo/mod.py'], to_folder: '/my/lib/' }];
|
||||||
const [paths, fetchPaths] = calculatePaths(fetch_cfg);
|
const [paths, fetchPaths] = calculatePaths(fetch_cfg);
|
||||||
expect(paths).toStrictEqual(["/my/lib/foo/__init__.py", "/my/lib/foo/mod.py"]);
|
expect(paths).toStrictEqual(['/my/lib/foo/__init__.py', '/my/lib/foo/mod.py']);
|
||||||
expect(fetchPaths).toStrictEqual(["foo/__init__.py", "foo/mod.py"]);
|
expect(fetchPaths).toStrictEqual(['foo/__init__.py', 'foo/mod.py']);
|
||||||
})
|
});
|
||||||
|
|
||||||
it("should calculate paths when from and files and to_folder is provided", () => {
|
it('should calculate paths when from and files and to_folder is provided', () => {
|
||||||
const fetch_cfg: FetchConfig[] = [{from: "http://a.com/download/", files: ["foo/__init__.py", "foo/mod.py"], to_folder: "/my/lib/"}];
|
const fetch_cfg: FetchConfig[] = [
|
||||||
|
{ from: 'http://a.com/download/', files: ['foo/__init__.py', 'foo/mod.py'], to_folder: '/my/lib/' },
|
||||||
|
];
|
||||||
const [paths, fetchPaths] = calculatePaths(fetch_cfg);
|
const [paths, fetchPaths] = calculatePaths(fetch_cfg);
|
||||||
expect(paths).toStrictEqual(["/my/lib/foo/__init__.py", "/my/lib/foo/mod.py"]);
|
expect(paths).toStrictEqual(['/my/lib/foo/__init__.py', '/my/lib/foo/mod.py']);
|
||||||
expect(fetchPaths).toStrictEqual(["http://a.com/download/foo/__init__.py", "http://a.com/download/foo/mod.py"]);
|
expect(fetchPaths).toStrictEqual(['http://a.com/download/foo/__init__.py', 'http://a.com/download/foo/mod.py']);
|
||||||
})
|
});
|
||||||
|
|
||||||
it("should error out while calculating paths when filename cannot be determined from 'from'", () => {
|
it("should error out while calculating paths when filename cannot be determined from 'from'", () => {
|
||||||
const fetch_cfg: FetchConfig[] = [{from: "http://google.com/", to_folder: "/tmp"}];
|
const fetch_cfg: FetchConfig[] = [{ from: 'http://google.com/', to_folder: '/tmp' }];
|
||||||
expect(()=>calculatePaths(fetch_cfg)).toThrowError("Couldn't determine the filename from the path http://google.com/");
|
expect(() => calculatePaths(fetch_cfg)).toThrowError(
|
||||||
})
|
"Couldn't determine the filename from the path http://google.com/",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("should calculate paths when to_file is explicitly supplied", () => {
|
it('should calculate paths when to_file is explicitly supplied', () => {
|
||||||
const fetch_cfg: FetchConfig[] = [{from: "http://a.com/data.csv?version=1", to_file: "pkg/tmp/data.csv"}];
|
const fetch_cfg: FetchConfig[] = [{ from: 'http://a.com/data.csv?version=1', to_file: 'pkg/tmp/data.csv' }];
|
||||||
const [paths, fetchPaths] = calculatePaths(fetch_cfg);
|
const [paths, fetchPaths] = calculatePaths(fetch_cfg);
|
||||||
expect(paths).toStrictEqual(["./pkg/tmp/data.csv"]);
|
expect(paths).toStrictEqual(['./pkg/tmp/data.csv']);
|
||||||
expect(fetchPaths).toStrictEqual(["http://a.com/data.csv?version=1"]);
|
expect(fetchPaths).toStrictEqual(['http://a.com/data.csv?version=1']);
|
||||||
})
|
});
|
||||||
|
|
||||||
it("should error out when both to_file and files parameters are provided", () => {
|
it('should error out when both to_file and files parameters are provided', () => {
|
||||||
const fetch_cfg: FetchConfig[] = [{from: "http://a.com/data.csv?version=1", to_file: "pkg/tmp/data.csv", files: ["a.py", "b.py"]}];
|
const fetch_cfg: FetchConfig[] = [
|
||||||
|
{ from: 'http://a.com/data.csv?version=1', to_file: 'pkg/tmp/data.csv', files: ['a.py', 'b.py'] },
|
||||||
|
];
|
||||||
expect(() => calculatePaths(fetch_cfg)).toThrowError("Cannot use 'to_file' and 'files' parameters together!");
|
expect(() => calculatePaths(fetch_cfg)).toThrowError("Cannot use 'to_file' and 'files' parameters together!");
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -15,20 +15,16 @@ describe('getLogger', () => {
|
|||||||
console.info = jest.fn();
|
console.info = jest.fn();
|
||||||
|
|
||||||
const logger = getLogger('prefix1');
|
const logger = getLogger('prefix1');
|
||||||
logger.info('hello world')
|
logger.info('hello world');
|
||||||
expect(console.info).toHaveBeenCalledWith(
|
expect(console.info).toHaveBeenCalledWith('[prefix1] hello world');
|
||||||
'[prefix1] hello world'
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logger.info handles multiple args', () => {
|
it('logger.info handles multiple args', () => {
|
||||||
console.info = jest.fn();
|
console.info = jest.fn();
|
||||||
|
|
||||||
const logger = getLogger('prefix2');
|
const logger = getLogger('prefix2');
|
||||||
logger.info('hello', 'world', 1, 2, 3)
|
logger.info('hello', 'world', 1, 2, 3);
|
||||||
expect(console.info).toHaveBeenCalledWith(
|
expect(console.info).toHaveBeenCalledWith('[prefix2] hello', 'world', 1, 2, 3);
|
||||||
'[prefix2] hello', 'world', 1, 2, 3
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('logger.{debug,warn,error} also works', () => {
|
it('logger.{debug,warn,error} also works', () => {
|
||||||
@@ -43,15 +39,8 @@ describe('getLogger', () => {
|
|||||||
logger.error('this is an error');
|
logger.error('this is an error');
|
||||||
|
|
||||||
expect(console.info).not.toHaveBeenCalled();
|
expect(console.info).not.toHaveBeenCalled();
|
||||||
expect(console.debug).toHaveBeenCalledWith(
|
expect(console.debug).toHaveBeenCalledWith('[prefix3] this is a debug');
|
||||||
'[prefix3] this is a debug'
|
expect(console.warn).toHaveBeenCalledWith('[prefix3] this is a warning');
|
||||||
)
|
expect(console.error).toHaveBeenCalledWith('[prefix3] this is an error');
|
||||||
expect(console.warn).toHaveBeenCalledWith(
|
|
||||||
'[prefix3] this is a warning'
|
|
||||||
)
|
|
||||||
expect(console.error).toHaveBeenCalledWith(
|
|
||||||
'[prefix3] this is an error'
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { describe, it, beforeEach, expect } from "@jest/globals"
|
import { describe, it, beforeEach, expect } from '@jest/globals';
|
||||||
import { UserError, ErrorCode } from "../../src/exceptions"
|
import { UserError, ErrorCode } from '../../src/exceptions';
|
||||||
import { PyScriptApp } from "../../src/main"
|
import { PyScriptApp } from '../../src/main';
|
||||||
|
|
||||||
describe("Test withUserErrorHandler", () => {
|
|
||||||
|
|
||||||
|
describe('Test withUserErrorHandler', () => {
|
||||||
class MyApp extends PyScriptApp {
|
class MyApp extends PyScriptApp {
|
||||||
myRealMain: any;
|
myRealMain: any;
|
||||||
|
|
||||||
@@ -24,46 +23,46 @@ describe("Test withUserErrorHandler", () => {
|
|||||||
|
|
||||||
it("userError doesn't stop execution", () => {
|
it("userError doesn't stop execution", () => {
|
||||||
function myRealMain() {
|
function myRealMain() {
|
||||||
throw new UserError(ErrorCode.GENERIC, "Computer says no");
|
throw new UserError(ErrorCode.GENERIC, 'Computer says no');
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = new MyApp(myRealMain);
|
const app = new MyApp(myRealMain);
|
||||||
app.main();
|
app.main();
|
||||||
const banners = document.getElementsByClassName("alert-banner");
|
const banners = document.getElementsByClassName('alert-banner');
|
||||||
expect(banners.length).toBe(1);
|
expect(banners.length).toBe(1);
|
||||||
expect(banners[0].innerHTML).toBe("(PY0000): Computer says no");
|
expect(banners[0].innerHTML).toBe('(PY0000): Computer says no');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("userError escapes by default", () => {
|
it('userError escapes by default', () => {
|
||||||
function myRealMain() {
|
function myRealMain() {
|
||||||
throw new UserError(ErrorCode.GENERIC, "hello <br>");
|
throw new UserError(ErrorCode.GENERIC, 'hello <br>');
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = new MyApp(myRealMain);
|
const app = new MyApp(myRealMain);
|
||||||
app.main();
|
app.main();
|
||||||
const banners = document.getElementsByClassName("alert-banner");
|
const banners = document.getElementsByClassName('alert-banner');
|
||||||
expect(banners.length).toBe(1);
|
expect(banners.length).toBe(1);
|
||||||
expect(banners[0].innerHTML).toBe("(PY0000): hello <br>");
|
expect(banners[0].innerHTML).toBe('(PY0000): hello <br>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("userError messageType=html don't escape", () => {
|
it("userError messageType=html don't escape", () => {
|
||||||
function myRealMain() {
|
function myRealMain() {
|
||||||
throw new UserError(ErrorCode.GENERIC, "hello <br>", "html");
|
throw new UserError(ErrorCode.GENERIC, 'hello <br>', 'html');
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = new MyApp(myRealMain);
|
const app = new MyApp(myRealMain);
|
||||||
app.main();
|
app.main();
|
||||||
const banners = document.getElementsByClassName("alert-banner");
|
const banners = document.getElementsByClassName('alert-banner');
|
||||||
expect(banners.length).toBe(1);
|
expect(banners.length).toBe(1);
|
||||||
expect(banners[0].innerHTML).toBe("(PY0000): hello <br>");
|
expect(banners[0].innerHTML).toBe('(PY0000): hello <br>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("any other exception should stop execution and raise", () => {
|
it('any other exception should stop execution and raise', () => {
|
||||||
function myRealMain() {
|
function myRealMain() {
|
||||||
throw new Error("Explosions!");
|
throw new Error('Explosions!');
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = new MyApp(myRealMain);
|
const app = new MyApp(myRealMain);
|
||||||
expect(() => app.main()).toThrow(new Error("Explosions!"))
|
expect(() => app.main()).toThrow(new Error('Explosions!'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ describe('RemoteInterpreter', () => {
|
|||||||
let interpreter: InterpreterClient;
|
let interpreter: InterpreterClient;
|
||||||
let stdio: CaptureStdio = new CaptureStdio();
|
let stdio: CaptureStdio = new CaptureStdio();
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
const config: AppConfig = {interpreters: [{src: "../pyscriptjs/node_modules/pyodide/pyodide.js"}]};
|
const config: AppConfig = { interpreters: [{ src: '../pyscriptjs/node_modules/pyodide/pyodide.js' }] };
|
||||||
interpreter = new InterpreterClient(config, stdio);
|
interpreter = new InterpreterClient(config, stdio);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,31 +4,29 @@ import { type Stdio, CaptureStdio, StdioMultiplexer, TargetedStdio } from '../..
|
|||||||
describe('CaptureStdio', () => {
|
describe('CaptureStdio', () => {
|
||||||
it('captured streams are initialized to empty string', () => {
|
it('captured streams are initialized to empty string', () => {
|
||||||
let stdio = new CaptureStdio();
|
let stdio = new CaptureStdio();
|
||||||
expect(stdio.captured_stdout).toBe("");
|
expect(stdio.captured_stdout).toBe('');
|
||||||
expect(stdio.captured_stderr).toBe("");
|
expect(stdio.captured_stderr).toBe('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('stdout() and stderr() captures', () => {
|
it('stdout() and stderr() captures', () => {
|
||||||
let stdio = new CaptureStdio();
|
let stdio = new CaptureStdio();
|
||||||
stdio.stdout_writeline("hello");
|
stdio.stdout_writeline('hello');
|
||||||
stdio.stdout_writeline("world");
|
stdio.stdout_writeline('world');
|
||||||
stdio.stderr_writeline("this is an error");
|
stdio.stderr_writeline('this is an error');
|
||||||
expect(stdio.captured_stdout).toBe("hello\nworld\n");
|
expect(stdio.captured_stdout).toBe('hello\nworld\n');
|
||||||
expect(stdio.captured_stderr).toBe("this is an error\n");
|
expect(stdio.captured_stderr).toBe('this is an error\n');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('reset() works', () => {
|
it('reset() works', () => {
|
||||||
let stdio = new CaptureStdio();
|
let stdio = new CaptureStdio();
|
||||||
stdio.stdout_writeline("aaa");
|
stdio.stdout_writeline('aaa');
|
||||||
stdio.stderr_writeline("bbb");
|
stdio.stderr_writeline('bbb');
|
||||||
stdio.reset();
|
stdio.reset();
|
||||||
expect(stdio.captured_stdout).toBe("");
|
expect(stdio.captured_stdout).toBe('');
|
||||||
expect(stdio.captured_stderr).toBe("");
|
expect(stdio.captured_stderr).toBe('');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('StdioMultiplexer', () => {
|
describe('StdioMultiplexer', () => {
|
||||||
let a: CaptureStdio;
|
let a: CaptureStdio;
|
||||||
let b: CaptureStdio;
|
let b: CaptureStdio;
|
||||||
@@ -44,10 +42,10 @@ describe('StdioMultiplexer', () => {
|
|||||||
// no listeners, messages are ignored
|
// no listeners, messages are ignored
|
||||||
multi.stdout_writeline('out 1');
|
multi.stdout_writeline('out 1');
|
||||||
multi.stderr_writeline('err 1');
|
multi.stderr_writeline('err 1');
|
||||||
expect(a.captured_stdout).toBe("");
|
expect(a.captured_stdout).toBe('');
|
||||||
expect(a.captured_stderr).toBe("");
|
expect(a.captured_stderr).toBe('');
|
||||||
expect(b.captured_stdout).toBe("");
|
expect(b.captured_stdout).toBe('');
|
||||||
expect(b.captured_stderr).toBe("");
|
expect(b.captured_stderr).toBe('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('redirects to multiple listeners', () => {
|
it('redirects to multiple listeners', () => {
|
||||||
@@ -59,11 +57,11 @@ describe('StdioMultiplexer', () => {
|
|||||||
multi.stdout_writeline('out 2');
|
multi.stdout_writeline('out 2');
|
||||||
multi.stderr_writeline('err 2');
|
multi.stderr_writeline('err 2');
|
||||||
|
|
||||||
expect(a.captured_stdout).toBe("out 1\nout 2\n");
|
expect(a.captured_stdout).toBe('out 1\nout 2\n');
|
||||||
expect(a.captured_stderr).toBe("err 1\nerr 2\n");
|
expect(a.captured_stderr).toBe('err 1\nerr 2\n');
|
||||||
|
|
||||||
expect(b.captured_stdout).toBe("out 2\n");
|
expect(b.captured_stdout).toBe('out 2\n');
|
||||||
expect(b.captured_stderr).toBe("err 2\n");
|
expect(b.captured_stderr).toBe('err 2\n');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -75,32 +73,30 @@ describe('TargetedStdio', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
//DOM element to capture stdout and stderr
|
//DOM element to capture stdout and stderr
|
||||||
let target_div = document.getElementById("output-id");
|
let target_div = document.getElementById('output-id');
|
||||||
|
|
||||||
if (target_div === null) {
|
if (target_div === null) {
|
||||||
target_div = document.createElement('div');
|
target_div = document.createElement('div');
|
||||||
target_div.id = "output-id";
|
target_div.id = 'output-id';
|
||||||
document.body.appendChild(target_div);
|
document.body.appendChild(target_div);
|
||||||
}
|
} else {
|
||||||
else {
|
target_div.innerHTML = '';
|
||||||
target_div.innerHTML = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//DOM element to capture stderr
|
//DOM element to capture stderr
|
||||||
let error_div = document.getElementById("error-id");
|
let error_div = document.getElementById('error-id');
|
||||||
|
|
||||||
if (error_div === null) {
|
if (error_div === null) {
|
||||||
error_div = document.createElement('div');
|
error_div = document.createElement('div');
|
||||||
error_div.id = "error-id";
|
error_div.id = 'error-id';
|
||||||
document.body.appendChild(error_div);
|
document.body.appendChild(error_div);
|
||||||
}
|
} else {
|
||||||
else {
|
error_div.innerHTML = '';
|
||||||
error_div.innerHTML = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const tag = document.createElement('div');
|
const tag = document.createElement('div');
|
||||||
tag.setAttribute("output", "output-id");
|
tag.setAttribute('output', 'output-id');
|
||||||
tag.setAttribute("stderr", "error-id");
|
tag.setAttribute('stderr', 'error-id');
|
||||||
|
|
||||||
capture = new CaptureStdio();
|
capture = new CaptureStdio();
|
||||||
targeted = new TargetedStdio(tag, 'output', true, true);
|
targeted = new TargetedStdio(tag, 'output', true, true);
|
||||||
@@ -113,28 +109,28 @@ describe('TargetedStdio', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('targeted id is set by constructor', () => {
|
it('targeted id is set by constructor', () => {
|
||||||
expect(targeted.source_attribute).toBe("output");
|
expect(targeted.source_attribute).toBe('output');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('targeted stdio/stderr also goes to multiplexer', () => {
|
it('targeted stdio/stderr also goes to multiplexer', () => {
|
||||||
multi.stdout_writeline("out 1");
|
multi.stdout_writeline('out 1');
|
||||||
multi.stderr_writeline("out 2");
|
multi.stderr_writeline('out 2');
|
||||||
expect(capture.captured_stdout).toBe("out 1\n");
|
expect(capture.captured_stdout).toBe('out 1\n');
|
||||||
expect(capture.captured_stderr).toBe("out 2\n");
|
expect(capture.captured_stderr).toBe('out 2\n');
|
||||||
expect(document.getElementById("output-id")?.innerHTML).toBe("out 1<br>out 2<br>");
|
expect(document.getElementById('output-id')?.innerHTML).toBe('out 1<br>out 2<br>');
|
||||||
expect(document.getElementById("error-id")?.innerHTML).toBe("out 2<br>");
|
expect(document.getElementById('error-id')?.innerHTML).toBe('out 2<br>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Add and remove targeted listener', () => {
|
it('Add and remove targeted listener', () => {
|
||||||
multi.stdout_writeline("out 1");
|
multi.stdout_writeline('out 1');
|
||||||
multi.removeListener(targeted);
|
multi.removeListener(targeted);
|
||||||
multi.stdout_writeline("out 2");
|
multi.stdout_writeline('out 2');
|
||||||
multi.addListener(targeted);
|
multi.addListener(targeted);
|
||||||
multi.stdout_writeline("out 3");
|
multi.stdout_writeline('out 3');
|
||||||
|
|
||||||
//all three should be captured by multiplexer
|
//all three should be captured by multiplexer
|
||||||
expect(capture.captured_stdout).toBe("out 1\nout 2\nout 3\n");
|
expect(capture.captured_stdout).toBe('out 1\nout 2\nout 3\n');
|
||||||
//out 2 should not be present in the DOM element
|
//out 2 should not be present in the DOM element
|
||||||
expect(document.getElementById("output-id")?.innerHTML).toBe("out 1<br>out 3<br>");
|
expect(document.getElementById('output-id')?.innerHTML).toBe('out 1<br>out 3<br>');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,73 +1,78 @@
|
|||||||
import { beforeEach, expect, describe, it } from "@jest/globals"
|
import { beforeEach, expect, describe, it } from '@jest/globals';
|
||||||
import { ensureUniqueId, joinPaths, createSingularWarning} from "../../src/utils"
|
import { ensureUniqueId, joinPaths, createSingularWarning } from '../../src/utils';
|
||||||
|
|
||||||
describe("Utils", () => {
|
|
||||||
|
|
||||||
|
describe('Utils', () => {
|
||||||
let element: HTMLElement;
|
let element: HTMLElement;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
element = document.createElement("div");
|
element = document.createElement('div');
|
||||||
})
|
});
|
||||||
|
|
||||||
it("ensureUniqueId sets unique id on element", async () => {
|
it('ensureUniqueId sets unique id on element', async () => {
|
||||||
expect(element.id).toBe("")
|
expect(element.id).toBe('');
|
||||||
|
|
||||||
ensureUniqueId(element)
|
ensureUniqueId(element);
|
||||||
|
|
||||||
expect(element.id).toBe("py-internal-0")
|
expect(element.id).toBe('py-internal-0');
|
||||||
})
|
});
|
||||||
|
|
||||||
it("ensureUniqueId sets unique id with increasing counter", async () => {
|
it('ensureUniqueId sets unique id with increasing counter', async () => {
|
||||||
const secondElement = document.createElement("div")
|
const secondElement = document.createElement('div');
|
||||||
|
|
||||||
expect(element.id).toBe("")
|
expect(element.id).toBe('');
|
||||||
expect(secondElement.id).toBe("")
|
expect(secondElement.id).toBe('');
|
||||||
|
|
||||||
ensureUniqueId(element)
|
ensureUniqueId(element);
|
||||||
ensureUniqueId(secondElement)
|
ensureUniqueId(secondElement);
|
||||||
|
|
||||||
// The counter will have been incremented on
|
// The counter will have been incremented on
|
||||||
// the previous test, make sure it keeps increasing
|
// the previous test, make sure it keeps increasing
|
||||||
expect(element.id).toBe("py-internal-1")
|
expect(element.id).toBe('py-internal-1');
|
||||||
expect(secondElement.id).toBe("py-internal-2")
|
expect(secondElement.id).toBe('py-internal-2');
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
describe("JoinPaths", () => {
|
describe('JoinPaths', () => {
|
||||||
it("should remove trailing slashes from the beginning and the end", () => {
|
it('should remove trailing slashes from the beginning and the end', () => {
|
||||||
const paths: string[] = ['///abc/d/e///'];
|
const paths: string[] = ['///abc/d/e///'];
|
||||||
const joinedPath = joinPaths(paths);
|
const joinedPath = joinPaths(paths);
|
||||||
expect(joinedPath).toStrictEqual('/abc/d/e');
|
expect(joinedPath).toStrictEqual('/abc/d/e');
|
||||||
})
|
});
|
||||||
|
|
||||||
it("should not remove slashes from the middle to preserve protocols such as http", () => {
|
it('should not remove slashes from the middle to preserve protocols such as http', () => {
|
||||||
const paths: string[] = ['http://google.com', '///data.txt'];
|
const paths: string[] = ['http://google.com', '///data.txt'];
|
||||||
const joinedPath = joinPaths(paths);
|
const joinedPath = joinPaths(paths);
|
||||||
expect(joinedPath).toStrictEqual('http://google.com/data.txt');
|
expect(joinedPath).toStrictEqual('http://google.com/data.txt');
|
||||||
})
|
});
|
||||||
|
|
||||||
it("should not join paths when they are empty strings", () => {
|
it('should not join paths when they are empty strings', () => {
|
||||||
const paths: string[] = ['', '///hhh/ll/pp///', '', 'kkk'];
|
const paths: string[] = ['', '///hhh/ll/pp///', '', 'kkk'];
|
||||||
const joinedPath = joinPaths(paths);
|
const joinedPath = joinPaths(paths);
|
||||||
expect(joinedPath).toStrictEqual('hhh/ll/pp/kkk');
|
expect(joinedPath).toStrictEqual('hhh/ll/pp/kkk');
|
||||||
})
|
});
|
||||||
|
|
||||||
describe("createSingularBanner", () => {
|
describe('createSingularBanner', () => {
|
||||||
it("should create one and new banner containing the sentinel text, and not duplicate it", () => {
|
it('should create one and new banner containing the sentinel text, and not duplicate it', () => {
|
||||||
//One warning banner with the desired text should be created
|
//One warning banner with the desired text should be created
|
||||||
createSingularWarning("A unique error message", "unique")
|
createSingularWarning('A unique error message', 'unique');
|
||||||
expect(document.getElementsByClassName("alert-banner")?.length).toEqual(1)
|
expect(document.getElementsByClassName('alert-banner')?.length).toEqual(1);
|
||||||
expect(document.getElementsByClassName("alert-banner")[0].textContent).toEqual(expect.stringContaining("A unique error message"))
|
expect(document.getElementsByClassName('alert-banner')[0].textContent).toEqual(
|
||||||
|
expect.stringContaining('A unique error message'),
|
||||||
|
);
|
||||||
|
|
||||||
//Should still only be one banner, since the second uses the existing sentinel value "unique"
|
//Should still only be one banner, since the second uses the existing sentinel value "unique"
|
||||||
createSingularWarning("This banner should not appear", "unique")
|
createSingularWarning('This banner should not appear', 'unique');
|
||||||
expect(document.getElementsByClassName("alert-banner")?.length).toEqual(1)
|
expect(document.getElementsByClassName('alert-banner')?.length).toEqual(1);
|
||||||
expect(document.getElementsByClassName("alert-banner")[0].textContent).toEqual(expect.stringContaining("A unique error message"))
|
expect(document.getElementsByClassName('alert-banner')[0].textContent).toEqual(
|
||||||
|
expect.stringContaining('A unique error message'),
|
||||||
|
);
|
||||||
|
|
||||||
//If the sentinel value is not provided, the entire msg is used as the sentinel
|
//If the sentinel value is not provided, the entire msg is used as the sentinel
|
||||||
createSingularWarning("A unique error message", null)
|
createSingularWarning('A unique error message', null);
|
||||||
expect(document.getElementsByClassName("alert-banner")?.length).toEqual(1)
|
expect(document.getElementsByClassName('alert-banner')?.length).toEqual(1);
|
||||||
expect(document.getElementsByClassName("alert-banner")[0].textContent).toEqual(expect.stringContaining("A unique error message"))
|
expect(document.getElementsByClassName('alert-banner')[0].textContent).toEqual(
|
||||||
})
|
expect.stringContaining('A unique error message'),
|
||||||
})
|
);
|
||||||
})
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user