mirror of
https://github.com/publiclab/image-sequencer.git
synced 2025-12-08 17:30:01 +01:00
Compare commits
1 Commits
npm-ci
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6cacb9431f |
75
.github/CODEOWNERS
vendored
75
.github/CODEOWNERS
vendored
@@ -1,75 +0,0 @@
|
|||||||
# <-- DOCS FOR THIS FILE -->
|
|
||||||
# This is a comment.
|
|
||||||
# Each line is a file pattern followed by one or more owners.
|
|
||||||
|
|
||||||
# These owners will be the default owners for everything in
|
|
||||||
# the repo. Unless a later match takes precedence,
|
|
||||||
# @global-owner1 and @global-owner2 will be requested for
|
|
||||||
# review when someone opens a pull request.
|
|
||||||
# * @global-owner1 @global-owner2
|
|
||||||
|
|
||||||
# Order is important; the last matching pattern takes the most
|
|
||||||
# precedence. When someone opens a pull request that only
|
|
||||||
# modifies JS files, only @js-owner and not the global
|
|
||||||
# owner(s) will be requested for a review.
|
|
||||||
# *.js @js-owner
|
|
||||||
|
|
||||||
# You can also use email addresses if you prefer. They'll be
|
|
||||||
# used to look up users just like we do for commit author
|
|
||||||
# emails.
|
|
||||||
# *.go docs@example.com
|
|
||||||
|
|
||||||
# In this example, @doctocat owns any files in the build/logs
|
|
||||||
# directory at the root of the repository and any of its
|
|
||||||
# subdirectories.
|
|
||||||
# /build/logs/ @doctocat
|
|
||||||
|
|
||||||
# The `docs/*` pattern will match files like
|
|
||||||
# `docs/getting-started.md` but not further nested files like
|
|
||||||
# `docs/build-app/troubleshooting.md`.
|
|
||||||
# docs/* docs@example.com
|
|
||||||
|
|
||||||
# In this example, @octocat owns any file in an apps directory
|
|
||||||
# anywhere in your repository.
|
|
||||||
# apps/ @octocat
|
|
||||||
|
|
||||||
# In this example, @doctocat owns any file in the `/docs`
|
|
||||||
# directory in the root of your repository.
|
|
||||||
# /docs/ @doctocat
|
|
||||||
# <-- /DOCS FOR THIS FILE -->
|
|
||||||
|
|
||||||
# <-- COMMON TO ALL MAINTAINERS -->
|
|
||||||
/*.json @publiclab/is-maintainers
|
|
||||||
/*.md @publiclab/is-maintainers
|
|
||||||
/*.lock @ubliclab/is-maintainers
|
|
||||||
/Gruntfile.js @publiclab/is-maintainers
|
|
||||||
/.github/ @publiclab/is-maintainers
|
|
||||||
/scripts/ @publiclab/is-maintainers
|
|
||||||
# <-- /COMMON TO ALL MAINTAINERS -->
|
|
||||||
|
|
||||||
# <-- SPECIFIC MAINTAINERS -->
|
|
||||||
/index.js @publiclab/is-cli-maintainers
|
|
||||||
/src/cli/ @publiclab/is-cli-maintainers
|
|
||||||
/src/CliUtils.js @publiclab/is-cli-maintainers
|
|
||||||
|
|
||||||
/src/*.js @publiclab/is-core-maintainers
|
|
||||||
/src/*.json @publiclab/is-core-maintainers
|
|
||||||
/src/util/ @publiclab/is-core-maintainers
|
|
||||||
/test/core/* @publiclab/is-core-maintainers
|
|
||||||
|
|
||||||
/src/modules/ @publiclab/is-module-maintainers
|
|
||||||
/docs/ @publiclab/is-module-maintainers
|
|
||||||
|
|
||||||
/test/ @publiclab/is-tests-maintainers
|
|
||||||
/jest* @publiclab/is-tests-maintainers
|
|
||||||
/eslint* @publiclab/is-tests-maintainers
|
|
||||||
/travis* @publiclab/is-tests-maintainers
|
|
||||||
.travis.yml @publiclab/is-tests-maintainers
|
|
||||||
.gitpod* @publiclab/is-tests-maintainers
|
|
||||||
/gitpod* @publiclab/is-tests-maintainers
|
|
||||||
|
|
||||||
/examples/ @publiclab/is-ui-maintainers
|
|
||||||
/icons/ @publiclab/is-ui-maintainers
|
|
||||||
/test/ui-2/test/* @publiclab/is-ui-maintainers
|
|
||||||
/test/ui/spec/* @publiclab/is-ui-maintainers
|
|
||||||
# <-- /SPECIFIC MAINTAINERS -->
|
|
||||||
@@ -1,10 +1,3 @@
|
|||||||
---
|
|
||||||
name: Bug report 🐞
|
|
||||||
about: Help us identify and fix a bug!
|
|
||||||
title: ''
|
|
||||||
labels: bug
|
|
||||||
---
|
|
||||||
|
|
||||||
### Please describe the problem (or idea)
|
### Please describe the problem (or idea)
|
||||||
|
|
||||||
> What happened just before the problem occurred? Or what problem could this idea solve?
|
> What happened just before the problem occurred? Or what problem could this idea solve?
|
||||||
@@ -17,13 +10,13 @@ labels: bug
|
|||||||
|
|
||||||
### Please show us where to look
|
### Please show us where to look
|
||||||
|
|
||||||
Paste in a full URL, starting with:
|
https://beta.sequencer.publiclab.org
|
||||||
|
|
||||||
> https://beta.sequencer.publiclab.org/
|
|
||||||
|
|
||||||
If you can share a screenshot or a GIF that is EXTRA helpful! 💖
|
### What's your PublicLab.org username?
|
||||||
|
|
||||||
|
> This can help us diagnose the issue:
|
||||||
|
|
||||||
If you can see a version number in the upper right, please note that!
|
|
||||||
|
|
||||||
|
|
||||||
### Browser, version, and operating system
|
### Browser, version, and operating system
|
||||||
39
.github/ISSUE_TEMPLATE/release_workflow.md
vendored
39
.github/ISSUE_TEMPLATE/release_workflow.md
vendored
@@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
name: New release checklist ✅
|
|
||||||
about: Coordinate steps to publish a new release
|
|
||||||
title: 'Checklist and coordination for v0.0.0 major/minor/patch release'
|
|
||||||
labels: release
|
|
||||||
assignees: '@publiclab/is-maintainers'
|
|
||||||
---
|
|
||||||
|
|
||||||
This template guides us through the steps of creating a new release, based on conversation and testing in [#1692](https://github.com/publiclab/image-sequencer/issues/1692).
|
|
||||||
|
|
||||||
Discuss with @publiclab/is-maintainers if anything is ambiguous!
|
|
||||||
|
|
||||||
<!-- NOTE: Change v0.0.0 to the appropriate release version -->
|
|
||||||
|
|
||||||
* [x] open an issue using the "release" template with this checklist with title `Checklist and coordination for v0.0.0 major/minor/patch release` (see [semantic versioning](https://docs.npmjs.com/about-semantic-versioning/))
|
|
||||||
* [ ] create a release [project](https://github.com/publiclab/image-sequencer/projects) from [this template](https://github.com/publiclab/image-sequencer/projects/5). You can copy a project from its menu.
|
|
||||||
* [ ] compile release notes below from corresponding [release project](https://github.com/publiclab/image-sequencer/projects).
|
|
||||||
* [ ] update version number in `examples/sw.js` (ex #1734) and `package.json` (ex #1695)
|
|
||||||
* [ ] finalize and merge to `main` branch (freeze merges to `main` branch until next step)
|
|
||||||
* [ ] merge, build and publish `/dist/` files to `stable` (merges to `main` branch can resume for next release)
|
|
||||||
* [ ] create a release on GitHub and use features description + release notes from below
|
|
||||||
* [ ] tag version number branch (i.e. `v0.0.0`)
|
|
||||||
* [ ] publish tagged branch to `npm`
|
|
||||||
* [ ] publish to live Github pages [demo](https://sequencer.publiclab.org) (with [bash script](https://github.com/publiclab/image-sequencer/pull/1703) from `/scripts/update-demo`) (from within GitPod works well)
|
|
||||||
* [ ] move anything necessary to next release project, i.e. <!-- Update this link -->https://github.com/publiclab/image-sequencer/projects/[insert project number]
|
|
||||||
* [ ] close this issue!
|
|
||||||
|
|
||||||
Noting we're now in this process in https://github.com/publiclab/image-sequencer/pull/1695 for `v3.6.0`.
|
|
||||||
|
|
||||||
****
|
|
||||||
|
|
||||||
### Release notes
|
|
||||||
Compile and edit release notes below, to be copied into the release description.
|
|
||||||
|
|
||||||
#### Added
|
|
||||||
|
|
||||||
#### Fixed
|
|
||||||
|
|
||||||
#### Changed
|
|
||||||
17
.github/config.yml
vendored
17
.github/config.yml
vendored
@@ -4,27 +4,22 @@
|
|||||||
|
|
||||||
# Comment to be posted to on first time issues
|
# Comment to be posted to on first time issues
|
||||||
newIssueWelcomeComment: |
|
newIssueWelcomeComment: |
|
||||||
Thanks for opening your first issue here! This space is [protected by our Code of Conduct](https://publiclab.org/conduct) - and we're here to help.
|
Thanks for opening your first issue here! Please follow the issue template to help us help you 👍🎉😄
|
||||||
Please follow the issue template to help us help you 👍🎉😄
|
If you have screenshots to share demonstrating the issue, that's really helpful! 📸 You can [make a gif](https://www.cockos.com/licecap/) too!
|
||||||
If you have screenshots to share demonstrating the issue, that's really helpful! 📸 You can [make a gif](https://www.cockos.com/licecap/) too!
|
|
||||||
Don't forget to join our [PublicLab Gitter channel](https://gitter.im/publiclab/publiclab) and our [ImageSequencer Gitter Channel](https://gitter.im/publiclab/image-sequencer) for some brainstorming discussions.
|
|
||||||
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
|
# Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
|
||||||
|
|
||||||
# Comment to be posted to on PRs from first time contributors in your repository
|
# Comment to be posted to on PRs from first time contributors in your repository
|
||||||
newPRWelcomeComment: |
|
newPRWelcomeComment: |
|
||||||
Thanks for opening this pull request! This space is [protected by our Code of Conduct](https://publiclab.org/conduct).
|
Thanks for opening this pull request!
|
||||||
There may be some errors, **but don't worry!** We're here to help! 👍🎉😄
|
There may be some errors, **but don't worry!** We're here to help! 👍🎉😄
|
||||||
Also please refer (https://github.com/publiclab/image-sequencer/blob/main/README.md) for installation help.
|
|
||||||
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
|
# Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
|
||||||
|
|
||||||
# Comment to be posted to on pull requests merged by a first time user
|
# Comment to be posted to on pull requests merged by a first time user
|
||||||
firstPRMergeComment: |
|
firstPRMergeComment: |
|
||||||
Congrats on merging your first pull request! 🙌🎉⚡️
|
Congrats on merging your first pull request! 🙌🎉⚡️
|
||||||
Your code will be published to https://beta.sequencer.publiclab.org in a day or two. Please test out your work on this testing server and report back with a comment that all has gone well!
|
Your code will be published to https://beta.sequencer.publiclab.org in a day or two.
|
||||||
In the meantime, can you tell us your Twitter handle so we can thank you properly also do join our weekly check-in to share your this week goal and the awesome work you did 😃.
|
In the meantime, can you tell us your Twitter handle so we can thank you properly?
|
||||||
Please find the link **pinned in the issue section**
|
Now that you've completed this, you can help someone else take their first step!
|
||||||
Now that you've completed this, you can help someone else take their first step! Try looking at this list of `first-timers-only` issues, and see if someone else is waiting for feedback, or even stuck! 😕
|
|
||||||
People often get stuck at the same steps, so you might be able to help someone get unstuck, or help lead them to some documentation that'd help. Reach out and be encouraging and friendly! 😄 🎉
|
|
||||||
See: [Public Lab's coding community!](https://code.publiclab.org)
|
See: [Public Lab's coding community!](https://code.publiclab.org)
|
||||||
|
|
||||||
# It is recommended to include as many gifs and emojis as possible
|
# It is recommended to include as many gifs and emojis as possible
|
||||||
|
|||||||
209
.github/workflows/tests.yml
vendored
209
.github/workflows/tests.yml
vendored
@@ -1,209 +0,0 @@
|
|||||||
name: tests
|
|
||||||
on: [pull_request]
|
|
||||||
jobs:
|
|
||||||
base-tests:
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Setup node
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: '12'
|
|
||||||
check-latest: true
|
|
||||||
- name: Cache node modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
env:
|
|
||||||
cache-name: cache-node-modules
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
|
||||||
${{ runner.os }}-build-
|
|
||||||
${{ runner.os }}-
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm ci
|
|
||||||
- name: "Base istanbul/tape node tests"
|
|
||||||
run: npm test
|
|
||||||
|
|
||||||
benchmark-tests:
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Setup node
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: '12'
|
|
||||||
check-latest: true
|
|
||||||
- name: Cache node modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
env:
|
|
||||||
cache-name: cache-node-modules
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
|
||||||
${{ runner.os }}-build-
|
|
||||||
${{ runner.os }}-
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm install
|
|
||||||
- name: "Benchmark tests"
|
|
||||||
run: npm run benchmark
|
|
||||||
|
|
||||||
gif-tests:
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Setup node
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: '12'
|
|
||||||
check-latest: true
|
|
||||||
- name: Cache node modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
env:
|
|
||||||
cache-name: cache-node-modules
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
|
||||||
${{ runner.os }}-build-
|
|
||||||
${{ runner.os }}-
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm install
|
|
||||||
- name: "Gif tests"
|
|
||||||
run: npm run gif-test
|
|
||||||
|
|
||||||
browserify-core-tests:
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Setup node
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: '12'
|
|
||||||
check-latest: true
|
|
||||||
- name: Cache node modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
env:
|
|
||||||
cache-name: cache-node-modules
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
|
||||||
${{ runner.os }}-build-
|
|
||||||
${{ runner.os }}-
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm install
|
|
||||||
- run: sudo apt-get install xvfb
|
|
||||||
- name: "Browserify core tests and run"
|
|
||||||
run: grunt tests && xvfb-run --auto-servernum npm run core-tests
|
|
||||||
|
|
||||||
jsmine-ui-tests:
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Setup node
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: '12'
|
|
||||||
check-latest: true
|
|
||||||
- name: Cache node modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
env:
|
|
||||||
cache-name: cache-node-modules
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
|
||||||
${{ runner.os }}-build-
|
|
||||||
${{ runner.os }}-
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm install
|
|
||||||
- name: "Jasmine UI tests (mocked browser env)"
|
|
||||||
run: npm run test-ui
|
|
||||||
|
|
||||||
jest-ui-tests:
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Setup node
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: '12'
|
|
||||||
check-latest: true
|
|
||||||
- name: Cache node modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
env:
|
|
||||||
cache-name: cache-node-modules
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
|
||||||
${{ runner.os }}-build-
|
|
||||||
${{ runner.os }}-
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm install
|
|
||||||
- name: "jest-puppeteer UI tests (full browser env)"
|
|
||||||
run: npm run test-ui-2
|
|
||||||
|
|
||||||
cli-tests:
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Setup node
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: '12'
|
|
||||||
check-latest: true
|
|
||||||
- name: Cache node modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
env:
|
|
||||||
cache-name: cache-node-modules
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
|
||||||
${{ runner.os }}-build-
|
|
||||||
${{ runner.os }}-
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm install
|
|
||||||
- name: "CLI tests"
|
|
||||||
run: npm run test-cli
|
|
||||||
|
|
||||||
grunt-build-test:
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Setup node
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: '12'
|
|
||||||
check-latest: true
|
|
||||||
- name: Cache node modules
|
|
||||||
uses: actions/cache@v2
|
|
||||||
env:
|
|
||||||
cache-name: cache-node-modules
|
|
||||||
with:
|
|
||||||
path: ~/.npm
|
|
||||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
|
||||||
${{ runner.os }}-build-
|
|
||||||
${{ runner.os }}-
|
|
||||||
- name: Install Dependencies
|
|
||||||
run: npm install
|
|
||||||
- name: "Grunt build test of dev environment"
|
|
||||||
run: grunt build
|
|
||||||
|
|
||||||
## Cache NPM folder
|
|
||||||
# cache:
|
|
||||||
# directories:
|
|
||||||
# - ~/.npm
|
|
||||||
# - ~/.cache
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
FROM gitpod/workspace-full
|
|
||||||
|
|
||||||
USER root
|
|
||||||
RUN sudo apt-get update && apt-get install -y apt-transport-https \
|
|
||||||
&& sudo apt-get install -y \
|
|
||||||
xserver-xorg-dev \
|
|
||||||
libxext-dev \
|
|
||||||
build-essential \
|
|
||||||
libxi-dev \
|
|
||||||
libglew-dev \
|
|
||||||
pkg-config \
|
|
||||||
libglu1-mesa-dev \
|
|
||||||
freeglut3-dev \
|
|
||||||
mesa-common-dev \
|
|
||||||
x11-apps \
|
|
||||||
libice6 \
|
|
||||||
libsm6 \
|
|
||||||
libxaw7 \
|
|
||||||
libxft2 \
|
|
||||||
libxmu6 \
|
|
||||||
libxpm4 \
|
|
||||||
libxt6 \
|
|
||||||
x11-apps \
|
|
||||||
xbitmaps \
|
|
||||||
ca-certificates \
|
|
||||||
fonts-liberation \
|
|
||||||
libappindicator3-1 \
|
|
||||||
libasound2 \
|
|
||||||
libatk-bridge2.0-0 \
|
|
||||||
libatk1.0-0 \
|
|
||||||
libc6 \
|
|
||||||
libcairo2 \
|
|
||||||
libcups2 \
|
|
||||||
libdbus-1-3 \
|
|
||||||
libexpat1 \
|
|
||||||
libfontconfig1 \
|
|
||||||
libgbm1 \
|
|
||||||
libgcc1 \
|
|
||||||
libglib2.0-0 \
|
|
||||||
libgtk-3-0 \
|
|
||||||
libnspr4 \
|
|
||||||
libnss3 \
|
|
||||||
libpango-1.0-0 \
|
|
||||||
libpangocairo-1.0-0 \
|
|
||||||
libstdc++6 \
|
|
||||||
libx11-6 \
|
|
||||||
libx11-xcb1 \
|
|
||||||
libxcb1 \
|
|
||||||
libxcomposite1 \
|
|
||||||
libxcursor1 \
|
|
||||||
libxdamage1 \
|
|
||||||
libxext6 \
|
|
||||||
libxfixes3 \
|
|
||||||
libxi6 \
|
|
||||||
libxrandr2 \
|
|
||||||
libxrender1 \
|
|
||||||
libxss1 \
|
|
||||||
libxtst6 \
|
|
||||||
lsb-release \
|
|
||||||
wget \
|
|
||||||
xdg-utils \
|
|
||||||
xvfb \
|
|
||||||
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/*
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
image:
|
|
||||||
file: .gitpod.dockerfile
|
|
||||||
tasks:
|
tasks:
|
||||||
- init: npm run setup
|
- init: npm run setup
|
||||||
command: npm start
|
command: npm start
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
sudo: required
|
sudo: required
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
|
- '8'
|
||||||
- '10'
|
- '10'
|
||||||
- '12'
|
|
||||||
env:
|
env:
|
||||||
- CXX=g++-4.8
|
- CXX=g++-4.8
|
||||||
before_script:
|
before_script:
|
||||||
@@ -23,9 +23,7 @@ jobs:
|
|||||||
- name: "Jasmine UI tests (mocked browser env)"
|
- name: "Jasmine UI tests (mocked browser env)"
|
||||||
script: npm run test-ui
|
script: npm run test-ui
|
||||||
- name: "jest-puppeteer UI tests (full browser env)"
|
- name: "jest-puppeteer UI tests (full browser env)"
|
||||||
script: npm run test-ui-2
|
script: npm run test-ui-2
|
||||||
- name: "CLI tests"
|
|
||||||
script: npm run test-cli
|
|
||||||
- name: "Grunt build test of dev environment"
|
- name: "Grunt build test of dev environment"
|
||||||
script: grunt build
|
script: grunt build
|
||||||
after_success:
|
after_success:
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ Most contribution (we imagine) would be in the form of API-compatible modules, w
|
|||||||
* [Ideas](#Contribution-ideas)
|
* [Ideas](#Contribution-ideas)
|
||||||
* [Grunt Tasks](#grunt-tasks)
|
* [Grunt Tasks](#grunt-tasks)
|
||||||
* [UI Helper Methods](#ui-helper-methods)
|
* [UI Helper Methods](#ui-helper-methods)
|
||||||
* [Scripts](#scripts)
|
|
||||||
|
|
||||||
****
|
****
|
||||||
|
|
||||||
@@ -375,7 +374,7 @@ module.exports =
|
|||||||
We are now using `eslint` and `husky` to help lint and format our code each time we commit. Eslint defines coding standards and helps in cleaning up the code. To run eslint for checking errors globally or within a specific file run:
|
We are now using `eslint` and `husky` to help lint and format our code each time we commit. Eslint defines coding standards and helps in cleaning up the code. To run eslint for checking errors globally or within a specific file run:
|
||||||
|
|
||||||
```
|
```
|
||||||
npx eslint .
|
npx eslint .
|
||||||
|
|
||||||
npx eslint <file path>
|
npx eslint <file path>
|
||||||
```
|
```
|
||||||
@@ -413,15 +412,15 @@ The following command is used for running the tasks: `grunt [task-name]`. Here `
|
|||||||
|
|
||||||
The method returns a scoped `jQuery` object which only searches for elements inside a given scope (a DOM element).
|
The method returns a scoped `jQuery` object which only searches for elements inside a given scope (a DOM element).
|
||||||
|
|
||||||
To use the method,
|
To use the method,
|
||||||
* import the `scopeSelector` and `scopeSelectorAll` methods from `lib/scopeQuery.js`
|
* import the `scopeSelector` and `scopeSelectorAll` methods from `lib/scopeQuery.js`
|
||||||
* call the methods with scope as a parameter
|
* call the methods with scope as a parameter
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var scopeQuery = require('./scopeQuery');
|
var scopeQuery = require('./scopeQuery');
|
||||||
|
|
||||||
var $step = scopeQuery.scopeSelector(scope),
|
var $step = scopeQuery.scopeSelector(scope),
|
||||||
$stepAll = scopeQuery.scopeSelectorAll(scope);
|
$stepAll = scopeQuery.scopeSelectorAll(scope);
|
||||||
```
|
```
|
||||||
This will return an object with a constructor which returns a `jQuery` object (from inside the scope) but with new `elem` and `elemAll` methods.
|
This will return an object with a constructor which returns a `jQuery` object (from inside the scope) but with new `elem` and `elemAll` methods.
|
||||||
|
|
||||||
@@ -434,7 +433,7 @@ This will return an object with a constructor which returns a `jQuery` object (f
|
|||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
```js
|
```js
|
||||||
//The scope is a div element with id=“container“ and there are three divs in it
|
//The scope is a div element with id=“container“ and there are three divs in it
|
||||||
//with ids „1“, „2“, and „3“, and all of them have a „child“ class attribute
|
//with ids „1“, „2“, and „3“, and all of them have a „child“ class attribute
|
||||||
|
|
||||||
var $step = require('./scopeQuery').scopeSelector(document.getElementById('container'));
|
var $step = require('./scopeQuery').scopeSelector(document.getElementById('container'));
|
||||||
@@ -459,23 +458,3 @@ The following code can be used
|
|||||||
$step('query').show().hide();
|
$step('query').show().hide();
|
||||||
$stepAll('q2').show().hide();
|
$stepAll('q2').show().hide();
|
||||||
```
|
```
|
||||||
|
|
||||||
## Scripts
|
|
||||||
The following shell scripts are present in the `scripts/` directory.
|
|
||||||
|
|
||||||
- `update-gh-pages`: This script can be used to update the `gh-pages` branch of this repo or a fork.
|
|
||||||
This script is not meant to be used directly as it runs in the current working directory.
|
|
||||||
If you run it on your primary local clone, it can **delete** the local changes. This script is made to be used in a github action
|
|
||||||
or in a temporary directory via another script, such as `update-demo`.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
1. Repo(to use as upstream) url in the form username/repo (default: publiclab/image-sequencer) NOTE: Github only
|
|
||||||
2. Branch to pull from eg: main or stable (default: stable)
|
|
||||||
3. CNAME URL (default: none)
|
|
||||||
4. Set the fourth argument to anything to bypass the warning. You will have to set this argument if you want to run this script in another script without needing
|
|
||||||
user interaction, such as in a github action.
|
|
||||||
|
|
||||||
- `update-demo`: A safe, interactive script that can be used to update the `gh-pages` branch of any image-sequencer fork.
|
|
||||||
This script is safe to use directly because it separately clones the repo in a temporary directory.
|
|
||||||
|
|
||||||
Arguments: None since it is a an *interactive* script, ie it asks the user for input.
|
|
||||||
|
|||||||
16
README.md
16
README.md
@@ -2,18 +2,13 @@ Image Sequencer
|
|||||||
====
|
====
|
||||||
|
|
||||||
[](https://publiclab.org/conduct)
|
[](https://publiclab.org/conduct)
|
||||||
[](https://badge.fury.io/js/image-sequencer)
|
|
||||||
[](https://travis-ci.org/publiclab/image-sequencer) [](https://codeclimate.com/github/publiclab/image-sequencer/maintainability) [](https://codecov.io/gh/publiclab/image-sequencer)
|
[](https://travis-ci.org/publiclab/image-sequencer) [](https://codeclimate.com/github/publiclab/image-sequencer/maintainability) [](https://codecov.io/gh/publiclab/image-sequencer)
|
||||||
[](https://gitpod.io/#https://github.com/publiclab/image-sequencer/)
|
[](https://gitpod.io/from-referrer/)
|
||||||
|
|
||||||
- **Latest Stable Demo**: https://sequencer.publiclab.org
|
- **Latest Stable Demo**: https://sequencer.publiclab.org
|
||||||
- **Latest Beta Demo**: https://beta.sequencer.publiclab.org
|
- **Latest Beta Demo**: https://beta.sequencer.publiclab.org
|
||||||
- **Stable Branch**: https://github.com/publiclab/image-sequencer/tree/stable/
|
- **Stable Branch**: https://github.com/publiclab/image-sequencer/tree/stable/
|
||||||
|
|
||||||
Begin running (and contributing to) this codebase immediately with [GitPod](https://gitpod.io) (this also opens the latest `main` branch code):
|
|
||||||
|
|
||||||
[](https://gitpod.io/#https://github.com/publiclab/image-sequencer)
|
|
||||||
|
|
||||||
## Why
|
## Why
|
||||||
|
|
||||||
Image Sequencer is different from other image processing systems because it's _non-destructive_: instead of modifying the original image, it **creates a new image at each step in a sequence**. This is because it:
|
Image Sequencer is different from other image processing systems because it's _non-destructive_: instead of modifying the original image, it **creates a new image at each step in a sequence**. This is because it:
|
||||||
@@ -620,7 +615,8 @@ The final frames are then converted back to a GIF but in the process, the time d
|
|||||||
Modules that do not work:
|
Modules that do not work:
|
||||||
1. ColorBar (Will get fixed upon fixing overlay as this is a meta module which uses overlay)
|
1. ColorBar (Will get fixed upon fixing overlay as this is a meta module which uses overlay)
|
||||||
2. FisheyeGL
|
2. FisheyeGL
|
||||||
3. Overlay
|
4. Overlay
|
||||||
4. Blend
|
5. Text Overlay (Almost fixed)
|
||||||
5. Histogram
|
6. Blend
|
||||||
6. WebGL Distort
|
7. Histogram
|
||||||
|
8. WebGL Distort
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
/* https://github.com/theleagueof/league-spartan */
|
/* https://github.com/theleagueof/league-spartan */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'League Spartan';
|
font-family: 'League Spartan';
|
||||||
src: url('https://cdn.jsdelivr.net/npm/fontsource-league-spartan@3/files/league-spartan-latin-600-normal.woff2') format('woff2'),
|
src: url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.eot');
|
||||||
url('https://cdn.jsdelivr.net/npm/fontsource-league-spartan@3/files/league-spartan-latin-600-normal.woff') format('woff');
|
src: url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.eot?#iefix') format('embedded-opentype'),
|
||||||
|
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.woff2') format('woff2'),
|
||||||
|
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.woff') format('woff'),
|
||||||
|
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.ttf') format('truetype'),
|
||||||
|
url('https://raw.githubusercontent.com/theleagueof/league-spartan/master/_webfonts/leaguespartan-bold.svg#league_spartanbold') format('svg');
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
@@ -40,6 +44,7 @@ body > .container-fluid {
|
|||||||
.panel {
|
.panel {
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
|
min-width:400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mouse {
|
.mouse {
|
||||||
@@ -61,6 +66,7 @@ body > .container-fluid {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #444;
|
color: #444;
|
||||||
|
min-width:300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropzone input {
|
.dropzone input {
|
||||||
@@ -150,13 +156,6 @@ body > .container-fluid {
|
|||||||
margin: 0px 0px 0px 10px;
|
margin: 0px 0px 0px 10px;
|
||||||
width: 250px;
|
width: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width: 768px) {
|
|
||||||
#dropzone {
|
|
||||||
margin: 0 0% 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#dwnld {
|
#dwnld {
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
@@ -325,7 +324,7 @@ a.name-header{
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
right: 2%;
|
right: 2%;
|
||||||
top: 5%;
|
top: 5%;
|
||||||
color: gray;
|
color: lightgray;
|
||||||
}
|
}
|
||||||
/* Non float rightward alignment*/
|
/* Non float rightward alignment*/
|
||||||
.right {
|
.right {
|
||||||
|
|||||||
@@ -340,7 +340,6 @@ window.onload = function () {
|
|||||||
else
|
else
|
||||||
step.imgElement.src = url;
|
step.imgElement.src = url;
|
||||||
insertPreview.updatePreviews(url, document.querySelector('#addStep'));
|
insertPreview.updatePreviews(url, document.querySelector('#addStep'));
|
||||||
DefaultHtmlStepUi(sequencer).updateDimensions(step);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -60,13 +60,13 @@
|
|||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
|
||||||
<header class="text-center">
|
<header class="text-center" style="min-width: 450px">
|
||||||
<h1><a href="/" target='_blank' class="name-header">Image Sequencer</a></h1>
|
<h1><a href="/" target='_blank' class="name-header">Image Sequencer</a></h1>
|
||||||
<p>
|
<p>
|
||||||
A pure JavaScript sequential image processing system, inspired by storyboards. Instead of modifying the original
|
A pure JavaScript sequential image processing system, inspired by storyboards. Instead of modifying the original
|
||||||
image, it
|
image, it
|
||||||
creates a new image at each step in a sequence.
|
creates a new image at each step in a sequence.
|
||||||
<a href="https://publiclab.org/image-sequencer">Learn more</a>
|
<a href="https://github.com/publiclab/image-sequencer/blob/main/README.md">Learn more</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Open Source
|
Open Source
|
||||||
@@ -218,7 +218,7 @@
|
|||||||
<h2>Need Help?</h2>
|
<h2>Need Help?</h2>
|
||||||
<p>
|
<p>
|
||||||
<a class="btn btn-default" href="https://github.com/publiclab/image-sequencer/issues">Ask a question</a>
|
<a class="btn btn-default" href="https://github.com/publiclab/image-sequencer/issues">Ask a question</a>
|
||||||
<a class="btn btn-default" href="https://gitter.im/publiclab/image-sequencer" target="_blank">Ask in our chatroom </a>
|
<a class="btn btn-default" href="https://publiclab.org/chat">Ask in our chatroom</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
@@ -232,7 +232,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<p id="version-number-text">Loading Version Number</p>
|
<p id="version-number-text">Unable to load version number</p>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ function DefaultHtmlSequencerUi(_sequencer, options) {
|
|||||||
function selectNewStepUi() {
|
function selectNewStepUi() {
|
||||||
var m = $(addStepSel + ' select').val();
|
var m = $(addStepSel + ' select').val();
|
||||||
if(!m) m = arguments[0];
|
if(!m) m = arguments[0];
|
||||||
else $(addStepSel + ' .info').html(_sequencer.modulesInfo(m).description);
|
$(addStepSel + ' .info').html(_sequencer.modulesInfo(m).description);
|
||||||
$(addStepSel + ' #add-step-btn').prop('disabled', false);
|
$(addStepSel + ' #add-step-btn').prop('disabled', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ function DefaultHtmlStepUi(_sequencer, options) {
|
|||||||
'"max="' +
|
'"max="' +
|
||||||
inputDesc.max +
|
inputDesc.max +
|
||||||
'"step="' +
|
'"step="' +
|
||||||
inputDesc.step + '">' + '<span>' + paramVal + '</span>';
|
(inputDesc.step ? inputDesc.step : 1) + '">' + '<span>' + paramVal + '</span>';
|
||||||
|
|
||||||
}
|
}
|
||||||
else html += '">';
|
else html += '">';
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ function mapHtmlTypes(inputInfo){
|
|||||||
switch(inputInfo.type.toLowerCase()){
|
switch(inputInfo.type.toLowerCase()){
|
||||||
case 'integer':
|
case 'integer':
|
||||||
htmlType = inputInfo.min != undefined ? 'range' : 'number';
|
htmlType = inputInfo.min != undefined ? 'range' : 'number';
|
||||||
if (htmlType === 'range') inputInfo.step = inputInfo.step || 1; // default range step size for integer
|
|
||||||
break;
|
break;
|
||||||
case 'string':
|
case 'string':
|
||||||
htmlType = 'text';
|
htmlType = 'text';
|
||||||
@@ -20,7 +19,6 @@ function mapHtmlTypes(inputInfo){
|
|||||||
break;
|
break;
|
||||||
case 'float':
|
case 'float':
|
||||||
htmlType = inputInfo.min != undefined ? 'range' : 'text';
|
htmlType = inputInfo.min != undefined ? 'range' : 'text';
|
||||||
if (htmlType === 'range') inputInfo.step = inputInfo.step || 0.1; // default range step size for float
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
htmlType = 'text';
|
htmlType = 'text';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const staticCacheName = 'image-sequencer-static-v3.6.0';
|
const staticCacheName = 'image-sequencer-static-v3.5.1';
|
||||||
self.addEventListener('install', event => {
|
self.addEventListener('install', event => {
|
||||||
console.log('Attempting to install service worker');
|
console.log('Attempting to install service worker');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
launch: {
|
launch: {
|
||||||
args: ['--no-sandbox', '--disable-setuid-sandbox'], // https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#setting-up-chrome-linux-sandbox
|
|
||||||
headless: process.env.HEADLESS !== 'false',
|
headless: process.env.HEADLESS !== 'false',
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
|
|||||||
6962
package-lock.json
generated
6962
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
38
package.json
38
package.json
@@ -1,18 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "image-sequencer",
|
"name": "image-sequencer",
|
||||||
"version": "3.6.0",
|
"version": "3.5.1",
|
||||||
"description": "A modular JavaScript image manipulation library modeled on a storyboard.",
|
"description": "A modular JavaScript image manipulation library modeled on a storyboard.",
|
||||||
"main": "src/ImageSequencer.js",
|
"main": "src/ImageSequencer.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"debug": "TEST=true node ./index.js -i ./examples/images/monarch.png -s invert",
|
"debug": "TEST=true node ./index.js -i ./examples/images/monarch.png -s invert",
|
||||||
"test": "TEST=true istanbul cover tape test/core/*.js test/core/ui/user-interface.js test/core/modules/*.js | tap-spec;",
|
"test": "TEST=true istanbul cover tape test/core/*.js test/core/ui/user-interface.js test/core/modules/*.js | tap-spec;",
|
||||||
"benchmark": "node test/core/sequencer/benchmark.js | tap-spec;",
|
"benchmark" : "node test/core/sequencer/benchmark.js | tap-spec;",
|
||||||
"gif-test": "node test/core/gifs/gif-test.js | tap-spec;",
|
"gif-test" : "node test/core/gifs/gif-test.js | tap-spec;",
|
||||||
"core-tests": "cat ./output/core-tests.js | tape-run --render=\"tap-spec\"",
|
"core-tests" : "cat ./output/core-tests.js | tape-run --render=\"tap-spec\"",
|
||||||
"test-all": "npm run test && npm run benchmark && npm run gif-test && grunt tests && npm run core-tests",
|
"test-all": "npm run test && npm run benchmark && npm run gif-test && grunt tests && npm run core-tests",
|
||||||
"test-ui": "node node_modules/jasmine/bin/jasmine test/ui/spec/*.js",
|
"test-ui": "node node_modules/jasmine/bin/jasmine test/ui/spec/*.js",
|
||||||
"test-ui-2": "node ./node_modules/.bin/jest",
|
"test-ui-2": "node ./node_modules/.bin/jest",
|
||||||
"test-cli": "node test/cli/*.js | tap-spec",
|
|
||||||
"setup": "npm i && npm i -g grunt grunt-cli && npm rebuild --build-from-source && grunt build",
|
"setup": "npm i && npm i -g grunt grunt-cli && npm rebuild --build-from-source && grunt build",
|
||||||
"start": "grunt serve"
|
"start": "grunt serve"
|
||||||
},
|
},
|
||||||
@@ -40,8 +39,8 @@
|
|||||||
"base64-img": "^1.0.4",
|
"base64-img": "^1.0.4",
|
||||||
"bootstrap": "^3.4.1",
|
"bootstrap": "^3.4.1",
|
||||||
"bootstrap-colorpicker": "^2.5.3",
|
"bootstrap-colorpicker": "^2.5.3",
|
||||||
"buffer": "~6.0.2",
|
"buffer": "~5.6.0",
|
||||||
"commander": "^6.2.0",
|
"commander": "^4.0.1",
|
||||||
"compressorjs": "^1.0.5",
|
"compressorjs": "^1.0.5",
|
||||||
"data-uri-to-buffer": "^3.0.0",
|
"data-uri-to-buffer": "^3.0.0",
|
||||||
"downloadjs": "^1.4.7",
|
"downloadjs": "^1.4.7",
|
||||||
@@ -56,22 +55,22 @@
|
|||||||
"image-sequencer-invert": "^1.0.0",
|
"image-sequencer-invert": "^1.0.0",
|
||||||
"imagejs": "0.0.9",
|
"imagejs": "0.0.9",
|
||||||
"imagemin": "^7.0.1",
|
"imagemin": "^7.0.1",
|
||||||
"imagemin-jpegtran": "^7.0.0",
|
"imagemin-jpegtran": "^6.0.0",
|
||||||
"imagemin-pngquant": "^9.0.1",
|
"imagemin-pngquant": "^8.0.0",
|
||||||
"imgareaselect": "git://github.com/jywarren/imgareaselect.git#v1.0.0-rc.2",
|
"imgareaselect": "git://github.com/jywarren/imgareaselect.git#v1.0.0-rc.2",
|
||||||
"istanbul": "^0.4.5",
|
"istanbul": "^0.4.5",
|
||||||
"jasmine": "^3.4.0",
|
"jasmine": "^3.4.0",
|
||||||
"jpegtran-bin": "^5.0.2",
|
"jpegtran-bin": "^4.0.0",
|
||||||
"jquery": "^3.3.1",
|
"jquery": "^3.3.1",
|
||||||
"jsdom": "^16.3.0",
|
"jsdom": "^15.0.0",
|
||||||
"jspdf": "^2.1.1",
|
"jspdf": "^1.5.3",
|
||||||
"jsqr": "^1.1.1",
|
"jsqr": "^1.1.1",
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"ndarray": "^1.0.18",
|
"ndarray": "^1.0.18",
|
||||||
"opencv.js": "^1.2.1",
|
"opencv.js": "^1.2.1",
|
||||||
"ora": "^5.1.0",
|
"ora": "^4.0.3",
|
||||||
"pace": "0.0.4",
|
"pace": "0.0.4",
|
||||||
"pngquant-bin": "^6.0.0",
|
"pngquant-bin": "^5.0.2",
|
||||||
"puppeteer": "^1.14.0",
|
"puppeteer": "^1.14.0",
|
||||||
"qrcode": "^1.3.3",
|
"qrcode": "^1.3.3",
|
||||||
"readline-sync": "^1.4.7",
|
"readline-sync": "^1.4.7",
|
||||||
@@ -86,7 +85,7 @@
|
|||||||
"@babel/plugin-proposal-object-rest-spread": "^7.4.3",
|
"@babel/plugin-proposal-object-rest-spread": "^7.4.3",
|
||||||
"@babel/plugin-syntax-object-rest-spread": "^7.2.0",
|
"@babel/plugin-syntax-object-rest-spread": "^7.2.0",
|
||||||
"babelify": "^10.0.0",
|
"babelify": "^10.0.0",
|
||||||
"browserify": "17.0.0",
|
"browserify": "16.5.0",
|
||||||
"eslint": "^6.1.0",
|
"eslint": "^6.1.0",
|
||||||
"grunt": "^1.0.3",
|
"grunt": "^1.0.3",
|
||||||
"grunt-browser-sync": "^2.2.0",
|
"grunt-browser-sync": "^2.2.0",
|
||||||
@@ -100,16 +99,15 @@
|
|||||||
"image-filter-threshold": "~2.0.1",
|
"image-filter-threshold": "~2.0.1",
|
||||||
"jasmine-core": "^3.3.0",
|
"jasmine-core": "^3.3.0",
|
||||||
"jasmine-jquery": "^2.1.1",
|
"jasmine-jquery": "^2.1.1",
|
||||||
"jasmine-spec-reporter": "^6.0.0",
|
"jasmine-spec-reporter": "^4.2.1",
|
||||||
"jest": "^26.1.0",
|
"jest": "^25.1.0",
|
||||||
"jest-puppeteer": "^4.3.0",
|
"jest-puppeteer": "^4.3.0",
|
||||||
"lint-staged": "^10.0.3",
|
"lint-staged": "^10.0.3",
|
||||||
"looks-same": "^7.0.0",
|
"looks-same": "^7.0.0",
|
||||||
"matchdep": "^2.0.0",
|
"matchdep": "^2.0.0",
|
||||||
"resemblejs": "^3.2.5",
|
|
||||||
"tap-spec": "^5.0.0",
|
"tap-spec": "^5.0.0",
|
||||||
"tape": "^4.9.2",
|
"tape": "^4.9.2",
|
||||||
"tape-run": "^8.0.0",
|
"tape-run": "^7.0.0",
|
||||||
"uglify-es": "^3.3.7"
|
"uglify-es": "^3.3.7"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
@@ -121,4 +119,4 @@
|
|||||||
"bin": {
|
"bin": {
|
||||||
"sequencer": "./index.js"
|
"sequencer": "./index.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
scriptsDir=$(realpath $(dirname $0))
|
|
||||||
|
|
||||||
echo -ne "Enter the repo to push to in the form username/repo (required): "
|
|
||||||
read -e pushRepo
|
|
||||||
|
|
||||||
echo -ne "Enter repo URL to pull from (upstream) in the form username/repo (default: publiclab/image-sequencer): "
|
|
||||||
read -e repoInput
|
|
||||||
|
|
||||||
echo -ne "Enter branch name (default: stable): "
|
|
||||||
read -e branchInput
|
|
||||||
|
|
||||||
echo -ne "Enter CNAME URL(default: none): "
|
|
||||||
read -e cnameUrlInput
|
|
||||||
|
|
||||||
tempDir=$(mktemp -d)
|
|
||||||
pushd $tempDir > /dev/null
|
|
||||||
|
|
||||||
git clone https://github.com/$pushRepo
|
|
||||||
pushd image-sequencer > /dev/null
|
|
||||||
|
|
||||||
$scriptsDir/update-gh-pages "$repoInput" "$branchInput" "$cnameUrlInput" "no warn"
|
|
||||||
|
|
||||||
popd > /dev/null
|
|
||||||
popd > /dev/null
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e # So that nothing wrong is published
|
|
||||||
|
|
||||||
warn() {
|
|
||||||
echo -e "\033[1;31m
|
|
||||||
------IMPORTANT------
|
|
||||||
THIS SCRIPT IS NOT MEANT TO BE USED DIRECTLY, PLEASE NEWLY CLONE THE REPO IN A SEPARATE DIRECTORY AND USE THE SCRIPT THERE.
|
|
||||||
USING THIS SCRIPT IN YOUR MAIN CLONE MAY DELETE YOUR LOCAL CHANGES.
|
|
||||||
This script is made to be reusable: If you want to manually update the demo, \
|
|
||||||
use the interactive script \`update-demo\`. This script can also be used in a github action.
|
|
||||||
|
|
||||||
You can set the 4th argument to anything to bypass this warning. \
|
|
||||||
Setting the 4th argument means that the first 3 arguments are also set which means that you know what you are doing (I assume).
|
|
||||||
------IMPORTANT------
|
|
||||||
\033[0m"
|
|
||||||
|
|
||||||
echo -ne "Do you still want to continue? [Y/n]: "
|
|
||||||
read -e yN
|
|
||||||
|
|
||||||
case $yN in
|
|
||||||
[yY][eE][sS] | [yY])
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Constants ---
|
|
||||||
deps="jquery bootstrap imgareaselect gifshot downloadjs selectize font-awesome bootstrap-colorpicker jspdf opencv.js/opencv.js" # A list of node_module dependencies to force commit
|
|
||||||
# --- Constants ---
|
|
||||||
|
|
||||||
# --- Arguments ---
|
|
||||||
# $1: Repo(to use as upstream) url in the form username/repo (default: publiclab/image-sequencer) NOTE: Github only
|
|
||||||
# $2: Branch to pull from eg: main or stable (default: stable)
|
|
||||||
# $3: CNAME URL (default: none)
|
|
||||||
# $4: Set the fourth argument to anything to bypass the warning.
|
|
||||||
|
|
||||||
if [[ "$1" != "" ]];
|
|
||||||
then
|
|
||||||
repo=$1
|
|
||||||
else
|
|
||||||
repo="publiclab/image-sequencer"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$2" != "" ]];
|
|
||||||
then
|
|
||||||
branch=$2
|
|
||||||
else
|
|
||||||
branch="stable"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$3" != "" ]];
|
|
||||||
then
|
|
||||||
CNAMEURL=$3
|
|
||||||
else
|
|
||||||
CNAMEURL=""
|
|
||||||
fi
|
|
||||||
# --- Arguments ---
|
|
||||||
|
|
||||||
# --- Main Script ---
|
|
||||||
if [[ "$4" == "" ]]; # Set a 4th argument to anything to bypass this warning.
|
|
||||||
then
|
|
||||||
warn
|
|
||||||
fi
|
|
||||||
|
|
||||||
git checkout gh-pages
|
|
||||||
git remote add upstream https://github.com/$repo
|
|
||||||
git fetch upstream
|
|
||||||
|
|
||||||
git reset --hard upstream/$branch
|
|
||||||
|
|
||||||
echo -e "Running setup script."
|
|
||||||
npm run setup
|
|
||||||
|
|
||||||
echo -e "Building dist files."
|
|
||||||
grunt production
|
|
||||||
|
|
||||||
if [ ! -f CNAME ];
|
|
||||||
then
|
|
||||||
echo -e "Creating CNAME"
|
|
||||||
touch CNAME
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo $CNAMEURL > CNAME
|
|
||||||
|
|
||||||
echo -e "Removing unnecessary files."
|
|
||||||
rm -R docs/
|
|
||||||
rm -R test/
|
|
||||||
rm CONTRIBUTING.md
|
|
||||||
rm index.js
|
|
||||||
|
|
||||||
echo -e "Copying important files from src/"
|
|
||||||
cp src/ui/prepareDynamic.js prepareDynamic.js
|
|
||||||
|
|
||||||
echo "Removing src/"
|
|
||||||
rm -R src/
|
|
||||||
mkdir -p src/ui/
|
|
||||||
mv prepareDynamic.js src/ui/prepareDynamic.js
|
|
||||||
|
|
||||||
echo -e "git add dist and node_modules dependencies."
|
|
||||||
git add .
|
|
||||||
|
|
||||||
for dep in $deps; # Force add node_modules dependencies
|
|
||||||
do
|
|
||||||
git add -f node_modules/$dep
|
|
||||||
done
|
|
||||||
|
|
||||||
git add -f dist/image-sequencer.js
|
|
||||||
git add -f dist/image-sequencer-ui.js
|
|
||||||
|
|
||||||
echo -e "committing and pusing."
|
|
||||||
git commit --no-verify -m "update"
|
|
||||||
git push -f
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
# --- Main Script ---
|
|
||||||
@@ -31,7 +31,6 @@ module.exports = {
|
|||||||
'gradient': require('./modules/Gradient'),
|
'gradient': require('./modules/Gradient'),
|
||||||
'grid-overlay': require('./modules/GridOverlay'),
|
'grid-overlay': require('./modules/GridOverlay'),
|
||||||
'import-image': require('./modules/ImportImage'),
|
'import-image': require('./modules/ImportImage'),
|
||||||
'mask': require('./modules/Mask'),
|
|
||||||
'minify-image': require('./modules/MinifyImage'),
|
'minify-image': require('./modules/MinifyImage'),
|
||||||
// 'invert': require('image-sequencer-invert'),
|
// 'invert': require('image-sequencer-invert'),
|
||||||
'invert': require('./modules/Invert'),
|
'invert': require('./modules/Invert'),
|
||||||
@@ -44,7 +43,6 @@ module.exports = {
|
|||||||
'resize': require('./modules/Resize'),
|
'resize': require('./modules/Resize'),
|
||||||
'rotate': require('./modules/Rotate'),
|
'rotate': require('./modules/Rotate'),
|
||||||
'saturation': require('./modules/Saturation'),
|
'saturation': require('./modules/Saturation'),
|
||||||
'shadow': require('./modules/Shadow'),
|
|
||||||
'text-overlay': require('./modules/TextOverlay'),
|
'text-overlay': require('./modules/TextOverlay'),
|
||||||
'threshold': require('./modules/Threshold'),
|
'threshold': require('./modules/Threshold'),
|
||||||
'tint': require('./modules/Tint'),
|
'tint': require('./modules/Tint'),
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
"desc": "angle of rotation of the halftone patterns in radians",
|
"desc": "angle of rotation of the halftone patterns in radians",
|
||||||
"default": "0.25",
|
"default": "0.25",
|
||||||
"min": "0",
|
"min": "0",
|
||||||
"max": "1.57",
|
"max": "1.57"
|
||||||
"step": "0.05"
|
|
||||||
},
|
},
|
||||||
"size": {
|
"size": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ module.exports = require('../../util/createMetaModule.js')(
|
|||||||
{ 'name': 'gradient', 'options': {} },
|
{ 'name': 'gradient', 'options': {} },
|
||||||
{ 'name': 'colormap', 'options': { colormap: options.colormap || defaults.colormap } },
|
{ 'name': 'colormap', 'options': { colormap: options.colormap || defaults.colormap } },
|
||||||
{ 'name': 'crop', 'options': { 'y': 0, 'w': '100%', 'h': options.h || defaults.h } },
|
{ 'name': 'crop', 'options': { 'y': 0, 'w': '100%', 'h': options.h || defaults.h } },
|
||||||
{ 'name': 'overlay', 'options': { 'x': options.x || defaults.x, 'y': options.y || defaults.y, 'offset': -4 } }
|
{ 'name': 'overlay', 'options': { 'x': options.x || defaults.h, 'y': options.y || defaults.y, 'offset': -4 } }
|
||||||
];
|
];
|
||||||
}, {
|
}, {
|
||||||
infoJson: require('./info.json')
|
infoJson: require('./info.json')
|
||||||
|
|||||||
@@ -29,13 +29,11 @@ module.exports = function CropModule(options, UI) {
|
|||||||
|
|
||||||
options.step.input = input.src;
|
options.step.input = input.src;
|
||||||
|
|
||||||
// We should do this via event/listener:
|
|
||||||
if (ui && ui.hide) ui.hide();
|
|
||||||
|
|
||||||
|
|
||||||
function extraManipulation(pixels) {
|
function extraManipulation(pixels) {
|
||||||
const newPixels = require('./Crop')(pixels, options, function() {
|
const newPixels = require('./Crop')(pixels, options, function() {
|
||||||
|
// We should do this via event/listener:
|
||||||
|
if (ui && ui.hide) ui.hide();
|
||||||
|
|
||||||
// Start custom UI setup (draggable UI)
|
// Start custom UI setup (draggable UI)
|
||||||
// Only once we have an input image
|
// Only once we have an input image
|
||||||
if (setupComplete === false && options.step.inBrowser && !options.noUI) {
|
if (setupComplete === false && options.step.inBrowser && !options.noUI) {
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ const kernelx = [
|
|||||||
[ 1, 2, 1]
|
[ 1, 2, 1]
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = function(pixels, highThresholdRatio, lowThresholdRatio, useHysteresis) {
|
let pixelsToBeSupressed = [];
|
||||||
let angles = [], grads = [], strongEdgePixels = [], weakEdgePixels = [], pixelsToBeSupressed = [];
|
|
||||||
|
|
||||||
|
module.exports = function(pixels, highThresholdRatio, lowThresholdRatio, useHysteresis) {
|
||||||
|
let angles = [], grads = [], strongEdgePixels = [], weakEdgePixels = [];
|
||||||
|
|
||||||
for (var x = 0; x < pixels.shape[0]; x++) {
|
for (var x = 0; x < pixels.shape[0]; x++) {
|
||||||
grads.push([]);
|
grads.push([]);
|
||||||
angles.push([]);
|
angles.push([]);
|
||||||
@@ -32,8 +34,8 @@ module.exports = function(pixels, highThresholdRatio, lowThresholdRatio, useHyst
|
|||||||
angles.slice(-1)[0].push(result.angle);
|
angles.slice(-1)[0].push(result.angle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nonMaxSupress(pixels, grads, angles, pixelsToBeSupressed); // Non Maximum Suppression: Filter fine edges.
|
nonMaxSupress(pixels, grads, angles); // Non Maximum Suppression: Filter fine edges.
|
||||||
doubleThreshold(pixels, highThresholdRatio, lowThresholdRatio, grads, strongEdgePixels, weakEdgePixels, pixelsToBeSupressed); // Double Threshold: Categorizes edges into strong and weak edges based on two thresholds.
|
doubleThreshold(pixels, highThresholdRatio, lowThresholdRatio, grads, strongEdgePixels, weakEdgePixels); // Double Threshold: Categorizes edges into strong and weak edges based on two thresholds.
|
||||||
if(useHysteresis.toLowerCase() == 'true') hysteresis(strongEdgePixels, weakEdgePixels); // Optional Hysteresis (very slow) to minimize edges generated due to noise.
|
if(useHysteresis.toLowerCase() == 'true') hysteresis(strongEdgePixels, weakEdgePixels); // Optional Hysteresis (very slow) to minimize edges generated due to noise.
|
||||||
|
|
||||||
strongEdgePixels.forEach(pixel => preserve(pixels, pixel)); // Makes the strong edges White.
|
strongEdgePixels.forEach(pixel => preserve(pixels, pixel)); // Makes the strong edges White.
|
||||||
@@ -110,13 +112,10 @@ function sobelFilter(pixels, x, y) {
|
|||||||
* @returns {Number} Category number of the given angle
|
* @returns {Number} Category number of the given angle
|
||||||
*/
|
*/
|
||||||
function categorizeAngle(angle){
|
function categorizeAngle(angle){
|
||||||
const pi = Math.PI;
|
if ((angle >= -22.5 && angle <= 22.5) || (angle < -157.5 && angle >= -180)) return 1;
|
||||||
angle = angle > 0 ? angle : pi - Math.abs(angle); // Diagonally flip the angle if it is negative (since edge remains the same)
|
else if ((angle >= 22.5 && angle <= 67.5) || (angle < -112.5 && angle >= -157.5)) return 2;
|
||||||
|
else if ((angle >= 67.5 && angle <= 112.5) || (angle < -67.5 && angle >= -112.5)) return 3;
|
||||||
if (angle <= pi / 8 || angle > 7 * pi / 8) return 1;
|
else if ((angle >= 112.5 && angle <= 157.5) || (angle < -22.5 && angle >= -67.5)) return 4;
|
||||||
else if (angle > pi / 8 && angle <= 3 * pi / 8) return 2;
|
|
||||||
else if (angle > 3 * pi / 8 && angle <= 5 * pi / 8) return 3;
|
|
||||||
else if (angle > 5 * pi / 8 && angle <= 7 * pi / 8) return 4;
|
|
||||||
|
|
||||||
/* Category Map
|
/* Category Map
|
||||||
* 1 => E-W
|
* 1 => E-W
|
||||||
@@ -145,7 +144,9 @@ const removeElem = (arr = [], elem) => { // Removes the specified element from t
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Non Maximum Supression without interpolation.
|
// Non Maximum Supression without interpolation.
|
||||||
function nonMaxSupress(pixels, grads, angles, pixelsToBeSupressed) {
|
function nonMaxSupress(pixels, grads, angles) {
|
||||||
|
angles = angles.map((arr) => arr.map(convertToDegrees));
|
||||||
|
|
||||||
for (let x = 0; x < pixels.shape[0]; x++) {
|
for (let x = 0; x < pixels.shape[0]; x++) {
|
||||||
for (let y = 0; y < pixels.shape[1]; y++) {
|
for (let y = 0; y < pixels.shape[1]; y++) {
|
||||||
|
|
||||||
@@ -158,7 +159,7 @@ function nonMaxSupress(pixels, grads, angles, pixelsToBeSupressed) {
|
|||||||
pixelsToBeSupressed.push([x, y]);
|
pixelsToBeSupressed.push([x, y]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if (!((grads[x][y] >= grads[x + 1][y + 1]) && (grads[x][y] >= grads[x - 1][y - 1]))){
|
if (!((grads[x][y] >= grads[x + 1][y + 1]) && (grads[x][y] >= grads[x - 1][y - 1]))){
|
||||||
pixelsToBeSupressed.push([x, y]);
|
pixelsToBeSupressed.push([x, y]);
|
||||||
@@ -182,11 +183,20 @@ function nonMaxSupress(pixels, grads, angles, pixelsToBeSupressed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method convertToDegrees
|
||||||
|
* @description Converts the given angle(in radians) to degrees.
|
||||||
|
* @param {Number} radians Angle in radians
|
||||||
|
* @returns {Number} Angle in degrees
|
||||||
|
*/
|
||||||
|
var convertToDegrees = radians => (radians * 180) / Math.PI;
|
||||||
|
|
||||||
// Finds the max value in a 2d array like grads.
|
// Finds the max value in a 2d array like grads.
|
||||||
var findMaxInMatrix = arr => Math.max(...arr.map(el => el.map(val => val ? val : 0)).map(el => Math.max(...el)));
|
var findMaxInMatrix = arr => Math.max(...arr.map(el => el.map(val => val ? val : 0)).map(el => Math.max(...el)));
|
||||||
|
|
||||||
// Applies the double threshold to the image.
|
// Applies the double threshold to the image.
|
||||||
function doubleThreshold(pixels, highThresholdRatio, lowThresholdRatio, grads, strongEdgePixels, weakEdgePixels, pixelsToBeSupressed) {
|
function doubleThreshold(pixels, highThresholdRatio, lowThresholdRatio, grads, strongEdgePixels, weakEdgePixels) {
|
||||||
|
|
||||||
const highThreshold = findMaxInMatrix(grads) * highThresholdRatio, // High Threshold relative to the strongest edge
|
const highThreshold = findMaxInMatrix(grads) * highThresholdRatio, // High Threshold relative to the strongest edge
|
||||||
lowThreshold = highThreshold * lowThresholdRatio; // Low threshold relative to high threshold
|
lowThreshold = highThreshold * lowThresholdRatio; // Low threshold relative to high threshold
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ module.exports = function edgeDetect(options, UI) {
|
|||||||
|
|
||||||
// The function which is called on every draw.
|
// The function which is called on every draw.
|
||||||
function draw(input, callback, progressObj) {
|
function draw(input, callback, progressObj) {
|
||||||
|
|
||||||
progressObj.stop(true);
|
progressObj.stop(true);
|
||||||
progressObj.overrideFlag = true;
|
progressObj.overrideFlag = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
module.exports = function Mask(options, UI, util) {
|
|
||||||
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
|
|
||||||
options.offset = options.offset || defaults.offset;
|
|
||||||
options.resize = options.resize || defaults.resize;
|
|
||||||
|
|
||||||
var output;
|
|
||||||
|
|
||||||
// This function is called on every draw.
|
|
||||||
function draw(input, callback, progressObj) {
|
|
||||||
progressObj.stop(true);
|
|
||||||
progressObj.overrideFlag = true;
|
|
||||||
|
|
||||||
var step = this;
|
|
||||||
|
|
||||||
var getPixels = require('get-pixels');
|
|
||||||
|
|
||||||
// convert offset as string to int
|
|
||||||
if (typeof options.offset === 'string')
|
|
||||||
options.offset = parseInt(options.offset);
|
|
||||||
|
|
||||||
// save first image's pixels
|
|
||||||
var priorStep = this.getStep(options.offset);
|
|
||||||
|
|
||||||
if (priorStep.output === undefined) {
|
|
||||||
this.output = input;
|
|
||||||
UI.notify('Offset Unavailable', 'offset-notification');
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
const alpha_masking = function(c, a) {
|
|
||||||
return (a * c + (255 - a) * c) / 255;
|
|
||||||
};
|
|
||||||
const internalSequencer = ImageSequencer({ inBrowser: false, ui: false });
|
|
||||||
internalSequencer.loadImage(priorStep.output.src, function() {
|
|
||||||
internalSequencer.importJSON([{ 'name': 'resize', 'options': { resize: options.resize } }]);
|
|
||||||
internalSequencer.run(function onCallback(internalOutput) {
|
|
||||||
|
|
||||||
getPixels(internalOutput, function(err, pixels) {
|
|
||||||
options.firstImagePixels = pixels;
|
|
||||||
|
|
||||||
function changePixel(r2, g2, b2, a2, x, y) {
|
|
||||||
let p = options.firstImagePixels;
|
|
||||||
let r1 = p.get(x, y, 0),
|
|
||||||
g1 = p.get(x, y, 1),
|
|
||||||
b1 = p.get(x, y, 2),
|
|
||||||
a1 = p.get(x, y, 3);
|
|
||||||
|
|
||||||
return [alpha_masking(r1, a2), alpha_masking(g1, a2), alpha_masking(b1, a2)];
|
|
||||||
}
|
|
||||||
|
|
||||||
function output(image, datauri, mimetype, wasmSuccess) {
|
|
||||||
step.output = {
|
|
||||||
src: datauri,
|
|
||||||
format: mimetype,
|
|
||||||
wasmSuccess,
|
|
||||||
useWasm: options.useWasm
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// run PixelManipulatin on second image's pixels
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
|
||||||
output: output,
|
|
||||||
ui: options.step.ui,
|
|
||||||
changePixel: changePixel,
|
|
||||||
format: input.format,
|
|
||||||
image: options.image,
|
|
||||||
inBrowser: options.inBrowser,
|
|
||||||
callback: callback,
|
|
||||||
useWasm: options.useWasm
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
options: options,
|
|
||||||
draw: draw,
|
|
||||||
output: output,
|
|
||||||
UI: UI
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
module.exports = [
|
|
||||||
require('./Module'),
|
|
||||||
require('./info.json')
|
|
||||||
];
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "mask",
|
|
||||||
"description": "Masks two images according to their Alpha values",
|
|
||||||
"inputs": {
|
|
||||||
"offset": {
|
|
||||||
"type": "integer",
|
|
||||||
"desc": "Choose which image to mask the current image with. Two steps back is -2, three steps back is -3 etc.",
|
|
||||||
"default": -2
|
|
||||||
},
|
|
||||||
"resize": {
|
|
||||||
"type": "string",
|
|
||||||
"desc": "Percentage value by which first image is to be resized",
|
|
||||||
"default": "125%"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md"
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,17 +1,15 @@
|
|||||||
module.exports = function Dynamic(options, UI, util) {
|
module.exports = function Dynamic(options, UI, util) {
|
||||||
|
|
||||||
const defaults = require('./../../util/getDefaults.js')(require('./info.json'));
|
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
|
||||||
options.x = options.x || defaults.x;
|
options.x = options.x || defaults.x;
|
||||||
options.y = options.y || defaults.y;
|
options.y = options.y || defaults.y;
|
||||||
|
|
||||||
if(options.step.inBrowser && !options.noUI && sequencer.getSteps().length < 2)
|
if(options.step.inBrowser && !options.noUI && sequencer.getSteps().length < 2)
|
||||||
options.offset = -1;
|
options.offset = -1;
|
||||||
|
|
||||||
let ui;
|
if (options.step.inBrowser && !options.noUI) var ui = require('./Ui.js')(options.step, UI);
|
||||||
|
|
||||||
if (options.step.inBrowser && !options.noUI) ui = require('./Ui.js')(options.step, UI);
|
var output;
|
||||||
|
|
||||||
let output;
|
|
||||||
|
|
||||||
// This function is called on every draw.
|
// This function is called on every draw.
|
||||||
function draw(input, callback, progressObj) {
|
function draw(input, callback, progressObj) {
|
||||||
@@ -21,15 +19,15 @@ module.exports = function Dynamic(options, UI, util) {
|
|||||||
progressObj.stop(true);
|
progressObj.stop(true);
|
||||||
progressObj.overrideFlag = true;
|
progressObj.overrideFlag = true;
|
||||||
|
|
||||||
const step = this;
|
var step = this;
|
||||||
|
|
||||||
const parseCornerCoordinateInputs = require('../../util/ParseInputCoordinates');
|
var parseCornerCoordinateInputs = require('../../util/ParseInputCoordinates');
|
||||||
|
|
||||||
// save the pixels of the base image
|
// save the pixels of the base image
|
||||||
const baseStepImage = this.getStep(options.offset).image;
|
var baseStepImage = this.getStep(options.offset).image;
|
||||||
const baseStepOutput = this.getOutput(options.offset);
|
var baseStepOutput = this.getOutput(options.offset);
|
||||||
|
|
||||||
const getPixels = require('get-pixels');
|
var getPixels = require('get-pixels');
|
||||||
|
|
||||||
getPixels(input.src, function(err, pixels) {
|
getPixels(input.src, function(err, pixels) {
|
||||||
// parse the inputs
|
// parse the inputs
|
||||||
@@ -49,29 +47,20 @@ module.exports = function Dynamic(options, UI, util) {
|
|||||||
|
|
||||||
function changePixel(r1, g1, b1, a1, x, y) {
|
function changePixel(r1, g1, b1, a1, x, y) {
|
||||||
|
|
||||||
const firstImagePixels = [r1, g1, b1, a1];
|
|
||||||
|
|
||||||
// overlay
|
// overlay
|
||||||
const p = options.secondImagePixels;
|
var p = options.secondImagePixels;
|
||||||
if (x >= options.x
|
if (x >= options.x
|
||||||
&& x - options.x < p.shape[0]
|
&& x - options.x < p.shape[0]
|
||||||
&& y >= options.y
|
&& y >= options.y
|
||||||
&& y - options.y < p.shape[1]){
|
&& y - options.y < p.shape[1])
|
||||||
|
return [
|
||||||
const secondImagePixels = [
|
|
||||||
p.get(x - options.x, y - options.y, 0),
|
p.get(x - options.x, y - options.y, 0),
|
||||||
p.get(x - options.x, y - options.y, 1),
|
p.get(x - options.x, y - options.y, 1),
|
||||||
p.get(x - options.x, y - options.y, 2),
|
p.get(x - options.x, y - options.y, 2),
|
||||||
p.get(x - options.x, y - options.y, 3)
|
p.get(x - options.x, y - options.y, 3)
|
||||||
];
|
];
|
||||||
|
|
||||||
if(secondImagePixels[3] === 0)
|
|
||||||
return firstImagePixels;
|
|
||||||
else
|
|
||||||
return secondImagePixels;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return firstImagePixels;
|
return [r1, g1, b1, a1];
|
||||||
}
|
}
|
||||||
|
|
||||||
function output(image, datauri, mimetype, wasmSuccess) {
|
function output(image, datauri, mimetype, wasmSuccess) {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
const imagejs = require('imagejs'),
|
||||||
|
pixelSetter = require('../../util/pixelSetter'),
|
||||||
|
ndarray = require('ndarray');
|
||||||
/*
|
/*
|
||||||
* Resize the image by given percentage value
|
* Resize the image by given percentage value
|
||||||
*/
|
*/
|
||||||
@@ -16,7 +19,44 @@ module.exports = function Resize(options, UI) {
|
|||||||
const step = this;
|
const step = this;
|
||||||
|
|
||||||
function extraManipulation(pixels) {
|
function extraManipulation(pixels) {
|
||||||
return require('./Resize')(pixels, options);
|
// Value above 100% scales up, and below 100% scales down
|
||||||
|
const resize_value = parseInt(options.resize.slice(0, -1));
|
||||||
|
|
||||||
|
if (resize_value == 100) return pixels;
|
||||||
|
|
||||||
|
|
||||||
|
const new_width = Math.round(pixels.shape[0] * (resize_value / 100)),
|
||||||
|
new_height = Math.round(pixels.shape[1] * (resize_value / 100));
|
||||||
|
|
||||||
|
const bitmap = new imagejs.Bitmap({ width: pixels.shape[0], height: pixels.shape[1] });
|
||||||
|
|
||||||
|
for (let x = 0; x < pixels.shape[0]; x++) {
|
||||||
|
for (let y = 0; y < pixels.shape[1]; y++) {
|
||||||
|
let r = pixels.get(x, y, 0),
|
||||||
|
g = pixels.get(x, y, 1),
|
||||||
|
b = pixels.get(x, y, 2),
|
||||||
|
a = pixels.get(x, y, 3);
|
||||||
|
|
||||||
|
bitmap.setPixel(x, y, r, g, b, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const resized = bitmap.resize({
|
||||||
|
width: new_width,
|
||||||
|
height: new_height,
|
||||||
|
algorithm: 'bicubicInterpolation'
|
||||||
|
});
|
||||||
|
|
||||||
|
const newPix = new ndarray([], [new_width, new_height, 4]);
|
||||||
|
|
||||||
|
for (let x = 0; x < new_width; x++) {
|
||||||
|
for (let y = 0; y < new_height; y++) {
|
||||||
|
const {r, g, b, a} = resized.getPixel(x, y);
|
||||||
|
pixelSetter(x, y, [r, g, b, a], newPix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newPix;
|
||||||
}
|
}
|
||||||
|
|
||||||
function output(image, datauri, mimetype, wasmSuccess) {
|
function output(image, datauri, mimetype, wasmSuccess) {
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
const imagejs = require('imagejs'),
|
|
||||||
pixelSetter = require('../../util/pixelSetter'),
|
|
||||||
ndarray = require('ndarray');
|
|
||||||
module.exports = function Resize(pixels, options) {
|
|
||||||
const resize_value = parseFloat(options.resize);
|
|
||||||
|
|
||||||
if (resize_value == 100) return pixels;
|
|
||||||
|
|
||||||
const new_width = Math.round(pixels.shape[0] * (resize_value / 100)),
|
|
||||||
new_height = Math.round(pixels.shape[1] * (resize_value / 100));
|
|
||||||
|
|
||||||
const bitmap = new imagejs.Bitmap({
|
|
||||||
width: pixels.shape[0],
|
|
||||||
height: pixels.shape[1]
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let x = 0; x < pixels.shape[0]; x++) {
|
|
||||||
for (let y = 0; y < pixels.shape[1]; y++) {
|
|
||||||
let r = pixels.get(x, y, 0),
|
|
||||||
g = pixels.get(x, y, 1),
|
|
||||||
b = pixels.get(x, y, 2),
|
|
||||||
a = pixels.get(x, y, 3);
|
|
||||||
|
|
||||||
bitmap.setPixel(x, y, r, g, b, a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const resized = bitmap.resize({
|
|
||||||
width: new_width,
|
|
||||||
height: new_height,
|
|
||||||
algorithm: 'bicubicInterpolation'
|
|
||||||
});
|
|
||||||
|
|
||||||
const newPix = new ndarray([], [new_width, new_height, 4]);
|
|
||||||
|
|
||||||
for (let x = 0; x < new_width; x++) {
|
|
||||||
for (let y = 0; y < new_height; y++) {
|
|
||||||
const { r, g, b, a } = resized.getPixel(x, y);
|
|
||||||
pixelSetter(x, y, [r, g, b, a], newPix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newPix;
|
|
||||||
};
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
* Create Shadow
|
|
||||||
*/
|
|
||||||
module.exports = function canvasResize(options, UI) {
|
|
||||||
|
|
||||||
var defaults = require('./../../util/getDefaults.js')(require('./info.json'));
|
|
||||||
const pixelSetter = require('../../util/pixelSetter.js');
|
|
||||||
|
|
||||||
var output;
|
|
||||||
|
|
||||||
function draw(input, callback, progressObj) {
|
|
||||||
|
|
||||||
options.X_value = parseInt(options.X_value || defaults.X_value);
|
|
||||||
options.Y_value = parseInt(options.Y_value || defaults.Y_value);
|
|
||||||
|
|
||||||
progressObj.stop(true);
|
|
||||||
progressObj.overrideFlag = true;
|
|
||||||
|
|
||||||
var step = this;
|
|
||||||
|
|
||||||
function extraManipulation(pixels) {
|
|
||||||
let [w, h] = pixels.shape;
|
|
||||||
let newPixels = require('ndarray')(new Uint8Array(4 * (w + Math.abs(options.X_value)) * (h + Math.abs(options.Y_value))).fill(0), [(w + Math.abs(options.X_value)), (h + Math.abs(options.Y_value)), 4]);
|
|
||||||
let iMax = w,
|
|
||||||
jMax = h;
|
|
||||||
if (options.X_value < 0 && options.Y_value < 0) {
|
|
||||||
for (var k = 0; k < Math.abs(options.X_value); k++) {
|
|
||||||
for (var l = 0; l < (h + Math.abs(options.Y_value)); l++) {
|
|
||||||
let val = 255 - ((k / Math.abs(options.X_value)) * 255);
|
|
||||||
pixelSetter(k, l, [val, val, val, 255], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var k = 0; k < (w + Math.abs(options.X_value)); k++) {
|
|
||||||
for (var l = 0; l < Math.abs(options.Y_value); l++) {
|
|
||||||
if (k < Math.abs(options.X_value) && k < l) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let val = 255 - ((l / Math.abs(options.Y_value)) * 255);
|
|
||||||
pixelSetter(k, l, [val, val, val, 255], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0; i < iMax && i < w; i++) {
|
|
||||||
for (let j = 0; j < jMax && j < h; j++) {
|
|
||||||
let x = i + Math.abs(options.X_value), y = j + Math.abs(options.Y_value);
|
|
||||||
pixelSetter(x, y, [pixels.get(i, j, 0), pixels.get(i, j, 1), pixels.get(i, j, 2), pixels.get(i, j, 3)], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (options.X_value >= 0 && options.Y_value >= 0) {
|
|
||||||
for (var k = w; k < (w + options.X_value); k++) {
|
|
||||||
for (var l = 0; l < (h + options.Y_value); l++) {
|
|
||||||
let val = (((k - w) / options.X_value) * 255);
|
|
||||||
pixelSetter(k, l, [val, val, val, 255], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var k = 0; k < (w + options.X_value); k++) {
|
|
||||||
for (var l = h; l < (h + options.Y_value); l++) {
|
|
||||||
if (k >= w && l >= h && ((k - w) >= (l - h))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let val = ((l - h) / options.Y_value * 255);
|
|
||||||
pixelSetter(k, l, [val, val, val, 255], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0; i < iMax && i < w; i++) {
|
|
||||||
for (let j = 0; j < jMax && j < h; j++) {
|
|
||||||
let x = i, y = j;
|
|
||||||
pixelSetter(x, y, [pixels.get(i, j, 0), pixels.get(i, j, 1), pixels.get(i, j, 2), pixels.get(i, j, 3)], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (options.X_value < 0 && options.Y_value >= 0) {
|
|
||||||
for (var k = 0; k < (w + Math.abs(options.X_value)); k++) {
|
|
||||||
for (var l = h; l < (h + options.Y_value); l++) {
|
|
||||||
let val = ((l - h) / options.Y_value * 255);
|
|
||||||
pixelSetter(k, l, [val, val, val, 255], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var k = 0; k < Math.abs(options.X_value); k++) {
|
|
||||||
for (var l = 0; l < (h + options.Y_value); l++) {
|
|
||||||
if (l + (k * (options.Y_value / Math.abs(options.X_value))) - (options.Y_value + h) > 0 && l >= h) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let val = 255 - ((k / Math.abs(options.X_value)) * 255);
|
|
||||||
pixelSetter(k, l, [val, val, val, 255], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0; i < iMax && i < w; i++) {
|
|
||||||
for (let j = 0; j < jMax && j < h; j++) {
|
|
||||||
let x = i + Math.abs(options.X_value), y = j;
|
|
||||||
pixelSetter(x, y, [pixels.get(i, j, 0), pixels.get(i, j, 1), pixels.get(i, j, 2), pixels.get(i, j, 3)], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (options.X_value >= 0 && options.Y_value < 0) {
|
|
||||||
for (var k = w; k < (w + options.X_value); k++) {
|
|
||||||
for (var l = 0; l < (h + Math.abs(options.Y_value)); l++) {
|
|
||||||
let val = (((k - w) / options.X_value) * 255);
|
|
||||||
pixelSetter(k, l, [val, val, val, 255], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (var k = 0; k < (w + options.X_value); k++) {
|
|
||||||
for (var l = 0; l < Math.abs(options.Y_value); l++) {
|
|
||||||
if (l >= ((options.X_value / Math.abs(options.Y_value)) * (w + options.X_value - k)) && k >= w) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let val = 255 - (l / Math.abs(options.Y_value) * 255);
|
|
||||||
pixelSetter(k, l, [val, val, val, 255], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0; i < iMax && i < w; i++) {
|
|
||||||
for (let j = 0; j < jMax && j < h; j++) {
|
|
||||||
let x = i, y = j + Math.abs(options.Y_value);
|
|
||||||
pixelSetter(x, y, [pixels.get(i, j, 0), pixels.get(i, j, 1), pixels.get(i, j, 2), pixels.get(i, j, 3)], newPixels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newPixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
function output(image, datauri, mimetype, wasmSuccess) {
|
|
||||||
step.output = { src: datauri, format: mimetype, wasmSuccess, useWasm: options.useWasm };
|
|
||||||
}
|
|
||||||
|
|
||||||
return require('../_nomodule/PixelManipulation.js')(input, {
|
|
||||||
output: output,
|
|
||||||
ui: options.step.ui,
|
|
||||||
extraManipulation: extraManipulation,
|
|
||||||
format: input.format,
|
|
||||||
image: options.image,
|
|
||||||
inBrowser: options.inBrowser,
|
|
||||||
callback: callback,
|
|
||||||
useWasm:options.useWasm
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
options: options,
|
|
||||||
draw: draw,
|
|
||||||
output: output,
|
|
||||||
UI: UI
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
module.exports = [
|
|
||||||
require('./Module'),
|
|
||||||
require('./info.json')
|
|
||||||
];
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "shadow",
|
|
||||||
"description": "Creates a two sided shadow.",
|
|
||||||
"inputs": {
|
|
||||||
"X_value": {
|
|
||||||
"type": "integer",
|
|
||||||
"desc": "X-value",
|
|
||||||
"default": 20
|
|
||||||
},
|
|
||||||
"Y_value": {
|
|
||||||
"type": "integer",
|
|
||||||
"desc": "Y-value",
|
|
||||||
"default": 20
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"docs-link":"https://github.com/publiclab/image-sequencer/blob/main/docs/MODULES.md#shadow-module"
|
|
||||||
}
|
|
||||||
@@ -51,47 +51,20 @@ function setInputStepInit() {
|
|||||||
video.onloadedmetadata = function(e) {
|
video.onloadedmetadata = function(e) {
|
||||||
video.play();
|
video.play();
|
||||||
};
|
};
|
||||||
|
|
||||||
document.getElementById('capture').addEventListener('click', function(stream){
|
|
||||||
context.drawImage(video, 0, 0, 400, 300);
|
|
||||||
options.onTakePhoto(canvas.toDataURL());
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('close').addEventListener('click', function () {
|
document.getElementById('close').addEventListener('click', function () {
|
||||||
stopStream(stream);
|
stopStream(stream);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function handleError(error) {
|
function handleError(error) {
|
||||||
console.log('navigator.getUserMedia error: ', error);
|
console.log('navigator.getUserMedia error: ', error);
|
||||||
|
|
||||||
// when user dismissed the camera access (includes closing of prompt which requests for camera access)
|
|
||||||
if(error.message == 'Permission denied' || error.message == 'NotAllowedError' || error.message == 'PermissionDismissedError'){
|
|
||||||
document.getElementById('capture').addEventListener('click', function(e) {
|
|
||||||
alert('Enable camera access in order to take picture');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// when user don't have webcam to use.
|
|
||||||
if(error.message == 'NotFoundError' || error.message == 'DevicesNotFoundError'){
|
|
||||||
alert('You do not have appropriate devices to use this Functionality');
|
|
||||||
}
|
|
||||||
|
|
||||||
// when webcam is already used by some other application
|
|
||||||
if(error.message == 'NotReadableError' || error.message == 'TrackStartError' || error.message == 'Concurrent mic process limit'){
|
|
||||||
alert('Your webcam is already in use by some other application');
|
|
||||||
}
|
|
||||||
|
|
||||||
// when some of the requested constraints can't be satisfied like high frame rate or high resolution
|
|
||||||
if(error.message == 'OverconstrainedError' || error.message == 'ConstraintNotSatisfiedError'){
|
|
||||||
console.log('Requested Constraints can not be satisfied ', error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);
|
navigator.mediaDevices.getUserMedia(constraints).then(handleSuccess).catch(handleError);
|
||||||
|
|
||||||
document.getElementById('close').addEventListener('click', function() {
|
|
||||||
video.style.display = 'none';
|
|
||||||
});
|
|
||||||
|
|
||||||
|
document.getElementById('capture').addEventListener('click', function(stream){
|
||||||
|
context.drawImage(video, 0, 0, 400, 300);
|
||||||
|
options.onTakePhoto(canvas.toDataURL());
|
||||||
|
});
|
||||||
|
|
||||||
function stopStream(stream) {
|
function stopStream(stream) {
|
||||||
stream.getVideoTracks().forEach(function (track) {
|
stream.getVideoTracks().forEach(function (track) {
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
require('../../src/ImageSequencer');
|
|
||||||
sequencer = ImageSequencer({ ui: true });
|
|
||||||
const saveSequence = require('../../src/cli/saveSequence.js');
|
|
||||||
const test = require('tape');
|
|
||||||
const { Command } = require('commander');
|
|
||||||
|
|
||||||
|
|
||||||
test('testing save sequence function', function (t) {
|
|
||||||
try {
|
|
||||||
let program = new Command();
|
|
||||||
program
|
|
||||||
.option('--save-sequence [string]', 'Name space separated with Stringified sequence');
|
|
||||||
|
|
||||||
program.parse(['node', 'test', '--save-sequence', '"invert brightness"']);
|
|
||||||
|
|
||||||
if (program.saveSequence)
|
|
||||||
saveSequence(program, sequencer);
|
|
||||||
t.true(1, 'creation success');
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
t.true(!error, 'creation fail');
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
let program = new Command();
|
|
||||||
program
|
|
||||||
.option('--save-sequence [string]', 'Name space separated with Stringified sequence');
|
|
||||||
|
|
||||||
program.parse(['node', 'test', '--save-sequence']);
|
|
||||||
|
|
||||||
if (program.saveSequence)
|
|
||||||
saveSequence(program, sequencer);
|
|
||||||
t.true(0, 'creation success');
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
t.true(1, 'creation fail');
|
|
||||||
}
|
|
||||||
t.end();
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,21 +1,4 @@
|
|||||||
const testModule = require('../templates/module-test'),
|
const testModule = require('../templates/module-test'),
|
||||||
benchmark = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAAAklEQVR4AewaftIAAAAzSURBVLXBAQEAMAiAME7/zN4Ssr2BzzEJSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhJYclMCJyy7k2QAAAAASUVORK5CYII=',
|
benchmark = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAYAAACpF6WWAAAAAklEQVR4AewaftIAAAAzSURBVLXBAQEAMAiAME7/zN4Ssr2BzzEJSEACEpCABCQgAQlIQAISkIAEJCABCUhAAhJYclMCJyy7k2QAAAAASUVORK5CYII=';
|
||||||
|
|
||||||
benchmark1 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAAAklEQVR4AewaftIAAAAkSURBVJXBAQEAMAiAME7/zN4Ksr2Bz5EEEkgggQQSSCCBBBIs6poCE8Zr7KAAAAAASUVORK5CYII=',
|
testModule('resize', {resize: '129%'}, benchmark);
|
||||||
|
|
||||||
benchmark2 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAklEQVR4AewaftIAAAAiSURBVI3BAQEAAAiAIPP/5uqCMAtHIJFEEkkkkUQSSSTRAzwDAhGkYPRhAAAAAElFTkSuQmCC',
|
|
||||||
|
|
||||||
benchmark3 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAAklEQVR4AewaftIAAAAdSURBVHXBAQEAMAiAME7/zN4Csr2Bz0GCBAkSJCwpbQIJAvmJUgAAAABJRU5ErkJggg==',
|
|
||||||
|
|
||||||
options1 = {
|
|
||||||
resize: '70.85%'
|
|
||||||
},
|
|
||||||
options2 = {
|
|
||||||
resize: '60 %'
|
|
||||||
},
|
|
||||||
options3 = {
|
|
||||||
resize: '40'
|
|
||||||
};
|
|
||||||
|
|
||||||
testModule('resize', {resize: '129%'}, benchmark);
|
|
||||||
require('../templates/options-test')('resize', [options1, options2, options3], [benchmark1, benchmark2, benchmark3]);
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,8 +1,6 @@
|
|||||||
const test = require('tape'),
|
const test = require('tape'),
|
||||||
base64Img = require('base64-img');
|
base64Img = require('base64-img');
|
||||||
|
|
||||||
const compare = require('resemblejs').compare;
|
|
||||||
|
|
||||||
const ImageSequencer = require('../../../src/ImageSequencer');
|
const ImageSequencer = require('../../../src/ImageSequencer');
|
||||||
|
|
||||||
const test_gif = require('../images/test.gif.js');
|
const test_gif = require('../images/test.gif.js');
|
||||||
@@ -17,37 +15,19 @@ target = 'test_outputs';
|
|||||||
* @param {String} [input="test_gif"] optional input image. Default is a test gif.
|
* @param {String} [input="test_gif"] optional input image. Default is a test gif.
|
||||||
*/
|
*/
|
||||||
module.exports = (moduleName, options, benchmark, input) => {
|
module.exports = (moduleName, options, benchmark, input) => {
|
||||||
let sequencer = ImageSequencer({ ui: false });
|
let sequencer = ImageSequencer({ui: false});
|
||||||
sequencer.loadImages(input || test_gif);
|
sequencer.loadImages(input || test_gif);
|
||||||
sequencer.addSteps(moduleName, options);
|
sequencer.addSteps(moduleName, options);
|
||||||
test(`${moduleName} module works correctly`, (t) => {
|
test(`${moduleName} module works correctly`, t => {
|
||||||
sequencer.run({ mode: 'test' }, () => {
|
sequencer.run({mode: 'test'}, () => {
|
||||||
let result = sequencer.steps[1].output.src;
|
let result = sequencer.steps[1].output.src;
|
||||||
|
|
||||||
base64Img.imgSync(result, target, `${moduleName}-result`);
|
base64Img.imgSync(result, target, `${moduleName}-result`);
|
||||||
base64Img.imgSync(benchmark, target, `${moduleName}-benchmark`);
|
base64Img.imgSync(benchmark, target, `${moduleName}-benchmark`);
|
||||||
|
|
||||||
let mismatch = 100;
|
t.equal(result === benchmark, true, `${moduleName} module works correctly with Gif`);
|
||||||
compare(
|
|
||||||
result,
|
|
||||||
benchmark,
|
|
||||||
{ returnEarlyThreshold: 5 },
|
|
||||||
(err, { rawMisMatchPercentage }) => {
|
|
||||||
if (err) {
|
|
||||||
console.log('An error while comparing!');
|
|
||||||
} else {
|
|
||||||
mismatch = rawMisMatchPercentage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
t.equal(
|
|
||||||
mismatch < 5,
|
|
||||||
true,
|
|
||||||
`${moduleName} module works correctly with Gif`
|
|
||||||
);
|
|
||||||
sequencer = null;
|
sequencer = null;
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
const timeout = process.env.SLOWMO ? 30000 : 10000;
|
|
||||||
const fs = require('fs');
|
|
||||||
beforeAll(async () => {
|
|
||||||
path = fs.realpathSync('file://../examples/index.html');
|
|
||||||
await page.goto('file://' + path, {waitUntil: 'domcontentloaded'});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Apply Button Works', () => {
|
|
||||||
test('Apply Button is clicked', async () => {
|
|
||||||
await page.waitForSelector('.step');
|
|
||||||
|
|
||||||
|
|
||||||
await page.click('[data-value=\'resize\']');
|
|
||||||
const Length1 = await page.evaluate(() => document.querySelectorAll('.step').length);
|
|
||||||
//Lets change the default value
|
|
||||||
expect(Length1).toBe(2);
|
|
||||||
// Let's check the source of the image output by the default values
|
|
||||||
const src1 = await page.evaluate(() => document.querySelectorAll('.step img')[1].src);
|
|
||||||
//Lets change the default value
|
|
||||||
await page.evaluate(() => document.querySelector('div[name="resize"] input').value = '');
|
|
||||||
await page.type('div[name="resize"] input', '50%');
|
|
||||||
//Wait for the apply button to get enabled then click
|
|
||||||
await page.waitForFunction('document.querySelector(".btn-save").disabled == false');
|
|
||||||
await page.$eval('.btn-save', elem => elem.click());
|
|
||||||
//Wait for the image to process with the new value
|
|
||||||
await page.waitForSelector('.load', {visible: false});
|
|
||||||
|
|
||||||
//Let's check the source of the image output by the new values
|
|
||||||
const src2 = await page.evaluate(() => document.querySelectorAll('.step img')[1].src);
|
|
||||||
//Expect default and new image to be changed
|
|
||||||
expect(src1).not.toEqual(src2);
|
|
||||||
|
|
||||||
|
|
||||||
}, timeout);
|
|
||||||
});
|
|
||||||
@@ -6,12 +6,10 @@ describe('HTML Types Mapping Function', function() {
|
|||||||
expect(mapHtmlTypes({type: 'percentage'})).toEqual({type: 'number'});
|
expect(mapHtmlTypes({type: 'percentage'})).toEqual({type: 'number'});
|
||||||
|
|
||||||
expect(mapHtmlTypes({type: 'integer'})).toEqual({type: 'number'});
|
expect(mapHtmlTypes({type: 'integer'})).toEqual({type: 'number'});
|
||||||
expect(mapHtmlTypes({type: 'integer', min: 20, max: 100})).toEqual({type: 'range', min: 20, max: 100, step: 1});
|
expect(mapHtmlTypes({type: 'integer', min: 20, max: 100})).toEqual({type: 'range', min: 20, max: 100});
|
||||||
expect(mapHtmlTypes({type: 'float', min: 20, max: 100})).toEqual({type: 'range', min: 20, max: 100, step: 0.1}); // should default to step = 1
|
|
||||||
|
|
||||||
expect(mapHtmlTypes({type: 'float'})).toEqual({type: 'text'});
|
expect(mapHtmlTypes({type: 'float'})).toEqual({type: 'text'});
|
||||||
expect(mapHtmlTypes({type: 'float', min: 20, max: 100})).toEqual({type: 'range', min: 20, max: 100, step: 0.1});
|
expect(mapHtmlTypes({type: 'float', min: 20, max: 100})).toEqual({type: 'range', min: 20, max: 100});
|
||||||
expect(mapHtmlTypes({type: 'float', min: 20, max: 100})).toEqual({type: 'range', min: 20, max: 100, step: 0.1}); // should default to step = 0.1
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('maps text type', function() {
|
it('maps text type', function() {
|
||||||
@@ -23,4 +21,4 @@ describe('HTML Types Mapping Function', function() {
|
|||||||
expect(mapHtmlTypes({type: 'select'})).toEqual({type: 'select'});
|
expect(mapHtmlTypes({type: 'select'})).toEqual({type: 'select'});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user