mirror of
https://github.com/exogen/t2-model-skinner.git
synced 2026-01-19 19:24:44 +00:00
bump fabric
This commit is contained in:
parent
9e127b683c
commit
c1cc0c73a1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
docs/_next/static/chunks/6cb39dc61a422734.js
Normal file
1
docs/_next/static/chunks/6cb39dc61a422734.js
Normal file
File diff suppressed because one or more lines are too long
1
docs/_next/static/chunks/d63fc3798baf75bd.js
Normal file
1
docs/_next/static/chunks/d63fc3798baf75bd.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -11,7 +11,7 @@ f:"$Sreact.suspense"
|
||||||
11:I[68027,[],"default"]
|
11:I[68027,[],"default"]
|
||||||
:HL["/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","style"]
|
:HL["/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","style"]
|
||||||
:HL["/t2-model-skinner/_next/static/chunks/be25e0c53b3e76c3.css","style"]
|
:HL["/t2-model-skinner/_next/static/chunks/be25e0c53b3e76c3.css","style"]
|
||||||
0:{"P":null,"b":"VY3oqBwyqvlStXl38ih2v","p":"/t2-model-skinner","c":["","gallery",""],"i":false,"f":[[["",{"children":["gallery",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}],{"children":["gallery",["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L4",null,{"Component":"$5","searchParams":{},"params":{},"promises":["$@6","$@7"]}],[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/be25e0c53b3e76c3.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-model-skinner/_next/static/chunks/6d7b92f74fb4b5af.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-model-skinner/_next/static/chunks/3710394f99078da4.js","async":true,"nonce":"$undefined"}]],["$","$L8",null,{"children":["$L9",["$","$La",null,{"promise":"$@b"}]]}]]}],{},null,false]},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Lc",null,{"children":"$Ld"}],null],["$","$Le",null,{"children":["$","div",null,{"hidden":true,"children":["$","$f",null,{"fallback":null,"children":"$L10"}]}]}]]}],false]],"m":"$undefined","G":["$11",[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"s":false,"S":true}
|
0:{"P":null,"b":"-yFPMzbzcZfNmotCttmg4","p":"/t2-model-skinner","c":["","gallery",""],"i":false,"f":[[["",{"children":["gallery",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}],{"children":["gallery",["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L4",null,{"Component":"$5","searchParams":{},"params":{},"promises":["$@6","$@7"]}],[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/be25e0c53b3e76c3.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-model-skinner/_next/static/chunks/6d7b92f74fb4b5af.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-model-skinner/_next/static/chunks/3710394f99078da4.js","async":true,"nonce":"$undefined"}]],["$","$L8",null,{"children":["$L9",["$","$La",null,{"promise":"$@b"}]]}]]}],{},null,false]},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Lc",null,{"children":"$Ld"}],null],["$","$Le",null,{"children":["$","div",null,{"hidden":true,"children":["$","$f",null,{"fallback":null,"children":"$L10"}]}]}]]}],false]],"m":"$undefined","G":["$11",[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"s":false,"S":true}
|
||||||
6:{}
|
6:{}
|
||||||
7:"$0:f:0:1:2:children:2:children:1:props:children:0:props:params"
|
7:"$0:f:0:1:2:children:2:children:1:props:children:0:props:params"
|
||||||
d:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
d:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -2,7 +2,7 @@
|
||||||
2:I[39756,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"]
|
2:I[39756,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"]
|
||||||
3:I[37457,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"]
|
3:I[37457,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"default"]
|
||||||
4:I[47257,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ClientPageRoot"]
|
4:I[47257,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ClientPageRoot"]
|
||||||
5:I[52683,["/t2-model-skinner/_next/static/chunks/00e36f5c4a673582.js","/t2-model-skinner/_next/static/chunks/d9e502f7607fcfba.js","/t2-model-skinner/_next/static/chunks/ada16a90703ade36.js","/t2-model-skinner/_next/static/chunks/e4e6678c9c61c198.js","/t2-model-skinner/_next/static/chunks/a55df98dcb3b60ad.js"],"default"]
|
5:I[52683,["/t2-model-skinner/_next/static/chunks/00e36f5c4a673582.js","/t2-model-skinner/_next/static/chunks/d63fc3798baf75bd.js","/t2-model-skinner/_next/static/chunks/a55df98dcb3b60ad.js","/t2-model-skinner/_next/static/chunks/6cb39dc61a422734.js","/t2-model-skinner/_next/static/chunks/ada16a90703ade36.js"],"default"]
|
||||||
8:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"OutletBoundary"]
|
8:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"OutletBoundary"]
|
||||||
a:I[11533,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"AsyncMetadataOutlet"]
|
a:I[11533,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"AsyncMetadataOutlet"]
|
||||||
c:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ViewportBoundary"]
|
c:I[97367,["/t2-model-skinner/_next/static/chunks/ff1a16fafef87110.js","/t2-model-skinner/_next/static/chunks/7dd66bdf8a7e5707.js"],"ViewportBoundary"]
|
||||||
|
|
@ -11,7 +11,7 @@ f:"$Sreact.suspense"
|
||||||
11:I[68027,[],"default"]
|
11:I[68027,[],"default"]
|
||||||
:HL["/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","style"]
|
:HL["/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","style"]
|
||||||
:HL["/t2-model-skinner/_next/static/chunks/df18f9fdc6a3cb7c.css","style"]
|
:HL["/t2-model-skinner/_next/static/chunks/df18f9fdc6a3cb7c.css","style"]
|
||||||
0:{"P":null,"b":"VY3oqBwyqvlStXl38ih2v","p":"/t2-model-skinner","c":["",""],"i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L4",null,{"Component":"$5","searchParams":{},"params":{},"promises":["$@6","$@7"]}],[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/df18f9fdc6a3cb7c.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-model-skinner/_next/static/chunks/00e36f5c4a673582.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-model-skinner/_next/static/chunks/d9e502f7607fcfba.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-model-skinner/_next/static/chunks/ada16a90703ade36.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/t2-model-skinner/_next/static/chunks/e4e6678c9c61c198.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/t2-model-skinner/_next/static/chunks/a55df98dcb3b60ad.js","async":true,"nonce":"$undefined"}]],["$","$L8",null,{"children":["$L9",["$","$La",null,{"promise":"$@b"}]]}]]}],{},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Lc",null,{"children":"$Ld"}],null],["$","$Le",null,{"children":["$","div",null,{"hidden":true,"children":["$","$f",null,{"fallback":null,"children":"$L10"}]}]}]]}],false]],"m":"$undefined","G":["$11",[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"s":false,"S":true}
|
0:{"P":null,"b":"-yFPMzbzcZfNmotCttmg4","p":"/t2-model-skinner","c":["",""],"i":false,"f":[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"children":["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L4",null,{"Component":"$5","searchParams":{},"params":{},"promises":["$@6","$@7"]}],[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/df18f9fdc6a3cb7c.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/t2-model-skinner/_next/static/chunks/00e36f5c4a673582.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/t2-model-skinner/_next/static/chunks/d63fc3798baf75bd.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/t2-model-skinner/_next/static/chunks/a55df98dcb3b60ad.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/t2-model-skinner/_next/static/chunks/6cb39dc61a422734.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/t2-model-skinner/_next/static/chunks/ada16a90703ade36.js","async":true,"nonce":"$undefined"}]],["$","$L8",null,{"children":["$L9",["$","$La",null,{"promise":"$@b"}]]}]]}],{},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Lc",null,{"children":"$Ld"}],null],["$","$Le",null,{"children":["$","div",null,{"hidden":true,"children":["$","$f",null,{"fallback":null,"children":"$L10"}]}]}]]}],false]],"m":"$undefined","G":["$11",[["$","link","0",{"rel":"stylesheet","href":"/t2-model-skinner/_next/static/chunks/258ad065ddacdc6d.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]]],"s":false,"S":true}
|
||||||
6:{}
|
6:{}
|
||||||
7:"$0:f:0:1:2:children:1:props:children:0:props:params"
|
7:"$0:f:0:1:2:children:1:props:children:0:props:params"
|
||||||
d:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
d:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
||||||
|
|
|
||||||
2736
package-lock.json
generated
2736
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -20,7 +20,7 @@
|
||||||
"@rc-component/slider": "^1.0.0",
|
"@rc-component/slider": "^1.0.0",
|
||||||
"@tanstack/react-query": "^5.90.5",
|
"@tanstack/react-query": "^5.90.5",
|
||||||
"comlink": "^4.4.2",
|
"comlink": "^4.4.2",
|
||||||
"fabric": "^5.5.2-browser",
|
"fabric": "^6.7.1",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"globby": "^13.1.2",
|
"globby": "^13.1.2",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
|
|
@ -35,13 +35,10 @@
|
||||||
"@eslint/js": "^9.38.0",
|
"@eslint/js": "^9.38.0",
|
||||||
"@next/bundle-analyzer": "^15.5.6",
|
"@next/bundle-analyzer": "^15.5.6",
|
||||||
"@next/eslint-plugin-next": "^15.5.6",
|
"@next/eslint-plugin-next": "^15.5.6",
|
||||||
"@types/fabric": "^5.3.10",
|
|
||||||
"@types/file-saver": "^2.0.7",
|
"@types/file-saver": "^2.0.7",
|
||||||
"@types/lodash.orderby": "^4.6.9",
|
"@types/lodash.orderby": "^4.6.9",
|
||||||
"@types/pngjs": "^6.0.5",
|
"@types/pngjs": "^6.0.5",
|
||||||
"@types/react": "^19.2.2",
|
"@types/react": "^19.2.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.46.1",
|
|
||||||
"@typescript-eslint/parser": "^8.46.1",
|
|
||||||
"eslint": "^9.38.0",
|
"eslint": "^9.38.0",
|
||||||
"eslint-plugin-react": "^7.37.5",
|
"eslint-plugin-react": "^7.37.5",
|
||||||
"eslint-plugin-react-hooks": "^7.0.0",
|
"eslint-plugin-react-hooks": "^7.0.0",
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,14 @@ import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import useCanvas from "./useCanvas";
|
import useCanvas from "./useCanvas";
|
||||||
import useSettings from "./useSettings";
|
import useSettings from "./useSettings";
|
||||||
import useTools from "./useTools";
|
import useTools from "./useTools";
|
||||||
import { fabric } from "fabric";
|
import { Canvas as FabricCanvas, InteractiveFabricObject } from "fabric";
|
||||||
import { createFabricImage } from "./fabricUtils";
|
import { createFabricImage } from "./fabricUtils";
|
||||||
|
|
||||||
type JSONSnapshot = ReturnType<(typeof Canvas.prototype)["toDatalessJSON"]>;
|
type JSONSnapshot = ReturnType<(typeof Canvas.prototype)["toDatalessJSON"]>;
|
||||||
|
|
||||||
function updateObjectControlOptions() {
|
function updateObjectControlOptions() {
|
||||||
fabric.Object.prototype.set({
|
InteractiveFabricObject.ownDefaults = {
|
||||||
|
...InteractiveFabricObject.ownDefaults,
|
||||||
transparentCorners: false,
|
transparentCorners: false,
|
||||||
borderColor: "#8afff1",
|
borderColor: "#8afff1",
|
||||||
cornerSize: 9,
|
cornerSize: 9,
|
||||||
|
|
@ -18,13 +19,13 @@ function updateObjectControlOptions() {
|
||||||
cornerStrokeColor: "#1c9f7c",
|
cornerStrokeColor: "#1c9f7c",
|
||||||
strokeWidth: 10,
|
strokeWidth: 10,
|
||||||
perPixelTargetFind: true,
|
perPixelTargetFind: true,
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CanvasProps {
|
export interface CanvasProps {
|
||||||
canvasId: string;
|
canvasId: string;
|
||||||
canvasType: "color" | "metallic";
|
canvasType: "color" | "metallic";
|
||||||
onChange: (canvas: fabric.Canvas) => void;
|
onChange: (canvas: FabricCanvas) => void;
|
||||||
baseImageUrl: string | null;
|
baseImageUrl: string | null;
|
||||||
textureSize: [number, number];
|
textureSize: [number, number];
|
||||||
defaultDrawingMode?: boolean;
|
defaultDrawingMode?: boolean;
|
||||||
|
|
@ -38,7 +39,7 @@ export default function Canvas({
|
||||||
defaultDrawingMode = false,
|
defaultDrawingMode = false,
|
||||||
}: CanvasProps) {
|
}: CanvasProps) {
|
||||||
const canvasElementRef = useRef<HTMLCanvasElement | null>(null);
|
const canvasElementRef = useRef<HTMLCanvasElement | null>(null);
|
||||||
const [canvas, setCanvas] = useState<fabric.Canvas | null>(null);
|
const [canvas, setCanvas] = useState<FabricCanvas | null>(null);
|
||||||
const { activeCanvas } = useTools();
|
const { activeCanvas } = useTools();
|
||||||
const { canvasPadding } = useSettings();
|
const { canvasPadding } = useSettings();
|
||||||
const { registerCanvas, unregisterCanvas } = useCanvas();
|
const { registerCanvas, unregisterCanvas } = useCanvas();
|
||||||
|
|
@ -105,13 +106,18 @@ export default function Canvas({
|
||||||
const isActive = activeCanvas === canvasId;
|
const isActive = activeCanvas === canvasId;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!canvasElementRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
preserveObjectStacking: true,
|
preserveObjectStacking: true,
|
||||||
targetFindTolerance: 2,
|
targetFindTolerance: 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
updateObjectControlOptions();
|
updateObjectControlOptions();
|
||||||
|
|
||||||
const canvas = new fabric.Canvas(canvasElementRef.current, options);
|
const canvas = new FabricCanvas(canvasElementRef.current, options);
|
||||||
|
|
||||||
let isSnapshotting = false;
|
let isSnapshotting = false;
|
||||||
let changeTimer: ReturnType<typeof setTimeout>;
|
let changeTimer: ReturnType<typeof setTimeout>;
|
||||||
|
|
@ -138,7 +144,7 @@ export default function Canvas({
|
||||||
if (JSON.stringify(snapshot) === JSON.stringify(lastSnapshot)) {
|
if (JSON.stringify(snapshot) === JSON.stringify(lastSnapshot)) {
|
||||||
return history;
|
return history;
|
||||||
} else {
|
} else {
|
||||||
return [...history.slice(-5), snapshot];
|
return [...history.slice(-10), snapshot];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setRedoHistory([]);
|
setRedoHistory([]);
|
||||||
|
|
@ -225,6 +231,11 @@ export default function Canvas({
|
||||||
canRedo,
|
canRedo,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setUndoHistory([]);
|
||||||
|
setRedoHistory([]);
|
||||||
|
}, [canvas, baseImageUrl, textureSize]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas && textureSize) {
|
if (canvas && textureSize) {
|
||||||
trackChanges.current = false;
|
trackChanges.current = false;
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ export default function CanvasInteractions({
|
||||||
className="CanvasInteractions"
|
className="CanvasInteractions"
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
onDragOver={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
}}
|
||||||
onDrop={async (event) => {
|
onDrop={async (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (ref.current) {
|
if (ref.current) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { InputHTMLAttributes, useEffect, useRef, useState } from "react";
|
import { InputHTMLAttributes, useEffect, useRef, useState } from "react";
|
||||||
import { fabric } from "fabric";
|
import { FabricImage } from "fabric";
|
||||||
import useCanvas from "./useCanvas";
|
import useCanvas from "./useCanvas";
|
||||||
import useTools from "./useTools";
|
import useTools from "./useTools";
|
||||||
import {
|
import {
|
||||||
|
|
@ -168,7 +168,7 @@ export default function CanvasTools() {
|
||||||
const hasSelection = selectedObjects.length > 0;
|
const hasSelection = selectedObjects.length > 0;
|
||||||
|
|
||||||
const selectionHasImages =
|
const selectionHasImages =
|
||||||
selectedObjects.filter((object) => object instanceof fabric.Image).length >
|
selectedObjects.filter((object) => object instanceof FabricImage).length >
|
||||||
0;
|
0;
|
||||||
|
|
||||||
const handleBackgroundColorChange: InputHTMLAttributes<HTMLInputElement>["onChange"] =
|
const handleBackgroundColorChange: InputHTMLAttributes<HTMLInputElement>["onChange"] =
|
||||||
|
|
@ -441,7 +441,7 @@ export default function CanvasTools() {
|
||||||
all (
|
all (
|
||||||
{canvas?._objects
|
{canvas?._objects
|
||||||
.filter(
|
.filter(
|
||||||
(object) => object instanceof fabric.Image
|
(object) => object instanceof FabricImage
|
||||||
)
|
)
|
||||||
.length.toLocaleString() ?? 0}
|
.length.toLocaleString() ?? 0}
|
||||||
)
|
)
|
||||||
|
|
@ -561,7 +561,7 @@ export default function CanvasTools() {
|
||||||
<label>
|
<label>
|
||||||
Opacity:{" "}
|
Opacity:{" "}
|
||||||
<strong>
|
<strong>
|
||||||
{contrast == null
|
{opacity == null
|
||||||
? "MULTIPLE VALUES"
|
? "MULTIPLE VALUES"
|
||||||
: `${Math.round((opacity ?? 1) * 100)}%`}
|
: `${Math.round((opacity ?? 1) * 100)}%`}
|
||||||
</strong>
|
</strong>
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ export default function ColorCanvas({
|
||||||
const handleChange = useCallback<CanvasProps["onChange"]>(
|
const handleChange = useCallback<CanvasProps["onChange"]>(
|
||||||
async (canvas) => {
|
async (canvas) => {
|
||||||
const imageUrl = canvas.toDataURL({
|
const imageUrl = canvas.toDataURL({
|
||||||
|
format: "png",
|
||||||
|
multiplier: 1,
|
||||||
top: canvasPadding,
|
top: canvasPadding,
|
||||||
left: canvasPadding,
|
left: canvasPadding,
|
||||||
width: textureSize[0],
|
width: textureSize[0],
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ export default function MetallicCanvas({
|
||||||
async (canvas) => {
|
async (canvas) => {
|
||||||
runningChangeHandlers.current += 1;
|
runningChangeHandlers.current += 1;
|
||||||
const imageUrl = canvas.toDataURL({
|
const imageUrl = canvas.toDataURL({
|
||||||
|
format: "png",
|
||||||
|
multiplier: 1,
|
||||||
top: canvasPadding,
|
top: canvasPadding,
|
||||||
left: canvasPadding,
|
left: canvasPadding,
|
||||||
width: textureSize[0],
|
width: textureSize[0],
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { ReactNode, useCallback, useEffect, useMemo, useState } from "react";
|
import { ReactNode, useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { fabric } from "fabric";
|
import {
|
||||||
|
FabricImage,
|
||||||
|
FabricObject,
|
||||||
|
ActiveSelection,
|
||||||
|
filters,
|
||||||
|
PencilBrush,
|
||||||
|
} from "fabric";
|
||||||
import { ToolsContext } from "./useTools";
|
import { ToolsContext } from "./useTools";
|
||||||
import useCanvas from "./useCanvas";
|
import useCanvas from "./useCanvas";
|
||||||
import useWarrior from "./useWarrior";
|
import useWarrior from "./useWarrior";
|
||||||
|
|
@ -15,7 +21,7 @@ const { materials } = modelConfig;
|
||||||
|
|
||||||
const defaultTextureSize = [512, 512] as [number, number];
|
const defaultTextureSize = [512, 512] as [number, number];
|
||||||
|
|
||||||
function lockObject(object: fabric.Object) {
|
function lockObject(object: FabricObject) {
|
||||||
object.lockMovementX = true;
|
object.lockMovementX = true;
|
||||||
object.lockMovementY = true;
|
object.lockMovementY = true;
|
||||||
object.lockScalingX = true;
|
object.lockScalingX = true;
|
||||||
|
|
@ -23,7 +29,7 @@ function lockObject(object: fabric.Object) {
|
||||||
object.lockRotation = true;
|
object.lockRotation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unlockObject(object: fabric.Object) {
|
function unlockObject(object: FabricObject) {
|
||||||
object.lockMovementX = false;
|
object.lockMovementX = false;
|
||||||
object.lockMovementY = false;
|
object.lockMovementY = false;
|
||||||
object.lockScalingX = false;
|
object.lockScalingX = false;
|
||||||
|
|
@ -31,9 +37,7 @@ function unlockObject(object: fabric.Object) {
|
||||||
object.lockRotation = false;
|
object.lockRotation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isActiveSelection(
|
function isActiveSelection(object: FabricObject): object is ActiveSelection {
|
||||||
object: fabric.Object
|
|
||||||
): object is fabric.ActiveSelection {
|
|
||||||
return object.type === "activeSelection";
|
return object.type === "activeSelection";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,14 +110,14 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
|
|
||||||
const [backgroundColor, setBackgroundColor] = useState("magenta");
|
const [backgroundColor, setBackgroundColor] = useState("magenta");
|
||||||
const [lockedObjects, setLockedObjects] = useState(
|
const [lockedObjects, setLockedObjects] = useState(
|
||||||
() => new Set<fabric.Object>()
|
() => new Set<FabricObject>()
|
||||||
);
|
);
|
||||||
const [brushColor, setBrushColor] = useState(200);
|
const [brushColor, setBrushColor] = useState(200);
|
||||||
const [brushSize, setBrushSize] = useState(10);
|
const [brushSize, setBrushSize] = useState(10);
|
||||||
const [filterMap, setFilterMap] = useState(
|
const [filterMap, setFilterMap] = useState(
|
||||||
() => new Map<fabric.Object, ObjectFilters>()
|
() => new Map<FabricObject, ObjectFilters>()
|
||||||
);
|
);
|
||||||
const [selectedObjects, setSelectedObjects] = useState<fabric.Object[]>(
|
const [selectedObjects, setSelectedObjects] = useState<FabricObject[]>(
|
||||||
() => []
|
() => []
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -131,7 +135,7 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
const { combineColorAndAlphaImageUrls } = useImageWorker();
|
const { combineColorAndAlphaImageUrls } = useImageWorker();
|
||||||
const { canvasPadding } = useSettings();
|
const { canvasPadding } = useSettings();
|
||||||
const [filterChanges, setFilterChanges] = useState<
|
const [filterChanges, setFilterChanges] = useState<
|
||||||
Array<[fabric.Object, ObjectFilters]>
|
Array<[FabricObject, ObjectFilters]>
|
||||||
>(() => []);
|
>(() => []);
|
||||||
const [layerMode, setLayerMode] = useState("BaseLayer");
|
const [layerMode, setLayerMode] = useState("BaseLayer");
|
||||||
|
|
||||||
|
|
@ -147,7 +151,7 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
|
|
||||||
const setFilter = useCallback(
|
const setFilter = useCallback(
|
||||||
(name: keyof ObjectFilters, value: number) => {
|
(name: keyof ObjectFilters, value: number) => {
|
||||||
const filterChanges: Array<[fabric.Object, ObjectFilters]> = [];
|
const filterChanges: Array<[FabricObject, ObjectFilters]> = [];
|
||||||
const newFilterMap = new Map(filterMap);
|
const newFilterMap = new Map(filterMap);
|
||||||
let applyObjects = selectedObjects;
|
let applyObjects = selectedObjects;
|
||||||
if (layerMode === "AllLayers") {
|
if (layerMode === "AllLayers") {
|
||||||
|
|
@ -156,7 +160,7 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
applyObjects = canvas?._objects.slice(0, 1) ?? [];
|
applyObjects = canvas?._objects.slice(0, 1) ?? [];
|
||||||
}
|
}
|
||||||
for (const applyObject of applyObjects) {
|
for (const applyObject of applyObjects) {
|
||||||
if (applyObject instanceof fabric.Image) {
|
if (applyObject instanceof FabricImage) {
|
||||||
const existingFilters = filterMap.get(applyObject) ?? {};
|
const existingFilters = filterMap.get(applyObject) ?? {};
|
||||||
const newFilters = { ...existingFilters, [name]: value };
|
const newFilters = { ...existingFilters, [name]: value };
|
||||||
newFilterMap.set(applyObject, newFilters);
|
newFilterMap.set(applyObject, newFilters);
|
||||||
|
|
@ -180,7 +184,7 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
applyObjects = canvas?._objects.slice(0, 1) ?? [];
|
applyObjects = canvas?._objects.slice(0, 1) ?? [];
|
||||||
}
|
}
|
||||||
applyObjects = applyObjects.filter(
|
applyObjects = applyObjects.filter(
|
||||||
(object) => object instanceof fabric.Image
|
(object) => object instanceof FabricImage
|
||||||
);
|
);
|
||||||
if (applyObjects.length) {
|
if (applyObjects.length) {
|
||||||
const getValue = (i: number) =>
|
const getValue = (i: number) =>
|
||||||
|
|
@ -210,10 +214,10 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const [selectedObject, newFilters] of filterChanges) {
|
for (const [selectedObject, newFilters] of filterChanges) {
|
||||||
if (selectedObject instanceof fabric.Image) {
|
if (selectedObject instanceof FabricImage) {
|
||||||
selectedObject.filters = [];
|
selectedObject.filters = [];
|
||||||
if (activeCanvasType === "metallic") {
|
if (activeCanvasType === "metallic") {
|
||||||
const grayscaleFilter = new fabric.Image.filters.Grayscale();
|
const grayscaleFilter = new filters.Grayscale();
|
||||||
selectedObject.filters.push(grayscaleFilter);
|
selectedObject.filters.push(grayscaleFilter);
|
||||||
}
|
}
|
||||||
for (const key in newFilters) {
|
for (const key in newFilters) {
|
||||||
|
|
@ -222,28 +226,28 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "HueRotation":
|
case "HueRotation":
|
||||||
selectedObject.filters.push(
|
selectedObject.filters.push(
|
||||||
new fabric.Image.filters.HueRotation({
|
new filters.HueRotation({
|
||||||
rotation: filterValue,
|
rotation: filterValue,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "Saturation":
|
case "Saturation":
|
||||||
selectedObject.filters.push(
|
selectedObject.filters.push(
|
||||||
new fabric.Image.filters.Saturation({
|
new filters.Saturation({
|
||||||
saturation: filterValue,
|
saturation: filterValue,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "Brightness":
|
case "Brightness":
|
||||||
selectedObject.filters.push(
|
selectedObject.filters.push(
|
||||||
new fabric.Image.filters.Brightness({
|
new filters.Brightness({
|
||||||
brightness: filterValue,
|
brightness: filterValue,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "Contrast":
|
case "Contrast":
|
||||||
selectedObject.filters.push(
|
selectedObject.filters.push(
|
||||||
new fabric.Image.filters.Contrast({
|
new filters.Contrast({
|
||||||
contrast: filterValue,
|
contrast: filterValue,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
@ -292,7 +296,7 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
const bringForward = useCallback(async () => {
|
const bringForward = useCallback(async () => {
|
||||||
const object = canvas.getActiveObject();
|
const object = canvas.getActiveObject();
|
||||||
if (object) {
|
if (object) {
|
||||||
canvas.bringForward(object, true);
|
canvas.bringObjectForward(object, true);
|
||||||
notifyChange();
|
notifyChange();
|
||||||
}
|
}
|
||||||
}, [canvas, notifyChange]);
|
}, [canvas, notifyChange]);
|
||||||
|
|
@ -304,7 +308,7 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
if (canvas._objects[0] === object || canvas._objects[1] === object) {
|
if (canvas._objects[0] === object || canvas._objects[1] === object) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
canvas.sendBackwards(object, true);
|
canvas.sendObjectBackwards(object, true);
|
||||||
notifyChange();
|
notifyChange();
|
||||||
}
|
}
|
||||||
}, [canvas, notifyChange]);
|
}, [canvas, notifyChange]);
|
||||||
|
|
@ -333,7 +337,7 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
if (!image.filters) {
|
if (!image.filters) {
|
||||||
image.filters = [];
|
image.filters = [];
|
||||||
}
|
}
|
||||||
const grayscaleFilter = new fabric.Image.filters.Grayscale();
|
const grayscaleFilter = new filters.Grayscale();
|
||||||
image.filters.push(grayscaleFilter);
|
image.filters.push(grayscaleFilter);
|
||||||
image.applyFilters();
|
image.applyFilters();
|
||||||
}
|
}
|
||||||
|
|
@ -346,6 +350,7 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
}
|
}
|
||||||
if (lastAddedImage) {
|
if (lastAddedImage) {
|
||||||
canvas.setActiveObject(lastAddedImage);
|
canvas.setActiveObject(lastAddedImage);
|
||||||
|
canvas.requestRenderAll();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[textureSize, activeCanvasType, metallicCanvas, canvas, setDrawingMode]
|
[textureSize, activeCanvasType, metallicCanvas, canvas, setDrawingMode]
|
||||||
|
|
@ -354,9 +359,7 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
const duplicate = useCallback(async () => {
|
const duplicate = useCallback(async () => {
|
||||||
const object = canvas.getActiveObject();
|
const object = canvas.getActiveObject();
|
||||||
if (object) {
|
if (object) {
|
||||||
const copy = await new Promise<fabric.Object>((resolve) =>
|
const copy = await object.clone();
|
||||||
object.clone(resolve)
|
|
||||||
);
|
|
||||||
copy.set({
|
copy.set({
|
||||||
top: (copy.top ?? 0) + 20,
|
top: (copy.top ?? 0) + 20,
|
||||||
left: (copy.left ?? 0) + 20,
|
left: (copy.left ?? 0) + 20,
|
||||||
|
|
@ -388,6 +391,8 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
const copyToMetallic = useCallback(async () => {
|
const copyToMetallic = useCallback(async () => {
|
||||||
if (activeCanvasType === "color" && metallicCanvas) {
|
if (activeCanvasType === "color" && metallicCanvas) {
|
||||||
const colorImageUrl = canvas.toDataURL({
|
const colorImageUrl = canvas.toDataURL({
|
||||||
|
format: "png",
|
||||||
|
multiplier: 1,
|
||||||
top: canvasPadding,
|
top: canvasPadding,
|
||||||
left: canvasPadding,
|
left: canvasPadding,
|
||||||
width: textureSize[0],
|
width: textureSize[0],
|
||||||
|
|
@ -397,7 +402,7 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
if (!image.filters) {
|
if (!image.filters) {
|
||||||
image.filters = [];
|
image.filters = [];
|
||||||
}
|
}
|
||||||
const grayscaleFilter = new fabric.Image.filters.Grayscale();
|
const grayscaleFilter = new filters.Grayscale();
|
||||||
image.filters.push(grayscaleFilter);
|
image.filters.push(grayscaleFilter);
|
||||||
image.applyFilters();
|
image.applyFilters();
|
||||||
metallicCanvas.centerObject(image);
|
metallicCanvas.centerObject(image);
|
||||||
|
|
@ -450,6 +455,8 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
let outputImageUrl;
|
let outputImageUrl;
|
||||||
|
|
||||||
const colorImageUrl = colorCanvas.toDataURL({
|
const colorImageUrl = colorCanvas.toDataURL({
|
||||||
|
format: "png",
|
||||||
|
multiplier: 1,
|
||||||
top: canvasPadding,
|
top: canvasPadding,
|
||||||
left: canvasPadding,
|
left: canvasPadding,
|
||||||
width: textureSize[0],
|
width: textureSize[0],
|
||||||
|
|
@ -458,6 +465,8 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
|
|
||||||
if (metallicCanvas) {
|
if (metallicCanvas) {
|
||||||
const metallicImageUrl = metallicCanvas.toDataURL({
|
const metallicImageUrl = metallicCanvas.toDataURL({
|
||||||
|
format: "png",
|
||||||
|
multiplier: 1,
|
||||||
top: canvasPadding,
|
top: canvasPadding,
|
||||||
left: canvasPadding,
|
left: canvasPadding,
|
||||||
width: textureSize[0],
|
width: textureSize[0],
|
||||||
|
|
@ -676,12 +685,18 @@ export default function ToolsProvider({ children }: { children: ReactNode }) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (metallicCanvas) {
|
if (metallicCanvas) {
|
||||||
|
if (!metallicCanvas.freeDrawingBrush) {
|
||||||
|
metallicCanvas.freeDrawingBrush = new PencilBrush(metallicCanvas);
|
||||||
|
}
|
||||||
metallicCanvas.freeDrawingBrush.width = brushSize;
|
metallicCanvas.freeDrawingBrush.width = brushSize;
|
||||||
}
|
}
|
||||||
}, [metallicCanvas, brushSize]);
|
}, [metallicCanvas, brushSize]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (metallicCanvas) {
|
if (metallicCanvas) {
|
||||||
|
if (!metallicCanvas.freeDrawingBrush) {
|
||||||
|
metallicCanvas.freeDrawingBrush = new PencilBrush(metallicCanvas);
|
||||||
|
}
|
||||||
metallicCanvas.freeDrawingBrush.color = `rgb(${brushColor}, ${brushColor}, ${brushColor})`;
|
metallicCanvas.freeDrawingBrush.color = `rgb(${brushColor}, ${brushColor}, ${brushColor})`;
|
||||||
}
|
}
|
||||||
}, [metallicCanvas, brushColor]);
|
}, [metallicCanvas, brushColor]);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
"use client";
|
import { FabricImage } from "fabric";
|
||||||
import { fabric } from "fabric";
|
|
||||||
|
|
||||||
export async function createFabricImage(url: string) {
|
export async function createFabricImage(url: string) {
|
||||||
const promise = new Promise<fabric.Image>((resolve) =>
|
const img = await FabricImage.fromURL(url, { crossOrigin: "anonymous" });
|
||||||
fabric.Image.fromURL(url, resolve, {
|
|
||||||
crossOrigin: "anonymous",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const img = await promise;
|
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
"use client";
|
"use client";
|
||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
import { fabric } from "fabric";
|
import { Canvas as FabricCanvas } from "fabric";
|
||||||
|
|
||||||
export interface CanvasInfo {
|
export interface CanvasInfo {
|
||||||
canvas: fabric.Canvas;
|
canvas: FabricCanvas;
|
||||||
notifyChange: () => void;
|
notifyChange: () => void;
|
||||||
isDrawingMode: boolean;
|
isDrawingMode: boolean;
|
||||||
setDrawingMode: (isDrawingMode: boolean) => void;
|
setDrawingMode: (isDrawingMode: boolean) => void;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
"use client";
|
"use client";
|
||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
import { fabric } from "fabric";
|
import { FabricObject } from "fabric";
|
||||||
|
|
||||||
interface ToolsContextValue {
|
interface ToolsContextValue {
|
||||||
activeCanvas: string | null;
|
activeCanvas: string | null;
|
||||||
activeCanvasType: string;
|
activeCanvasType: string;
|
||||||
setActiveCanvasType: (canvasType: string) => void;
|
setActiveCanvasType: (canvasType: string) => void;
|
||||||
selectedObjects: Array<fabric.Object>;
|
selectedObjects: Array<FabricObject>;
|
||||||
brushSize: number;
|
brushSize: number;
|
||||||
setBrushSize: (brushSize: number) => void;
|
setBrushSize: (brushSize: number) => void;
|
||||||
brushColor: number;
|
brushColor: number;
|
||||||
|
|
@ -42,7 +42,7 @@ interface ToolsContextValue {
|
||||||
name: string;
|
name: string;
|
||||||
format: string;
|
format: string;
|
||||||
}) => Promise<void>;
|
}) => Promise<void>;
|
||||||
lockedObjects: Set<fabric.Object>;
|
lockedObjects: Set<FabricObject>;
|
||||||
backgroundColor: string;
|
backgroundColor: string;
|
||||||
setBackgroundColor: (backgroundColor: string) => void;
|
setBackgroundColor: (backgroundColor: string) => void;
|
||||||
selectedMaterialIndex: number;
|
selectedMaterialIndex: number;
|
||||||
|
|
|
||||||
5
types/fabric.d.ts
vendored
5
types/fabric.d.ts
vendored
|
|
@ -1,5 +0,0 @@
|
||||||
/// <reference types="fabric" />
|
|
||||||
declare module "fabric" {
|
|
||||||
// Re-export the DT namespace as the module's export.
|
|
||||||
export { fabric };
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue