jspaint

2025-12-11 0 864

JS油漆

基于像素完美的基于Web的MS Paint Remake等…尝试一下!然后加入Discord服务器分享您的艺术品!

JS Paint重新创建了MS油漆的每个工具和菜单,甚至还鲜为人知的功能,以高度的保真度。

它支持主题,其他文件类型和可访问性功能,例如停留点击器和语音识别。

啊,是的,好老油漆。不是带有丝带或新的Skeuomormormormormorphic的界面的那个,可以占据近一半的屏幕。 (而不是更新的油漆3D。)

Windows 95、98和XP是涂料的黄金年。您有一个工具箱和一个颜色盒,一个前景颜色和背景颜色,这就是您所需要的。

事情很简单。

但是我们想撤消三个以上的动作。我们想编辑透明图像。我们不能只继续使用旧油漆。

这就是为什么我要制作JS油漆。我想把优质的旧油漆带入现代时代。

当前的改进包括:

  • 开源(MIT许可)
  • 跨平台
  • 移动友好
    • 触摸支持:用两个手指振作起来,然后捏缩放
    • 单击/点击选定的颜色区域以交换前景和背景颜色
    • 查看>全屏到切换全屏模式,非常适合小屏幕
    • Extras>快速撤消按钮以添加浮动撤消按钮,以便更轻松访问

      • (默认情况下,触摸设备的默认情况下可能会启用)
  • 网络功能
    • 文件>从URL加载…从Web打开图像。
    • 文件>上传到IMGUR ,将当前图像上传到Imgur。
    • 粘贴支持从URL加载。
    • 您可以创建将在JS油漆中打开Web图像的链接。例如,此链接将以一个模板为单位开始:https://jspaint.app/#load:https://i.imgur.com/zjmrwwb.png
    • 基本的多用户协作支持。在jspaint .App/#会话中启动会话:多用户测试,然后将链接发送给您的朋友!它不是无缝的;其他用户的操作中断您在做什么,反之亦然。会议不是私人的,您可能随时失去工作。如果您想要更好的协作支持,请遵循Mopaint的开发。
  • Extras>主题以更改应用程序的外观。
    • 黑暗变体
    • 矢量工具图标手工制作以匹配像素艺术版本,用于现代和经典主题
    • 神秘的主题,以万圣节的精神
    • 冬季主题,带有特殊的调色板,包括糖果甘蔗条纹和出现日历样式襟翼,揭示了每个工具的像素艺术
    • Bubblegum主题,具有商务粉红色配色方案和AI生成的图标
  • Extras>放大UI以使按钮和菜单更大,以便使用眼睛跟踪器,头部跟踪器或其他课程输入设备使用。对于平板电脑来说,也可能不错,但目前的电话也不太适合。
  • Extras>“停留”点击器可以通过悬停在一个位置上,以使用眼睛跟踪器或头部跟踪器来自动单击。
    • 突出显示的按钮将突出显示,并在延迟后执行点击。
    • 支持拖动窗户并在画布上绘制。
    • 只需使用一个网络摄像头,您就可以使用Extras> Head Tracker使用Enable ViaCam(Head Tracker),Gazepointer(Exewerter)或内置的Tracky Mouse头跟踪器进行尝试。
    • 使用Tracky Mouse API可以轻松地将此功能添加到其他Web应用程序中。
  • Extras>语音识别以用您的声音控制应用程序。
    • 选择工具和颜色(“填充工具”,“橙色”等)
    • 欣赏视图(“向下滚动并向左滚动”或“向西南”等)
    • 探索菜单,或激活任何菜单项而不首先打开菜单
    • 与Windows互动
    • 用文本工具指示文本
  • 从当前文档历史记录中创建动画GIF。可从Extras菜单或CTRL+Shift+G中访问。这很漂亮,您应该尝试一下!不过,您可能需要限制图像的大小。
  • 加载并保存许多带有颜色的调色板格式>获得颜色和颜色>保存颜色。 (我为此做了一个库:Anypalette.js。)
    • 您还可以将调色板文件拖放到应用程序中以进行加载。

