Auto-format code with VS Code

Format JS and HTML using VS Code extension: https://marketplace.visualstudio.com/items?itemName=jbockle.jbockle-format-files

Dedented some files for now to make the diff intelligible:
- tools.js
- menus.js
- speech-recognition.js
- simulate-random-gestures.js
main
Isaiah Odhner 2022-01-18 13:33:44 -05:00
parent 5f64f1c251
commit 8053b38e58
37 changed files with 2692 additions and 2633 deletions

View File

@ -1,5 +1,6 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JS Paint</title>
@ -34,7 +35,8 @@
This is not an @import in classic.css because it needs RTLCSS and I'm not applying RTLCSS to themes yet.
So I added .not-for-modern logic to theme.js to exclude these styles depending on the theme.
-->
<link href="lib/98.css/98.custom-build.css" class="flippable-layout-stylesheet not-for-modern" rel="stylesheet" type="text/css">
<link href="lib/98.css/98.custom-build.css" class="flippable-layout-stylesheet not-for-modern" rel="stylesheet"
type="text/css">
<link rel="apple-touch-icon" href="images/icons/apple-icon-180x180.png">
<!-- Chrome will pick the largest image for some reason, instead of the most appropriate one. -->
@ -68,6 +70,7 @@
<script src="src/error-handling-basic.js"></script>
<script src="src/theme.js"></script>
</head>
<body>
<div id="about-paint" style="display: none">
<h1 id="about-paint-header">
@ -84,10 +87,12 @@
There's a new version of JS Paint. <a id="refresh-to-update" href=".">Refresh</a> to get it.
</div>
<div class="on-third-party-host">
This instance of JS Paint is outdated compared to <a href="https://jspaint.app" target="_blank">jspaint.app</a>.
This instance of JS Paint is outdated compared to <a href="https://jspaint.app"
target="_blank">jspaint.app</a>.
</div>
<div class="on-dev-host">
This version of JS Paint is outdated compared to <a href="https://jspaint.app" target="_blank">jspaint.app</a>.
This version of JS Paint is outdated compared to <a href="https://jspaint.app"
target="_blank">jspaint.app</a>.
</div>
</div>
<div id="checking-for-updates" hidden>
@ -102,10 +107,12 @@
</div>
<p>JS Paint is a web-based remake of MS Paint by <a href="https://isaiahodhner.io/">Isaiah Odhner</a>.</p>
<p>Read about the project and extra features on <a href="https://github.com/1j01/jspaint#readme">the readme</a>.</p>
<p>Read about the project and extra features on <a href="https://github.com/1j01/jspaint#readme">the readme</a>.
</p>
<p>Request features and report bugs <a href="https://github.com/1j01/jspaint/issues">on GitHub</a>
or <a href="mailto:isaiahodhner@gmail.com?subject=JS%20Paint">by email</a>.</p>
<p>Support the project at <a href="https://www.paypal.me/IsaiahOdhner" target="_blank">paypal.me/IsaiahOdhner</a>.</p>
<p>Support the project at <a href="https://www.paypal.me/IsaiahOdhner"
target="_blank">paypal.me/IsaiahOdhner</a>.</p>
</div>
<div id="news" hidden>
<!-- <article class="news-entry" id="news-2021-saving">
@ -155,7 +162,8 @@
<article class="news-entry" id="news-2021-saving">
<h1>The GUIcci Update</h1>
<time datetime="2021-12-08">2021-12-08</time>
<img width="640" height="360" style="max-width: 100%; height: auto; image-rendering: auto;" alt="" src="https://i.postimg.cc/tgBncKfJ/guicii-update.png"/>
<img width="640" height="360" style="max-width: 100%; height: auto; image-rendering: auto;" alt=""
src="https://i.postimg.cc/tgBncKfJ/guicii-update.png" />
<h2>New Features</h2>
<p>
<b>View > Zoom > Show Thumbnail</b> to show a preview of the image at a small size, great for pixel art.
@ -166,7 +174,8 @@
</p>
<p>
<b>Alt+Mousewheel</b> to zoom in and out quickly on desktop.
Unlike the Magnifier tool, this allows you to zoom while making (or moving) a selection, for added precision.
Unlike the Magnifier tool, this allows you to zoom while making (or moving) a selection, for added
precision.
</p>
<p>
Added <b>View > Fullscreen</b> to toggle fullscreen mode. This is nice for using JS Paint on your phone.
@ -181,25 +190,34 @@
you can now dock it back when dragging the titlebar.
Previously to dock it you had to double click the titlebar, or drag it by the edge of the window.
</p>
<img alt="Area that you have to click to drag a toolbar out into a window (in green)" src="https://i.postimg.cc/7LB18Gcg/toolbar-drag-out-area.png" width="480" height="380" style="max-width: 100%; height: auto; image-rendering: auto;"/>
<img alt="Area that you have to click to drag a toolbar out into a window (in green)"
src="https://i.postimg.cc/7LB18Gcg/toolbar-drag-out-area.png" width="480" height="380"
style="max-width: 100%; height: auto; image-rendering: auto;" />
<p>
<b>Menus</b> are now fully keyboard (and screen reader) accessible.
In particular, you can hold <kbd>Alt</kbd> and press the access key of a menu button to open the menu,
and then (without <kbd>Alt</kbd>) press the access key of a menu item to select it.
The access key of an item is the underlined letter, or the first letter of the item's text if there's no underline.
The access key of an item is the underlined letter, or the first letter of the item's text if there's no
underline.
</p>
<p>
<b>Error details</b> are now hidden by default in error dialogs.
The details may be more overwhelming than useful in a lot of cases,
but if you need them, you can expand the details.
</p>
<img alt="Example error message box saying 'File not found', with details collapsed." src="https://i.postimg.cc/ZR1qpVGw/file-not-found.png" width="408" height="145" style="max-width: 100%; height: auto; image-rendering: auto;">
<img alt="Example error message box saying 'File not found', with details collapsed."
src="https://i.postimg.cc/ZR1qpVGw/file-not-found.png" width="408" height="145"
style="max-width: 100%; height: auto; image-rendering: auto;">
<p>
<b>File > Exit</b> now exits to the official web desktop,
<a target="_blank" href="https://98.js.org"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABKklEQVR42qWTMW7DMAxFKYC+RC/hQR065xSdOyRDr9CxV8gQDzlK5g7RkLmn6CwCCimSchIoWkrAgESTj5+kHeCfFnpORCyPPiLqxgYP9gC/ZyKYEIG+CPAbn0JCr6okizmgvmdIF8BZxUhNgVdv8k3FvCdIu/u228VBnkiUGTZBzgyb1CcASBqdlhAMUEx6aAokWc8KqGCGzB+0lmMTyI0cBUmSV28zMRXzT4bECiI/l+NUZ/J0Cz0TACx6Tiwej9jfQkvIufZ8eVM1tM+1uiTHyP5P7H9IccvtxGCVSg0W6ZDUdz6cYbe8DgAHKKf3P9j8bnhQ0rSJY0DcOm2gwCFSugKqozT51V704xoDQItFWMeTFp+ZbQEGtm4o3/hsoLa1IaC3ocf/4QotsZxI//135gAAAABJRU5ErkJggg==" width="16" height="16" alt=""> 98.js.org</a>,
<a target="_blank" href="https://98.js.org"><img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABKklEQVR42qWTMW7DMAxFKYC+RC/hQR065xSdOyRDr9CxV8gQDzlK5g7RkLmn6CwCCimSchIoWkrAgESTj5+kHeCfFnpORCyPPiLqxgYP9gC/ZyKYEIG+CPAbn0JCr6okizmgvmdIF8BZxUhNgVdv8k3FvCdIu/u228VBnkiUGTZBzgyb1CcASBqdlhAMUEx6aAokWc8KqGCGzB+0lmMTyI0cBUmSV28zMRXzT4bECiI/l+NUZ/J0Cz0TACx6Tiwej9jfQkvIufZ8eVM1tM+1uiTHyP5P7H9IccvtxGCVSg0W6ZDUdz6cYbe8DgAHKKf3P9j8bnhQ0rSJY0DcOm2gwCFSugKqozT51V704xoDQItFWMeTFp+ZbQEGtm4o3/hsoLa1IaC3ocf/4QotsZxI//135gAAAABJRU5ErkJggg=="
width="16" height="16" alt=""> 98.js.org</a>,
a re-creation of Windows 98, full of games and applications.
</p>
<img class="inset-deep" src="https://i.postimg.cc/SKHrYpx3/98-js-org-screenshot.png" alt="The 98.js desktop featuring desktop icons, a taskbar, and various application windows." style="max-width: 100%; height: auto; image-rendering: auto;">
<img class="inset-deep" src="https://i.postimg.cc/SKHrYpx3/98-js-org-screenshot.png"
alt="The 98.js desktop featuring desktop icons, a taskbar, and various application windows."
style="max-width: 100%; height: auto; image-rendering: auto;">
<p>
This project spun out of JS Paint, and I have implemented now
Sound Recorder, Notepad, Calculator, and even Windows Explorer,
@ -244,17 +262,20 @@
</p>
<h2>Fixes</h2>
<p>
<b>Menu buttons</b> are easier to open on a touch screen. Sometimes you had to tap twice before the menu opened.
<b>Menu buttons</b> are easier to open on a touch screen. Sometimes you had to tap twice before the menu
opened.
</p>
<p>
Fixed <b>large square brush</b> continuity (it left gaps before, due to a half-implemented optimization).
Fixed <b>large square brush</b> continuity (it left gaps before, due to a half-implemented
optimization).
</p>
<p>
The <b>selection and textboxes</b> no longer "blow up" if you resize them to a minimal size.
They are now limited when you drag an edge past the opposite edge.
</p>
<p>
Fixed a bug where vertically thin selections were difficult or impossible to drag (despite showing a drag cursor).
Fixed a bug where vertically thin selections were difficult or impossible to drag (despite showing a
drag cursor).
(The draggable region was offset outside of the selection box.)
Fixed a similar bug where tool previews would get offset if the canvas's height was very small.
</p>
@ -264,7 +285,8 @@
It's now considerably smarter than Windows 10 about where it lets you drag handles from.
</p>
<p>
In <b>Image > Flip/Rotate</b>, you can now click the custom degrees input field before selecting the "Rotate by angle" option.
In <b>Image > Flip/Rotate</b>, you can now click the custom degrees input field before selecting the
"Rotate by angle" option.
</p>
<p>
The magnifier preview and other tool previews are now hidden while dragging the Colors box or Tools box.
@ -272,8 +294,10 @@
the preview outline for dragging/docking a tool window.
</p>
<p>
For languages that read <b>right-to-left</b>, the History view (<b>Edit > History</b>) now uses a right-to-left layout,
and the color box and tool box no longer flip their layout when dragging them into a window or docking them back to a side of the application.
For languages that read <b>right-to-left</b>, the History view (<b>Edit > History</b>) now uses a
right-to-left layout,
and the color box and tool box no longer flip their layout when dragging them into a window or docking
them back to a side of the application.
</p>
<p>
The history view and error messages use <b>more localized text</b>.
@ -282,7 +306,8 @@
Fixed <b>cut off icons</b> in buttons in the help window toolbar in the Modern theme.
</p>
<p>
All windows now have a default-focused control, and the last focused control in the window is remembered for when you refocus the window.
All windows now have a default-focused control, and the last focused control in the window is remembered
for when you refocus the window.
</p>
<p>
<b>File > New</b> and <b>File > Open</b> now create a new autosave session,
@ -313,20 +338,26 @@
who will then smile a nasty smile and steal Christmas from you.
You can get it back with <b>Extras > Theme > Winter</b>.
</p>
<img class="inset-deep" alt="Winter theme screenshot with candy canes and a text box saying Enjoy!" src="https://i.postimg.cc/SxFtjy8z/winter-theme-enjoy.png" width="440" height="380" style="max-width: 100%; height: auto; image-rendering: auto;"/>
<img class="inset-deep" alt="Winter theme screenshot with candy canes and a text box saying Enjoy!"
src="https://i.postimg.cc/SxFtjy8z/winter-theme-enjoy.png" width="440" height="380"
style="max-width: 100%; height: auto; image-rendering: auto;" />
</article>
<article class="news-entry" id="news-2020-accessibility-update">
<h1>The Accessibility Update</h1>
<time datetime="2020-12-20">2020-12-20</time>
<img width="965" height="399" style="max-width: 100%; height: auto; image-rendering: auto;" alt="Hello in several languages, eye gaze guiding a cursor, and a sea lion barking into a microphone." src="https://i.postimg.cc/j29yrZbm/untitled-23.png"/>
<img width="965" height="399" style="max-width: 100%; height: auto; image-rendering: auto;"
alt="Hello in several languages, eye gaze guiding a cursor, and a sea lion barking into a microphone."
src="https://i.postimg.cc/j29yrZbm/untitled-23.png" />
<h2>Multi-Lingual Support</h2>
<p>JS Paint is now largely localized into 26 languages.</p>
<p>
How am I releasing so many languages at the initial release of multi-lingual support, you may ask?
Well, this project has the somewhat unique opportunity to reuse localizations from an existing program, since it's primarily a remake of MS Paint.
Well, this project has the somewhat unique opportunity to reuse localizations from an existing program,
since it's primarily a remake of MS Paint.
</p>
<p>
I downloaded and installed <a target="_blank" href="https://postimg.cc/4Y1V24wN">26 versions of Windows 98 in virtual machines</a>,
I downloaded and installed <a target="_blank" href="https://postimg.cc/4Y1V24wN">26 versions of Windows
98 in virtual machines</a>,
and extracted text from mspaint.exe in each one of them,
using a set of scripts that I wrote to to help me automate the process.
</p>
@ -334,24 +365,34 @@
To change the language, go to <b>Extras > Language</b>.
Your preferred language may already be detected, if specified in system or browser settings.
</p>
<img width="1280" height="720" style="max-width: 100%; height: auto; image-rendering: auto;" alt="26 languages, right off the bat!" src="https://i.postimg.cc/G2bH92fp/language-menu.png"/>
<img width="1280" height="720" style="max-width: 100%; height: auto; image-rendering: auto;"
alt="26 languages, right off the bat!" src="https://i.postimg.cc/G2bH92fp/language-menu.png" />
<p>For Arabic and Hebrew, right-to-left layout is supported!</p>
<p>I tried my hand at some Arabic calligraphy...</p>
<img width="1141" height="800" style="max-width: 100%; height: auto; image-rendering: auto;" alt="Calligraphy where the shapes of the tools in Paint make up Arabic words for them." src="https://i.postimg.cc/NFX2TTp1/untitled-45.png"/>
<img width="1141" height="800" style="max-width: 100%; height: auto; image-rendering: auto;"
alt="Calligraphy where the shapes of the tools in Paint make up Arabic words for them."
src="https://i.postimg.cc/NFX2TTp1/untitled-45.png" />
<p>
If you want to contribute translations, <a target="_blank" href="https://github.com/1j01/jspaint/issues/80">get in touch!</a>
If you want to contribute translations, <a target="_blank"
href="https://github.com/1j01/jspaint/issues/80">get in touch!</a>
I need to do some technical work to set up for community translations on a public platform,
but I'm glad people have already expressed interest in helping translate!
(I also want to simplify the language in various parts of the UI before asking people to translate them.)
(I also want to simplify the language in various parts of the UI before asking people to translate
them.)
</p>
<h2>Eye Gaze Mode</h2>
<img width="511" height="360" style="max-width: 100%; height: auto; image-rendering: auto;" alt="You can use eye gaze or head movements to control the cursor." src="https://i.postimg.cc/2yC137gc/20.png"/>
<img width="511" height="360" style="max-width: 100%; height: auto; image-rendering: auto;"
alt="You can use eye gaze or head movements to control the cursor."
src="https://i.postimg.cc/2yC137gc/20.png" />
<p>Eye Gaze Mode lets you control JS Paint without using your hands.</p>
<p>It's intended for use with an eye tracker, head tracker, or other coarse input scenario.</p>
<p>You don't need a thousand-dollar eye tracker device to play around with this, just a webcam and some free software.</p>
<p>You don't need a thousand-dollar eye tracker device to play around with this, just a webcam and some free
software.</p>
<p>
I recommend <a target="_blank" href="https://eviacam.crea-si.com/">Enable Viacam</a>, which is <em>not</em> an eye gaze tracker,
but rather a general video movement tracker that you can set up to track your head movement (or your torso or hand or anything else).
I recommend <a target="_blank" href="https://eviacam.crea-si.com/">Enable Viacam</a>, which is
<em>not</em> an eye gaze tracker,
but rather a general video movement tracker that you can set up to track your head movement (or your
torso or hand or anything else).
</p>
<p>
Eye tracking via a webcam has a ways to go, but it's also pretty amazing in its own right.
@ -370,19 +411,24 @@
It can also be frustrating, and takes some practice to master.
</p>
<p>
A good place to start is coloring line art using just the Fill tool (<img src="help/p_paint.gif" width="15" height="11" alt="">):
A good place to start is coloring line art using just the Fill tool (<img src="help/p_paint.gif"
width="15" height="11" alt="">):
</p>
<ul>
<li>
<a target="_blank" href="https://duckduckgo.com/?t=canonical&q=coloring+pages&atb=v232-1&iax=images&ia=images">Find coloring pages online</a>,
<a target="_blank"
href="https://duckduckgo.com/?t=canonical&q=coloring+pages&atb=v232-1&iax=images&ia=images">Find
coloring pages online</a>,
and copy and paste them into JS Paint.
</li>
<li>
You can convert them to black and white in <b>Image > Attributes</b>, and then switch back to Colors.
You can convert them to black and white in <b>Image > Attributes</b>, and then switch back to
Colors.
(This makes it work better with the Fill tool.)
</li>
<li>
Enable Eye Gaze Mode with <b>Extras > Eye Gaze Mode</b> and note that it will start clicking where you hover.
Enable Eye Gaze Mode with <b>Extras > Eye Gaze Mode</b> and note that it will start clicking where
you hover.
You can disable this dwell clicking with the eye icon in the bottom of the screen.
</li>
<li>
@ -394,9 +440,12 @@
I decided to make this available as a separate option. Access with <b>Extras > Vertical Color Box</b>.
</p>
<h2>Speech Recognition</h2>
<img width="549" height="275" style="max-width: 100%; height: auto; image-rendering: auto;" alt="The sea lion says &quot;Art! Art! Art!&quot; into a microphone." src="https://i.postimg.cc/BnQ8cpY2/Art-Art-Art.png"/>
<img width="549" height="275" style="max-width: 100%; height: auto; image-rendering: auto;"
alt="The sea lion says &quot;Art! Art! Art!&quot; into a microphone."
src="https://i.postimg.cc/BnQ8cpY2/Art-Art-Art.png" />
<p>
Using only your voice, you can switch tools and colors, pan the view, click on buttons on the screen by name, and use most menu items.
Using only your voice, you can switch tools and colors, pan the view, click on buttons on the screen by
name, and use most menu items.
You can even say "draw a cat in a party hat" to have JS Paint try to sketch a cat in a party hat.
</p>
<p>This feature pairs well with Eye Gaze Mode for a more complete hands free experience.</p>
@ -404,33 +453,43 @@
The feature is only available on Chrome, and only understands English.
Note that Chrome sends your voice to Google servers.
</p>
<p>Access with <b>Extras > Speech Recognition</b>. If this option is grayed out, your browser is not supported.</p>
<p>Access with <b>Extras > Speech Recognition</b>. If this option is grayed out, your browser is not
supported.</p>
<p>JS Paint will show what it thinks you said in the status bar at the bottom of the screen.</p>
<p>
There are many synonyms for commands, and often you can do things with very short phrases like "Curve" to switch to the Curve tool.
If it's not recognizing your voice for short commands like "Curve" or "Cut", you may want to try longer phrases like "Curve tool" or "Cut selection",
There are many synonyms for commands, and often you can do things with very short phrases like "Curve"
to switch to the Curve tool.
If it's not recognizing your voice for short commands like "Curve" or "Cut", you may want to try longer
phrases like "Curve tool" or "Cut selection",
as this helps it distinguish the sound as speech, rather than a cough for instance.
</p>
<h2>Edit Colors Dialog</h2>
<p>I also implemented the Edit Colors dialog. Previously this used the native system color picker, and didn't work for some people.</p>
<p>I also implemented the Edit Colors dialog. Previously this used the native system color picker, and
didn't work for some people.</p>
<p>Access with <b>Colors > Edit Colors</b> or double click a color in the palette to edit.</p>
<figure>
<img width="496" height="350" style="max-width: 100%; height: auto; image-rendering: auto;" src="https://i.postimg.cc/cLNgWH0r/Peek-2020-12-04-00-31.gif"/>
<figcaption>An animation morphing between JS Paint and MS Paint's color picking dialog. It's pretty close, other than the font.</figcaption>
<img width="496" height="350" style="max-width: 100%; height: auto; image-rendering: auto;"
src="https://i.postimg.cc/cLNgWH0r/Peek-2020-12-04-00-31.gif" />
<figcaption>An animation morphing between JS Paint and MS Paint's color picking dialog. It's pretty
close, other than the font.</figcaption>
</figure>
<p>Keyboard shortcuts are supported in this dialog, and for mobile devices with small screens, I made it treat adding custom colors as a separate screen.</p>
<p>Keyboard shortcuts are supported in this dialog, and for mobile devices with small screens, I made it
treat adding custom colors as a separate screen.</p>
<h2>Conclusion</h2>
<p>
JS Paint should be way more accessible now. And futuristic.
<p>
<p>
Of course there's always more that could be done.
Eye Gaze Mode could use brush stroke smoothing, and Speech Recognition could use Artificial General Intelligence.
Eye Gaze Mode could use brush stroke smoothing, and Speech Recognition could use Artificial General
Intelligence.
</p>
<p>
I'd love to see people using JS Paint, especially the Eye Gaze Mode and Speech Recognition,
so if you record a video of using JS Paint, please
<a target="_blank" href="https://docs.google.com/forms/d/e/1FAIpQLSdGgS6TS4wBV89v8NoYHenh1eI8jYBfgwYBdPx-OaCEG5EW7g/viewform?usp=sf_link">send it to me through this form.</a>
<a target="_blank"
href="https://docs.google.com/forms/d/e/1FAIpQLSdGgS6TS4wBV89v8NoYHenh1eI8jYBfgwYBdPx-OaCEG5EW7g/viewform?usp=sf_link">send
it to me through this form.</a>
This lets me know what's actually important to people, and what's confusing,
and it gives me motivation to work on new features.
</p>
@ -438,17 +497,20 @@
<article class="news-entry" id="news-2019-winter-update">
<h1>Winter Update</h1>
<time datetime="2019-12-20">2019-12-20</time>
<img width="563" height="334" style="max-width: 100%; height: auto; image-rendering: auto;" alt="" src="https://i.postimg.cc/63Wc6vpG/2019-winter-update-candy-cane.gif"/>
<img width="563" height="334" style="max-width: 100%; height: auto; image-rendering: auto;" alt=""
src="https://i.postimg.cc/63Wc6vpG/2019-winter-update-candy-cane.gif" />
<h2>Winter Theme</h2>
<p>
A new UI skin is available, under <b>Extras &gt; Themes &gt; Winter</b>, featuring winter and holiday icons, festive fonts, and a palette with seasonal colors and peppermint patterns.
A new UI skin is available, under <b>Extras &gt; Themes &gt; Winter</b>, featuring winter and holiday
icons, festive fonts, and a palette with seasonal colors and peppermint patterns.
</p>
<img width="256" height="16" alt="" src="images/winter/tools.png" />
<p>
Merry Christmas and happy Hanukkah!
</p>
<h2>Better History</h2>
<b class="new">New:</b> Jump to any point in the document's history, forwards or backwards, with <b>Edit &gt; History</b> or <kbd>Ctrl+Shift+Y</kbd>.
<b class="new">New:</b> Jump to any point in the document's history, forwards or backwards, with <b>Edit
&gt; History</b> or <kbd>Ctrl+Shift+Y</kbd>.
<ul>
<li>
Click on Text in the history view to go back to text editing.
@ -457,14 +519,17 @@
You can return to when a selection existed.
</li>
<li>
Note: these states are skipped over with normal Undo and Redo, so you need to use the History window.
Note: these states are skipped over with normal Undo and Redo, so you need to use the History
window.
</li>
<li>
Branching history: if you undo, and then make changes, you can get back to everything.
Future states are preserved.
</li>
</ul>
<b class="bad">Warning:</b> History is not saved with the autosave. Document history will be lost if you refresh the page, or close the tab, or if the tab crashes, or if you close or restart your browser, or likely if you're just on a phone and the mobile browser loses focus.
<b class="bad">Warning:</b> History is not saved with the autosave. Document history will be lost if you
refresh the page, or close the tab, or if the tab crashes, or if you close or restart your browser, or
likely if you're just on a phone and the mobile browser loses focus.
<h2>Improved Mobile Support</h2>
<p>
<b class="new">New:</b> Use two fingers to pan the view.
@ -474,7 +539,8 @@
With that, combined with multitouch panning,
JS Paint is much more useable on a phone.
</p>
<p><b class="bad">Caveat:</b> It's slow on some devices, and parts of the interface are still too small for touch.</p>
<p><b class="bad">Caveat:</b> It's slow on some devices, and parts of the interface are still too small for
touch.</p>
</article>
<article class="news-entry" id="news-2019-polygon-text-and-select">
<h1>Polygon, Text, and Select</h1>
@ -485,7 +551,8 @@
This applies to selections, textboxes, and the main canvas handles.
</p>
<p>
Resizing things while zoomed in is <a target="_blank" href="https://github.com/1j01/jspaint/issues/13#issuecomment-562247085">finally fixed</a>!
Resizing things while zoomed in is <a target="_blank"
href="https://github.com/1j01/jspaint/issues/13#issuecomment-562247085">finally fixed</a>!
</p>
<p>
The Text tool now perfectly previews the pixels that will be placed on the canvas.
@ -496,7 +563,8 @@
and <a target="_blank" href="https://jsfiddle.net/1j01/qkvfjn1r/">here</a> if you're interested.)
</p>
<p>
With the fill-only option selected, the Polygon tool now previews with inverted lines, like MS Paint does.
With the fill-only option selected, the Polygon tool now previews with inverted lines, like MS Paint
does.
(When you finish the polygon, the boundary of the shape matches the preview exactly,
because it actually <em>does</em> draw a stroke, just the same color as the fill.)
</p>
@ -522,7 +590,8 @@
<h1>The Grid, Custom Zoom, and Dynamic Cursors</h1>
<time datetime="2019-10-09">2019-10-09</time>
<p>
<b class="new">New:</b> The Grid. Zoom to 4x+ and use <b>View &gt; Zoom &gt; Show Grid</b> or <kbd>Ctrl+G</kbd> to enable.
<b class="new">New:</b> The Grid. Zoom to 4x+ and use <b>View &gt; Zoom &gt; Show Grid</b> or
<kbd>Ctrl+G</kbd> to enable.
This works with browser zoom as well to provide crisp gridlines even if you zoom in with your browser.
</p>
<p>
@ -542,7 +611,8 @@
<h1>Full Clipboard Support</h1>
<time datetime="2019-09-21">2019-09-21</time>
<p>
JS Paint now lets you copy real image data to the Clipboard, both with keyboard shortcuts and from the Edit menu.
JS Paint now lets you copy real image data to the Clipboard, both with keyboard shortcuts and from the
Edit menu.
This feature is available in Chrome 76+. Other browsers don't support it yet, as of Sep 2019.
</p>
<p>
@ -555,19 +625,23 @@
background: white;
color: black;
}
.news-entry {
padding: 20px;
max-width: 563px;
}
.news-entry>h1 {
font-size: 1.3em;
margin: 0;
margin-bottom: 0.3em;
}
.news-entry>time {
font-size: 1.2em;
color: gray;
}
.news-entry>h2 {
font-size: 1.9em;
font-weight: normal;
@ -575,9 +649,11 @@
margin-bottom: 0.3em;
margin-top: 0.3em;
}
.news-entry .new {
color: green;
}
.news-entry .bad {
color: #d11a29;
}
@ -602,7 +678,8 @@
<script src="lib/os-gui/MenuBar.js"></script>
<script src="lib/imagetracer_v1.2.5.js"></script>
<script src="src/app-localization.js"></script> <!-- must not be async/deferred, as it uses document.write(); and must come before other app code which uses localization functions -->
<script src="src/app-localization.js"></script>
<!-- must not be async/deferred, as it uses document.write(); and must come before other app code which uses localization functions -->
<script src="src/msgbox.js"></script>
<script src="src/functions.js"></script>
<script src="src/helpers.js"></script>
@ -656,17 +733,12 @@
<svg style="position: absolute; pointer-events: none; bottom: 100%;">
<defs>
<filter id="disabled-inset-filter" x="0" y="0" width="1px" height="1px">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="
<feColorMatrix in="SourceGraphic" type="matrix" values="
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
-1000 -1000 -1000 1 0
"
result="black-parts-isolated"
/>
" result="black-parts-isolated" />
<feFlood result="shadow-color" flood-color="var(--ButtonShadow)" />
<feFlood result="hilight-color" flood-color="var(--ButtonHilight)" />
<feOffset in="black-parts-isolated" dx="1" dy="1" result="offset" />
@ -678,22 +750,18 @@
</feMerge>
</filter>
<filter id="disabled-inset-filter-2" x="0" y="0" width="1px" height="1px">
<feColorMatrix
in="SourceGraphic"
type="matrix"
values="
<feColorMatrix in="SourceGraphic" type="matrix" values="
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
-1 -1 -0 1 0
"
result="black-and-blue-parts-isolated"
/>
" result="black-and-blue-parts-isolated" />
<feFlood result="shadow-color" flood-color="var(--ButtonShadow)" />
<feFlood result="hilight-color" flood-color="var(--ButtonHilight)" />
<feOffset in="black-and-blue-parts-isolated" dx="1" dy="1" result="offset" />
<feComposite in="hilight-color" in2="offset" operator="in" result="hilight-colored-offset" />
<feComposite in="shadow-color" in2="black-and-blue-parts-isolated" operator="in" result="shadow-colored"/>
<feComposite in="shadow-color" in2="black-and-blue-parts-isolated" operator="in"
result="shadow-colored" />
<feMerge>
<feMergeNode in="hilight-colored-offset" />
<feMergeNode in="shadow-colored" />
@ -702,4 +770,5 @@
</defs>
</svg>
</body>
</html>

