Spellcheck

main
Isaiah Odhner 2021-06-19 19:58:47 -04:00
parent 3c8b71a9fb
commit 977c8c3b65
21 changed files with 607 additions and 122 deletions

5
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"recommendations": [
"streetsidesoftware.code-spell-checker"
]
}

481
.vscode/settings.json vendored
View File

@ -7,5 +7,484 @@
"**/images": true,
"**/lib": true,
"**/out": true
}
},
"cSpell.words": [
"APNGs",
"Adlm",
"Afaan",
"Afaraf",
"Allaire",
"Aragonés",
"Asụsụ",
"Avaric",
"Avañe'ẽ",
"Ayisyen",
"Aymar",
"Azərbaycan",
"BMPs",
"Bahasa",
"Bamanankan",
"Basa",
"Bgau",
"Bislama",
"Bizaad",
"Bokmål",
"Bopo",
"Bosanski",
"Brasileiro",
"Bresenham",
"Bresenham's",
"Brezhoneg",
"Català",
"Chamoru",
"Chewa",
"Chichewa",
"Chinyanja",
"Chuang",
"Clippy",
"Corel",
"Corsa",
"Corsu",
"Cpath",
"Crect",
"Csvg",
"Cue",
"Cuengh",
"Cueŋƅ",
"Cymraeg",
"Cyrl",
"DIALOGEX",
"Dansk",
"Darude",
"Davvis",
"Davvisámegiella",
"Deutsch",
"Dhivehi",
"Dili",
"Divehi",
"Dorerin",
"Dzongkha",
"Eesti",
"Euskara",
"Euskera",
"Excelsi",
"Eʋegbe",
"Fa'a",
"Faka",
"Faroese",
"Fiteny",
"Fran",
"Français",
"Française",
"Frysk",
"Fsvg",
"Fulah",
"Fulfulde",
"Fwww",
"Føroyskt",
"GIFs",
"Gaeilge",
"Gaelg",
"Gagana",
"Gailck",
"Galego",
"Gikuyu",
"Glag",
"Grischun",
"Gàidhlig",
"HKEY",
"Hanb",
"Hant",
"Hiri",
"Hrvatski",
"IIFE",
"Ikinyarwanda",
"Ikirundi",
"Imgur",
"Inkscape",
"Interlingue",
"Italiano",
"Iñupiatun",
"JSGF",
"Jasc",
"Jawa",
"Jazyk",
"Jezik",
"Język",
"Kajin",
"Kalaallisut",
"Kalaallit",
"Kalba",
"Kanuri",
"Kernewek",
"Khoj",
"Kichwa",
"Kieli",
"Kikongo",
"Kiluba",
"Kinyarwanda",
"Kiswahili",
"Kolour",
"Konami",
"Kreyòl",
"Krita",
"Kuanyama",
"Kurdî",
"Kwanyama",
"Latine",
"Latn",
"Latvie",
"Latviešu",
"Lenga",
"Letzeburgesch",
"Lietuvių",
"Limburgan",
"Limburgish",
"Limburgs",
"Linb",
"Lingála",
"Luba",
"Luciferi",
"Luxembourgish",
"Lëtzebuergesch",
"MSIE",
"Macromedia",
"Malti",
"Melayu",
"Mopaint",
"Motu",
"Naoero",
"Nbat",
"Ndebele",
"Ndonga",
"Nederlands",
"Nkoo",
"Norsk",
"Nuosu",
"Nuosuhxop",
"Nyanja",
"Occitan",
"Odhner",
"Optikey",
"Oqaasii",
"Oromo",
"Oromoo",
"Ossetian",
"Otjiherero",
"Owambo",
"Oʻzbek",
"Phlp",
"Photoshop",
"Polski",
"Polszczyzna",
"Português",
"Pulaar",
"Pular",
"Pushto",
"RGBAs",
"RTLCSS",
"Rege",
"Română",
"Rumantsch",
"Runa",
"Rundi",
"STRINGTABLE",
"Sami",
"Sango",
"Sardu",
"Satana",
"Satanas",
"Scribus",
"Sesotho",
"Setswana",
"Shft",
"Shona",
"Shqip",
"Simi",
"Sinhala",
"Skencil",
"Slovenski",
"Slovenský",
"Slovenčina",
"Slovenščina",
"Soomaali",
"Soomaaliga",
"Sotho",
"Suomen",
"Svenska",
"Swati",
"Tiếng",
"Toçikī",
"Tshivenḓa",
"Tsonga",
"Tvcy",
"Türkçe",
"UPNG",
"Uyghur",
"Uyghurche",
"Vakaviti",
"Valencian",
"Valoda",
"Venda",
"Viacam",
"Việt",
"Vlaams",
"Volapük",
"Vosa",
"Walon",
"Wayback",
"Wikang",
"Wollof",
"Xitsonga",
"Yângâ",
"Zhuang",
"Zhōngwén",
"airb",
"ajeļ",
"allowfullscreen",
"anypalette",
"apng",
"autosave",
"autoupdating",
"bepis",
"bgcolor",
"classid",
"clipart",
"clsid",
"colorbox",
"contenteditable",
"d'Òc",
"desaturated",
"draggable",
"egbe",
"ellipticals",
"endonym",
"eqeqeq",
"equivalize",
"ertical",
"esque",
"eyedrop",
"farbling",
"fieldsets",
"firebaseapp",
"fliph",
"flippable",
"flipv",
"floodfill",
"floodfilling",
"focusring",
"fontbox",
"frowny",
"fudgedness",
"ghostwhite",
"gons",
"gridlines",
"hackily",
"hacky",
"haha",
"hcanvas",
"hctx",
"hilight",
"hslrgb",
"hsrgb",
"humbnail",
"icns",
"iconify",
"idhlig",
"iframe's",
"iframes",
"isaiahodhner",
"isded",
"jfif",
"jnordberg",
"jspaint",
"jsperf",
"keyshortcuts",
"lerp",
"libgconf",
"libtess",
"liveweb",
"llpaper",
"localforage",
"lrgb",
"lsid",
"ltres",
"mediump",
"megiella",
"mimg",
"mobipaint",
"monospace",
"mouseleave",
"msapplication",
"mspaint",
"multitools",
"multitouch",
"multiuser",
"murl",
"nesw",
"nevermind",
"nomine",
"nostri",
"numberofcolors",
"numpad",
"nwse",
"occluder",
"octree",
"oleobject",
"onwriteend",
"orizontal",
"ovaloid",
"ovaloids",
"oviforms",
"paintbucket",
"paypal",
"peggys",
"pixeling",
"pointerenter",
"pointerleave",
"pointermove",
"pointerup",
"pseudorandomly",
"psppalette",
"qtres",
"rbaycan",
"redoable",
"reenable",
"reimplement",
"repurposable",
"rerender",
"rerendered",
"resizer",
"retarget",
"retargeted",
"rgba",
"rk",
"rotologo",
"roundrect",
"roundrects",
"royskt",
"rrect",
"scrollable",
"shader's",
"sketchpalette",
"skeuomorphic",
"slenska",
"sorthweast",
"soundcloud",
"spacebar",
"spraycan",
"spraypaint",
"spraypainting",
"styl",
"stylable",
"submenu",
"submenus",
"subwindows",
"tabbable",
"tabindex",
"tesselator",
"tessy",
"textareas",
"textbox",
"textboxes",
"themepack",
"throwie",
"timespan",
"tina",
"titlebar",
"togglable",
"tracedata",
"tracky",
"tzebuergesch",
"ufeff",
"undecagons",
"undoable",
"undoables",
"undocked",
"undos",
"unfocusing",
"uniquify",
"unmaximize",
"unpremultiplied",
"upiatun",
"ustom",
"vaporwave",
"verts",
"viewports",
"webglcontextlost",
"webglcontextrestored",
"webp",
"woah",
"xtras",
"youtube",
"zbek",
"zoomable",
"zoomer",
"zyk",
"Æвзаг",
"Íslenska",
"Český",
"Čeština",
"Ελληνικά",
"Јазик",
"Језик",
"Ўзбек",
"Авар",
"Аҧсуа",
"Аҧсшәа",
"Башҡорт",
"Беларуская",
"Български",
"Бызшәа",
"Език",
"Ирон",
"Коми",
"Кыргыз",
"Кыргызча",
"Македонски",
"Мова",
"Монгол",
"Мотт",
"Нохчийн",
"Русский",
"Словѣньскъ",
"Српски",
"Татар",
"Теле",
"Тили",
"Тоҷикӣ",
"Тілі",
"Түркмен",
"Українська",
"Чӑваш",
"Чӗлхи",
"Ѩзыкъ",
"Қазақ",
"Ӏарул",
"Հայերեն",
"עברית",
"أۇزبېك",
"ئۇيغۇرچە",
"اردو",
"العربية",
"بهاس",
"تاجیکی",
"سندھی",
"سنڌي",
"فارسی",
"كشميري",
"ملايو",
"پنجابی",
"پښتو",
"کوردی",
"ພາສາລາວ",
"ქართული",
"ትግርኛ",
"አማርኛ",
"ᐃᓄᒃᑎᑐᑦ",
"ᐊᓂᔑᓈᐯᒧᐎᓐ",
"ᓀᐦᐃᔭᐍᐏᐣ",
"ꦧꦱꦗꦮ",
""
]
}

