Xprite ã®ããã¿
Xprite 㯠Aseprite ã®ãšãã£ã¿ãŒããã©ãŠã¶ã«æã¡èŸŒã¿ãŸãããã€ã³ã¹ããŒã«ãã¢ã«ãŠã³ãäœæãäžèŠã§ãäœåãä¿åãããµãŒããŒããããŸããããã®èšäºã§ã¯ããã©ãŠã¶ã§ .aseprite ãèªã¿æžãããæ¹æ³ãCanvas ã§ãã£ãããããã¯ã»ã«ãæãæ¹æ³ãäœåã®ä¿åå Žæããªãã©ã€ã³ã§ãšãã£ã¿ãŒãéãããã¿ããããŠããŠã¹åãã«äœããããã¹ã¯ãããã®ç»é¢ãæããã³ãã¹ããã®ç»é¢ã«ã©ãåãããŠãããããæè¡çãªåŽé¢ãã説æããŸãã
å šäœå
ãšãã£ã¿ãŒã®åŠçã¯ãã¹ãŠãã©ãŠã¶å ã§è¡ãããŸããéãåŠç㯠Web Worker ã§åããä¿åã«ã¯ãã©ãŠã¶æšæºã® IndexedDB ãš OPFS ã䜿ããŸãããããã¯ãŒã¯ã䜿ãã®ã¯ãããŒãžã®èªã¿èŸŒã¿ãå¿åã®ã¢ã¯ã»ã¹è§£æã®éä¿¡ããã£ãŒãããã¯ã®éä¿¡ã ãã§ãã
ãã©ãŠã¶ã§ .aseprite ãèªã¿æžããã
ãã¡ã€ã«åœ¢åŒ
.aseprite ã¯ãªãã«ãšã³ãã£ã¢ã³ã®ãã€ããªåœ¢åŒã§ã128 ãã€ãã®ããããŒã®åŸã«ãè€æ°ã®ãã£ã³ã¯ãããªããã¬ãŒã ãç¶ããŸããããããŒã®ããžãã¯ãã³ããŒã¯ 0xA5E0ãåãã¬ãŒã ã®ãã®ã¯ 0xF1FA ã§ãããã³ãŒããŒã¯æ¬¡ã®ãã£ã³ã¯ãæ±ããŸãã
| ãã£ã³ã¯ã®çš®é¡ | å 容 |
|---|---|
0x2004 |
ã¬ã€ã€ãŒïŒéåžžã¬ã€ã€ãŒãã°ã«ãŒããã¿ã€ã«ãããã¬ã€ã€ãŒ |
0x2005 |
ã»ã«ïŒçã®ãã¯ã»ã«ããªã³ã¯ã»ã«ãzlib å§çž®ãã¯ã»ã«ãå§çž®ã¿ã€ã«ããã |
0x2006 |
ã»ã«ã®è¿œå ããŒã¿ïŒæ£ç¢ºãªäœçœ®ãšãµã€ãºïŒ |
0x2007 |
ã«ã©ãŒãããã¡ã€ã« |
0x2008 |
å€éšãã¡ã€ã«ã®åç § |
0x2018 |
ã¿ã°ïŒã¢ãã¡ãŒã·ã§ã³ã®ç¯å²ïŒ |
0x2019 |
ãã¬ãã |
0x2020 |
ãŠãŒã¶ãŒããŒã¿ïŒããã¹ããè²ãããããã£ïŒ |
0x2022 |
ã¹ã©ã€ã¹ |
0x2023 |
ã¿ã€ã«ã»ãã |
å€ã 0x0004 ãš 0x000B ã®ãã¬ãããã£ã³ã¯ãèªã¿èŸŒã¿ãéæšå¥šã®ãã¹ã¯ïŒ0x2016ïŒãšãã¹ïŒ0x2017ïŒã®ãã£ã³ã¯ãèªèããŸãã
å ã«æ€æ»ãããããããã³ãŒã
ãã©ãŠã¶ã§éããã¡ã€ã«ã¯ã©ãããæ¥ããã®ãããããªãã®ã§ããã³ãŒã㯠2 段éã§è¡ããŸãã1 åç®ã¯ãã¡ã€ã«å šäœãèµ°æ»ãããã¹ãŠã®ãã£ã³ã¯ã®é·ãããªãã»ãããåæ°ããã¡ã€ã«å ã«åãŸã£ãŠãããã確èªããŸããå®éã®ãã³ãŒãã¯ãã®åŸã§å§ãŸããŸããå£ãããã¡ã€ã«ãäžéãè¶ ãããã¡ã€ã«ã¯ãéäžã§å€±æããã®ã§ã¯ãªãèµ°æ»ã®æ®µéã§èŠã€ãããŸããçŸåšã®äžéã¯æ¬¡ã®ãšããã§ãã
| é ç® | äžé |
|---|---|
| ãã£ã³ãã¹ã®äžèŸº | 32,768 ãã¯ã»ã« |
| 1 æã®ç»å | 6,400 äžãã¯ã»ã« |
| ãã¬ãŒã | 4,096 |
| ã¬ã€ã€ãŒ | 256 |
Worker ã§ãã³ãŒã
æ°åãã¬ãŒã ãå±éããã«ã¯æéãããããã¡ã€ã³ã¹ã¬ããã§è¡ããšç»é¢ãåºãŸã£ãŠããŸããŸãããã¡ã€ã«ãéããšå°çšã®ãã³ãŒãçš Worker ã«æž¡ãããã³ãŒããããã¯ã»ã«ãããã¡ãŒã¯ Transferable ãªããžã§ã¯ããšããŠã³ããŒããã«ã¡ã€ã³ã¹ã¬ãããžæ»ããŸãããã©ãŠã¶ã Worker ã«å¯Ÿå¿ããŠããªãå Žåã Worker ã倱æããå Žåã¯ãã¡ã€ã³ã¹ã¬ããã§ã®ãã³ãŒãã«ãã©ãŒã«ããã¯ããŸãã
ãã¯ã»ã«ããŒã¿ã¯ zlib ã§å§çž®ãããŠããŸãããã©ãŠã¶æšæºã® DecompressionStream("deflate") ãåªå
ããå±éç匟ãé²ãããåºåããã£ã³ã¯ããããŒã§å®£èšããããµã€ãºãŸã§ã«å¶éããŸãã察å¿ããŠããªãå Žå㯠fflate ã䜿ããŸããããäžæ¹ã®å±éçµè·¯ã§ã¯ã宣èšããããµã€ãºã¡ããã©ã®åºåãããã¡ãŒã確ä¿ããAdler-32 ãã§ãã¯ãµã ãæ€èšŒããŸãã
å¿ èŠãªãã¯ã»ã«ã ãå±éãã
ãã¡ã€ã«ãéãããšããRGB ã®ã»ã«ã¯æ€èšŒãããŸããããã¹ãŠãå±éãããããã§ã¯ãããŸãããå ã®å§çž®ãã€ãã¯ã¡ã¢ãªã«æ®ããåãã¬ãŒã ã¯å¿ èŠã«ãªã£ããšãã«å±éããŸãã倧ããªãããžã§ã¯ãã§ããäžåºŠã«ãã¹ãŠãã¡ã¢ãªã«å±éããå¿ èŠã¯ãããŸããã
倿ŽããŠããªãéšåã¯ãã®ãŸãŸæžãæ»ã
.aseprite ã«ä¿åãããšãããšã³ã³ãŒããŒã¯æãå ããŠããªãå
容ããã®ãŸãŸæ®ããŸãã
- 倿ŽããŠããªãã»ã«ã¯ãéãããšãããä¿æããŠããå§çž®ãã€ãããåå§çž®ããã«æžãæ»ããŸãã
- æªç¥ã®ãã£ã³ã¯ã¯ãã®ãŸãŸæžãæ»ãã®ã§ãæ°ããããŒãžã§ã³ã® Aseprite ã§äœã£ããã¡ã€ã«ã Xprite ã§ä¿åããŠãããŒã¿ã¯å€±ãããŸããã
- åå§çž®ããã»ã«ã¯ãå§çž®çãçããŒã¿ããå°ããå Žåã«ã ãå§çž®çã䜿ããŸãã
- å§çž®ã«ã¯ãã©ãŠã¶æšæºã®
CompressionStreamã䜿ããŸãã察å¿ããŠããªãå Žåã¯éå§çž®ã§ä¿åãããŸãããµã€ãºã¯å€§ãããªããŸãããAseprite ã§éããŸãã
Canvas 2D ã ãã§ãã£ã³ãã¹ãæç»ãã
Xprite 㯠WebGL ã䜿ããŸããããããçµµã®ãã£ã³ãã¹ã¯ãããŠãå°ãããé£ããã®ã¯ãã¹ãŠã®ãã¯ã»ã«ããã£ããä¿ã€ããšã§ããã©ã®ãºãŒã åçã§ããã©ã®ç»é¢å¯åºŠã§ãããã¯ã»ã«ã¯ãã©ãŠã¶ããŒããããã®ã§ã¯ãªããçžã®ã¯ã£ããããæ£æ¹åœ¢ãšããŠè¡šç€ºãããªããã°ãªããŸããã
ã¬ã€ã€ãŒããç»é¢ãŸã§
æç»äžããšãã£ã¿ãŒã¯åã¹ãããŒã¯ã§å€ãã£ãç©åœ¢ãèšé²ããæç»åŠçã§ã¯æ¯åç»åå šäœãéãçŽãã®ã§ã¯ãªãããã®ç¯å²ã ããç»åãã£ã³ãã¹ã«æžã蟌ã¿ãŸããã§ãããã£ããã¥ãŒïŒãã¯ã»ã«ãåžæŸæš¡æ§ãã°ãªããïŒã¯ããŒã¹ãã£ã³ãã¹ã«ãã£ãã·ã¥ããŸãããã£ãã·ã¥ããŒã«ã¯ãã¯ã»ã«ã®ããŒãžã§ã³ããã¥ãŒã®äœçœ®ã衚瀺èšå®ãªã©ãå«ãŸããŸããã«ãŒãœã«ãåãããŠãããŒã¯å€ãããªãã®ã§ãããŒã¹ãã£ã³ãã¹ãåå©çšãããã©ã·ã«ãŒãœã«ã®ãã¬ãã¥ãŒã ããæãçŽããŸãã
æŽæ°åãšå°æ°å
æåŸã®æ®µéã§ãã¥ãŒãç»é¢ã«æç»ããŸãããã¥ãŒãç»é¢ã«ã¡ããã©æŽæ°åã§å¯Ÿå¿ããå Žåã¯ãç»åã®ã¹ã ãŒãžã³ã°ããªãã«ããŠãã©ãŠã¶ã® drawImage ã«ä»»ããŸãã
if (Number.isInteger(scaleX) && Number.isInteger(scaleY) /* and no offset */) {
presentation.imageSmoothingEnabled = false;
presentation.drawImage(sourceCanvas, 0, 0, sourceWidth, sourceHeight,
0, 0, canvas.width, canvas.height);
return;
}
presentation.putImageData(renderer.render(context.getImageData(...)), 0, 0);
ç»é¢å¯åºŠ 1.5 ããã©ãŠã¶ã®ãºãŒã 110% ã®ãããªå°æ°åã§ã¯ããã©ãŠã¶ããšã« drawImage ã®ãµã³ããªã³ã°ãç°ãªããŸãããã¯ã»ã«ã®åã®å¹
ãäžæãã«ãªã£ãããç»åå
šäœãåãã¯ã»ã«ããããããŸãããã®å Žåã¯ãã¢ã¬ã¹ããã€ããŒã®ãµã³ããªã³ã°ãèªåã§è¡ããŸããæç»å
ã®ãµã€ãºã«å¯ŸããŠãååã»åè¡ãã©ã®å
ãã¯ã»ã«ã«å¯Ÿå¿ããããäºåã«èšç®ãã2 ã€ã® Int32Array ã«ãã¯ã¢ããããŒãã«ã«ä¿åããŸãããµã³ããªã³ã°ã§ã¯åãã¯ã»ã«ã 1 ã€ã® Uint32 ãšããŠã³ããŒããåãè¡ãç¶ãéšå㯠copyWithin ã§ãŸãšããŠã³ããŒããŸãã
ã€ã³ã¿ãŒãã§ãŒã¹ãåãèãæ¹ã§ããã¹ãŠã®ã³ã³ãããŒã«ãè«çãã¯ã»ã«ããã 2 ãµã³ãã«ã§æç»ããŸãããã©ãŠã¶ã®ãŠã£ã³ããŠãµã€ãºãå€ããŠãå€ããã®ã¯ã¯ãŒã¯ã¹ããŒã¹ã®å€§ããã ãã§ããã¿ã³ãã¡ãã¥ãŒã®å€§ããã¯å€ãããŸããã
ç»åã®èªã¿èŸŒã¿ãšãšã¯ã¹ããŒã
PNGãJPEGãWebP ãªã©ã®ç»åã®ãšã³ã³ãŒããšãã³ãŒãã¯ãã©ãŠã¶ãè¡ããŸãã
- ãã³ãŒãã¯
createImageBitmapãåªå ãã<img>èŠçŽ ããã©ãŒã«ããã¯ã«äœ¿ããŸãã - ãšã³ã³ãŒãã¯
OffscreenCanvas.convertToBlobãåªå ãã<canvas>ã®toBlobããã©ãŒã«ããã¯ã«äœ¿ããŸãã - ãã©ãŠã¶ã圢åŒã«å¯Ÿå¿ããŠããªããšãã
toBlobã¯ãšã©ãŒãåºããã«é»ã£ãŠ PNG ãè¿ããŸãããã®ããããšã³ã³ãŒãåŸã«çµæã®å®éã®çš®é¡ã確èªãããšã¯ã¹ããŒãã®åã« 1Ã1 ã®ãã¹ãç»åããšã³ã³ãŒãããŠããã©ãŠã¶ãã©ã®åœ¢åŒããšã¯ã¹ããŒãã§ãããã調ã¹ãŸãã
äœåã®ä¿åå Žæ
ãããžã§ã¯ãã®ä¿åå 㯠2 ã€ãããååãä»ããŠä¿å... ã® ä¿åå ã§éžã³ãŸãã