编辑功能:

  • 使用alt+鼠标轮缩放进出
  • 编辑透明图像!要创建一个透明的图像,请转到Image>属性…然后选择透明,然后确定,然后图像>清除图像或使用橡皮擦工具。具有任何半透明像素的图像将以透明模式打开。
  • 您可以在持有CTRL时进行选择来裁剪图像
  • 旋转的键盘快捷键: CTRL+。和ctrl+, ( <和> )
  • 图像中的任何任意角度旋转>翻转/旋转
  • 在图像>伸展/偏斜中,您可以一次拉伸超过500%
  • 缩放到任意比例的视图>缩放>自定义…
  • 缩放将画布安装在窗口中,并带有视图>缩放>缩放>缩放到窗口
  • 无关紧要的填充:使用填充工具时,通过保持换档来替换整个图像中的颜色

其他改进:

  • 垂直颜色盒模式,可从额外访问>垂直颜色框访问
  • 您可以在任何缩放级别使用文本工具(它可以预览最终在画布上的精确像素)。
  • 如果您的浏览器支持它,则可以在文本框中使用SpellCheck。
  • 与Windows 10的油漆相比,调整大小的调节大小更容易抓取。
  • 省略了一些缩略图视图错误,例如在错误的位置显示的选择。
  • 无限的undos/重做(与Windows XP中的3个相反,或Windows 7中的50个)
  • 撤消历史是非线性的,这意味着如果您撤消并做其他重做的事情,那么重做就不会丢弃。相反,在历史树中创建了一个新的分支。通过编辑>“历史”或“ ctrl+shift+y”跳到历史上的任何点
  • 自动保留图像的备份。每个图像只有一个备份,这不会给您带来很多安全。请记住使用文件>保存或ctrl+s保存!使用文件>管理存储管理备份。

限制:

使用工具的一些事情尚未完成。请参阅todo.md

Web应用程序中的完整剪贴板支持需要一个浏览器支持带有images的异步剪贴板API,即在撰写时76+ Chrome。

在其他浏览器中,您仍然可以使用CTRL+C复制,用CTRL+X切割,然后用Ctrl+V粘贴,但是从JS涂料中复制的数据只能粘贴到其他JS涂料的实例中。外部图像可以粘贴到中。

支持的文件格式

图像格式

配x节省JPEG会引入使用填充工具或透明选择时引起问题的工件。

配x节省某些格式将减少图像中的颜色数量。

与MS Paint不同,您可以使用Edit> Undo来恢复节省的色彩或质量降低。这不会撤消文件,但允许您使用文件>另存为更高质量的不同格式。

建议保存为PNG,因为它可以在保留全质量的同时提供小文件尺寸。

文件扩展 姓名 读 写 阅读调色板 写调色板
.png PNG ✅ ✅
.bmp,.dib 单色位图 ✅ ✅ ✅
.bmp,.dib 16颜色位图 ✅ ✅ ✅
.bmp,.dib 256颜色位图 ✅ ✅ ✅
.bmp,.dib 24位位图 ✅ ✅ N/A。 N/A。
.tif,.tiff,.dng,.cr2,.nef TIFF(加载第一页) ✅ ✅
.pdf PDF(加载第一页) ✅
.webp WebP
.gif GIF
.jpeg,.jpg jpeg N/A。 N/A。
.svg SVG(仅默认尺寸)
.ico ICO(仅默认尺寸)

当前,标记的功能保留到浏览器中以支持或不支持。如果标记了“写入”,则格式将出现在文件类型下拉列表中,但在尝试保存时可能不起作用。有关打开文件,请参见Wikipedia的浏览器映像格式支持表,以获取更多信息。

标记的功能可能很快即将到来,不适用的N/A手段。

“ Read Palette”是指自动将颜色加载到颜色框中(从索引的颜色图像),“ Write Palette”是指编写索引的颜色图像。

调色板格式

使用颜色>保存颜色和颜色>获得颜色,您可以以许多不同格式保存和加载颜色,以兼容各种程序。

如果您想在另一个应用程序中添加广泛的调色板支持,我将此功能作为库提供:Anypalette.js

