JS PINTURAUn remake de pintura de MS basado en la web perfecto para píxel y más ... ¡Pruébelo! ¡Luego únase al servidor Discord para compartir su arte!
JS Paint recrea todas las herramientas y menú de pintura de MS, e incluso características poco conocidas, con un alto grado de fidelidad.
Admite temas, tipos de archivos adicionales y características de accesibilidad como el modo de mirada y reconocimiento de voz.

Ah sí, buena pintura vieja. No el que tiene las cintas o la nueva Skeuomorphic con la interfaz que puede ocupar casi la mitad de la pantalla. (Y no la pintura más nueva en 3D).
Windows 95, 98 y XP fueron los años dorados de pintura. Tenía una caja de herramientas y una caja de color, un color de primer plano y un color de fondo, y eso era todo lo que necesitaba.
Las cosas eran simples.
Pero queremos deshacer más de tres acciones. Queremos editar imágenes transparentes. No podemos seguir usando la pintura vieja.
Por eso estoy haciendo pintar a JS. Quiero traer una buena pintura vieja a la era moderna.
Características de edición:
Mejoras misceláneas:

Algunas cosas con las herramientas aún no se han hecho. Ver TODO.MD
El soporte completo del portapapeles en la aplicación web requiere un navegador que admite la API del portapapeles Async con imágenes, a saber, Chrome 76+ al momento de escribir.
En otros navegadores, aún puede copiar con Ctrl+C , cortar con Ctrl+X y pegar con Ctrl+V , pero los datos copiados de la pintura JS solo se pueden pegar en otros casos de pintura JS. Se pueden pegar imágenes externas.
A diferencia de la pintura de MS, puede usar Editar> Deshacer para revertir el color o la reducción de la calidad del ahorro. Esto no deshace el guardar el archivo, pero le permite guardar en un formato diferente con mayor calidad, usando el archivo> guardar como .
Se recomienda guardar como PNG, ya que proporciona pequeños tamaños de archivo mientras conserva la calidad completa.
| Extensión de archivo | Nombre | Leer | Escribir | Leer paleta | Paleta de escritura |
|---|---|---|---|---|---|
| .png | Png | ✅ | ✅ | ||
| .bmp, .dib | Mapa de bits monocromático | ✅ | ✅ | ✅ | |
| .bmp, .dib | 16 mapa de bits de color | ✅ | ✅ | ✅ | |
| .bmp, .dib | 256 mapa de bits de color | ✅ | ✅ | ✅ | |
| .bmp, .dib | Mapa de bits de 24 bits | ✅ | ✅ | N / A | N / A |
| .tif, .tiff, .dng, .cr2, .nef | TIFF (carga la primera página) | ✅ | ✅ | ||
| PDF (carga la primera página) | ✅ | ||||
| .webp | Webp | ||||
| .gif | Gif | ||||
| .jpeg, .jpg | Jpeg | N / A | N / A | ||
| .svg | SVG (solo tamaño predeterminado) | ||||
| .ICO | ICO (solo tamaño predeterminado) |
Las capacidades marcadas con el navegador se quedan actualmente en el navegador para soportar o no. Si "Write" está marcado, el formato aparecerá en el menú desplegable del tipo de archivo, pero es posible que no funcione cuando intente guardar. Para abrir archivos, consulte la tabla de soporte de formato de imagen del navegador de Wikipedia para obtener más información.
Las capacidades marcadas con pueden llegar pronto, y N/A significa no aplicable.
"Leer paleta" se refiere a cargar los colores en la caja de colores automáticamente (desde una imagen de color indexada), y "Write Palette" se refiere a escribir una imagen de color indexada.
Con colores> Guardar colores y colores> Obtener colores, puede guardar y cargar colores en muchos formatos diferentes, para compatibilidad con una amplia gama de programas.
Si desea agregar un amplio soporte de paleta a otra aplicación, he puesto esta funcionalidad disponible como biblioteca:
Anypalette.js
| Extensión de archivo | Nombre | Programas | Leer | Escribir |
|---|---|---|---|---|
| .camarada | Paleta de riff | MS Paint para Windows 95 y Windows NT 4.0 | ✅ | ✅ |
| .gpl | Paleta | Gimp, Inkscape, Krita, KolourPaint, Scribus, CinePaint, MyPaint | ✅ | ✅ |
| .CoCo | Swatch de color Adobe | Adobe Photoshop | ✅ | ✅ |
| .Plaza bursátil norteamericana | Adobe Swatch Exchange | Adobe Photoshop, InDesign e Illustrator | ✅ | ✅ |
| .TXT | Paleta de pintura.net | Paint.net | ✅ | ✅ |
| .acto | Mesa de color de adobe | Adobe Photoshop e Illustrator | ✅ | ✅ |
| .pal, .ppalette | Paleta de pintura Taller Pro | Paint Shop Pro (Jasc Software / Corel) | ✅ | ✅ |
| .HPL | Paleta de casas | Allaire Homesite / Macromedia Coldfusion | ✅ | ✅ |
| .cs | COLORSHEMER | ColorSchemer Studio | ✅ | |
| .camarada | Paleta de estrellas | Estrella | ✅ | ✅ |
| .wpe | Paleta de terreno de Starcraft | Estrella | ✅ | ✅ |
| .sketchpalette | Paleta | Bosquejo | ✅ | ✅ |
| .pl | Paleta de skencil | Skencil (anteriormente llamado Sketch) | ✅ | ✅ |
| .soc | Colores de StarOffice | StarOffice, OpenOffice, LibreOffice | ✅ | ✅ |
| .bandera | Colección de colores de kolourpaint | Kolourpaint | ✅ | ✅ |
| .bandera | Esquema de color de escritorio de plasma | Escritorio de plasma kde | ✅ | |
| .tema | Tema de Windows | Escritorio de Windows | ✅ | |
| . | Tema de Windows | Escritorio de Windows | ✅ | |
| .css, .scss, .styl | Hojas de estilo en cascada | Navegadores web / páginas web | ✅ | ✅ |
| .html, .svg, .js | Cualquier archivo de texto con colores CSS | Navegadores web / páginas web | ✅ |
Hay un modo en blanco y negro con patrones en lugar de colores en la paleta, a los que puede obtener de la imagen> atributos ...
Puede arrastrar la caja de color y la caja de herramientas si los agarra por el lugar correcto. Incluso puedes arrastrarlos a pequeñas ventanas. Puede acoplar las ventanas de regreso al lado haciendo doble clic en sus barras de título.
Además del color de primer plano de clic izquierdo y el color de fondo de clic derecho, hay un tercer color al que puede acceder manteniendo CTRL mientras dibuja. Comienza sin color, por lo que deberá mantener presionado CTRL y seleccionar un color primero. Lo elegante de esta ranura de color es que puede presionar y liberar CTRL para cambiar los colores mientras dibujan .
Puede aplicar transformaciones de imagen como Flip/Rotar, estirar/sesgar o invertir (en el menú Imagen), ya sea a toda la imagen o a una selección. Intente garabatear con la herramienta Seleccionar de forma libre y luego haciendo una imagen> invertir
Estos consejos y trucos de un tutorial para MS Paint también funcionan en JS Paint:
JS Paint se puede instalar como una aplicación web progresiva (PWA), aunque todavía no funciona fuera de línea. Busque el indicador de instalación en la barra de direcciones.
Características de PWA:
Características faltantes:
También lo he convertido en una aplicación de escritorio con electrones y forra de electrones. Puede descargarlo desde la página de lanzamientos.