| ä¿åå | 䜿ããã©ãŠã¶ã®æ©èœ | 䜿ããªãå Žå |
|---|---|---|
| ãã¡ã€ã«ãããŒãžã£ãŒ | File System Access API | 代ããã«ãã¡ã€ã«ãããŠã³ããŒã |
| ãã©ãŠã¶ | IndexedDB + OPFS | ãããžã§ã¯ãã®ããŒã¿ã代ããã« IndexedDB ã«ä¿å |
ãã©ãŠã¶å ã®ãããžã§ã¯ãã¯ãã®ç«¯æ«ã®ãã®ãã©ãŠã¶ã«ã ãååšããåæãããŸããããµã€ãã®ããŒã¿ãæ¶å»ãããšåé€ãããŸãããŠãŒã¶ãŒã¬ã€ããã芧ãã ããã
ãã¡ã€ã«ãããŒãžã£ãŒïŒå ã®ãã¡ã€ã«ã«çŽæ¥æžãæ»ã
File System Access API ã«å¯Ÿå¿ãããã©ãŠã¶ïŒãã¹ã¯ãããçã® ChromeãEdge ãªã©ïŒã§ã¯ãéã ãš ä¿å ã§ã·ã¹ãã ã®ãã¡ã€ã«ãã€ã¢ãã°ã衚瀺ãããŸããåŸãããã®ã¯ãã¡ã€ã«ã®ã³ããŒã§ã¯ãªãããã¡ã€ã«ãã³ãã«ã§ãã
- ãã¡ã€ã«ãã³ãã«ã¯ IndexedDB ã«ä¿åãããã®ã§ã次㮠ä¿å ã§ã¯ä¿åå ãå°ããã«åããã¡ã€ã«ã«æžãæ»ããŸãã
- æžã蟌ãåã«èªã¿æžãã®æš©éãæ±ãã
createWritable()ã§æžã蟌ã¿ãŸãã - ãã©ãŠã¶ã¯ãã¡ã€ã«ãã€ã¢ãã°ããŠãŒã¶ãŒã®ã¯ãªãã¯ããçŽæ¥éãããšãæ±ããã®ã§ãã¯ãªãã¯çŽåŸã«ä»ã®éåæåŠçãæãŸã
showSaveFilePicker()ãåŒã³åºããŸãã - ããŒãžãä»ã®ãµã€ãã® iframeïŒã²ãŒã ããŒã¿ã«ãªã©ïŒã«åã蟌ãŸããŠããå Žåããã©ãŠã¶ã¯ãã¡ã€ã«ãã€ã¢ãã°ãèš±å¯ããŸããããã®å Žå Xprite ã¯ãé察å¿ã®ãã©ãŠã¶ãšåãããã«ãã¡ã€ã«ãããŠã³ããŒãããŸãã
ãã©ãŠã¶ïŒIndexedDB ã®ã«ã¿ãã°ãš OPFS ã®ããŒã¿
ãã©ãŠã¶ã«ä¿åãããããžã§ã¯ãã®ã«ã¿ãã°ïŒååããµã€ãºãæŽæ°æ¥æãçŸåšã®ããŒãžã§ã³ïŒã¯åžžã« IndexedDB ã«ãããŸãããããžã§ã¯ãã®ããŒã¿ã¯ãã§ããéã OPFSïŒãªãªãžã³ãã©ã€ããŒããã¡ã€ã«ã·ã¹ãã ããã©ãŠã¶ãåãµã€ãã«äžããéå
¬éã®ãã£ã¹ã¯é åïŒã«ä¿åããŸããOPFS ã䜿ãã®ã¯ããã©ãŠã¶ã Workerãnavigator.storage.getDirectory()ãWeb Locksãæžã蟌ã¿å¯èœãªãã¡ã€ã«ãã³ãã«ã«å¯Ÿå¿ããŠããå Žåã ãã§ããä¿åæ¹åŒã¯ãããžã§ã¯ãã®äœææã«æ±ºãŸãããã®åŸã¯å€ãããªãã®ã§ããã©ãŠã¶ã®å¯Ÿå¿ç¶æ³ãå€ãã£ãŠãå€ããããžã§ã¯ããæ¶ããããšã¯ãããŸããã
OPFS ã®èªã¿æžãã¯å°çšã® Worker ã§è¡ããåæã¢ã¯ã»ã¹ãã³ãã«ïŒcreateSyncAccessHandleïŒã§æžã蟌ã¿ãåãè©°ãããã©ãã·ã¥ãè¡ããŸããä¿åã®ãã³ã«æ¬¡ã®æé ããã©ããŸãã
ããŒã¿ã®ç Žæãé²ãããã®ã«ãŒã«ãããã€ããããŸãã
- æžã蟌ãã ããŒã¿ã¯è¿œèšã®ã¿ã§ããåããŒã¯äžåºŠããæžã蟌ãããéäžã§å€±æãããã¡ã€ã«ã¯åé€ãããŸãã
- çŸåšã®ããŒãžã§ã³ãåãæ¿ããã®ã¯æåŸã®ã«ã¿ãã°ã®ãã©ã³ã¶ã¯ã·ã§ã³ã ãã§ããããä»ã®ã¿ããå ã«çŸåšã®ããŒãžã§ã³ãå€ããŠããªãå Žåã«éããŸãïŒã³ã³ãã¢ã»ã¢ã³ãã»ã¹ã¯ããïŒã
- Xprite ãè€æ°ã®ã¿ãã§éãããŠãããšãã¯ãWeb Locks ã§æžã蟌ã¿ãæä»å¶åŸ¡ããŸãã
.asepriteã®ãã£ã³ã¯å¢çã§åå²ããã®ã§ã倿ŽããŠããªããã¬ãŒã ãã¬ã€ã€ãŒã¯åãã»ã°ã¡ã³ãã«æ®ããŸãã1 ãã¬ãŒã ãç·šéããŠããå€ãã£ãã»ã°ã¡ã³ãã ããæžã蟌ãŸããŸãã
èªå埩å
èªå埩å ã¯ãã©ãŠã¶ãžã®ä¿åãšåãä¿åçµè·¯ã䜿ããŸããç·šéäžãXprite ã¯åæèšå®ã§ 2 åããšã«åŸ©å ããŒã¿ãä¿åãã7 æ¥éä¿æããŸããééãšæ¥æ°ã¯ ç·šé â ç°å¢èšå® â ãã¡ã€ã« ã§å€æŽã§ããŸãããã©ãŠã¶ãçªç¶éããå Žåã¯ãããŒã ã§ ãã¡ã€ã«ã埩å ... ãéžã¶ãšäœæ¥ãåãæ»ããŸãã
å ±æãªã³ã¯ïŒã¹ãã©ã€ã㯠# ã®åŸãã«ãã
ãã¡ã€ã« â å
±æ... ã¯äœãã¢ããããŒãããŸãããã¹ãã©ã€ãã¯å§çž®ãããŠããªã³ã¯ã® #share= 以éã®éšåïŒURL ãã©ã°ã¡ã³ãïŒã«æžã蟌ãŸããŸãããã©ãŠã¶ã¯ # 以éããµãŒããŒã«éããªãã®ã§ãå
±æã§ãµãŒããŒã«è§Šããããšã¯ãããŸããã