文件扩展 姓名 程序 读 写
。朋友 即兴调色板 Windows 95和Windows NT 4.0的MS油漆 ✅ ✅
.gpl gimp调色板 gimp,inkscape,krita,kolourpaint,scribus,cinepaint,mypaint ✅ ✅
.aco Adobe颜色色板 Adobe Photoshop ✅ ✅
.ase Adobe Swatch Exchange Adobe Photoshop,Indesign和Illustrator ✅ ✅
。TXT paint.net调色板 paint.net ✅ ✅
。行为 Adobe颜色表 Adobe Photoshop和Illustrator ✅ ✅
.pal,.psppalette 油漆店Pro调色板 Paint Shop Pro(JASC软件 / Corel) ✅ ✅
.hpl 家庭调色板 Allaire Homesite / Macromedia Coldfusion ✅ ✅
。CS Colorschemer Colorschemer Studio ✅
。朋友 星际船调色板 星际争霸 ✅ ✅
.wpe 星形地形调色板 星际争霸 ✅ ✅
.sketchpalette 草图调色板 草图 ✅ ✅
.spl 滑雪调色板 Skencil(以前称为素描) ✅ ✅
.soc Staroffice颜色 Staroffice,OpenOffice,Libreoffice ✅ ✅
。颜色 KolourPaint Color Collection Kolourpaint ✅ ✅
。颜色 等离子桌面配色方案 KDE等离子桌面 ✅
。主题 Windows主题 Windows桌面 ✅
.themepack Windows主题 Windows桌面 ✅
.css,.scss,.styl 级联样式表 网络浏览器 /网页 ✅ ✅
.html,.svg,.js 任何具有CSS颜色的文本文件 网络浏览器 /网页 ✅