View File

@ -148,8 +148,8 @@ If you want to add extensive palette support to another application, I've made t
| .pal, .psppalette | [Paint Shop Pro] Palette | [Paint Shop Pro] (Jasc Software / Corel) | ✅ | ✅ |
| .hpl | [Homesite] Palette | Allaire [Homesite] / Macromedia [ColdFusion] | ✅ | ✅ |
| .cs | ColorSchemer | ColorSchemer Studio | ✅ | |
| .pal | [Starcraft] Palette | [Starcraft] | ✅ | ✅ |
| .wpe | [Starcraft] Terrain Palette | [Starcraft] | ✅ | ✅ |
| .pal | [StarCraft] Palette | [StarCraft] | ✅ | ✅ |
| .wpe | [StarCraft] Terrain Palette | [StarCraft] | ✅ | ✅ |
| .sketchpalette | [Sketch] Palette | [Sketch] | ✅ | ✅ |
| .spl | [Skencil] Palette | [Skencil] (formerly called Sketch) | ✅ | ✅ |
| .soc | StarOffice Colors | [StarOffice], [OpenOffice], [LibreOffice] | ✅ | ✅ |
@ -181,10 +181,10 @@ If you want to add extensive palette support to another application, I've made t
* These Tips and Tricks from [a tutorial for MS Paint](https://www.albinoblacksheep.com/tutorial/mspaint)
also work in JS Paint:
* [x] Brush Scaling (<kbd>+</kbd> & <kbd>-</kbd> on the Numpad to adjust brush size)
* [x] Brush Scaling (<kbd>+</kbd> & <kbd>-</kbd> on the number pad to adjust brush size)
* [x] "Custom Brushes" (hold <kbd>Shift</kbd> and drag the selection to smear it)
* [x] The 'Stamp' "Tool" (hold <kbd>Shift</kbd> and click the selection to stamp it)
* [x] Image Scaling (<kbd>+</kbd> & <kbd>-</kbd> on the Numpad to scale the selection by factors of 2)
* [x] Image Scaling (<kbd>+</kbd> & <kbd>-</kbd> on the number pad to scale the selection by factors of 2)
* [x] Color Replacement (right mouse button with Eraser to selectively replace the foreground color with the background color)
* [x] The Grid (<kbd>Ctrl+G</kbd> & Zoom to 4x+)
* [x] Quick Undo (Pressing a second mouse button cancels the action you were performing.

11
TODO.md
View File

@ -27,7 +27,7 @@
* Error symbol for error message dialogs
* Menu separator spacing
* I want to give most things a revisit later on for Pixel Perfection
* Fill bucket and airbrush cursors are supposed to have inverty parts
* Fill bucket and airbrush cursors are supposed to invert the background in parts
* Custom cursors in Edge; apparently they require `.cur` files? ugh
* The canvas-area's border is different in Firefox and Edge from Chrome
@ -73,7 +73,7 @@
* Cursors from other users that go outside the parent can cause the page to be scrollable
* Painting textures on 3D models
* And onto tesselating patterns which I imagine can be a special case of 3D models
* And onto tessellating patterns which I imagine can be a special case of 3D models
* Save text and record transformations so the image can be saved as
SVG (or HTML?) with invisible selectable transformed text elements?
@ -91,9 +91,10 @@ SVG (or HTML?) with invisible selectable transformed text elements?
* Alternative way to access "Color Eraser" feature without a secondary mouse button?
* Alternative access to functionality that would normally require a keyboard (with a numpad!)
* Numpad +/-: Increase/Decrease brush size, Double/Halve selection size, ...
* Shift (toggle):
* Proportional, Smear / Trail Selection
* "Snap to 8 directions" / "Octosnap"?
* Shift (toggles; rename contextually?):
* Proportional Resize
* Smear / Trail Selection
* Snap to 8 directions
* An isometric mode would also be good
* Ctrl+Select: Crop tool or "Crop to selection" option
* Don't drag toolbars out into windows with touch

View File

@ -24,8 +24,8 @@
</li>
<li>
For the latest technical information on 98.js.org products, you can also find answers at GitHub.
From README articles in the repositories, to Troubleshooting <small>that there arent any</small> Wizards,
the repos on GitHub have the specific resources most likely to help you find the answer to your question.
From README articles in the repositories, to Troubleshooting <small>that there aren't any</small> Wizards,
the repositories on GitHub have the specific resources most likely to help you find the answer to your question.
To begin your search, go to <a href="https://github.com/1j01/98" target="_blank">Support Online</a>.
</li>
</ul>

View File

@ -103,7 +103,7 @@
</p>
<p>
To change the language, go to <b>Extras > Language</b>.
Your prefered language may already be detected, if specified in system or browser settings.
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"/>
<p>For Arabic and Hebrew, right-to-left layout is supported!</p>
@ -129,7 +129,7 @@
Try <a target="_blank" href="https://sourceforge.net/projects/gazepointer/">GazePointer</a>.
</p>
<p>
Eye gaze tracking requires significant calibration, and if the callibration is off,
Eye gaze tracking requires significant calibration, and if the calibration is off,
it's hard to use because you can't look where you want to look to interact with things.
This is why I recommend head tracking (if that's an option for you),
because then you can freely look around, and control the cursor <em>independently</em>,
@ -141,7 +141,7 @@
It can also be frustrating, and takes some practice to master.
</p>
<p>
A good place to start is coloring lineart 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>
@ -383,7 +383,7 @@
return text.replace(/\s?\(&.\)/, "").replace(/([^&]|^)&([^&\s])/, "$1$2");
}
function display_hotkey(text) {
// misnomer: using .menu-hotkey out of lazyness, instead of a more general term like .hotkey or .accelerator
// misnomer: using .menu-hotkey out of laziness, instead of a more general term like .hotkey or .accelerator
return `<span style="white-space: pre">${text.replace(/([^&]|^)&([^&\s])/, "$1<span class='menu-hotkey'>$2</span>").replace(/&&/g, "&")}</span>`;
}
function get_hotkey(text) {

View File

@ -143,7 +143,7 @@ class OnCanvasSelection extends OnCanvasObject {
// doc/this or canvas/cutout, either of those pairs would result in variable names of equal length which is nice :)
const canvasImageData = main_ctx.getImageData(this.x, this.y, this.width, this.height);
const cutoutImageData = cutout.ctx.getImageData(0, 0, this.width, this.height);
// cutoutImageData is initialzed with the shape to be cut out (whether rectangular or polygonal)
// cutoutImageData is initialized with the shape to be cut out (whether rectangular or polygonal)
// and should end up as the cut out image data for the selection
// canvasImageData is initially the portion of image data on the canvas,
// and should end up as... the portion of image data on the canvas that it should end up as.

View File

@ -85,7 +85,7 @@ let polychrome_palette = palette;
let monochrome_palette = make_monochrome_palette();
// https://github.com/kouzhudong/win2k/blob/ce6323f76d5cd7d136b74427dad8f94ee4c389d2/trunk/private/shell/win16/comdlg/color.c#L38-L43
// These are a fallback in case colors are not recieved from some driver.
// These are a fallback in case colors are not received from some driver.
// const default_basic_colors = [
// "#8080FF", "#80FFFF", "#80FF80", "#80FF00", "#FFFF80", "#FF8000", "#C080FF", "#FF80FF",
// "#0000FF", "#00FFFF", "#00FF80", "#40FF00", "#FFFF00", "#C08000", "#C08080", "#FF00FF",
@ -525,7 +525,7 @@ $news_indicator.on("click auxclick", (event)=> {
event.preventDefault();
show_news();
});
// @TODO: use localstorage to show until clicked, if available
// @TODO: use localStorage to show until clicked, if available
// and show for a longer period of time after the update, if available
if (Date.now() < Date.parse("Jan 5 2021 23:42:42 GMT-0500")) {
$status_area.append($news_indicator);
@ -1744,7 +1744,7 @@ async function init_eye_gaze_mode() {
})
);
// These are matched on exactly for speech recognition synonymization
// These are matched on exactly, for code that provides speech command synonyms
const pause_button_text = "Pause Dwell Clicking";
const resume_button_text = "Resume Dwell Clicking";
@ -1998,7 +1998,7 @@ prevent_selection($toolbox);
// prevent_selection($toolbox2);
prevent_selection($colorbox);
// Stop drawing (or dragging or whatver) if you Alt+Tab or whatever
// Stop drawing (or dragging or whatever) if you Alt+Tab or whatever
$G.on("blur", () => {
$G.triggerHandler("pointerup");
});

View File

@ -97,13 +97,13 @@ function show_edit_colors_window($swatch_to_edit, color_selection_slot_to_edit)
present_rgbas.every((present_rgba)=> `${present_rgba}` !== `${old_rgba}`)
) {
// Find the nearer color in the image data to replace.
const dists = present_rgbas.map((rgba)=>
const distances = present_rgbas.map((rgba)=>
Math.abs(rgba[0] - old_rgba[0]) +
Math.abs(rgba[1] - old_rgba[1]) +
Math.abs(rgba[2] - old_rgba[2]) +
Math.abs(rgba[3] - old_rgba[3])
);
if (dists[0] < dists[1]) {
if (distances[0] < distances[1]) {
old_rgba = present_rgbas[0];
} else {
old_rgba = present_rgbas[1];
@ -289,7 +289,7 @@ function choose_color(initial_color, callback) {
maybe_reenable_button_for_mobile_navigation();
});
// for mobile layout, re-enable button because it's a navigation button in that case, rather than a one-off expando
// for mobile layout, re-enable button because it's a navigation button in that case, rather than one-time expand action
const maybe_reenable_button_for_mobile_navigation = ()=> {
// if ($right.is(":hidden")) {
if ($w.width() < 300 || document.body.classList.contains("eye-gaze-mode")) {

View File

@ -10,7 +10,7 @@ const fs = require("fs");
const path = require("path");
const argv = require("electron").remote.process.argv;
// @TODO: let user apply this setting somewhere in the UI (toggleable)
// @TODO: let user apply this setting somewhere in the UI (togglable)
// (Note: it would be better to use REG.EXE to apply the change, rather than a .reg file)
// This registry modification changes the right click > Edit option for images in Windows Explorer
const reg_contents = `Windows Registry Editor Version 5.00

View File

@ -53,7 +53,7 @@ function change_some_url_params(updates, {replace_history_state=false}={}) {
if (updates[exclusive_param]) {
exclusive_params.forEach((param)=> {
if (param !== exclusive_param) {
updates[param] = null; // must be enumerated (for Object.assign) but falsey, to get removed from the URL
updates[param] = null; // must be enumerated (for Object.assign) but falsy, to get removed from the URL
}
});
}
@ -185,7 +185,7 @@ function update_helper_layer_immediately() {
// (The magnifier preview is especially confusing looking together with the component preview!)
if ($("body").hasClass("dragging") && !pointer_active) {
// tools_to_preview.length = 0;
// Curve and Polygon tools have a persistant state over multiple gestures,
// Curve and Polygon tools have a persistent state over multiple gestures,
// which is, as of writing, part of the "tool preview"; it's ugly,
// but at least they don't have ALSO a brush like preview, right?
// so we can just allow those thru
@ -889,10 +889,10 @@ function are_you_sure(action, canceled){
}
function please_enter_a_number() {
const $msgw = new $FormToolWindow("Invalid Value").addClass("dialogue-window");
$msgw.$main.text(localize("Please enter a number."));
$msgw.$Button(localize("OK"), () => {
$msgw.close();
const $w = new $FormToolWindow("Invalid Value").addClass("dialogue-window");
$w.$main.text(localize("Please enter a number."));
$w.$Button(localize("OK"), () => {
$w.close();
}).focus();
}
@ -907,7 +907,7 @@ function show_error_message(message, error){
// Chrome includes the error message in the error.stack string, whereas Firefox doesn't.
// Also note that there can be Exception objects that don't have a message (empty string) but a name,
// for instance Exception { message: "", name: "NS_ERROR_FAILURE", ... } for out of memory when resizing the canvas too large in Firefox.
// Chrome just lets you bring the system to a grating hault by trying to grab too much memory.
// Chrome just lets you bring the system to a grating halt by trying to grab too much memory.
// Firefox does too sometimes.
let error_string = error.stack;
if (!error_string) {
@ -1345,7 +1345,7 @@ function go_to_history_node(target_history_node, canceling) {
const current_image_data = main_ctx.getImageData(0, 0, main_canvas.width, main_canvas.height);
if (!current_history_node.image_data || !image_data_match(current_history_node.image_data, current_image_data, 5)) {
window.console && console.log("Canvas image data changed outside of undoable", current_history_node, "current_history_node.image_data:", current_history_node.image_data, "document's current image data:", current_image_data);
undoable({name: "Unknown [GTHN]", use_loose_canvas_changes: true}, ()=> {});
undoable({name: "Unknown [go_to_history_node]", use_loose_canvas_changes: true}, ()=> {});
}
current_history_node = target_history_node;
@ -2326,7 +2326,7 @@ function image_attributes(){
}
// 1. Must be after canvas resize to avoid weird undoable interaction and such.
// 2. Check that monchrome option changed, same as above.
// 2. Check that monochrome option changed, same as above.
// a) for monochrome_info variable to be available
// b) Consider the case where color is introduced to the canvas while in monochrome mode.
// We only want to show this dialog if it would also change the palette (above), never leave you on an outdated palette.
@ -2586,16 +2586,16 @@ function image_stretch_and_skew(){
const skew_y = $RowInput($fieldset_skew.find("table"), "skew-y", localize("V&ertical:"), 0, localize("Degrees"), -90, 90);
$w.$Button(localize("OK"), () => {
const xscale = parseFloat(stretch_x.val())/100;
const yscale = parseFloat(stretch_y.val())/100;
const hskew = parseFloat(skew_x.val())/360*TAU;
const vskew = parseFloat(skew_y.val())/360*TAU;
if (isNaN(xscale) || isNaN(yscale) || isNaN(hskew) || isNaN(vskew)) {
const x_scale = parseFloat(stretch_x.val())/100;
const y_scale = parseFloat(stretch_y.val())/100;
const h_skew = parseFloat(skew_x.val())/360*TAU;
const v_skew = parseFloat(skew_y.val())/360*TAU;
if (isNaN(x_scale) || isNaN(y_scale) || isNaN(h_skew) || isNaN(v_skew)) {
please_enter_a_number();
return;
}
try {
stretch_and_skew(xscale, yscale, hskew, vskew);
stretch_and_skew(x_scale, y_scale, h_skew, v_skew);
} catch (exception) {
if (exception.name === "NS_ERROR_FAILURE") {
// or localize("There is not enough memory or resources to complete operation.")

View File

@ -427,8 +427,8 @@ function $Iframe(options){
// var $iframe = $win.$iframe = $Iframe({src: options.src});
// $win.$content.append($iframe);
// var iframe = $win.iframe = $iframe[0];
// // @TODO: should I instead of having iframe.$window, have a get$Window type of dealio?
// // where all is $window needed?
// // @TODO: should I instead of having iframe.$window, have something like get$Window?
// // Where all is $window needed?
// // I know it's used from within the iframe contents as frameElement.$window
// iframe.$window = $win;

View File

@ -233,8 +233,8 @@ function bresenham_line(x1, y1, x2, y2, callback){
}
}
function brosandham_line(x1, y1, x2, y2, callback){
// Bresenham's line argorithm with a callback between going horizontal and vertical
function bresenham_dense_line(x1, y1, x2, y2, callback){
// Bresenham's line algorithm with a callback between going horizontal and vertical
x1=~~x1; x2=~~x2; y1=~~y1; y2=~~y2;
const dx = Math.abs(x2 - x1);
@ -685,30 +685,30 @@ function rotate(angle){
});
}
function stretch_and_skew(xscale, yscale, hsa, vsa){
function stretch_and_skew(x_scale, y_scale, h_skew, v_skew){
apply_image_transformation({
name:
(hsa !== 0 || vsa !== 0) ? (
(xscale !== 1 || yscale !== 1) ? localize("Stretch and Skew") : localize("Skew")
(h_skew !== 0 || v_skew !== 0) ? (
(x_scale !== 1 || y_scale !== 1) ? localize("Stretch and Skew") : localize("Skew")
) : localize("Stretch"),
icon: get_help_folder_icon(
(hsa !== 0) ? "p_skew_h.png" :
(vsa !== 0) ? "p_skew_v.png" :
(yscale !== 1) ? (
(xscale !== 1) ? "p_stretch_both.png" : "p_stretch_v.png"
(h_skew !== 0) ? "p_skew_h.png" :
(v_skew !== 0) ? "p_skew_v.png" :
(y_scale !== 1) ? (
(x_scale !== 1) ? "p_stretch_both.png" : "p_stretch_v.png"
) : "p_stretch_h.png"
),
}, (original_canvas, original_ctx, new_canvas, new_ctx) => {
const w = original_canvas.width * xscale;
const h = original_canvas.height * yscale;
const w = original_canvas.width * x_scale;
const h = original_canvas.height * y_scale;
let bb_min_x = +Infinity;
let bb_max_x = -Infinity;
let bb_min_y = +Infinity;
let bb_max_y = -Infinity;
const corner = (x01, y01) => {
const x = Math.tan(hsa)*h*x01 + w*y01;
const y = Math.tan(vsa)*w*y01 + h*x01;
const x = Math.tan(h_skew)*h*x01 + w*y01;
const y = Math.tan(v_skew)*w*y01 + h*x01;
bb_min_x = Math.min(bb_min_x, x);
bb_max_x = Math.max(bb_max_x, x);
bb_min_y = Math.min(bb_min_y, y);
@ -737,8 +737,8 @@ function stretch_and_skew(xscale, yscale, hsa, vsa){
new_ctx.save();
new_ctx.transform(
1, // x scale
Math.tan(vsa), // vertical skew (skewY)
Math.tan(hsa), // horizontal skew (skewX)
Math.tan(v_skew), // vertical skew (skewY)
Math.tan(h_skew), // horizontal skew (skewX)
1, // y scale
-bb_x, // x translation
-bb_y // y translation
@ -990,37 +990,37 @@ function draw_grid(ctx, scale) {
const tessy = (function initTesselator() {
// function called for each vertex of tesselator output
function vertexCallback(data, polyVertArray) {
function vertex_callback(data, poly_vert_array) {
// window.console && console.log(data[0], data[1]);
polyVertArray[polyVertArray.length] = data[0];
polyVertArray[polyVertArray.length] = data[1];
poly_vert_array[poly_vert_array.length] = data[0];
poly_vert_array[poly_vert_array.length] = data[1];
}
function begincallback(type) {
function begin_callback(type) {
if (type !== libtess.primitiveType.GL_TRIANGLES) {
window.console && console.log(`Expected TRIANGLES but got type: ${type}`);
}
}
function errorcallback(errno) {
function error_callback(errno) {
window.console && console.log('error callback');
window.console && console.log(`error number: ${errno}`);
}
// callback for when segments intersect and must be split
function combinecallback(coords/*, data, weight*/) {
function combine_callback(coords/*, data, weight*/) {
// window.console && console.log('combine callback');
return [coords[0], coords[1], coords[2]];
}
function edgeCallback(/*flag*/) {
function edge_callback(/*flag*/) {
// don't really care about the flag, but need no-strip/no-fan behavior
// window.console && console.log('edge flag: ' + flag);
}
const tessy = new libtess.GluTesselator();
// tessy.gluTessProperty(libtess.gluEnum.GLU_TESS_WINDING_RULE, libtess.windingRule.GLU_TESS_WINDING_POSITIVE);
tessy.gluTessCallback(libtess.gluEnum.GLU_TESS_VERTEX_DATA, vertexCallback);
tessy.gluTessCallback(libtess.gluEnum.GLU_TESS_BEGIN, begincallback);
tessy.gluTessCallback(libtess.gluEnum.GLU_TESS_ERROR, errorcallback);
tessy.gluTessCallback(libtess.gluEnum.GLU_TESS_COMBINE, combinecallback);
tessy.gluTessCallback(libtess.gluEnum.GLU_TESS_EDGE_FLAG, edgeCallback);
tessy.gluTessCallback(libtess.gluEnum.GLU_TESS_VERTEX_DATA, vertex_callback);
tessy.gluTessCallback(libtess.gluEnum.GLU_TESS_BEGIN, begin_callback);
tessy.gluTessCallback(libtess.gluEnum.GLU_TESS_ERROR, error_callback);
tessy.gluTessCallback(libtess.gluEnum.GLU_TESS_COMBINE, combine_callback);
tessy.gluTessCallback(libtess.gluEnum.GLU_TESS_EDGE_FLAG, edge_callback);
return tessy;
}());

View File

@ -976,8 +976,8 @@ window.menus = {
"summon devil", "summon the devil", "summon devil theme", "summon the devil theme",
"welcome devil", "welcome the devil", "welcome devil theme", "welcome the devil theme",
"I beseach thee", "I entreat thee", "I summon thee", "I call upon thy name", "I call upon thine name", "Lord Satan", "hail Satan", "hail Lord Satan", "O Mighty Satan", "Oh Mighty Satan",
"In nomine Dei nostri Satanas Luciferi Excelsi", "Rege Satanas", "Ave Satanas",
"I beseech thee", "I entreat thee", "I summon thee", "I call upon thy name", "I call upon thine name", "Lord Satan", "hail Satan", "hail Lord Satan", "O Mighty Satan", "Oh Mighty Satan",
"In nomine Dei nostri Satanas Luciferi Excelsi", "Rege Satanas", "Ave Satanas","Rege Satana", "Ave Satana",
"go demonic", "go daemonic", "go occult", "666",
"begin ritual", "begin the ritual", "begin a ritual",
"start ritual", "start the ritual", "start a ritual",

View File

@ -309,13 +309,13 @@
const draw_cursor = () => {
cursor_canvas.width = cursor_image.width;
cursor_canvas.height = cursor_image.height;
const cctx = cursor_canvas.ctx;
cctx.fillStyle = other_user.color;
cctx.fillRect(0, 0, cursor_canvas.width, cursor_canvas.height);
cctx.globalCompositeOperation = "multiply";
cctx.drawImage(cursor_image, 0, 0);
cctx.globalCompositeOperation = "destination-atop";
cctx.drawImage(cursor_image, 0, 0);
const cursor_ctx = cursor_canvas.ctx;
cursor_ctx.fillStyle = other_user.color;
cursor_ctx.fillRect(0, 0, cursor_canvas.width, cursor_canvas.height);
cursor_ctx.globalCompositeOperation = "multiply";
cursor_ctx.drawImage(cursor_image, 0, 0);
cursor_ctx.globalCompositeOperation = "destination-atop";
cursor_ctx.drawImage(cursor_image, 0, 0);
};
if (cursor_image.complete) {
draw_cursor();
@ -363,7 +363,7 @@
}
write_canvas_to_database();
});
// Any time we change or recieve the image data
// Any time we change or receive the image data
_fb_on(this.fb_data, "value", snap => {
log("Firebase data update");
const uri = snap.val();

View File

@ -1530,7 +1530,7 @@ window.interpret_command = (input_text, default_to_entering_text)=> {
"unmaximize", "unmaximize button", "unmaximize window", "unmaximize window button",
"restore", "restore button", "restore window", "restore window button", "restore window size", "restore window size button",
"enlarge window", "make window small", "make window smallagain", "make window smaller", "make window smaller again",
"enlarge window", "make window small", "make window small again", "make window smaller", "make window smaller again",
];
}
if (button.matches(".window-minimize-button")) {
@ -1820,8 +1820,8 @@ window.trace_and_sketch = (subject_imagedata)=> {
// const subject_imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height);
// const pal = palette.map((color)=> get_rgba_from_color(color)).map(([r, g, b, a])=> ({r, g, b, a}));
const tracedata = ImageTracer.imagedataToTracedata(subject_imagedata, { ltres:1, qtres:0.01, scale:10, /*pal,*/ numberofcolors: 6, });
const {layers} = tracedata;
const trace_data = ImageTracer.imagedataToTracedata(subject_imagedata, { ltres:1, qtres:0.01, scale:10, /*pal,*/ numberofcolors: 6, });
const {layers} = trace_data;
const brush = get_tool_by_id(TOOL_BRUSH);
select_tool(brush);

View File

@ -125,32 +125,32 @@ const $ChooseShapeStyle = () => {
{stroke: false, fill: true}
],
({stroke, fill}, is_chosen, reuse_canvas) => {
const sscanvas = reuse_canvas(39, 21);
const ssctx = sscanvas.ctx;
const ss_canvas = reuse_canvas(39, 21);
const ss_ctx = ss_canvas.ctx;
// border px inwards amount
let b = 5;
const style = getComputedStyle(sscanvas);
ssctx.fillStyle = is_chosen ? style.getPropertyValue("--HilightText") : style.getPropertyValue("--WindowText");
const style = getComputedStyle(ss_canvas);
ss_ctx.fillStyle = is_chosen ? style.getPropertyValue("--HilightText") : style.getPropertyValue("--WindowText");
if(stroke){
// just using a solid rectangle for the stroke
// so as not to have to deal with the pixel grid with strokes
ssctx.fillRect(b, b, sscanvas.width-b*2, sscanvas.height-b*2);
ss_ctx.fillRect(b, b, ss_canvas.width-b*2, ss_canvas.height-b*2);
}
// go inward a pixel for the fill
b += 1;
ssctx.fillStyle = style.getPropertyValue("--ButtonShadow");
ss_ctx.fillStyle = style.getPropertyValue("--ButtonShadow");
if(fill){
ssctx.fillRect(b, b, sscanvas.width-b*2, sscanvas.height-b*2);
ss_ctx.fillRect(b, b, ss_canvas.width-b*2, ss_canvas.height-b*2);
}else{
ssctx.clearRect(b, b, sscanvas.width-b*2, sscanvas.height-b*2);
ss_ctx.clearRect(b, b, ss_canvas.width-b*2, ss_canvas.height-b*2);
}
return sscanvas;
return ss_canvas;
},
({stroke, fill}) => {
$chooser.stroke = stroke;
@ -183,17 +183,17 @@ const $choose_brush = $Choose(
return things;
})(),
(o, is_chosen, reuse_canvas) => {
const cbcanvas = reuse_canvas(10, 10);
const style = getComputedStyle(cbcanvas);
const cb_canvas = reuse_canvas(10, 10);
const style = getComputedStyle(cb_canvas);
const shape = o.shape;
const size = o.size;
const color = is_chosen ? style.getPropertyValue("--HilightText") : style.getPropertyValue("--WindowText");
stamp_brush_canvas(cbcanvas.ctx, 5, 5, shape, size);
replace_colors_with_swatch(cbcanvas.ctx, color);
stamp_brush_canvas(cb_canvas.ctx, 5, 5, shape, size);
replace_colors_with_swatch(cb_canvas.ctx, color);
return cbcanvas;
return cb_canvas;
}, ({shape, size}) => {
brush_shape = shape;
brush_size = size;
@ -203,13 +203,13 @@ const $choose_brush = $Choose(
const $choose_eraser_size = $Choose(
[4, 6, 8, 10],
(size, is_chosen, reuse_canvas) => {
const cecanvas = reuse_canvas(39, 16);
const ce_canvas = reuse_canvas(39, 16);
const style = getComputedStyle(cecanvas);
cecanvas.ctx.fillStyle = is_chosen ? style.getPropertyValue("--HilightText") : style.getPropertyValue("--WindowText");
render_brush(cecanvas.ctx, "square", size);
const style = getComputedStyle(ce_canvas);
ce_canvas.ctx.fillStyle = is_chosen ? style.getPropertyValue("--HilightText") : style.getPropertyValue("--WindowText");
render_brush(ce_canvas.ctx, "square", size);
return cecanvas;
return ce_canvas;
},
size => {
eraser_size = size;
@ -221,12 +221,12 @@ const $choose_stroke_size = $Choose(
[1, 2, 3, 4, 5],
(size, is_chosen, reuse_canvas) => {
const w = 39, h = 12, b = 5;
const cscanvas = reuse_canvas(w, h);
const cs_canvas = reuse_canvas(w, h);
const center_y = (h - size) / 2;
const style = getComputedStyle(cscanvas);
cscanvas.ctx.fillStyle = is_chosen ? style.getPropertyValue("--HilightText") : style.getPropertyValue("--WindowText");
cscanvas.ctx.fillRect(b, ~~center_y, w - b*2, size);
return cscanvas;
const style = getComputedStyle(cs_canvas);
cs_canvas.ctx.fillStyle = is_chosen ? style.getPropertyValue("--HilightText") : style.getPropertyValue("--WindowText");
cs_canvas.ctx.fillRect(b, ~~center_y, w - b*2, size);
return cs_canvas;
},
size => {
stroke_size = size;

View File

@ -77,18 +77,18 @@ window.tools = [{
});
},
paint_iteration(x, y) {
// Constrain the inverty paint brush position to the canvas
// Constrain the inversion paint brush position to the canvas
x = Math.min(main_canvas.width, x);
x = Math.max(0, x);
y = Math.min(main_canvas.height, y);
y = Math.max(0, y);
// Find the dimensions on the canvas of the tiny square to invert
const inverty_size = 2;
const rect_x = ~~(x - inverty_size/2);
const rect_y = ~~(y - inverty_size/2);
const rect_w = inverty_size;
const rect_h = inverty_size;
const inversion_size = 2;
const rect_x = ~~(x - inversion_size/2);
const rect_y = ~~(y - inversion_size/2);
const rect_w = inversion_size;
const rect_h = inversion_size;
const ctx_dest = this.preview_canvas.ctx;
const id_src = main_ctx.getImageData(rect_x, rect_y, rect_w, rect_h);
@ -1320,7 +1320,7 @@ tools.forEach((tool)=> {
const brush = tool.get_brush();
const circumference_points = get_circumference_points_for_brush(brush.shape, brush.size);
tool.mask_canvas.ctx.fillStyle = stroke_color;
const iterate_line = brush.size > 1 ? brosandham_line : bresenham_line;
const iterate_line = brush.size > 1 ? bresenham_dense_line : bresenham_line;
iterate_line(pointer_previous.x, pointer_previous.y, pointer.x, pointer.y, (x, y)=> {
for (const point of circumference_points) {
tool.mask_canvas.ctx.fillRect(x + point.x, y + point.y, 1, 1);

View File

@ -616,9 +616,9 @@ html, body, .jspaint {
position: absolute;
/*background: rgba(255, 0, 0, 0.5);*/ /* debug */
}
.grab-region.is-middle {
/* .grab-region.is-middle { */
/*background: rgba(255, 255, 0, 0.5);*/ /* debug */
}
/* } */
.textbox::before {
/* allow dragging textbox */
/* In mspaint the border drawn around selections and textboxes extends out from them,
@ -690,8 +690,8 @@ html, body, .jspaint {
display: flex !important; /* overriding `.window:not(.edit-colors-window) .window-content label` */
}
.flip-and-rotate input:disabled {
/* pointer events already can't get recieved on disabled input elements,
but this lets them be recieved on a parent,
/* pointer events already can't get received on disabled input elements,
but this lets them be received on a parent,
in order to enable the element */
pointer-events: none;
}

View File

@ -616,9 +616,9 @@ html, body, .jspaint {
position: absolute;
/*background: rgba(255, 0, 0, 0.5);*/ /* debug */
}
.grab-region.is-middle {
/* .grab-region.is-middle { */
/*background: rgba(255, 255, 0, 0.5);*/ /* debug */
}
/* } */
.textbox::before {
/* allow dragging textbox */
/* In mspaint the border drawn around selections and textboxes extends out from them,
@ -690,8 +690,8 @@ html, body, .jspaint {
display: flex !important; /* overriding `.window:not(.edit-colors-window) .window-content label` */
}
.flip-and-rotate input:disabled {
/* pointer events already can't get recieved on disabled input elements,
but this lets them be recieved on a parent,
/* pointer events already can't get received on disabled input elements,
but this lets them be received on a parent,
in order to enable the element */
pointer-events: none;
}

View File

@ -229,7 +229,7 @@ body,
}
.component-ghost:not(.dock):after,
.component-ghost:not(.dock):before,
/* @TODO: thiccer resize ghost (4px instead of 3px) */
/* @TODO: thicker resize ghost (4px instead of 3px) */
.resize-ghost.thick:after,
.resize-ghost.thick:before {
content: '';