- ãŸãšããåŠçãå§çž®ããã³ãŒãã¯ãã¹ãŠ Worker ã§è¡ããŸããZstd 㯠WebAssembly ãšããŠåãããŸãã¬ãã« 19 ã§å§çž®ãã1 MiB æªæºã®çµæã¯ããã«é«ãã¬ãã«ã§å§çž®ãçŽããŸããWebAssembly ã®èªã¿èŸŒã¿ã«å€±æããå Žå㯠DEFLATE ã ãã䜿ãããªã³ã¯ã¯åé¡ãªãéããŸãã
- QR ã³ãŒãã®è±æ°åã¢ãŒã㯠1 æåããã 5.5 ããããã䜿ããããã€ãã¢ãŒãããã³ã³ãã¯ããªã®ã§ãQR ã³ãŒãã«ã¯ãã®ã¢ãŒãã®æåã ãã§ã§ãã Base43 ãšã³ã³ãŒãã䜿ããŸãã
- ãªã³ã¯ãéããšããšãã£ã¿ãŒã¯
#share=以éã®ããŒã¿ãèªã¿åããããã«history.replaceStateã§ã¢ãã¬ã¹ããŒããåãé€ããŠãããWorker ã«æž¡ããŠãã³ãŒãããŸãã - 1,800 æåãè¶ ãããªã³ã¯ã«ã¯ããã£ããã¢ããªã«ãã£ãŠã¯éäžã§åããããšããããšããèŠåã衚瀺ãããŸãã8,192 æåãè¶ ãããªã³ã¯ã¯äœæãããŸããã
ãªã³ã¯ã«ã¯ç·šéå¯èœãªãããžã§ã¯ãããŸãããšå«ãŸããŸãããªã³ã¯å šäœãæã€äººã¯èª°ã§ãéããŠãæå¹æéã¯ãªããåãæ¶ãããšãã§ããŸããããªã³ã¯ã QR ã³ãŒãããã£ããã¢ããªã§éããšããã®ã¢ããªã«ãäœåã®ããŒã¿ãæž¡ããŸãã
ãªãã©ã€ã³å©çšïŒäžåºŠã« 1 ã€ã®å®å šãªããŒãžã§ã³
Xprite ããã¹ã¯ããããããŒã ç»é¢ã«è¿œå ãããšãService Worker ããšãã£ã¿ãŒããã£ãã·ã¥ãããããã¯ãŒã¯ããªããŠãéããããã«ãªããŸãïŒãã£ãã·ã¥ã«ã¯ãå ã«äžåºŠãªã³ã©ã€ã³ã§ãšãã£ã¿ãŒãéãå¿ èŠããããŸããæé ã¯ãŠãŒã¶ãŒã¬ã€ããã芧ãã ããïŒããã£ãã·ã¥ã®æ¹éã¯ãããŒãžã§ã³ã®äžè²«æ§ãä¿ã€ããšã軞ã«ããŠããŸãã
- ãã«ãããšã«ããã®ããŒãžã§ã³ã®ãªãœãŒã¹ãããã§ã¹ããçæãããã¹ãŠã®ãã¡ã€ã«ã« SRI ããã·ã¥ãä»ããŸããã€ã³ã¹ããŒã«æã«
cache.addAllã§ãããã§ã¹ãå šäœãäžåºŠã«ãã£ãã·ã¥ããŸãã1 ã€ã§ãããŠã³ããŒãã«å€±æãããããã·ã¥ãäžèŽããªãã£ãããããšããã®ããŒãžã§ã³ã¯æå¹ã«ãªããªãã®ã§ãæ°æ§ã®ãã¡ã€ã«ãæ··ããããšã¯ãããŸããã - ãã¹ãŠãã£ãã·ã¥ãçµãããšãæºåå®äºãã®ããŒã«ãŒãæžã蟌ã¿ããªãã©ã€ã³èµ·åã§ã¯ãã®ããŒã«ãŒãããããŒãžã§ã³ã ãã䜿ããŸãã
- æ°ããããŒãžã§ã³ã¯ã€ã³ã¹ããŒã«ããããšããã«åãæ¿ãããŸããããã§ã«éããŠããããŒãžã¯å€ãã³ãŒãã§åãç¶ããŸããããã·ã¥ä»ãã®ãã¡ã€ã«åãæã€å€ãã¢ã»ããã¯æ®ããŠããã®ã§ããããã®ããŒãžãèªã¿èŸŒããŸãã
- ãã£ãã·ã¥ããã®ã¯ãã«ãææç©ã ãã§ããã¢ã¯ã»ã¹è§£æããã£ãŒãããã¯ã®éä¿¡å ããµã€ãã®ããŒãžã¯ãã£ãã·ã¥ãéããŸããã
- å€ãããŒãžã§ã³ã®ãã£ãã·ã¥ã¯ããã¹ãŠã®ãšãã£ã¿ãŒãŠã£ã³ããŠãéããåŸã§ã ãåé€ããŸãã
察å¿ããŠãããã©ãŠã¶ã§ã¯æ°žç¶ã¹ãã¬ãŒãžïŒnavigator.storage.persist()ïŒãèŠæ±ãã容éãè¶³ããªããªã£ããšãã«ãã©ãŠã¶ãäœåãæ¶å»ããå¯èœæ§ãäžããŠããŸãã
ã¿ããã¹ã¯ãªãŒã³ãšãã³
ããŠã¹ã®ãã€ã³ã¿ãŒã¯ 1 ã€ã§ãããã¿ããã¹ã¯ãªãŒã³ã«ã¯ãã³ãšè€æ°ã®æãåæã«è§ŠããããšããããŸããå ¥åã¬ã€ã€ãŒã¯æ¬¡ã®ã«ãŒã«ã§åŠçããŸãã
| ç¶æ³ | åäœ |
|---|---|
| ãã³ãšæãåæã«è§Šãã | ãã³ãåªå ãããæã®æäœãäžæãã |
| ãã³ãæ€åºããåŸ | æã®ã²ãã®èª€ã¿ãããé²ããããåæèšå®ã§ã¯ 1 æ¬æã§ãã£ã³ãã¹ãã¹ã¯ããŒã« |
| 2 æ¬ç®ã®æãè§Šãã | çŸåšã®ã¹ãããŒã¯ãåãæ¶ãã2 æ¬æã®ãžã§ã¹ãã£ãŒãéå§ |
| 2 æ¬æã§ãã³ã | ãã£ã³ãã¹ããºãŒã |
| 2 æ¬æã»3 æ¬æã§ã¿ãã | å ã«æ»ãã»ããçŽã |
| æãè§ŠããåŸ | ãŸãã¿ããããã©ãã°ããå€å®ããŠããç·šéãå§ãã |
ãã©ãã°ã®ãããå€ããã€ã³ã¿ãŒã®çš®é¡ã§å€ãããŸããæã¯ 8 CSS ãã¯ã»ã«ãè¶ ããŠåããªããšãã©ãã°ãšã¿ãªãããŸããããããŠã¹ããã³ã¯ 1 ãã¯ã»ã«ã§ååã§ãã
ãã现ããã¹ãããŒã¯
ãã©ãŠã¶ã¯åŠçãæžããããã1 ãã¬ãŒã å
ã®è€æ°ã® pointermove ã€ãã³ãã 1 ã€ã«ãŸãšããŸãããã³ã§æããšãã¯ãgetCoalescedEvents() ãããŸãšãããããµã³ãã«ããã¹ãŠåãåºããããããã®çå§ã®å€ã䜿ããŸãããã©ãŠã¶ã¯äºæž¬ãµã³ãã«ãæäŸããŸãããXprite ã¯äœ¿ããŸãããäºæž¬ããç¹ã¯å®éã®ã¹ãããŒã¯ãšäžèŽããªãããšããããæäœå±¥æŽã«å
¥ã£ãŠã¯ãªããªãããã§ãã
/** Real samples only: predicted input must never reach document history. */
const coalesced = event.getCoalescedEvents?.() ?? [];
const actual = coalesced.filter(
(point) => point.pointerId === event.pointerId && point.pointerType === "pen",
);
iPad ã® Apple Pencil
iPad ã® Safari ã§ã¯ãApple Pencil ã§è§Šãããšåæèšå®ã§ããã¹ãéžæãã¹ã¯ãªãã«ãªã©ã®ã·ã¹ãã ã®åäœãèµ·ããŸããReact ã®ã¿ãããªã¹ããŒã¯ããã·ãã§æ¢å®ã®åäœãæ¢ããããªãããããã£ã³ãã¹ãšãã©ãã°å¯èœãªã³ã³ãããŒã«ã«éããã·ãã®ãã€ãã£ã touchstart ãªã¹ããŒãçŽæ¥ç»é²ããtouchType ã stylus ã®ãšãã ã preventDefault() ãåŒã³åºããŸããããã¹ãæ¬ãªã©ã®ç·šéå¯èœãªé åã«ã¯åœ±é¿ããªãã®ã§ãããã§ã¯ã¹ã¯ãªãã«ã§æžã蟌ããŸãã
ã¬ã€ã¢ãŠãïŒãã¹ã¯ãããã®ãŠã£ã³ããŠãã瞊åãã®ã¹ãããŸã§
Xprite ã®ã€ã³ã¿ãŒãã§ãŒã¹ã¯ Aseprite 1.3 ãåçŸããŠããŸãããã€ã¢ãã°ã®ãµã€ãºãã³ã³ãããŒã«ã®äœçœ®ã¯ Aseprite 1.3.18 ãèšæž¬ãããã®ã§ããã¹ãã§äžèŽãä¿ã£ãŠããŸããããŒãã®ç»å㯠Aseprite ã®ãããçµµã¹ã¿ã€ã«ã«å£ããäžåœèªã»æ¥æ¬èªã»éåœèªã®ã€ã³ã¿ãŒãã§ãŒã¹ã«ã¯ Fusion Pixel ãã©ã³ãã䜿ã£ãŠããŸãã
ã¯ã€ããªç»é¢ã§ã¯ãäžã«ã¡ãã¥ãŒããŒãå·Šã«ãã¬ãããå³ã«ããŒã«ãäžã«ã¿ã€ã ã©ã€ã³ãšãããããªãã¿ã®ãã¹ã¯ãããã¬ã€ã¢ãŠãã«ãªããŸãã