你可知道?

  • 有一个黑色和白色模式,带有图案,而不是调色板中的颜色,您可以从图像>属性…

  • 如果您在正确的位置抓住颜色框和工具箱,则可以将其拖动。您甚至可以将它们拖到小窗户中。您可以双击其标题栏,将窗户放回侧面。

  • 除了左键单击前景颜色和右键单击背景颜色外,还可以通过绘制CTRL访问第三种颜色。它从没有颜色开始,因此您需要保持CTRL并首先选择颜色。关于此颜色插槽的奇特之处在于,您可以在绘制时按和释放CTRL以切换颜色。

  • 您可以将图像转换(例如翻转/旋转,伸展/偏斜或反转(在图像菜单中)应用于整个图像或选择。尝试使用自由形式的选择工具涂抹,然后进行图像>倒置

  • 这些MS油漆教程中的技巧和技巧也可以在JS Paint中起作用:

    • 刷缩放(在数字垫上+ & -调整刷子尺寸)
    • “自定义刷子”(保持移位并拖动选择以涂抹它)
    • “邮票”“工具”(保持轮换并单击选择以打印)
    • 图像缩放(在数字垫上+ & -以2缩放选择的选择)
    • 颜色更换(用橡皮擦右键鼠标按钮,以选择性地用背景颜色替换前景颜色)
    • 网格( Ctrl+G &Zoom至4x+)
    • 快速撤消(按第二个鼠标按钮取消您执行的动作。如果您偶然这样做,我也可以重做!)
    • 滚动轮虫(嗯,也许不要重新创建这个?)

桌面应用

PWA

JS油漆可以安装为渐进式网络应用程序(PWA),尽管它尚未脱机。在地址栏中查找安装提示。

PWA功能:

  • 没有地址栏;网络和本地之间的中间地面
  • 跨平台(MacOS,Windows,Linux,Android,iOS)
  • 基本文件集成:
    • 文件>打开
    • 文件>保存下载文件后,要求使用文件名和格式
    • 将文件拖到窗口上以打开它们

缺少功能:

  • 直接保存到文件已实现,但目前未启用。

    我担心数据丢失的原因有两个:1。文件的行为>“保存 / ctrl+s的行为”的变化,从有效地执行直接覆盖文件,尽管我为此做了一个警告对话框,但不再显示选项; 2。有一个错误的错误,保存的文件最终完全空(零字节),我不知道这是我的代码还是铬中的错误。

  • 离线支持未实施。

    我已经对此进行了一些刺伤,但我不是唯一的一个,但是有一些巨大的警告,例如开发服务器无法在不破坏服务工作者的情况下实现重新负载。

电子

我还将其置于带电子和电子锻造的桌面应用程序中。您可以从“发行”页面下载它。

电子应用功能:

  • 类似于本地的体验(在没有地址栏的窗口中运行)
  • 跨平台(MacOS,Windows,Linux)
  • 剪贴板支持
  • 文件可以通过各种方式打开:
    • 文件>打开
    • 拖到窗口
    • 拖放到MacOS上的码头图标
    • 拖放到桌面快捷方式上
    • 右键单击>在文件管理器中打开(MACOS和Linux)

      • 在Windows上,您可以手动将通往可执行文件的路径粘贴到Open -with Dialog中,您可以通过在任务栏中右键单击应用程序,然后右键单击应用程序的名称并选择属性来找到。在“快捷”选项卡中,目标字段是通往可执行文件的路径。以这种方式打开应用程序后,该应用程序将显示在列表的开放式上,如果选择“始终”,它将成为该文件类型的默认应用程序。
    • 命令行:在终端中键入jspaint Path/to/file.png
  • 文件>保存将直接保存到文件
  • 文件>设置为墙纸(瓷砖)和文件>设置为墙纸(中心)
  • 在MacOS上,标题栏中显示了代表当前打开文件的图标。您可以将此图标拖到其他应用程序中,例如,在电子邮件中包括您要编辑的图像。有未保存的更改时,图标会变暗。
电子应用程序限制
  • 基础:
    • 默认情况下执行在Mac和Windows上被阻止
      • 在MacOS上,您需要CTRL+单击该文件,然后说打开
      • 在Windows上,您需要说“更多信息”,然后说“运行”(或“无论如何运行”?)
      • 我需要支付代码签名费以避免这种费用。基本上是勒索的安全性。
    • 没有自动更新。显然,我需要支付代码签名的费用才能获得此免费服务。
      • 也就是说,关于油漆的帮助>至少在新闻更新方面,可以告诉您JS油漆是否过时。
    • 电子已经过时。例如,它可能包含已修复的图像解码漏洞。但是,我采取了预防措施来沙箱应用程序,并将写入访问权限限制在应用程序中明确打开的文件列表中,该列表由主过程控制,与渲染器过程分开,该过程将处理图像解码。
    • 只能一次打开一个单个编辑窗口。
    • 文件菜单的最新文件列表尚未实现,也没有特定于OS的跳跃菜单。
  • 末节:
    • 如果您在“管理存储对话框”中单击“打开链接”之前,请显示一个非常令人困惑的消息。
    • WebGL错误消息告诉您刷新而不提供重新加载的方法;另外,将应用程序称为网页感觉没有打印
    • 文件>“打开”对话框没有所有文件(*。*)选项,并且支持的文件类型列表并不详尽;例如,可以加载AVIF图像,但仅通过拖放来加载
    • 拖放显示两个“将更改保存到x?”对话彼此?
  • 我不确定所有这些仍然是问题,需要重新测试它们:
    • 退出不会完全退出应用程序,只有在打开的窗口…预期的行为时才关闭窗口?不应该右键单击>退出真的退出吗? https://stac*kover**flow.com/questions/44316306/how-to-to-quit-electron-app-on-mac
    • 当保存更改提示提示时,退出不会显示/焦点窗口
    • Ctrl+C未在Mac/Linux电子/电子#5273上退出
      • 这是因为editor_window.on(“关闭”)调用预防违规,可能是一个功能,但需要显示/聚焦窗口
      • https://st*a*cko*verflow.com/questions/75362687/electron-js-processes-do-not-exit-on-app-quit
    • 打开SVG文件也无法通过命令行参数(拖动到文件资源管理器中的快捷方式)工作),即使拖动并掉入窗口工作中也是如此。
      • 似乎将加载SVG作为调色板加载…这是我遇到的东西吗?

开发设置

克隆仓库。

如果没有它,请安装Node.js,然后在项目目录中打开命令提示符 /终端。

质量保证

运行NPM运行皮棉以检查拼写错误,类型错误,代码样式问题和其他问题。

运行NPM运行格式以自动修复格式问题,或NPX ESLINT-修复所有可自动固定问题的文件。

格式规则配置为与VS Code的内置格式化器的兼容性。

运行NPM测试以使用柏树运行基于浏览器的测试。 (不幸的是,启动和运行测试很慢。)

运行NPM运行接受以接受任何视觉更改。不幸的是,这重新运行了所有测试,而不是接受先前测试的结果,因此您最终可能会得到与以前的测试不同的结果。如果使用GitHub桌面,则可以以四种不同的模式查看图像的差异。

