jspaint

2025-12-11 0 696

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小时在线 专业服务