ãã®ã¬ã€ã¢ãŠãã¯çžŠåãã®ã¹ããã«ã¯åãŸããŸãããã¯ãŒã¯ã¹ããŒã¹ã®ã¬ã€ã¢ãŠã ã èªåïŒåæèšå®ïŒã®ãšãã¯ã䜿ããé åã«åãããŠã¬ã€ã¢ãŠããéžã³ãŸããã¯ã€ãã¬ã€ã¢ãŠã ã ã³ã³ãã¯ãã¬ã€ã¢ãŠã ã«åºå®ããããšãã§ããŸãããŠãŒã¶ãŒã¬ã€ããã芧ãã ãããã«ãŒã«ã¯æ¬¡ã®ãšããã§ãã
| åºæº | æ¡ä»¶ | çµæ |
|---|---|---|
| 䜿ããé åã®çžŠæšªæ¯ | 1.2 ä»¥äž | ã¯ã€ãã¬ã€ã¢ãŠãïŒããã«ãåšå²ã«é 眮 |
| 䜿ããé åã®çžŠæšªæ¯ | 1.2 æªæº | ã³ã³ãã¯ãã¬ã€ã¢ãŠãïŒããŒã«ãäžã«äžåã«äžŠã¹ããã¬ãããšã¿ã€ã ã©ã€ã³ã¯ãã£ã³ãã¹ã®äžã®ã¿ãã« |
| 䜿ããé åã®å¹ | 768 CSS ãã¯ã»ã«æªæº | ã€ã³ã¿ãŒãã§ãŒã¹ãã³ã³ãã¯ããªå¯åºŠã«åãæ¿ã |
| ã¿ãããã€ã³ããŸãã¯ãã€ã³ã¿ãŒã®ç²ŸåºŠ | ã¿ãããã€ã³ããããããŸã㯠(pointer: coarse) |
ã¿ããæäœã¢ãŒã |
ã³ã³ãã¯ãã¬ã€ã¢ãŠãã§ã¯ãã¡ãã¥ãŒããŒã¯å·Šäžã® â° ãã¿ã³ã«ãŸãšããããã€ã³ã¿ãŒãã§ãŒã¹ã¯ããããè§äžžãªã©ã®ã»ãŒããšãªã¢ãé¿ããŠé 眮ãããŸãã