要打开Cypress UI,请先运行NPM运行测试:start-server,然后同时进行NPM运行CY:打开

测试还与Travis CI连续集成。

Web应用程序(https://*jsp**aint.app)

使用NPM I安装依赖关系后,请使用NPM Run Dev启动实时填充服务器。

确保在balout.css中使用任何布局重要样式。在更新布局时,使用RTLCSS生成了样式表的左右版本。
您应该通过将语言更改为阿拉伯语或希伯来语来测试RTL布局。转到Extras>“语言>ال样”或“עברעבר” 。
有关如何控制RTL布局,请参见控制指令。

有一个VS代码启动任务,用于附加到Chrome进行调试。有关使用说明,请参见.vscode/启动。

桌面应用(电子)

  • 使用NPM i安装依赖项
  • 使用NPM运行电子启动电子应用:开始

包括电子选,因此您可以使用F5 / Ctrl+R进行重新加载,而F12 / Ctrl+Shift+I打开DevTools。

您可以使用NPM运行电子来构建生产:制作

有一个VS代码启动任务,用于调试电子主过程。对于渲染器过程,您可以使用嵌入式的Chrome DevTools。

部署

可以使用常规Web服务器部署JS涂料。

没有什么需要编译的。

CORS代理

可选地,如果将URL粘贴到JS Paint中,则可以设置Anywhere Server的CORS Anywhere Server,或使用#load:<URL>功能,其中不在同一域上。

默认情况下,它将使用设置的CORS使用CORS来与jspaint .App一起使用。

它是在Heroku上免费托管的,您可以设置自己的实例并将其配置为与自己的域一起使用。

您必须使用自己的实例URL查找并替换https://jspaint-cors-proxy.her**ok*uapp.com。

多人游戏支持

多人支持当前依赖于不是开源软件的Firebase。

您可以创建一个Firebase实时数据库实例,并编辑JS Paint的Sessions.js指向它,在设置Web应用程序时,用Firebase Console替换了传递给initializeapp的配置。

但是到目前为止,多人游戏模式非常卑鄙。应该用开源的东西代替,更安全,更高效,更健壮。

嵌入您的网站

简单的

将其添加到您的HTML:

 < iframe src =\" https://j*spaint*.*app \" width =\" 100% \" height =\" 100% \" > </ iframe > 

从图像开始

您可以通过向URL添加#load:<url>从URL加载图像。

 < iframe src =\" https://j*spaint*.*app#load:https://j*spaint*.*app/favicon.ico \" width =\" 100% \" height =\" 100% \" > </ iframe >

先进的

如果要控制JS涂料,如何保存/加载文件或直接访问画布,则有一个不稳定的API。

首先,您需要克隆回购,因此您可以将iFrame指向本地副本。

JS油漆的本地副本必须托管与包含页面同一Web服务器,或者更具体地说,必须共享相同的来源。

拥有本地副本也意味着API随时都不会破裂。

如果将JS涂料克隆到一个名为jspaint的文件夹中,该文件夹与要嵌入的页面相同的文件夹中,您可以使用此信息:

jspaint -iframe\” width=\”100%\” height=\”100%\”></iframe>\”>

 < iframe src =\" jspaint /index.html \" id =\" jspaint -iframe \" width =\" 100% \" height =\" 100% \" > </ iframe >

如果它居住在其他地方,则可能需要添加../到路径的开始,才能上升一个水平。例如,src =“ ../../ apps/ jspaint /index.html”。您也可以使用绝对URL,例如src =“ https://*e*xa*mple.com/cool-apps/jspaint/index.html”。

更改文件的保存/加载方式

您可以使用JS Paint的SystemHooks API覆盖文件保存和打开对话框。

jspaint-iframe\”);
var jspaint = iframe.contentWindow;
// Wait for systemHooks object to exist (the iframe needs to load)
waitUntil(()=> jspaint .systemHooks, 500, ()=> {
// Hook in
jspaint .systemHooks.showSaveFileDialog = async ({ formats, defaultFileName, defaultPath, defaultFileFormatID, getBlob, savedCallbackUnreliable, dialogTitle }) => { … };
jspaint .systemHooks.showOpenFileDialog = async ({ formats }) => { … };
jspaint .systemHooks.writeBlobToHandle = async (save_file_handle, blob) => { … };
jspaint .systemHooks.readBlobFromHandle = async (file_handle) => { … };
});
// General function to wait for a condition to be met, checking at regular intervals
function waitUntil(test, interval, callback) {
if (test()) {
callback();
} else {
setTimeout(waitUntil, interval, test, interval, callback);
}
}
</script>\”>

 < script >
var iframe = document . getElementById ( \" jspaint -iframe\" ) ;
var jspaint = iframe . contentWindow ;
// Wait for systemHooks object to exist (the iframe needs to load)
waitUntil ( ( ) => jspaint . systemHooks , 500 , ( ) => {
	// Hook in
	jspaint . systemHooks . showSaveFileDialog = async ( { formats , defaultFileName , defaultPath , defaultFileFormatID , getBlob , savedCallbackUnreliable , dialogTitle } ) => { ... } ;
	jspaint . systemHooks . showOpenFileDialog = async ( { formats } ) => { ... } ;
	jspaint . systemHooks . writeBlobToHandle = async ( save_file_handle , blob ) => { ... } ;
	jspaint . systemHooks . readBlobFromHandle = async ( file_handle ) => { ... } ;
} ) ;
// General function to wait for a condition to be met, checking at regular intervals
function waitUntil ( test , interval , callback ) {
	if ( test ( ) ) {
		callback ( ) ;
	} else {
		setTimeout ( waitUntil , interval , test , interval , callback ) ;
	}
}
</ script >

斑点代表内存中文件的内容。

文件句柄是可以识别文件的任何东西。您可以拥有此概念,并定义如何识别文件。从索引到数组到Dropbox文件ID,再到IPFS URL,再到文件路径,它可能是任何东西。我忘记了它可以是任何类型,也许它可能是字符串。

一旦有了文件句柄的概念,就可以使用系统挂钩实现文件拾取器,以及函数以读写文件。

命令 使用的钩子
文件>另存为 systemhooks.showsavefiledialog,然后选择文件时,systemhooks.writeblobtohandle
文件>打开 systemhooks.showopenfiledialog,然后选择文件时,systemhooks.readblobfromhandle
文件>保存 systemhooks.writeblobtohandle(或与文件相同>保存,如尚未打开文件)
编辑>复制到 systemhooks.showsavefiledialog,然后选择文件时,systemhooks.writeblobtohandle
编辑>粘贴 systemhooks.showopenfiledialog,然后选择文件时,systemhooks.readblobfromhandle
文件>设置为墙纸(瓷砖) systemhooks.setWallPaperiled如果定义,else systemhooks.setwallpaperered如果定义,则与文件>另存为
文件>设置为墙纸(中心) Systemhooks.setWallPaperered如果定义,则与文件>另存为
Extras>渲染历史为GIF 与文件相同>另存为
颜色>保存颜色 与文件相同>另存为
颜色>获得颜色 与文件相同>打开

最初加载文件

要使用加载用于编辑的文件启动该应用程序,请等待应用程序加载,然后使用文件句柄readBlobFromHandle调用,并告诉应用程序加载该文件blob。

 const file_handle = \"initial-file-to-load\" ;
systemHooks . readBlobFromHandle ( file_handle ) . then ( file => {
	if ( file ) {
		contentWindow . open_from_file ( file , file_handle ) ;
	}
} , ( error ) => {
	// Note: in some cases, this handler may not be called, and instead an error message is shown by readBlobFromHandle directly.
	contentWindow . show_error_message ( `Failed to open file ${ file_handle } ` , error ) ;
} ) ;

这很笨拙,将来可能会有一个查询字符串参数来通过其句柄加载初始文件。 (自我注意:它需要等待您的系统挂钩注册,以某种方式。)

已经有一个查询字符串参数可以从URL加载:

 < iframe src =\" https://j*spaint*.*app?load:SOME_URL_HERE \" > </ iframe >

但这不会设置用于保存的文件句柄。

集成为墙纸

您可以定义两个功能来设置墙纸,将通过文件>设置为墙纸(瓷砖)和文件>设置为墙纸(中心) 。

  • systemhooks.setWallPaperTiled =(canvas)=> {…};
  • systemhooks.setWallPaperered =(canvas)=> {…};

如果仅定义SystemHooks.SetWallPaperered,JS Paint将尝试猜测屏幕的尺寸并铺图像,并通过调用SystemHooks.setWallPaperered功能应用它。

如果您不指定SystemHooks.setWallPaperered,则使用SystemHooks.showsavefiledialog和SystemHooks.writeBlobtoHandle保存文件(<原始文件名> wallpaper.png)。

这是一个完整的示例,支持持续的自定义墙纸作为包含页面上的背景:

jspaint.systemHooks.setWallpaperCentered = (canvas) => {
canvas.toBlob((blob) => {
setDesktopWallpaper(blob, \”no-repeat\”, true);
});
};
jspaint .systemHooks.setWallpaperTiled = (canvas) => {
canvas.toBlob((blob) => {
setDesktopWallpaper(blob, \”repeat\”, true);
});
};

function setDesktopWallpaper(file, repeat, saveToLocalStorage) {
const blob_url = URL.createObjectURL(file);
wallpaper.style.backgroundImage = `url(${blob_url})`;
wallpaper.style.backgroundRepeat = repeat;
wallpaper.style.backgroundPosition = \”center\”;
wallpaper.style.backgroundSize = \”auto\”;
if (saveToLocalStorage) {
const fileReader = new FileReader();
fileReader.onload = () => {
localStorage.setItem(\”wallpaper-data-url\”, fileReader.result);
localStorage.setItem(\”wallpaper-repeat\”, repeat);
};
fileReader.onerror = () => {
console.error(\”Error reading file (for setting wallpaper)\”, file);
};
fileReader.readAsDataURL(file);
}
}

// Initialize the wallpaper from localStorage, if it exists
try {
const wallpaper_data_url = localStorage.getItem(\”wallpaper-data-url\”);
const wallpaper_repeat = localStorage.getItem(\”wallpaper-repeat\”);
if (wallpaper_data_url) {
fetch(wallpaper_data_url).then(response => response.blob()).then(file => {
setDesktopWallpaper(file, wallpaper_repeat, false);
});
}
} catch (error) {
console.error(error);
}\”>

 const wallpaper = document . querySelector ( \"body\" ) ; // or some other element

jspaint . systemHooks . setWallpaperCentered = ( canvas ) => {
	canvas . toBlob ( ( blob ) => {
		setDesktopWallpaper ( blob , \"no-repeat\" , true ) ;
	} ) ;
} ;
jspaint . systemHooks . setWallpaperTiled = ( canvas ) => {
	canvas . toBlob ( ( blob ) => {
		setDesktopWallpaper ( blob , \"repeat\" , true ) ;
	} ) ;
} ;

function setDesktopWallpaper ( file , repeat , saveToLocalStorage ) {
	const blob_url = URL . createObjectURL ( file ) ;
	wallpaper . style . backgroundImage = `url( ${ blob_url } )` ;
	wallpaper . style . backgroundRepeat = repeat ;
	wallpaper . style . backgroundPosition = \"center\" ;
	wallpaper . style . backgroundSize = \"auto\" ;
	if ( saveToLocalStorage ) {
		const fileReader = new FileReader ( ) ;
		fileReader . onload = ( ) => {
			localStorage . setItem ( \"wallpaper-data-url\" , fileReader . result ) ;
			localStorage . setItem ( \"wallpaper-repeat\" , repeat ) ;
		} ;
		fileReader . onerror = ( ) => {
			console . error ( \"Error reading file (for setting wallpaper)\" , file ) ;
		} ;
		fileReader . readAsDataURL ( file ) ;
	}
}

// Initialize the wallpaper from localStorage, if it exists
try {
	const wallpaper_data_url = localStorage . getItem ( \"wallpaper-data-url\" ) ;
	const wallpaper_repeat = localStorage . getItem ( \"wallpaper-repeat\" ) ;
	if ( wallpaper_data_url ) {
		fetch ( wallpaper_data_url ) . then ( response => response . blob ( ) ) . then ( file => {
			setDesktopWallpaper ( file , wallpaper_repeat , false ) ;
		} ) ;
	}
} catch ( error ) {
	console . error ( error ) ;
}

有点递归,对不起;可能会更简单。就像仅使用数据URL。 (实际上,我认为我想使用blob URL,以免它用超长的URL膨胀DOM Insportor。这实际上是DevTools UX错误。也许他们已经改善了这一点?)

指定画布大小

您可以加载具有所需尺寸的文件。目前没有特殊的API。

请参阅最初加载文件。

指定主题

您可以以编程方式更改主题:

jspaint-iframe\”);
var jspaint = iframe.contentWindow;
jspaint .set_theme(\”modern.css\”);\”>

 var iframe = document . getElementById ( \" jspaint -iframe\" ) ;
var jspaint = iframe . contentWindow ;
jspaint . set_theme ( \"modern.css\" ) ;

但这将破坏用户的喜好。

Extras>“主题”菜单仍然可以使用,但是在重新加载页面时,偏好不会持续。

将来可能会有一个查询字符串参数来指定默认主题。您还可以分配jspaint更改默认主题。

指定语言

与主题类似,您可以尝试以编程方式更改语言:

jspaint-iframe\”);
var jspaint = iframe.contentWindow;
jspaint .set_language(\”ar\”);\”>

 var iframe = document . getElementById ( \" jspaint -iframe\" ) ;
var jspaint = iframe . contentWindow ;
jspaint . set_language ( \"ar\" ) ;

但这实际上会要求用户重新加载应用程序以更改语言。

Extras>“语言”菜单仍将起作用,但是每次重新加载页面时,用户都会不愿更改语言。

将来可能会有一个查询字符串参数来指定默认语言。您还可以分配jspaint来更改默认语言。

添加自定义菜单

尚未支持。您可以分叉jspaint并添加自己的菜单。

直接访问画布

通过访问画布,您可以实现图纸的实时预览,例如,实时更新游戏引擎中的纹理。

jspaint-iframe\”);
// contentDocument here refers to the webpage loaded in the iframe, not the image document loaded in jspaint .
// We\’re just reaching inside the iframe to get the canvas.
var canvas = iframe.contentDocument.querySelector(\”.main-canvas\”);\”>

 var iframe = document . getElementById ( \" jspaint -iframe\" ) ;
// contentDocument here refers to the webpage loaded in the iframe, not the image document loaded in jspaint .
// We\'re just reaching inside the iframe to get the canvas.
var canvas = iframe . contentDocument . querySelector ( \".main-canvas\" ) ;

建议不要将其用于加载文档,因为它不会更改文档标题或重置撤消/重做历史记录等。而是使用open_from_file。

执行自定义操作

如果您想制作按钮或其他UI来对文档进行操作,则应该(可能)使其变得不可行。这很容易,只需将您的动作包裹在通话中。

jspaint-iframe\”);
var jspaint = iframe.contentWindow;
var icon = new Image();
icon.src = \”some-folder/some-image-15×11-pixels.png\”;
jspaint .undoable({
name: \”Seam Carve\”,
icon: icon, // optional
}, function() {
// do something to the canvas
});\”>

 var iframe = document . getElementById ( \" jspaint -iframe\" ) ;
var jspaint = iframe . contentWindow ;
var icon = new Image ( ) ;
icon . src = \"some-folder/some-image-15x11-pixels.png\" ;
jspaint . undoable ( {
	name : \"Seam Carve\" ,
	icon : icon , // optional
} , function ( ) {
	// do something to the canvas
} ) ; 

async函数systemhooks.showsavefiledialog({格式,defaultFileName,defaultpath,defaultfileformatid,getBlob,savedcallbackunrable,dialogTitle})

定义此功能以覆盖默认保存对话框。这既用于保存图像,调色板文件和动画。

参数:

  • 格式:代表文件类型的对象数组,并具有以下属性:
    • 格式化:唯一标识格式的字符串(可能与模拟型相同)
    • Mimetype(可选):文件格式的指定媒体类型,例如“ Image/png”(调色板格式没有此属性)
    • 名称:文件格式的名称,例如“ WebP”
    • nameWithExtensions:文件格式的名称,然后是扩展名列表,例如“ Tiff(*.tif;*。tiff)”
    • 扩展:一个文件扩展名,不包括DOT,首选扩展名,例如[“ BMP”,“ DIB”]
  • DefaultFilename(可选):建议的文件名,例如“ Untitled.png”或打开文档的名称

下载源码

通过命令行克隆项目:

git clone https://github.com/1j01/jspaint.git

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 建站资源 jspaint https://www.zuozi.net/35162.html

litegraph.js
上一篇: litegraph.js
react quill
下一篇: react quill
常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务