Características de la aplicación de electrones:
jspaint path/to/file.png en el terminaleditor_window.on("close") llamando preventDefault y puede ser una característica, pero necesita mostrar/enfocar la ventanaClon el repositorio.
Instale Node.js Si no lo tiene, luego abra un símbolo del sistema / terminal en el directorio del proyecto.
Ejecute npm run lint para verificar los errores de ortografía, los errores de tipo, los problemas de estilo de código y otros problemas.
Ejecute npm run format para solucionar automáticamente los problemas de formato, o npx eslint --fix para solucionar todos los problemas autoexibles.
Las reglas de formato están configuradas para compatibilidad con el formateador incorporado de VS Code.
Ejecute npm test para ejecutar pruebas basadas en el navegador con Cypress. (Desafortunadamente, es lento para iniciar y ejecutar pruebas).
Ejecutar npm run accept para aceptar cualquier cambio visual. Desafortunadamente, esto vuelve a ejecutar todas las pruebas, en lugar de aceptar resultados de la prueba anterior, por lo que podría terminar con resultados diferentes que la prueba anterior. Si usa GitHub Desktop, puede ver diferencias de imágenes, en cuatro modos diferentes.
Para abrir la interfaz de usuario de Cypress, primero ejecute npm run test:start-server , luego simultáneamente npm run cy:open
Las pruebas también se ejecutan en integración continua con Travis CI.
Después de instalar dependencias con npm i , use npm run dev para iniciar un servidor de recuperación en vivo.
Asegúrese de que cualquier estilos de diseño sea en layout.css . Al actualizar layout.css , se genera una versión de derecha a la izquierda de la hoja de estilo, utilizando RTLCSS.
Debe probar el diseño RTL cambiando el idioma a árabe o hebreo. Vaya a Extras> Lenguaje> العربية o עברית .
Consulte las directivas de control sobre cómo controlar el diseño RTL.
Hay una tarea de lanzamiento de código VS para adjuntar a Chrome para la depuración. Consulte .vscode/launch.json para obtener instrucciones de uso.
npm inpm run electron:startSe incluye la DEBUG de electrones, por lo que puede usar F5 / CTRL+R para recargar y F12 / Ctrl+Shift+I para abrir los DevTools.
Puede construir para la producción con npm run electron:make
Hay una tarea de lanzamiento de código VS para depurar el proceso principal de Electron. Para el proceso de renderizador, puede usar los Devtools de Chrome incrustados.
JS Paint se puede implementar utilizando un servidor web normal.
Nada necesita ser compilado.
Opcionalmente, puede configurar un servidor Cors Anywhere, para cargar imágenes desde la web, si pega una URL en JS Paint, o usa la función #load:<URL> con imágenes que no están en el mismo dominio.
Por defecto, utilizará una instancia de Cors en cualquier lugar configurada para funcionar con jsPaint.app.
Está alojado de forma gratuita en Heroku, y puede configurar su propia instancia y configurarla para que funcione con su propio dominio.
Tendrá que encontrar y reemplazar https://jspaint-cors-proxy.herokuapp.com con su propia URL de instancia.
El soporte multijugador actualmente se basa en Firebase, que no es un software de código abierto.
Puede crear una instancia de base de datos de Firebase Real en tiempo y editar sessions.js de JS Paint.js para señalarla, reemplazando la config pasada a initializeApp con la configuración desde la consola Firebase cuando configura una aplicación web.
Pero el modo multijugador es muy malo hasta ahora. Debe reemplazarse con algo de código abierto, más seguro, más eficiente y más robusto.
Agregue esto a su HTML:
< iframe src =" https://jspaint.app " width =" 100% " height =" 100% " > </ iframe > Puede hacer que cargue una imagen de una URL agregando #load:<URL> a la URL.
< iframe src =" https://jspaint.app#load:https://jspaint.app/favicon.ico " width =" 100% " height =" 100% " > </ iframe >Si desea controlar la pintura JS, cómo guarda/carga archivos, o acceder a los lienzos directamente, hay una API inestable.
Primero debe clonar el repositorio, para que pueda apuntar un iframe a su copia local.
La copia local de JS Paint debe alojarse en el mismo servidor web que la página que contiene, o más específicamente, tiene que compartir el mismo origen.
Tener una copia local también significa que las cosas no se romperán en cualquier momento que cambie la API.
Si JS Paint está clonado en una carpeta llamada jspaint , que vive en la misma carpeta que la página en la que desea incrustarla, puede usar esto:
< iframe src =" jspaint/index.html " id =" jspaint-iframe " width =" 100% " height =" 100% " > </ iframe > Si vive en otro lugar, es posible que deba agregar ../ al comienzo del camino, para subir un nivel. Por ejemplo, src="../../apps/jspaint/index.html" . También puede usar una URL absoluta, como src="https://example.com/cool-apps/jspaint/index.html" .
Puede anular los cuadros de diálogo Guardar y abrir el archivo con la API systemHooks de JS Paint.
< 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 >Un blob representa el contenido de un archivo en la memoria.
Un mango de archivo es cualquier cosa que pueda identificar un archivo. Puedes poseer este concepto y definir cómo identificar archivos. Podría ser cualquier cosa, desde un índice en una matriz, a una ID de archivo de Dropbox, a una URL de IPFS, a una ruta de archivo. Puede ser cualquier tipo, o tal vez tenga que ser una cadena, olvido.
Una vez que tenga un concepto de mango de archivo, puede implementar recolectores de archivos utilizando los ganchos del sistema y funciona para leer y escribir archivos.
| Dominio | Ganchos utilizados |
|---|---|
| Archivo> Guardar como | systemHooks.showSaveFileDialog , luego, cuando se elige un archivo, systemHooks.writeBlobToHandle |
| Archivo> Abrir | systemHooks.showOpenFileDialog , luego, cuando se elige un archivo, systemHooks.readBlobFromHandle |
| Archivo> Guardar | systemHooks.writeBlobToHandle (o igual que el archivo> Guardar como si aún no hubiera un archivo abierto) |
| Editar> Copiar a | systemHooks.showSaveFileDialog , luego, cuando se elige un archivo, systemHooks.writeBlobToHandle |
| Editar> Pegar desde | systemHooks.showOpenFileDialog , luego, cuando se elige un archivo, systemHooks.readBlobFromHandle |
| Archivo> Establecer como Wallpaper (Azule) | systemHooks.setWallpaperTiled si se define, de lo contrario, systemHooks.setWallpaperCentered si se define, de lo contrario, lo mismo que archivo> guardar como |
| Archivo> Establecer como fondo de pantalla (centrado) | systemHooks.setWallpaperCentered si se define, de lo contrario, lo mismo que el archivo> guardar como |
| Extras> Renderizar la historia como GIF | Igual que el archivo> Guardar como |
| Colores> Guardar colores | Igual que el archivo> Guardar como |
| Colores> obtener colores | Igual que el archivo> Abrir |
Para iniciar la aplicación con un archivo cargado para editar, espere a que la aplicación se cargue, luego llame systemHooks.readBlobFromHandle con un mango de archivo y dígale a la aplicación que cargue esa mancha de archivo.
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 ) ;
} ) ;Esto es torpe, y en el futuro puede haber un parámetro de cadena de consulta para cargar un archivo inicial por su mango. (Nota para uno mismo: tendrá que esperar a que los ganchos de su sistema se registren, de alguna manera).
Ya hay un parámetro de cadena de consulta para cargarse de una URL:
< iframe src =" https://jspaint.app?load:SOME_URL_HERE " > </ iframe >Pero esto no configurará el mango del archivo para guardar.
Puede definir dos funciones para establecer el fondo de pantalla, que se utilizará por archivo> establecer como fondo de pantalla (mosaico) y archivo> set como fondo de pantalla (centrado) .
systemHooks.setWallpaperTiled = (canvas) => { ... };systemHooks.setWallpaperCentered = (canvas) => { ... }; Si define solo systemHooks.setWallpaperCentered , JS Paint intentará adivinar las dimensiones de su pantalla y manchar la imagen, aplicándola llamando a su función systemHooks.setWallpaperCentered .
Si no especifica systemHooks.setWallpaperCentered , JS Paint se debe guardar un archivo ( <original file name> wallpaper.png ) usando systemHooks.showSaveFileDialog y systemHooks.writeBlobToHandle .
Aquí hay un ejemplo completo que admite un fondo de pantalla personalizado persistente como fondo en la página que contiene:
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 ) ;
}Es un poco recursivo, lo siento; Probablemente podría hacerse más simple. Como solo usando URL de datos. (En realidad, creo que quería usar URL de blob solo para que no hague el inspector DOM con una URL súper larga. Lo cual es realmente un error de DevTools UX. ¿Tal vez hayan mejorado esto?)
Puede cargar un archivo que tenga las dimensiones deseadas. No hay una API especial para esto en este momento.
Consulte Cargar un archivo inicialmente.
Podrías cambiar el tema programáticamente:
var iframe = document . getElementById ( "jspaint-iframe" ) ;
var jspaint = iframe . contentWindow ;
jspaint . set_theme ( "modern.css" ) ;Pero esto romperá la preferencia del usuario.
El menú Extras> Temas seguirá funcionando, pero la preferencia no persistirá al recargar la página.
En el futuro puede haber un parámetro de cadena de consulta para especificar el tema predeterminado. También puede bifurcar JSPaint para cambiar el tema predeterminado.
Similar al tema, puede intentar cambiar el lenguaje programáticamente:
var iframe = document . getElementById ( "jspaint-iframe" ) ;
var jspaint = iframe . contentWindow ;
jspaint . set_language ( "ar" ) ;Pero esto en realidad le pedirá al usuario que recargue la aplicación para cambiar los idiomas.
El menú de idiomas extras> seguirá funcionando, pero el usuario se molestará en cambiar el idioma cada vez que vuelva a cargar la página.
En el futuro puede haber un parámetro de cadena de consulta para especificar el idioma predeterminado. También puede desembolsar JSPAINT para cambiar el idioma predeterminado.
No es compatible todavía. Podrías bifurcar JSPaint y agregar tus propios menús.
Con el acceso al lienzo, puede implementar una vista previa en vivo de su dibujo, por ejemplo, actualizar una textura en un motor de juego en tiempo real.
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" ) ; Se recomienda no usar esto para cargar un documento, ya que no cambiará el título del documento o restablecerá el historial de deshacer/rehacer, entre otras cosas. En su lugar, use open_from_file .
Si desea hacer botones u otra interfaz de usuario para hacer cosas al documento, debería (probablemente) hacerlo no se pueda Es muy fácil, solo envuelva su acción en una llamada a undoable .
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
} ) ; systemHooks.showSaveFileDialog({ formats, defaultFileName, defaultPath, defaultFileFormatID, getBlob, savedCallbackUnreliable, dialogTitle })Defina esta función para anular el cuadro de diálogo Guardar predeterminado. Esto se usa tanto para guardar imágenes como para archivos de paleta y animaciones.
Argumentos:
formats : una matriz de objetos que representan tipos de archivos, con las siguientes propiedades:formatID : una cadena que identifica de manera única el formato (puede ser el mismo que mimeType )mimeType (opcional): el tipo de medios designado del formato del archivo, por ejemplo "image/png" (los formatos de paleta no tienen esta propiedad)name : el nombre del formato de archivo, por ejemplo, "WebP"nameWithExtensions : el nombre del formato de archivo seguido de una lista de extensiones, por ejemplo "TIFF (*.tif;*.tiff)"extensions : una matriz de extensiones de archivo, excluyendo el punto, con la extensión preferida primero, por ejemplo, ["bmp", "dib"]defaultFileName (opcional): un nombre de archivo sugerido, por ejemplo "Untitled.png" o el nombre de un documento abierto.defaultPath (opcional): un mango de archivo para un documento que se abrió, por lo que puede guardarlo fácilmente en la misma carpeta. Nomero: esto puede no ser una ruta, depende de cómo defina los manijas de los archivos.defaultFileFormatID (opcional): el formatID de un formato de archivo para seleccionar de forma predeterminada.async function getBlob(formatID) : una función que llame para obtener un archivo en uno de los formatos compatibles. Toma un formatID y devuelve una Promise que se resuelve con un Blob que representa el contenido del archivo para guardar.function savedCallbackUnreliable({ newFileName, newFileFormatID, newFileHandle, newBlob }) (opcional): una función que llama cuando el usuario ha guardado el archivo. El newBlob debe venir de getBlob(newFileFormatID) .dialogTitle (opcional): un título para el cuadro de diálogo Guardar. Tenga en cuenta la inversión del control aquí: JS Paint llama a su systemHooks.showSaveFileDialog , y luego llame a la función getBlob de JS Paint. Una vez que getBlob se resuelve, puede llamar a la función savedCallbackUnreliable que se define por JS Paint. (Ojalá pueda aclarar esto en el futuro).
También tenga en cuenta que esta función es responsable de guardar el archivo, no solo para elegir una ubicación de guardado. Puede reutilizar su función systemHooks.writeBlobToHandle si es útil.
systemHooks.showOpenFileDialog({ formats })Defina esta función para anular el cuadro de diálogo abierto predeterminado. Esto se usa para abrir imágenes y paletas.
Argumentos:
formats : Igual que systemHooks.showSaveFileDialog Tenga en cuenta que esta función es responsable de cargar el contenido del archivo, no solo elegir un archivo. Puede reutilizar su sistema systemHooks.readBlobFromHandle si es útil.
systemHooks.writeBlobToHandle(fileHandle, blob)Defina esta función para decirle a JS Paint cómo guardar un archivo.
Argumentos:
fileHandle : un identificador de archivo, según lo definido por su sistema, que representa el archivo para escribir.blob : un Blob que representa el contenido del archivo para guardar.Devoluciones:
Promise que se resuelve con true si el archivo definitivamente se guardó con éxito, false si ocurrió un error o el usuario cancelado, o undefined si no se sabe si el archivo se guardó con éxito, como es el caso con la descarga del archivo con <a href="..." download="..."> . La promesa no debe rechazar; Los errores deben manejarse mostrando un mensaje de error y devolviendo false . systemHooks.readBlobFromHandle(fileHandle)Defina esta función para decirle a JS Paint cómo cargar un archivo.
Argumentos:
fileHandle : un identificador de archivo, según lo definido por su sistema, que representa el archivo para leer. systemHooks.setWallpaperTiled(canvas)Defina esta función para decirle a JS Paint cómo configurar el fondo de pantalla. Vea la integración del set como papel tapiz para un ejemplo.
Argumentos:
canvas : un HTMLCanvasElement con la imagen para establecerse como fondo de pantalla. systemHooks.setWallpaperCentered(canvas)Defina esta función para decirle a JS Paint cómo configurar el fondo de pantalla. Vea la integración del set como papel tapiz para un ejemplo.
Argumentos:
canvas : un HTMLCanvasElement con la imagen para establecerse como fondo de pantalla. undoable({ name, icon }, actionFunction)Use esto para que una acción no se pueda deshacer.
Esta función toma una instantánea del lienzo y algún otro estado, y luego llama a la función actionFunction . Crea una entrada en la historia para que se pueda deshacer.
Argumentos:
name : un nombre para la acción, por ejemplo "Brush" o "Rotate Image 270°"icon (opcional): una Image para mostrar en la ventana del historial. Se recomienda ser 15x11 píxeles.actionFunction : una función que no toma argumentos y modifica el lienzo. show_error_message(message, [error])Use esto para mostrar un cuadro de diálogo Mensaje de error, opcionalmente con detalles de error expandible.
Argumentos:
message : texto sin formato para mostrar en el cuadro de diálogo.error (opcional): un objeto Error para mostrar en el cuadro de diálogo, colapsado de forma predeterminada en una sección expandible de "detalles". open_from_file(blob, source_file_handle)Use esto para cargar un archivo en la aplicación.
Argumentos:
blob : un objeto Blob que representa el archivo para cargar.source_file_handle : un mango de archivo correspondiente para el archivo, según lo definido por su sistema.Perdón por la API peculiar. La API es nueva, y partes de ella no han sido diseñadas en absoluto. Esto fue solo un truco del que llegué a depender, alcanzando las partes internas de JS Paint para cargar un archivo. Decidí documentarlo como la primera versión de la API, ya que querré un ChangeLog al actualizar mi uso de todos modos.
set_theme(theme_file_name)Use esto para cambiar el aspecto de la aplicación.
Argumentos:
theme_file_name : el nombre del archivo del tema para cargar, uno de:"classic.css" : el tema de Windows98."dark.css" : el tema oscuro."modern.css" : el tema moderno."winter.css" : el tema festivo de invierno."occult.css" : un tema satánico. set_language(language_code)Puede usar esto para cambiar el idioma de la aplicación. Pero en realidad, mostrará un aviso al usuario que cambie el idioma, porque la aplicación debe volver a cargar para aplicar el cambio. Y si ese diálogo no está en el idioma correcto, bueno, probablemente se confundirán.
Argumentos:
language_code : el código de idioma a usar, por ejemplo "en" para inglés, "zh" para chino tradicional ", "zh-simplified" para chino simplificado, etc. La API cambiará mucho, pero los cambios se documentarán en ChangeLog.
No solo un historial de cambios, sino una guía de migración/actualización.
Para Noticias del Proyecto General, haga clic en Extras> Noticias del proyecto en la aplicación.
JS Paint es un software gratuito y de código abierto, con licencia bajo la licencia MIT permisiva.