View File

@ -487,8 +487,7 @@ for (const [format_id, format] of Object.entries(AnyPalette.formats)) {
palette_formats.push({
formatID: format_id,
name: format.name,
nameWithExtensions: `${format.name} (${
format.fileExtensions.map((extension)=> `*.${extension}`).join(";")
nameWithExtensions: `${format.name} (${format.fileExtensions.map((extension) => `*.${extension}`).join(";")
})`,
extensions: format.fileExtensions,
});
@ -1298,14 +1297,10 @@ const lerp = (a, b, b_ness)=> a + (b - a) * b_ness;
const color_ramp = (num_colors, start_hsla, end_hsla) =>
Array(num_colors).fill().map((_undefined, index, array) =>
`hsla(${
lerp(start_hsla[0], end_hsla[0], index/array.length)
}deg, ${
lerp(start_hsla[1], end_hsla[1], index/array.length)
}%, ${
lerp(start_hsla[2], end_hsla[2], index/array.length)
}%, ${
lerp(start_hsla[3], end_hsla[3], index/array.length)
`hsla(${lerp(start_hsla[0], end_hsla[0], index / array.length)
}deg, ${lerp(start_hsla[1], end_hsla[1], index / array.length)
}%, ${lerp(start_hsla[2], end_hsla[2], index / array.length)
}%, ${lerp(start_hsla[3], end_hsla[3], index / array.length)
}%)`
);

View File

@ -1196,8 +1196,7 @@ function show_resource_load_error_message(error){
if (error.code === "cross-origin-blob-uri") {
$message.html(`
<p>Can't load image from address starting with "blob:".</p>
${
firefox ?
${firefox ?
`<p>Try "Copy Image" instead of "Copy Image Location".</p>` :
`<p>Try "Copy image" instead of "Copy image address".</p>`
}

View File

@ -36,8 +36,7 @@
<h1>Woah!</h1>
<p>Your browser may have cleared the canvas due to memory usage.</p>
<p>Undo to recover the document, and remember to save with <b>File > Save</b>!</p>
${
backup_impossible ?
${backup_impossible ?
"<p><b>Note:</b> No automatic backup is possible unless you enable Cookies in your browser.</p>"
: (
no_longer_blank ?

View File

@ -1343,8 +1343,7 @@ recognition.onresult = function(event) {
const interpretations = interpret_command(command, true);
if (interpretations.length) {
const interpretation = choose_interpretation(interpretations);
$status_text.html(`Speech:&nbsp;<span style="white-space: pre;">${
command.replace(
$status_text.html(`Speech:&nbsp;<span style="white-space: pre;">${command.replace(
new RegExp(escapeRegExp(interpretation.match_text), "i"),
(important_text) => `<b>${important_text}</b>`,
)

View File

@ -71,14 +71,11 @@
$(rotologo).css({
transform:
`perspective(4000px) rotateY(${
Math.sin(Date.now() / 5000)
}turn) rotateX(${
0
`perspective(4000px) rotateY(${Math.sin(Date.now() / 5000)
}turn) rotateX(${0
}turn) translate(-50%, -50%) translateZ(500px)`,
filter:
`hue-rotate(${
Math.sin(Date.now() / 4000)
`hue-rotate(${Math.sin(Date.now() / 4000)
// @TODO: slow down and stop when you pause
}turn)`,
});
@ -95,10 +92,8 @@
$window.css({
transform:
`perspective(4000px) rotateY(${
-(offsetLeft + ($window.outerWidth() - parent.innerWidth) / 2) / parent.innerWidth / 3
}turn) rotateX(${
(offsetTop + ($window.outerHeight() - parent.innerHeight) / 2) / parent.innerHeight / 3
`perspective(4000px) rotateY(${-(offsetLeft + ($window.outerWidth() - parent.innerWidth) / 2) / parent.innerWidth / 3
}turn) rotateX(${(offsetTop + ($window.outerHeight() - parent.innerHeight) / 2) / parent.innerHeight / 3
}turn)`,
transformOrigin: "50% 50%",
transformStyle: "preserve-3d",

View File

@ -1,4 +1,3 @@
<div id="news" hidden>
<article class="news-entry" id="news-3000-aliens">
<h1>Extraterrestrial Life</h1>
@ -17,6 +16,7 @@
background: black;
color: aqua;
}
.news-entry {
background: rgba(0, 255, 255, 0.2);
color: aqua;
@ -26,15 +26,18 @@
max-width: 30em;
margin: 10px;
}
.news-entry>h1 {
font-size: 1.3em;
margin: 0;
margin-bottom: 0.5em;
}
.news-entry>time {
font-size: 1.3em;
color: rgba(0, 255, 255, 0.5);
}
.news-entry .new {
color: lime;
}