ã¬ã€ã¢ãŠããšæäœã¢ãŒãã¯å¥ã ã«æ±ºãŸããŸããæšªåãã® iPad ã¯ã¯ã€ãã¬ã€ã¢ãŠããšã¿ããæäœãåæã«äœ¿ããŸãããã¹ã¯ãããã®ãã©ãŠã¶ã®ãŠã£ã³ããŠãçãããšã³ã³ãã¯ãã¬ã€ã¢ãŠãã«åãæ¿ãããŸãããããŠã¹æäœã®ãŸãŸã§ãã
Xprite ãéä¿¡ããããŒã¿
ç·šéãä¿åãå ±æã§ã¯ãããã¯ãŒã¯ã䜿ããŸãããéä¿¡ãããããŒã¿ã¯ 2 çš®é¡ã ãã§ãã
| ããŒã¿ | éä¿¡ããããšã | å«ãŸãããã® | å«ãŸããªããã® |
|---|---|---|---|
| å©çšç¶æ³ã®è§£æ | å ¬åŒã®ãŠã§ãçã䜿ã£ããšã | ããŒãžã®èšªåãæ©èœã®å©çšããšã©ãŒã®çš®é¡ããã©ãŠã¶ã®æ©èœãããããã®äœçœ® | äœåã®ãã¯ã»ã«ãããã¥ã¡ã³ãåãããŒã«ã«ã®ãã¡ã€ã«ãã¹ |
| ãã£ãŒããã㯠| äžå ·åã»ãèŠæ ãéä¿¡ãããšã | ãã£ãŒãããã¯ã®çš®é¡ãã¡ãã»ãŒãžãä»»æã®ã¡ãŒã«ã¢ãã¬ã¹ãçŸåšã®èšªåã®è©³çް | â |
å©çšç¶æ³ã®è§£æã¯ PostHog CloudïŒç±³åœïŒã«éãããŸãã
- 蚪åè
ID ã¯ãã©ãŠã¶ã®
localStorageã«ä¿åãããŸãã - å ã® IP ã¢ãã¬ã¹ã¯ãããããã®äœçœ®ãä»ããåŸã«ç Žæ£ãããŸãã
- ã»ãã·ã§ã³é²ç»ãšã¯ãªãã¯ã®èªåååŸã¯ã©ã¡ãããªãã§ãã
- ãã©ãŠã¶ã§ãã©ããã³ã°æåŠïŒDo Not TrackïŒããªã³ã«ã㊠Xprite ãéãçŽããšããã以éã¯å©çšããŒã¿ãéä¿¡ãããŸããã
詳ããã¯ãã©ã€ãã·ãŒã«ã€ããŠãã芧ãã ããã
ãªãŒãã³ãœãŒã¹
ããã§èª¬æãããã¹ãŠã®ãœãŒã¹ã³ãŒã㯠GitHub ã§å ¬éããŠããŸãããšãã£ã¿ãŒã®ã³ãŒã㯠GPL-2.0-only ã©ã€ã»ã³ã¹ã§ãã