Restructure project directories (#333)
`/client/web` -> `/frontend` `/client/cli` -> *delete for now* `/client/native` -> *delete for now* `/core/editor` -> `/editor` `/core/document` -> `/graphene` `/core/renderer` -> `/charcoal` `/core/proc-macro` -> `/proc-macros` *(now plural)*
49
frontend/.eslintrc.js
Normal file
@@ -0,0 +1,49 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
es2020: true,
|
||||
},
|
||||
extends: ["plugin:vue/vue3-essential", "@vue/airbnb", "@vue/typescript/recommended", "plugin:prettier-vue/recommended", "prettier"],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
},
|
||||
settings: {
|
||||
"import/resolver": {
|
||||
// `node` must be listed first!
|
||||
node: {},
|
||||
webpack: { config: require.resolve("@vue/cli-service/webpack.config.js") },
|
||||
},
|
||||
"prettier-vue": {
|
||||
SFCBlocks: {
|
||||
template: true,
|
||||
style: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
ignorePatterns: ["node_modules/", "dist/", "pkg/", "wasm/pkg/*", "!.*.js", "!.*.ts", "!.*.json"],
|
||||
rules: {
|
||||
indent: ["error", "tab", { SwitchCase: 1 }],
|
||||
quotes: ["error", "double"],
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"eol-last": ["error", "always"],
|
||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-param-reassign": ["error", { props: false }],
|
||||
"import/prefer-default-export": "off",
|
||||
"max-len": ["error", { code: 200, tabWidth: 4 }],
|
||||
"@typescript-eslint/camelcase": "off",
|
||||
"@typescript-eslint/no-use-before-define": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
|
||||
camelcase: ["error", { allow: ["^(?:[a-z]+_)*[a-z]+$"] }],
|
||||
"prettier-vue/prettier": [
|
||||
"error",
|
||||
{
|
||||
tabWidth: 4,
|
||||
tabs: true,
|
||||
printWidth: 200,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
4
frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
node_modules/
|
||||
dist/
|
||||
pkg/
|
||||
wasm/pkg/*
|
||||
3
frontend/assets/12px-solid/checkmark.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<polygon points="5.19,11.83 0.18,7.44 1.82,5.56 4.81,8.17 10,1.25 12,2.75" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 147 B |
3
frontend/assets/12px-solid/close-x.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<polygon points="10,3 9,2 6,5 3,2 2,3 5,6 2,9 3,10 6,7 9,10 10,9 7,6" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 142 B |
3
frontend/assets/12px-solid/dropdown-arrow.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<polygon points="6,7 2.5,4 2.5,6 6,9 9.5,6 9.5,4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 122 B |
6
frontend/assets/12px-solid/fullscreen-enter.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<polygon points="11,8 11,11 8,11 8,12 12,12 12,8" />
|
||||
<polygon points="1,1 4,1 4,0 0,0 0,4 1,4" />
|
||||
<polygon points="4,11 1,11 1,8 0,8 0,12 4,12" />
|
||||
<polygon points="11,1 11,4 12,4 12,0 8,0 8,1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 268 B |
6
frontend/assets/12px-solid/fullscreen-exit.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<polygon points="9,12 9,9 12,9 12,8 8,8 8,12" />
|
||||
<polygon points="3,3 0,3 0,4 4,4 4,0 3,0" />
|
||||
<polygon points="0,9 3,9 3,12 4,12 4,8 0,8" />
|
||||
<polygon points="9,3 9,0 8,0 8,4 12,4 12,3" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 260 B |
10
frontend/assets/12px-solid/grid.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<rect width="1" height="12" x="4" y="0" />
|
||||
<rect width="1" height="12" x="1" y="0" />
|
||||
<rect width="1" height="12" x="7" y="0" />
|
||||
<rect width="1" height="12" x="10" y="0" />
|
||||
<rect width="12" height="1" x="0" y="4" />
|
||||
<rect width="12" height="1" x="0" y="1" />
|
||||
<rect width="12" height="1" x="0" y="7" />
|
||||
<rect width="12" height="1" x="0" y="10" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 422 B |
3
frontend/assets/12px-solid/info.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<path d="M6,0C2.69,0,0,2.69,0,6s2.69,6,6,6s6-2.69,6-6S9.31,0,6,0z M6.35,11C5.71,11,5.2,10.49,5.2,9.85c0-0.63,0.51-1.15,1.15-1.15c0.63,0,1.15,0.51,1.15,1.15C7.49,10.49,6.98,11,6.35,11z M8.59,5.04C8.2,5.76,7.21,5.98,7.21,6.9v0.99h-1.8V6.9c0-1.89,1.88-1.62,1.88-3.12c0-1.41-2.16-1.88-2.77,0.15L3,3.46C4.25-0.96,10.66,1.2,8.59,5.04z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 402 B |
4
frontend/assets/12px-solid/link.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<path d="M4.68,9.32L4,10c-0.53,0.53-1.47,0.53-2,0C1.73,9.73,1.59,9.38,1.59,9S1.73,8.27,2,8l2.5-2.5c0.27-0.27,0.62-0.41,1-0.41s0.73,0.15,1,0.41l1-1c-1.07-1.07-2.93-1.07-4,0L1,7C0.47,7.53,0.17,8.24,0.17,9S0.47,10.47,1,11s1.24,0.83,2,0.83S4.47,11.53,5,11l1.27-1.27C5.71,9.7,5.17,9.56,4.68,9.32z" />
|
||||
<path d="M11,1C9.93-0.07,8.07-0.07,7,1L5.7,2.3c0.56,0.03,1.11,0.16,1.61,0.39L8,2c0.27-0.27,0.62-0.41,1-0.41S9.73,1.73,10,2s0.41,0.62,0.41,1S10.27,3.73,10,4L7.5,6.5c-0.53,0.53-1.47,0.53-2,0l-1,1c0.53,0.53,1.24,0.83,2,0.83s1.47-0.29,2-0.83L11,5c0.53-0.53,0.83-1.24,0.83-2S11.53,1.53,11,1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 657 B |
10
frontend/assets/12px-solid/overlays.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<rect width="3" height="3" />
|
||||
<rect width="3" height="3" y="9" />
|
||||
<rect width="1" height="4" y="4" />
|
||||
<rect width="4" height="1" x="4" y="11" />
|
||||
<rect width="1" height="4" x="11" y="4" />
|
||||
<rect width="3" height="3" x="9" />
|
||||
<rect width="3" height="3" x="9" y="9" />
|
||||
<rect width="4" height="1" x="4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 378 B |
3
frontend/assets/12px-solid/reset-colors.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<path d="M10,4c0-2.2-1.8-4-4-4S2,1.8,2,4c0,0.7,0.2,1.4,0.6,2C2.2,6.6,2,7.3,2,8c0,2.2,1.8,4,4,4s4-1.8,4-4c0-0.7-0.2-1.4-0.6-2C9.8,5.4,10,4.7,10,4z M6,1c1.7,0,3,1.3,3,3S7.7,7,6,7S3,5.7,3,4S4.3,1,6,1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 271 B |
6
frontend/assets/12px-solid/snapping.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<path d="M7.5,7.5L6,9C5.17,9.83,3.83,9.83,3,9S2.17,6.83,3,6l1.5-1.5L3,3L1.5,4.5c-1.66,1.66-1.66,4.34,0,6s4.34,1.66,6,0L9,9L7.5,7.5z" />
|
||||
<polygon points="4,2 5.5,0.5 7,2 5.5,3.5" />
|
||||
<polygon points="8.5,6.5 10,5 11.5,6.5 10,8" />
|
||||
<polygon points="12,0 8.29,1.21 9.29,3.21 7,4 7,5 10.71,3.79 9.71,1.79 12,1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 381 B |
3
frontend/assets/12px-solid/swap.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<path d="M7,3L4,0L1,3h2v4h2V3H7z M8,12l3-3H9V5H7v4H5L8,12z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 132 B |
5
frontend/assets/12px-solid/vertical-ellipsis.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<circle cx="6" cy="2" r="1.5" />
|
||||
<circle cx="6" cy="6" r="1.5" />
|
||||
<circle cx="6" cy="10" r="1.5" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 171 B |
3
frontend/assets/12px-solid/warning.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<path d="M11.9,9.79L6.96,0.58c-0.41-0.77-1.5-0.77-1.92,0L0.1,9.79C-0.19,10.33,0.2,11,0.81,11h10.39C11.8,11,12.19,10.33,11.9,9.79z M6.9,2.5L6.67,7H5.33L5.1,2.5L6.9,2.5z M6,10.3c-0.63,0-1.15-0.51-1.15-1.15C4.85,8.51,5.37,8,6,8c0.63,0,1.15,0.51,1.15,1.15C7.15,9.78,6.63,10.3,6,10.3z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 353 B |
3
frontend/assets/12px-solid/window-button-win-close.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<polygon points="11,1.7 10.3,1 6,5.3 1.7,1 1,1.7 5.3,6 1,10.3 1.7,11 6,6.7 10.3,11 11,10.3 6.7,6" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 170 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<path d="M11,1v10H1V1H11z M10,2H2v8h8V2z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 114 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<rect x="1" y="5" width="10" height="1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 112 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
|
||||
<path d="M11,9H9v2H1V3h2V1h8V9z M8,4H2v6h6V4z M10,2H4v1h5v5h1V2z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 138 B |
5
frontend/assets/16px-solid/align-bottom.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<rect y="15" width="16" height="1" />
|
||||
<rect x="9" y="6" width="5" height="7" />
|
||||
<rect x="2" width="5" height="13" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 188 B |
5
frontend/assets/16px-solid/align-horizontal-center.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<rect x="8" width="1" height="16" />
|
||||
<rect x="5" y="2" width="7" height="5" />
|
||||
<rect x="2" y="9" width="13" height="5" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 193 B |
5
frontend/assets/16px-solid/align-left.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<rect width="1" height="16" />
|
||||
<rect x="3" y="2" width="7" height="5" />
|
||||
<rect x="3" y="9" width="13" height="5" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 187 B |
5
frontend/assets/16px-solid/align-right.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<rect x="15" width="1" height="16" />
|
||||
<rect x="6" y="2" width="7" height="5" />
|
||||
<rect y="9" width="13" height="5" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 188 B |
5
frontend/assets/16px-solid/align-top.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<rect width="16" height="1" />
|
||||
<rect x="9" y="3" width="5" height="7" />
|
||||
<rect x="2" y="3" width="5" height="13" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 187 B |
5
frontend/assets/16px-solid/align-vertical-center.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<rect y="8" width="16" height="1" />
|
||||
<rect x="9" y="5" width="5" height="7" />
|
||||
<rect x="2" y="2" width="5" height="13" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 193 B |
4
frontend/assets/16px-solid/boolean-difference.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<polygon points="12,4 12,12 4,12 4,16 16,16 16,4" />
|
||||
<polygon points="12,4 12,0 0,0 0,12 4,12 4,4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 172 B |
3
frontend/assets/16px-solid/boolean-intersect.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M12,4V0H0v12h4v4h12V4H12z M1,11V1h10v3H4v7H1z M15,15H5v-3h7V5h3V15z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 150 B |
3
frontend/assets/16px-solid/boolean-subtract-back.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M12,4V0H0v12h4v4h12V4H12z M1,1h10v10H1V1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 124 B |
3
frontend/assets/16px-solid/boolean-subtract-front.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M12,4V0H0v12h4v4h12V4H12z M15,15H5V5h10V15z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 126 B |
3
frontend/assets/16px-solid/boolean-union.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<polygon points="12,4 12,0 0,0 0,12 4,12 4,16 16,16 16,4" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 130 B |
4
frontend/assets/16px-solid/copy.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M9,5L5,9v7h9V5H9z M13,15H6v-5h4V6h3V15z" />
|
||||
<polygon points="5,1 2,4 2,13 4,13 4,12 3,12 3,5 6,5 6,2 11,2 11,4 12,4 12,1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 204 B |
3
frontend/assets/16px-solid/eye-hidden.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M8,4c3.5,0,5.9,2.8,6.8,4c-0.9,1.2-3.3,4-6.8,4S2.1,9.2,1.2,8C2.1,6.8,4.5,4,8,4 M8,3C3,3,0,8,0,8s3,5,8,5s8-5,8-5S13,3,8,3L8,3z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 207 B |
4
frontend/assets/16px-solid/eye-visible.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M8,3C3,3,0,8,0,8s3,5,8,5s8-5,8-5S13,3,8,3z M8,12c-2.2,0-4-1.8-4-4s1.8-4,4-4s4,1.8,4,4S10.2,12,8,12z" />
|
||||
<circle cx="9" cy="7" r="1.2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 216 B |
3
frontend/assets/16px-solid/file.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M7,0L2,5v11h12V0H7z M13,15H3V6h5V1h5V15z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 123 B |
8
frontend/assets/16px-solid/flip-horizontal.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M15,4.6v6.8l-4-2V6.6L15,4.6 M16,3l-6,3v4l6,3V3L16,3z" />
|
||||
<polygon points="5,10 0,13 0,3 5,6" />
|
||||
<rect x="7" y="13" width="1" height="2" />
|
||||
<rect x="7" y="9" width="1" height="2" />
|
||||
<rect x="7" y="5" width="1" height="2" />
|
||||
<rect x="7" y="1" width="1" height="2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 348 B |
8
frontend/assets/16px-solid/flip-vertical.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M9.4,11l2,4H4.6l2-4H9.4 M10,10H6l-3,6h10L10,10L10,10z" />
|
||||
<polygon points="6,5 3,0 13,0 10,5" />
|
||||
<rect x="1" y="7" width="2" height="1" />
|
||||
<rect x="5" y="7" width="2" height="1" />
|
||||
<rect x="9" y="7" width="2" height="1" />
|
||||
<rect x="13" y="7" width="2" height="1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 349 B |
3
frontend/assets/16px-solid/graphite-logo.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M5.5,10.2c0.1,0.2,0,0.3-0.1,0.4c-0.2,0.1-0.3,0-0.4-0.1c0,0,0,0,0,0L2.7,6.7c-0.1-0.2,0-0.3,0.1-0.4c0.2-0.1,0.3,0,0.4,0.1L5.5,10.2z M14.9,14.9L14.9,14.9C14.9,14.9,14.9,15,14.9,14.9C14.8,15,14.8,15,14.9,14.9L14.9,14.9c-0.5,0.2-1,0.4-1.5,0.5c-0.5,0.1-1.1,0.2-1.6,0.2c-0.5,0.1-1.1,0.1-1.6,0c-0.5,0-1.1-0.1-1.6-0.1l-1.6-0.1c-1.7,0-3.9-0.1-4.4-0.1s-1.1-0.2-1.1-0.3c0-0.1,0.3-0.2,0.6-0.2c0.5-0.1,1.1-0.2,1.7-0.3c0.6-0.1,2-0.2,4.1-0.2c0.8,0,1.8,0,1.8,0c0.6,0,1,0,1.9,0c0.7,0,1.1,0,1.2,0c0.3,0,0.6,0.1,0.9,0.2l-2.6-1.9c-0.2,0.1-0.4,0.2-0.7,0.2H4.5c-0.5,0-0.9-0.2-1.1-0.6l-2.9-5c-0.2-0.4-0.2-0.9,0-1.3l2.9-5C3.6,0.5,4,0.3,4.5,0.3h5.8c0.5,0,0.9,0.2,1.1,0.6l2.9,5l0,0l0,0c0,0.1,0.1,0.2,0.1,0.3c0,0,0,0.1,0,0.1c0,0.1,0,0.1,0,0.2c0,0,0.7,7.2,0.7,7.8v0C15.2,14.6,15.1,14.8,14.9,14.9L14.9,14.9z M4.3,1.9L4.2,2l3.6,6.2c0.4-0.1,0.9-0.2,1.4-0.2l0.9-1.3l1.6-0.2c0.2-0.4,0.5-0.8,0.8-1.1l-2.1-3.7c-0.1-0.2-0.3-0.3-0.5-0.3H4.8C4.6,1.6,4.4,1.7,4.3,1.9z M9.4,11.6l-2-1.4C7.4,10.1,7.3,10,7.3,10l0,0L3.5,3.3l-1.7,3c-0.1,0.2-0.1,0.4,0,0.6l2.6,4.5c0.1,0.2,0.3,0.3,0.5,0.3L9.4,11.6z M13.5,11.3l-0.5-4.6c-0.3,0.3-0.5,0.7-0.7,1l-1.6,0.2L9.8,9.2c-0.4,0-0.8,0-1.3,0.1l3.7,2.7C12.5,11.6,13,11.3,13.5,11.3L13.5,11.3z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
4
frontend/assets/16px-solid/paste.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M12,1H8.72C8.38,0.4,7.74,0,7,0S5.62,0.4,5.28,1H2C1.45,1,1,1.45,1,2v12c0,0.55,0.45,1,1,1h3v-1H2V2h2v1c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1V2h2v2h1V2C13,1.45,12.55,1,12,1z" />
|
||||
<path d="M10,5L6,9v7h9V5H10z M14,15H7v-5h4V6h3V15z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 309 B |
3
frontend/assets/16px-solid/view-mode-normal.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<circle cx="8" cy="8" r="8" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 100 B |
3
frontend/assets/16px-solid/view-mode-outline.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M8,1c3.9,0,7,3.1,7,7s-3.1,7-7,7s-7-3.1-7-7S4.1,1,8,1 M8,0C3.6,0,0,3.6,0,8s3.6,8,8,8s8-3.6,8-8S12.4,0,8,0L8,0z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 192 B |
23
frontend/assets/16px-solid/view-mode-pixels.svg
Normal file
@@ -0,0 +1,23 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<rect x="7" y="1" width="2" height="2" />
|
||||
<rect x="13" y="4" width="2" height="2" />
|
||||
<rect x="13" y="7" width="2" height="2" />
|
||||
<rect x="13" y="10" width="2" height="2" />
|
||||
<rect x="7" y="13" width="2" height="2" />
|
||||
<rect x="10" y="13" width="2" height="2" />
|
||||
<rect x="4" y="13" width="2" height="2" />
|
||||
<rect x="1" y="10" width="2" height="2" />
|
||||
<rect x="1" y="7" width="2" height="2" />
|
||||
<rect x="1" y="4" width="2" height="2" />
|
||||
<rect x="4" y="1" width="2" height="2" />
|
||||
<rect x="10" y="10" width="2" height="2" />
|
||||
<rect x="4" y="10" width="2" height="2" />
|
||||
<rect x="7" y="10" width="2" height="2" />
|
||||
<rect x="10" y="7" width="2" height="2" />
|
||||
<rect x="4" y="7" width="2" height="2" />
|
||||
<rect x="7" y="7" width="2" height="2" />
|
||||
<rect x="10" y="4" width="2" height="2" />
|
||||
<rect x="4" y="4" width="2" height="2" />
|
||||
<rect x="7" y="4" width="2" height="2" />
|
||||
<rect x="10" y="1" width="2" height="2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 987 B |
6
frontend/assets/16px-solid/viewport-design-mode.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M15,6.06V15H9.69c-0.22,0.36-0.49,0.69-0.79,1H16V4.46C15.71,4.96,15.37,5.49,15,6.06z" />
|
||||
<path d="M5.57,9.4c-1.22,0.07-2.27,1.09-2.94,3.05C1.94,14.47,0,15.36,0,15.36c2.08,0.71,4.3,0.95,6.26,0.08c1.75-0.78,2.38-2.35,2.22-3.76C8.35,10.58,7.27,9.3,5.57,9.4z" />
|
||||
<path d="M15.42,0.08c-0.69-0.55-3.27,1.97-6.11,5.14c-1,1.12-1.99,2.3-2.6,3.34C7.17,8.6,7.66,8.78,8.11,9.12C8.67,9.55,9,10.05,9.14,10.49c0.94-0.86,1.75-1.96,2.68-3.3C14.29,3.65,16.11,0.62,15.42,0.08z" />
|
||||
<path d="M0.74,11.81c0.08-0.24,0.17-0.43,0.26-0.65V1h9.52c0.38-0.38,0.72-0.71,1.05-1H0v12.93C0.29,12.65,0.58,12.28,0.74,11.81z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 673 B |
6
frontend/assets/16px-solid/viewport-guide-mode.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<polygon points="11.85,0 11.15,0 0,11.15 0,12.85 1.5,11.35 2.58,12.42 3.42,11.58 2.35,10.5 3.5,9.35 5.58,11.42 6.42,10.58 4.35,8.5 5.5,7.35 6.58,8.42 7.42,7.58 6.35,6.5 7.5,5.35 9.58,7.42 10.42,6.58 8.35,4.5 9.5,3.35 10.58,4.42 11.42,3.58 10.35,2.5 11.5,1.35 14.65,4.5 3.15,16 4.85,16 16,4.85 16,4.15" />
|
||||
<polygon points="14,0 16,2 16,0" />
|
||||
<polygon points="15,8.68 15,15 8.68,15 7.68,16 16,16 16,7.68" />
|
||||
<polygon points="0,0 0,8.32 1,7.32 1,1 7.32,1 8.32,0" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 535 B |
6
frontend/assets/16px-solid/viewport-select-mode.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M15,1v1.85c0.37,0.32,0.7,0.66,1,1.02V0H0v3.19c0.24-0.28,0.49-0.55,0.78-0.81C0.85,2.32,0.93,2.27,1,2.21V1H15z" />
|
||||
<path d="M0,11.17v4.37l1-0.66v-2.15c-0.15-0.28-0.27-0.58-0.34-0.89C0.42,11.62,0.2,11.39,0,11.17z" />
|
||||
<path d="M15,12.74V15H8.54c-0.23,0.24-0.41,0.52-0.55,0.77L7.86,16H16v-4.11C15.7,12.2,15.37,12.49,15,12.74z" />
|
||||
<path d="M2.54,10.76c-0.01,0.49,0.12,0.96,0.41,1.33c0.35,0.45,1.02,0.93,2.29,0.93c0.03,0,0.07-0.01,0.1-0.01C5.19,13.78,4.62,14.86,2.91,16h2.38c0.4-0.41,0.71-0.81,0.94-1.19l0,0c0.87-1.57,2.19-2.48,3.72-2.54c3.31-0.14,5.61-1.86,5.61-4.2c0-2.98-3.07-5.42-7.47-5.94C5.86,1.87,3.63,2.52,2.11,3.88C1.03,4.84,0.44,6.02,0.44,7.22C0.44,8.57,1.2,9.83,2.54,10.76z M6.91,11.81c-0.03,0.02-0.06,0.04-0.09,0.06c-0.04-0.23-0.1-0.38-0.12-0.45c-0.33-0.86-1.11-1.01-1.62-1.11c-0.15-0.03-0.31-0.06-0.45-0.11c-0.11-0.05-0.22-0.1-0.33-0.15C4.51,9.75,4.85,9.49,5.3,9.43c0.85-0.1,1.48,0.1,1.77,0.56C7.34,10.45,7.27,11.14,6.91,11.81z M3.1,5c1.03-0.92,2.49-1.42,4.01-1.42c0.27,0,0.53,0.02,0.8,0.05c4.04,0.47,6.15,2.6,6.15,4.45c0,1.49-1.72,2.6-4.18,2.7c-0.4,0.02-0.78,0.09-1.16,0.19c0.05-0.63-0.08-1.24-0.39-1.75c-0.6-0.97-1.78-1.43-3.22-1.26c-0.84,0.1-1.6,0.6-2.08,1.32c-0.71-0.6-1.1-1.31-1.1-2.04C1.94,6.47,2.36,5.66,3.1,5z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
6
frontend/assets/16px-solid/zoom-in.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M15.7,14.2l-4-4l-1.5,1.5l4,4c0.4,0.4,1.1,0.4,1.5,0C16.1,15.3,16.1,14.6,15.7,14.2z" />
|
||||
<path d="M6.5,1.4c2.8,0,5.1,2.3,5.1,5.1s-2.3,5.1-5.1,5.1S1.4,9.3,1.4,6.5S3.7,1.4,6.5,1.4 M6.5,0C2.9,0,0,2.9,0,6.5S2.9,13,6.5,13S13,10.1,13,6.5S10.1,0,6.5,0L6.5,0z" />
|
||||
<rect x="3" y="5.8" width="7" height="1.5" />
|
||||
<rect x="5.8" y="3" width="1.5" height="7" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 426 B |
5
frontend/assets/16px-solid/zoom-out.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path d="M15.7,14.2l-4-4l-1.5,1.5l4,4c0.4,0.4,1.1,0.4,1.5,0C16.1,15.3,16.1,14.6,15.7,14.2z" />
|
||||
<path d="M6.5,1.4c2.8,0,5.1,2.3,5.1,5.1s-2.3,5.1-5.1,5.1S1.4,9.3,1.4,6.5S3.7,1.4,6.5,1.4 M6.5,0C2.9,0,0,2.9,0,6.5S2.9,13,6.5,13S13,10.1,13,6.5S10.1,0,6.5,0L6.5,0z" />
|
||||
<rect x="3" y="5.8" width="7" height="1.5" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 379 B |
5
frontend/assets/16px-solid/zoom-reset.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<polygon points="0,6.5 2.9,11.5 5.7,6.5" />
|
||||
<path d="M8.2,12.6c-0.2,0-0.4,0-0.6,0c-0.9-0.1-1.8-0.4-2.6-0.8l0.7-1.2c0.6,0.4,1.3,0.6,2,0.6c1.3,0.1,2.6-0.3,3.6-1.1s1.6-2,1.7-3.3c0.2-2.7-1.8-5-4.4-5.3C7.3,1.3,6.1,1.7,5.1,2.6c-1,0.8-1.6,2-1.7,3.3c0,0.5,0,1,0.1,1.5L2.1,7.7c-0.2-0.7-0.2-1.3-0.2-2c0.2-1.7,0.9-3.2,2.2-4.3C5.5,0.4,7.1-0.1,8.8,0c3.5,0.3,6,3.3,5.7,6.8c-0.1,1.7-0.9,3.2-2.2,4.3C11.1,12.1,9.7,12.6,8.2,12.6z" />
|
||||
<path d="M15.8,14.4l-3.3-4L11,11.7l3.3,4c0.3,0.4,1,0.5,1.4,0.1C16.1,15.4,16.1,14.8,15.8,14.4z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 586 B |
6
frontend/assets/16px-two-tone/mouse-hint-drag.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path class="dim" d="M8,7c0,0.55-0.45,1-1,1l0,0C6.45,8,6,7.55,6,7V4.5c0-0.55,0.45-1,1-1l0,0c0.55,0,1,0.45,1,1V7z" />
|
||||
<path class="bright" d="M11,16c-0.18,0-0.36-0.1-0.45-0.28c-0.12-0.25-0.02-0.55,0.22-0.67C10.87,15.01,13,13.88,13,11V6c0-0.28,0.22-0.5,0.5-0.5S14,5.72,14,6v5c0,3.52-2.66,4.89-2.78,4.95C11.15,15.98,11.08,16,11,16z" />
|
||||
<path class="bright" d="M14.5,15c-0.13,0-0.26-0.05-0.35-0.15c-0.19-0.19-0.2-0.51,0-0.7C14.17,14.12,15,13.2,15,11V8c0-0.28,0.22-0.5,0.5-0.5S16,7.72,16,8v3c0,2.68-1.1,3.81-1.15,3.85C14.76,14.95,14.63,15,14.5,15z" />
|
||||
<path class="dim" d="M9,2c1.1,0,2,0.9,2,2v6c0,2.21-1.79,4-4,4s-4-1.79-4-4V4c0-1.1,0.9-2,2-2H9 M9,1H5C3.35,1,2,2.35,2,4v6c0,2.76,2.24,5,5,5s5-2.24,5-5V4C12,2.35,10.65,1,9,1L9,1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 799 B |
6
frontend/assets/16px-two-tone/mouse-hint-lmb-drag.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path class="bright" d="M11,16c-0.18,0-0.36-0.1-0.45-0.28c-0.12-0.25-0.02-0.55,0.22-0.67C10.87,15.01,13,13.88,13,11V6c0-0.28,0.22-0.5,0.5-0.5S14,5.72,14,6v5c0,3.52-2.66,4.89-2.78,4.95C11.15,15.98,11.08,16,11,16z" />
|
||||
<path class="bright" d="M14.5,15c-0.13,0-0.26-0.05-0.35-0.15c-0.19-0.19-0.2-0.51,0-0.7C14.17,14.12,15,13.2,15,11V8c0-0.28,0.22-0.5,0.5-0.5S16,7.72,16,8v3c0,2.68-1.1,3.81-1.15,3.85C14.76,14.95,14.63,15,14.5,15z" />
|
||||
<path class="bright" d="M7,1H5C3.35,1,2,2.35,2,4v4h5V1z" />
|
||||
<path class="dim" d="M9,1H8v1h1c1.1,0,2,0.9,2,2v6c0,2.21-1.79,4-4,4s-4-1.79-4-4V9H2v1c0,2.76,2.24,5,5,5s5-2.24,5-5V4C12,2.35,10.65,1,9,1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 703 B |
4
frontend/assets/16px-two-tone/mouse-hint-lmb.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path class="bright" d="M8,1H6C4.35,1,3,2.35,3,4v4h5V1z" />
|
||||
<path class="dim" d="M10,1H9v1h1c1.1,0,2,0.9,2,2v6c0,2.21-1.79,4-4,4s-4-1.79-4-4V9H3v1c0,2.76,2.24,5,5,5s5-2.24,5-5V4C13,2.35,11.65,1,10,1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 273 B |
6
frontend/assets/16px-two-tone/mouse-hint-mmb-drag.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path class="bright" d="M8,7c0,0.55-0.45,1-1,1l0,0C6.45,8,6,7.55,6,7V4.5c0-0.55,0.45-1,1-1l0,0c0.55,0,1,0.45,1,1V7z" />
|
||||
<path class="bright" d="M11,16c-0.18,0-0.36-0.1-0.45-0.28c-0.12-0.25-0.02-0.55,0.22-0.67C10.87,15.01,13,13.88,13,11V6c0-0.28,0.22-0.5,0.5-0.5S14,5.72,14,6v5c0,3.52-2.66,4.89-2.78,4.95C11.15,15.98,11.08,16,11,16z" />
|
||||
<path class="bright" d="M14.5,15c-0.13,0-0.26-0.05-0.35-0.15c-0.19-0.19-0.2-0.51,0-0.7C14.17,14.12,15,13.2,15,11V8c0-0.28,0.22-0.5,0.5-0.5S16,7.72,16,8v3c0,2.68-1.1,3.81-1.15,3.85C14.76,14.95,14.63,15,14.5,15z" />
|
||||
<path class="dim" d="M9,2c1.1,0,2,0.9,2,2v6c0,2.21-1.79,4-4,4s-4-1.79-4-4V4c0-1.1,0.9-2,2-2H9 M9,1H5C3.35,1,2,2.35,2,4v6c0,2.76,2.24,5,5,5s5-2.24,5-5V4C12,2.35,10.65,1,9,1L9,1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 802 B |
4
frontend/assets/16px-two-tone/mouse-hint-mmb.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path class="bright" d="M9,7c0,0.55-0.45,1-1,1l0,0C7.45,8,7,7.55,7,7V4.5c0-0.55,0.45-1,1-1l0,0c0.55,0,1,0.45,1,1V7z" />
|
||||
<path class="dim" d="M10,2c1.1,0,2,0.9,2,2v6c0,2.21-1.79,4-4,4s-4-1.79-4-4V4c0-1.1,0.9-2,2-2H10 M10,1H6C4.35,1,3,2.35,3,4v6c0,2.76,2.24,5,5,5s5-2.24,5-5V4C13,2.35,11.65,1,10,1L10,1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 375 B |
4
frontend/assets/16px-two-tone/mouse-hint-none.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path class="dim" d="M9,7c0,0.55-0.45,1-1,1l0,0C7.45,8,7,7.55,7,7V4.5c0-0.55,0.45-1,1-1l0,0c0.55,0,1,0.45,1,1V7z" />
|
||||
<path class="dim" d="M10,2c1.1,0,2,0.9,2,2v6c0,2.21-1.79,4-4,4s-4-1.79-4-4V4c0-1.1,0.9-2,2-2H10 M10,1H6C4.35,1,3,2.35,3,4v6c0,2.76,2.24,5,5,5s5-2.24,5-5V4C13,2.35,11.65,1,10,1L10,1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 372 B |
6
frontend/assets/16px-two-tone/mouse-hint-rmb-drag.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path class="bright" d="M11,16c-0.18,0-0.36-0.1-0.45-0.28c-0.12-0.25-0.02-0.55,0.22-0.67C10.87,15.01,13,13.88,13,11V6c0-0.28,0.22-0.5,0.5-0.5S14,5.72,14,6v5c0,3.52-2.66,4.89-2.78,4.95C11.15,15.98,11.08,16,11,16z" />
|
||||
<path class="bright" d="M14.5,15c-0.13,0-0.26-0.05-0.35-0.15c-0.19-0.19-0.2-0.51,0-0.7C14.17,14.12,15,13.2,15,11V8c0-0.28,0.22-0.5,0.5-0.5S16,7.72,16,8v3c0,2.68-1.1,3.81-1.15,3.85C14.76,14.95,14.63,15,14.5,15z" />
|
||||
<path class="bright" d="M7,1h2c1.65,0,3,1.35,3,3v4H7V1z" />
|
||||
<path class="dim" d="M5,1h1v1H5C3.9,2,3,2.9,3,4v6c0,2.21,1.79,4,4,4s4-1.79,4-4V9h1v1c0,2.76-2.24,5-5,5s-5-2.24-5-5V4C2,2.35,3.35,1,5,1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 701 B |
4
frontend/assets/16px-two-tone/mouse-hint-rmb.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<path class="dim" d="M8,1h2c1.65,0,3,1.35,3,3v4H8V1z" />
|
||||
<path class="bright" d="M6,1h1v1H6C4.9,2,4,2.9,4,4v6c0,2.21,1.79,4,4,4s4-1.79,4-4V9h1v1c0,2.76-2.24,5-5,5s-5-2.24-5-5V4C3,2.35,4.35,1,6,1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 269 B |
5
frontend/assets/16px-two-tone/mouse-hint-scroll-down.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<polygon class="bright" points="5.5,4 8,6 10.5,4 10.5,6 8,8 5.5,6" />
|
||||
<polygon class="bright" points="5.5,0 8,2 10.5,0 10.5,2 8,4 5.5,2" />
|
||||
<path class="dim" d="M11.5,1.42v1.28C11.8,3.06,12,3.5,12,4v6c0,2.21-1.79,4-4,4s-4-1.79-4-4V4c0-0.5,0.2-0.94,0.5-1.29V1.42C3.61,1.94,3,2.9,3,4v6c0,2.76,2.24,5,5,5s5-2.24,5-5V4C13,2.9,12.39,1.94,11.5,1.42z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 418 B |
5
frontend/assets/16px-two-tone/mouse-hint-scroll-up.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||
<polygon class="bright" points="10.5,4 8,2 5.5,4 5.5,2 8,0 10.5,2" />
|
||||
<polygon class="bright" points="10.5,8 8,6 5.5,8 5.5,6 8,4 10.5,6" />
|
||||
<path class="dim" d="M11.5,1.42v1.28C11.8,3.06,12,3.5,12,4v6c0,2.21-1.79,4-4,4s-4-1.79-4-4V4c0-0.5,0.2-0.94,0.5-1.29V1.42C3.61,1.94,3,2.9,3,4v6c0,2.76,2.24,5,5,5s5-2.24,5-5V4C13,2.9,12.39,1.94,11.5,1.42z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 418 B |
4
frontend/assets/24px-full-color/node-type-path.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#FFFFFF;" d="M23.34,4.06c0.14-0.94-0.18-1.88-0.85-2.55s-1.62-0.98-2.55-0.85c-5.27,0.77-10.61,0.77-15.88,0C3.12,0.53,2.18,0.84,1.51,1.51S0.53,3.13,0.66,4.06c0.77,5.27,0.77,10.61,0,15.88c-0.14,0.94,0.18,1.88,0.85,2.55s1.62,0.98,2.55,0.85c5.27-0.77,10.61-0.77,15.88,0c0.14,0.02,0.29,0.03,0.43,0.03c0.79,0,1.55-0.31,2.12-0.88c0.67-0.67,0.98-1.62,0.85-2.55C22.57,14.67,22.57,9.33,23.34,4.06z" />
|
||||
<path style="fill:#65BBE5;" d="M19.89,9.01c-0.17,0.02-2.18,0.26-4.89,1.01V9H9v3.28c-1.6,0.79-3.2,1.75-4.64,2.95c-0.42,0.35-0.48,0.98-0.13,1.41C4.43,16.88,4.71,17,5,17c0.23,0,0.45-0.08,0.64-0.23C6.68,15.9,7.83,15.16,9,14.53V15h6v-2.9c2.88-0.84,5.07-1.1,5.11-1.11c0.55-0.06,0.94-0.56,0.88-1.11C20.93,9.34,20.43,8.95,19.89,9.01z M13,13h-2v-2h2V13z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 828 B |
8
frontend/assets/24px-two-tone/layout-crop-tool.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#FFFFFF;" d="M20,4H7v2h11v18h2V4z" />
|
||||
<path style="fill:#FFFFFF;" d="M6,18V0H4v20h13v-2H6z" />
|
||||
<rect style="fill:#FFFFFF;" x="21" y="18" width="3" height="2" />
|
||||
<rect style="fill:#FFFFFF;" x="0" y="4" width="3" height="2" />
|
||||
<path style="fill:#C5C5C5;" d="M21,5l3-3l-1-1l-2,2V5z" />
|
||||
<path style="fill:#C5C5C5;" d="M17,7L7,17h2l8-8V7z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 430 B |
4
frontend/assets/24px-two-tone/layout-eyedropper-tool.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#C5C5C5;" d="M19.78,7.76l2.49-2.49c0.96-0.96,0.98-2.52,0.04-3.5l0,0c-0.97-1.01-2.58-1.03-3.57-0.04l-2.49,2.49l-1.06-1.06c-0.39-0.39-1.02-0.39-1.41,0l-1.46,1.46l7.07,7.07l1.46-1.46c0.39-0.39,0.39-1.02,0-1.41L19.78,7.76z" />
|
||||
<path style="fill:#FFFFFF;" d="M15.63,9.93L5.9,19.65c-0.12,0.08-0.59,0.15-0.9,0.2c-0.32,0.05-0.68,0.1-1.05,0.2c0.09-0.38,0.15-0.73,0.2-1.05c0.05-0.31,0.12-0.78,0.18-0.88l9.74-9.74l-0.99-0.99c0,0-8.88,8.88-9.74,9.74c-0.86,0.86-0.24,2.89-1.66,4.31l0.88,0.88c1.41-1.41,3.45-0.8,4.31-1.66s9.74-9.74,9.74-9.74L15.63,9.93z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 632 B |
5
frontend/assets/24px-two-tone/layout-navigate-tool.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#FFFFFF;" d="M23.56,21.45l-6.68-6.69C15.64,16.7,13.47,18,11,18c-3.86,0-7-3.14-7-7c0-2.56,1.39-4.8,3.45-6.02L7.36,4.94L5.25,4.08C3.26,5.73,2,8.22,2,11c0,4.97,4.03,9,9,9c1.95,0,3.74-0.63,5.21-1.68l5.23,5.24c0.58,0.59,1.53,0.59,2.12,0C24.15,22.98,24.15,22.03,23.56,21.45z" />
|
||||
<path style="fill:#C5C5C5;" d="M19.92,9.97c-0.23-2.01-1.12-3.89-2.56-5.33c-1.44-1.44-3.32-2.33-5.33-2.56l-0.2-1.48L7.89,3.65l4.61,1.89l-0.19-1.4c1.37,0.26,2.64,0.91,3.64,1.91c1,1,1.66,2.27,1.91,3.64l-1.4-0.19l1.89,4.61l3.05-3.94L19.92,9.97z" />
|
||||
<path style="fill:#FFFFFF;" d="M7.82,14.88c-0.18,0-0.36-0.07-0.5-0.21C6.34,13.69,5.8,12.39,5.8,11s0.54-2.69,1.52-3.68c0.27-0.27,0.72-0.27,0.99,0s0.27,0.72,0,0.99C7.6,9.03,7.2,9.98,7.2,11s0.4,1.97,1.11,2.69c0.27,0.27,0.27,0.72,0,0.99C8.18,14.81,8,14.88,7.82,14.88z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 875 B |
4
frontend/assets/24px-two-tone/layout-select-tool.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<polygon style="fill:#C5C5C5;" points="23,18.5 21,16.5 21,18 18,18 18,15 19.5,15 17.5,13 15.5,15 17,15 17,18 14,18 14,16.5 12,18.5 14,20.5 14,19 17,19 17,22 15.5,22 17.5,24 19.5,22 18,22 18,19 21,19 21,20.5" />
|
||||
<path style="fill:#FFFFFF;" d="M7,4.83L12.17,10H10H9.17l-0.59,0.59L7,12.17V4.83 M5,0v17l5-5h7L5,0L5,0z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 388 B |
7
frontend/assets/24px-two-tone/parametric-fill-tool.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<circle style="fill:#FFFFFF;" cx="10.57" cy="13.36" r="1.75" />
|
||||
<path style="fill:#D6536E;" d="M16.87,7.06c-1.51-1.57-3.35-2.78-5.4-3.52c0.58,2.14,1.72,4.07,3.31,5.61c1.41,1.54,3.26,2.61,5.3,3.05C19.5,10.22,18.39,8.44,16.87,7.06z" />
|
||||
<path style="fill:#FFFFFF;" d="M9.88,13.67C4.27,1.33,5.35,0.71,5.93,0.37c0.83-0.48,1.71,0.04,4.74,4.32L9.44,5.56C8.31,3.97,7.57,3.04,7.08,2.49c0.57,2.14,2.39,6.66,4.16,10.55L9.88,13.67z" />
|
||||
<path style="fill:#FFFFFF;" d="M17.32,6.6c-1.72-1.69-3.77-3.01-6.01-3.89L0,14.02c0.88,2.24,2.2,4.29,3.89,6.01c1.72,1.69,3.77,3.01,6.01,3.89l11.31-11.31h0C20.33,10.37,19.01,8.32,17.32,6.6z M9.55,22.15c-1.7-0.79-3.26-1.86-4.6-3.17c-1.31-1.35-2.38-2.9-3.17-4.61l9.08-9.08c0.87,1.65,1.98,3.16,3.29,4.49c1.33,1.31,2.84,2.42,4.49,3.29L9.55,22.15z M15.2,8.72c-1.34-1.37-2.46-2.95-3.3-4.67c1.74,0.81,3.34,1.92,4.72,3.26c1.34,1.38,2.45,2.97,3.26,4.71C18.15,11.18,16.57,10.07,15.2,8.72z" />
|
||||
<path style="fill:#D6536E;" d="M23.32,17.36c-0.64-1.77-1.39-3.49-2.27-5.16c-0.47-0.44-1.41-0.63-1.71-1.23c-0.45-0.51-1.71-0.4-0.79,0.32c1.39,1.07,1.7,1.14,1.62,2.35c-0.26,1.3-0.78,2.53-1.53,3.62c-4.05,6.65,1.99,6.65,1.99,6.65S25.75,23.92,23.32,17.36z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<rect x="2.5" y="4.5" style="fill:#D6536E;" width="19" height="15" />
|
||||
<path style="fill:#FFFFFF;" d="M20.5,4h-17C2.67,4,2,4.67,2,5.5v13C2,19.33,2.67,20,3.5,20h17c0.83,0,1.5-0.67,1.5-1.5v-13C22,4.67,21.33,4,20.5,4z M5.12,14.73C5.4,15.44,6.05,15.93,6.8,16c-0.75,0.07-1.4,0.56-1.68,1.27h0c-0.19-0.55-0.58-1-1.1-1.27C4.54,15.74,4.93,15.28,5.12,14.73z M4.02,12c0.52-0.26,0.91-0.72,1.1-1.27C5.4,11.44,6.05,11.93,6.8,12c-0.75,0.07-1.4,0.56-1.68,1.27h0C4.93,12.72,4.54,12.26,4.02,12z M5.12,9.27L5.12,9.27c-0.19-0.55-0.59-1-1.1-1.27c0.52-0.26,0.91-0.72,1.1-1.27C5.4,7.44,6.05,7.93,6.8,8C6.05,8.07,5.4,8.56,5.12,9.27z M21,18.5c0,0.28-0.22,0.5-0.5,0.5h-1.45c0.53-0.03,0.96-0.46,0.96-1c0-0.56-0.45-1.01-1.01-1.01s-1.01,0.45-1.01,1.01c0,0.54,0.43,0.97,0.96,1h-2.94c0.25-0.26,0.41-0.61,0.41-1c0-0.79-0.64-1.42-1.42-1.42s-1.42,0.64-1.42,1.42c0,0.39,0.16,0.74,0.41,1h-1.55c0.2-0.28,0.32-0.63,0.32-1c0-0.97-0.78-1.75-1.75-1.75S9.25,17.03,9.25,18c0,0.37,0.12,0.72,0.32,1H8.73c0.21-0.35,0.32-0.76,0.28-1.19C8.92,16.85,8.16,16.09,7.2,16c1.1-0.1,1.91-1.09,1.81-2.19C8.92,12.85,8.16,12.09,7.2,12c1.1-0.1,1.91-1.09,1.81-2.19C8.92,8.85,8.16,8.09,7.2,8c1.1-0.1,1.91-1.09,1.81-2.19C8.98,5.51,8.88,5.24,8.74,5h0.83c-0.2,0.28-0.32,0.63-0.32,1c0,0.97,0.78,1.75,1.75,1.75c0.97,0,1.75-0.78,1.75-1.75c0-0.37-0.12-0.72-0.32-1h1.55c-0.25,0.26-0.41,0.61-0.41,1c0,0.79,0.64,1.42,1.42,1.42S16.42,6.79,16.42,6c0-0.39-0.16-0.74-0.41-1h2.94c-0.53,0.03-0.96,0.46-0.96,1c0,0.56,0.45,1.01,1.01,1.01S20.01,6.56,20.01,6c0-0.54-0.43-0.97-0.96-1h1.45C20.78,5,21,5.22,21,5.5V18.5z M16.42,14c0,0.79-0.64,1.42-1.42,1.42s-1.42-0.64-1.42-1.42c0-0.79,0.64-1.42,1.42-1.42S16.42,13.21,16.42,14z M20.01,14c0,0.56-0.45,1.01-1.01,1.01s-1.01-0.45-1.01-1.01s0.45-1.01,1.01-1.01S20.01,13.44,20.01,14z M20.01,10c0,0.56-0.45,1.01-1.01,1.01s-1.01-0.45-1.01-1.01S18.44,8.99,19,8.99S20.01,9.44,20.01,10z M16.42,10c0,0.79-0.64,1.42-1.42,1.42s-1.42-0.64-1.42-1.42c0-0.79,0.64-1.42,1.42-1.42S16.42,9.21,16.42,10z M12.75,10c0,0.97-0.78,1.75-1.75,1.75c-0.97,0-1.75-0.78-1.75-1.75c0-0.97,0.78-1.75,1.75-1.75S12.75,9.03,12.75,10z M12.75,14c0,0.97-0.78,1.75-1.75,1.75c-0.97,0-1.75-0.78-1.75-1.75c0-0.97,0.78-1.75,1.75-1.75S12.75,13.03,12.75,14z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
5
frontend/assets/24px-two-tone/parametric-text-tool.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#FFFFFF;" d="M4,3v5h1c0,0,0-3,4-3h2v13.5c0,1.1,0,2-3,2V22h9v-1.5c-3,0-3-0.9-3-2V5h2c4,0,4,3,4,3h1V3H4z" />
|
||||
<path style="fill:#D6536E;" d="M5,20H1v2h5v-1C6,20.45,5.55,20,5,20z" />
|
||||
<path style="fill:#D6536E;" d="M20,20c-0.55,0-1,0.45-1,1v1h5v-2H20z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 340 B |
4
frontend/assets/24px-two-tone/raster-brush-tool.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#E4BB72;" d="M12.96,17.06c-0.18-1.51-1.66-3.27-4-3.14c-1.68,0.1-3.12,1.49-4.04,4.2c-0.95,2.78-3.62,4-3.62,4 c2.86,0.97,5.92,1.31,8.61,0.11C12.32,21.15,13.19,19,12.96,17.06z" />
|
||||
<path style="fill:#FFFFFF;" d="M22.49,1.1C21.54,0.35,18,3.81,14.1,8.17c-1.38,1.54-2.74,3.16-3.57,4.59c0.62,0.07,1.3,0.31,1.92,0.77c0.78,0.59,1.23,1.29,1.42,1.9c1.29-1.18,2.4-2.69,3.68-4.53C20.94,6.02,23.45,1.86,22.49,1.1z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 491 B |
4
frontend/assets/24px-two-tone/raster-clone-tool.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<rect x="4" y="20" style="fill:#E4BB72;" width="16" height="2" />
|
||||
<path style="fill:#FFFFFF;" d="M19.01,15.52c-1.29-0.33-2.51-0.57-3.93-0.93c-0.62-0.15-1.51-0.55-1.58-1.59v-2.7c0.12-0.4,0.42-0.7,0.56-0.83C15.22,8.71,16,7.45,16,6c0-2.21-1.79-4-4-4S8,3.79,8,6c0,1.4,0.72,2.63,1.81,3.34l-0.01,0c0,0,0.69,0.52,0.69,1.22V13c-0.06,1.04-0.95,1.43-1.58,1.59c-1.42,0.35-2.64,0.6-3.93,0.93C3.94,15.78,3,16.36,3,17v2h18v-2C21,16.36,20.06,15.78,19.01,15.52z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 520 B |
5
frontend/assets/24px-two-tone/raster-detail-tool.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#E4BB72;" d="M19.47,14.93c0.06,0.95-0.01,1.86-0.21,2.7l1.48,2.97h-3c-0.48,0.55-1.06,1.02-1.72,1.4H23L19.47,14.93z" />
|
||||
<path style="fill:#E4BB72;" d="M6.27,20.6h-3l1.48-2.97c-0.21-0.84-0.27-1.75-0.21-2.7L1,22h6.99C7.33,21.62,6.75,21.15,6.27,20.6z" />
|
||||
<path style="fill:#FFFFFF;" d="M16.4,9.91C14.53,6.79,13,3.97,12,2.07c-1,1.9-2.53,4.72-4.4,7.84c-1.88,3.15-2.23,6.57-0.89,8.92C7.72,20.62,9.6,21.6,12,21.6s4.28-0.98,5.29-2.77C18.62,16.48,18.28,13.06,16.4,9.91z M9.4,11.5c0.6,6.5,3.6,8,3.6,8C5,20,9.4,11.5,9.4,11.5z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 606 B |
5
frontend/assets/24px-two-tone/raster-heal-tool.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#FFFFFF;" d="M12,6l-6,6l6,6l6-6L12,6z M9,13c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1s1,0.45,1,1C10,12.55,9.55,13,9,13z M12,16c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1s1,0.45,1,1C13,15.55,12.55,16,12,16z M12,13c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1s1,0.45,1,1C13,12.55,12.55,13,12,13z M12,10c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1s1,0.45,1,1C13,9.55,12.55,10,12,10z M15,13c-0.55,0-1-0.45-1-1c0-0.55,0.45-1,1-1s1,0.45,1,1C16,12.55,15.55,13,15,13z" />
|
||||
<path style="fill:#E4BB72;" d="M1,17c0,0-1,3,1,5s5,1,5,1l4-4l-6-6L1,17z" />
|
||||
<path style="fill:#E4BB72;" d="M22,2c-2-2-5-1-5-1l-4,4l6,6l4-4C23,7,24,4,22,2z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 686 B |
12
frontend/assets/24px-two-tone/raster-patch-tool.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#E4BB72;" d="M22.45,8.23l-3.38,1.23c-0.36,0.13-0.55,0.54-0.42,0.9c0.1,0.28,0.37,0.46,0.66,0.4
|
||||
c0.08,0,0.16-0.01,0.24-0.04l3.38-1.23c0.36-0.13,0.55-0.54,0.42-0.9c-0.1-0.28-0.37-0.46-0.66-0.46C22.61,8.18,22.53,8.2,22.45,8.23z" />
|
||||
<path style="fill:#E4BB72;" d="M19.55,16.77l3.38-1.23c0.36-0.13,0.55-0.54,0.42-0.9c-0.1-0.28-0.37-0.46-0.66-0.46c-0.08,0-0.16,0.01-0.24,0.04l-3.38,1.23c-0.36,0.13-0.55,0.54-0.42,0.9c0.1,0.28,0.37,0.46,0.66,0.46C19.39,16.82,19.47,16.8,19.55,16.77z" />
|
||||
<path style="fill:#E4BB72;" d="M15.77,21.45l-1.23-3.38c-0.1-0.28-0.37-0.46-0.66-0.46c-0.08,0-0.16,0.01-0.24,0.04c-0.36,0.13-0.55,0.54-0.42,0.9l1.23,3.38c0.1,0.28,0.37,0.46,0.66,0.46c0.08,0,0.16-0.01,0.24-0.04C15.72,22.22,15.91,21.81,15.77,21.45z" />
|
||||
<path style="fill:#E4BB72;" d="M14.64,1.65c-0.36,0.13-0.55,0.54-0.42,0.9l1.23,3.38c0.1,0.28,0.37,0.46,0.66,0.46c0.08,0,0.16-0.01,0.24-0.04c0.36-0.13,0.55-0.54,0.42-0.9l-1.23-3.38c-0.1-0.28-0.37-0.46-0.66-0.46C14.8,1.61,14.72,1.62,14.64,1.65z" />
|
||||
<path style="fill:#E4BB72;" d="M9.77,21.45l-1.23-3.38c-0.1-0.28-0.37-0.46-0.66-0.46c-0.08,0-0.16,0.01-0.24,0.04c-0.36,0.13-0.55,0.54-0.42,0.9l1.23,3.38c0.1,0.28,0.37,0.46,0.66,0.46c0.08,0,0.16-0.01,0.24-0.04C9.72,22.22,9.91,21.81,9.77,21.45z" />
|
||||
<path style="fill:#E4BB72;" d="M1.55,15.77l3.38-1.23c0.36-0.13,0.55-0.54,0.42-0.9c-0.1-0.28-0.37-0.46-0.66-0.46c-0.08,0-0.16,0.01-0.24,0.04l-3.38,1.23c-0.36,0.13-0.55,0.54-0.42,0.9c0.1,0.28,0.37,0.46,0.66,0.46C1.39,15.82,1.47,15.8,1.55,15.77z" />
|
||||
<path style="fill:#E4BB72;" d="M8.64,1.65c-0.36,0.13-0.55,0.54-0.42,0.9l1.23,3.38c0.1,0.28,0.37,0.46,0.66,0.46c0.08,0,0.16-0.01,0.24-0.04c0.36-0.13,0.55-0.54,0.42-0.9L9.54,2.07c-0.1-0.28-0.37-0.46-0.66-0.46C8.8,1.61,8.72,1.62,8.64,1.65z" />
|
||||
<path style="fill:#E4BB72;" d="M4.45,7.23L1.07,8.46c-0.36,0.13-0.55,0.54-0.42,0.9c0.1,0.28,0.37,0.46,0.66,0.46c0.08,0,0.16-0.01,0.24-0.04l3.38-1.23c0.36-0.13,0.55-0.54,0.42-0.9c-0.1-0.28-0.37-0.46-0.66-0.46C4.61,7.18,4.53,7.2,4.45,7.23z" />
|
||||
<path style="fill:#FFFFFF;" d="M20.03,18.09c-0.23,0.08-0.47,0.13-0.72,0.13c-0.88,0-1.67-0.56-1.98-1.38c-0.19-0.53-0.17-1.1,0.07-1.61c0.24-0.51,0.66-0.89,1.18-1.09L21,13.27v-1.53l-0.97,0.35c-0.23,0.08-0.47,0.13-0.72,0.13c-0.88,0-1.67-0.56-1.98-1.38c-0.4-1.09,0.17-2.3,1.26-2.69L21,7.27V6c0-1.1-0.9-2-2-2h-1.27l0.35,0.97c0.4,1.09-0.17,2.3-1.26,2.69c-0.23,0.08-0.47,0.13-0.72,0.13c-0.88,0-1.67-0.56-1.98-1.38L13.27,4h-1.53l0.35,0.97c0.4,1.09-0.17,2.3-1.26,2.69c-0.23,0.08-0.47,0.13-0.72,0.13c-0.88,0-1.67-0.56-1.98-1.38L7.27,4H5C3.9,4,3,4.9,3,6v0.27l0.97-0.35C4.2,5.83,4.44,5.78,4.69,5.78c0.88,0,1.67,0.56,1.98,1.38c0.19,0.53,0.17,1.1-0.07,1.61C6.36,9.28,5.94,9.67,5.41,9.86L3,10.73v1.53l0.97-0.35c0.23-0.08,0.47-0.13,0.72-0.13c0.88,0,1.67,0.56,1.98,1.38c0.19,0.53,0.17,1.1-0.07,1.61c-0.24,0.51-0.66,0.89-1.18,1.09L3,16.73V18c0,1.1,0.9,2,2,2h1.27l-0.35-0.97c-0.4-1.09,0.17-2.3,1.26-2.69c0.23-0.08,0.47-0.13,0.72-0.13c0.88,0,1.67,0.56,1.98,1.38L10.73,20h1.53l-0.35-0.97c-0.4-1.09,0.17-2.3,1.26-2.69c0.23-0.08,0.47-0.13,0.72-0.13c0.88,0,1.67,0.56,1.98,1.38L16.73,20H19c1.1,0,2-0.9,2-2v-0.27L20.03,18.09z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
8
frontend/assets/24px-two-tone/raster-relight-tool.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#E4BB72;" d="M13,11c-1.5-1.5-3.83-2.17-4.5-1.5l-2.48,2.48c1.16,0.27,2.49,1.08,3.71,2.29 c1.26,1.26,2.04,2.56,2.29,3.71l2.48-2.48C15.17,14.83,14.5,12.5,13,11z" />
|
||||
<path style="fill:#E4BB72;" d="M22.5,1.5c-1-1-2.5-1.5-3-1l-8,8c1.33,0,4,2.67,4,4l8-8C24,4,23.5,2.5,22.5,1.5z M17.77,7.23l-1.55,1.55c-0.13,0.13-0.33,0.13-0.45,0l-0.55-0.55c-0.13-0.13-0.13-0.33,0-0.45l1.55-1.55c0.13-0.13,0.33-0.13,0.45,0l0.55,0.55C17.9,6.9,17.9,7.1,17.77,7.23z" />
|
||||
<path style="fill:#FFFFFF;" d="M8.74,15.26c-1.67-1.67-3.55-2.45-4.29-1.71c-0.73,0.73,0.04,2.61,1.71,4.29 c1.67,1.67,3.55,2.45,4.29,1.71C11.19,18.81,10.41,16.93,8.74,15.26z" />
|
||||
<path style="fill:#FFFFFF;" d="M2.5,22.25c-0.19,0-0.38-0.07-0.53-0.22c-0.29-0.29-0.29-0.77,0-1.06l2-2c0.29-0.29,0.77-0.29,1.06,0s0.29,0.77,0,1.06l-2,2C2.88,22.18,2.69,22.25,2.5,22.25z" />
|
||||
<path style="fill:#FFFFFF;" d="M7,23.75c-0.06,0-0.12-0.01-0.18-0.02c-0.4-0.1-0.65-0.51-0.55-0.91l0.5-2c0.1-0.4,0.5-0.65,0.91-0.55c0.4,0.1,0.65,0.51,0.55,0.91l-0.5,2C7.64,23.52,7.34,23.75,7,23.75z" />
|
||||
<path style="fill:#FFFFFF;" d="M1,17.75c-0.34,0-0.64-0.23-0.73-0.57c-0.1-0.4,0.14-0.81,0.55-0.91l2-0.5c0.4-0.1,0.81,0.14,0.91,0.55c0.1,0.4-0.14,0.81-0.55,0.91l-2,0.5C1.12,17.74,1.06,17.75,1,17.75z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
4
frontend/assets/24px-two-tone/vector-ellipse-tool.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#FFFFFF;" d="M12,6c4.41,0,8,2.69,8,6s-3.59,6-8,6s-8-2.69-8-6S7.59,6,12,6 M12,4C6.48,4,2,7.58,2,12s4.48,8,10,8s10-3.58,10-8S17.52,4,12,4L12,4z" />
|
||||
<ellipse style="fill:#65BBE5;" cx="12" cy="12" rx="6.5" ry="4.5" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 302 B |
6
frontend/assets/24px-two-tone/vector-freehand-tool.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#65BBE5;" d="M21.98,15.79c-0.12-0.54-0.65-0.89-1.19-0.77c-0.08,0.02-2.09,0.46-4.39,2.18c-0.77,0.57-1.4,1.09-1.99,1.57c-1.21,0.99-2.17,1.78-3.69,2.47c-0.59,0.27-1.84,0.72-3.57,0.75l-3.61,1.55C4.68,23.84,5.81,24,6.94,24c0.02,0,0.05,0,0.07,0c2.2-0.01,3.8-0.59,4.55-0.94c1.75-0.8,2.85-1.7,4.13-2.75c0.56-0.46,1.17-0.96,1.91-1.51c1.93-1.44,3.6-1.82,3.61-1.82C21.75,16.86,22.09,16.33,21.98,15.79z" />
|
||||
<path style="fill:#65BBE5;" d="M18.5,5.5c-1-1-2.5-1.5-3-1L5,15c0.39,0.24,1.23,0.1,1.59,0.38c0.36,0.28,0.3,1.06,0.63,1.4c0.33,0.33,1.11,0.28,1.4,0.63C8.9,17.77,8.76,18.61,9,19L19.5,8.5C20,8,19.5,6.5,18.5,5.5z M16.5,7.5l-7,7c-0.14,0.14-0.32,0.21-0.5,0.21s-0.36-0.07-0.5-0.21c-0.28-0.28-0.28-0.72,0-1l7-7c0.28-0.28,0.72-0.28,1,0C16.78,6.78,16.78,7.22,16.5,7.5z" />
|
||||
<path style="fill:#FFFFFF;" d="M7.35,18.47l-2.39,1.71c-0.1-0.27-0.22-0.51-0.42-0.71c-0.2-0.2-0.44-0.32-0.71-0.42l1.71-2.39C5.14,16.61,4.5,16.42,4,16l-3,7l7-3C7.58,19.5,7.39,18.86,7.35,18.47z" />
|
||||
<path style="fill:#FFFFFF;" d="M21.99,2.01C21,1,19.5,0.5,19,1l-2,2c2,0,4,2,4,4l2-2C23.5,4.5,22.98,3.02,21.99,2.01z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
4
frontend/assets/24px-two-tone/vector-line-tool.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#65BBE5;" d="M5.83,21.71h1.66c0.75,0,1.47-0.3,2-0.83l11.4-11.4c0.53-0.53,0.83-1.25,0.83-2V5.83L5.83,21.71z" />
|
||||
<polygon style="fill:#FFFFFF;" points="20.29,2.29 2.29,20.29 3.71,21.71 21.71,3.71" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 286 B |
4
frontend/assets/24px-two-tone/vector-path-tool.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<polygon style="fill:#FFFFFF;" points="5,0 5,17 10,12 17,12" />
|
||||
<path style="fill:#65BBE5;" d="M20.77,14.36c-0.35-0.42-0.98-0.48-1.41-0.13c-1.04,0.87-2.19,1.6-3.36,2.24V16h-6v2.9c-2.88,0.84-5.07,1.1-5.11,1.11c-0.55,0.06-0.94,0.56-0.88,1.11C4.06,21.62,4.5,22,5,22c0.04,0,0.07,0,0.11-0.01c0.17-0.02,2.18-0.26,4.89-1.01V22h6v-3.28c1.6-0.79,3.2-1.75,4.64-2.95C21.06,15.42,21.12,14.78,20.77,14.36z M14,20h-2v-2h2V20z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 486 B |
4
frontend/assets/24px-two-tone/vector-pen-tool.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#65BBE5;" d="M22.47,4.86C21.91,3.14,19.23,1.15,17.26,1c-3.4,0.35-6.56,2.34-6.32,4.93c0.14-0.29,0.31-0.57,0.53-0.84c0.17-0.21,0.39-0.37,0.63-0.46c0.61-0.23,1.23-0.35,1.86-0.35c1.61,0,3.22,0.8,4.43,2.2c1.07,1.24,1.62,2.72,1.45,3.87c-0.04,0.26-0.14,0.5-0.3,0.7c-0.3,0.38-0.68,0.68-1.11,0.91C22.67,12.01,22.59,6.63,22.47,4.86z" />
|
||||
<path style="fill:#FFFFFF;" d="M12.63,6.03c-3.51,2.79-7.69,5.59-7.81,6.45C4.48,15,1,21,1,22l6.49-7.21c-0.21-0.55-0.08-1.24,0.38-1.77c0.63-0.73,1.65-0.88,2.28-0.34c0.63,0.54,0.62,1.58-0.02,2.3c-0.41,0.47-0.98,0.7-1.51,0.65L2,23c1,0,7.12-4.65,10.48-4.78c0.33-0.01,3.71-4.64,5.87-8.09C18.59,8.47,15.81,4.74,12.63,6.03z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 735 B |
4
frontend/assets/24px-two-tone/vector-rectangle-tool.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#FFFFFF;" d="M20,6v12H4V6H20 M22,4H2v16h20V4L22,4z" />
|
||||
<rect x="5.5" y="7.5" style="fill:#65BBE5;" width="13" height="9" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 212 B |
4
frontend/assets/24px-two-tone/vector-shape-tool.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#FFFFFF;" d="M12,4.47l7.65,5.55L16.73,19H7.27l-2.92-8.98L12,4.47 M12,2L2,9.26L5.82,21h12.36L22,9.26L12,2L12,2z" />
|
||||
<polygon style="fill:#65BBE5;" points="12,6.32 6.12,10.6 8.36,17.5 15.64,17.5 17.88,10.6" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 296 B |
7
frontend/assets/24px-two-tone/vector-spline-tool.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path style="fill:#FFFFFF;" d="M12.94,5.12c1.37-0.78,3.61-1.54,7.22-2.13l-0.32-1.97c-3.88,0.63-6.69,1.54-8.5,2.76C12.01,4.05,12.56,4.52,12.94,5.12z" />
|
||||
<path style="fill:#FFFFFF;" d="M11.06,18.88c-1.37,0.78-3.61,1.54-7.22,2.13l0.32,1.97c3.88-0.63,6.69-1.54,8.5-2.76C12,19.95,11.44,19.48,11.06,18.88z" />
|
||||
<path style="fill:#FFFFFF;" d="M11.8,9.99c-0.53,0.32-1.14,0.51-1.8,0.51c-0.08,0-0.16-0.02-0.24-0.02c0.42,0.74,0.94,1.45,1.44,2.12c0.36,0.48,0.7,0.95,1,1.41c0.53-0.32,1.14-0.51,1.8-0.51c0.08,0,0.16,0.02,0.24,0.02c-0.42-0.74-0.94-1.45-1.44-2.12C12.44,10.92,12.1,10.45,11.8,9.99z" />
|
||||
<circle style="fill:#65BBE5;" cx="14" cy="17" r="2" />
|
||||
<circle style="fill:#65BBE5;" cx="10" cy="7" r="2" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 767 B |
12954
frontend/package-lock.json
generated
Normal file
57
frontend/package.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "graphite-web-frontend",
|
||||
"version": "0.1.0",
|
||||
"description": "Graphite's web app frontend. Planned to be replaced by a Rust native GUI framework in the future.",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve || npm install && vue-cli-service serve",
|
||||
"build": "vue-cli-service build || npm install && vue-cli-service build",
|
||||
"lint": "vue-cli-service lint || (npm install && vue-cli-service lint)",
|
||||
"lint-no-fix": "vue-cli-service lint --no-fix || (echo 'Please run `npm run lint`. If the linter execution fails, try running `npm install` first.' && false)"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/graphiteeditor/graphite.git"
|
||||
},
|
||||
"author": "Graphite Authors <contact@graphite.design>",
|
||||
"license": "Apache-2.0",
|
||||
"homepage": "https://www.graphite.design",
|
||||
"dependencies": {
|
||||
"vue": "~3.0.11",
|
||||
"vue-class-component": "^8.0.0-0",
|
||||
"vue-loader": "~16.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^2.33.0",
|
||||
"@typescript-eslint/parser": "^2.33.0",
|
||||
"@vue/cli-plugin-eslint": "^4.5.13",
|
||||
"@vue/cli-plugin-typescript": "^4.5.13",
|
||||
"@vue/cli-service": "^4.5.13",
|
||||
"@vue/compiler-sfc": "~3.0.11",
|
||||
"@vue/eslint-config-airbnb": "^5.0.2",
|
||||
"@vue/eslint-config-typescript": "^5.0.2",
|
||||
"@wasm-tool/wasm-pack-plugin": "github:wasm-tool/wasm-pack-plugin",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-import": "^2.23.4",
|
||||
"eslint-plugin-prettier-vue": "^3.1.0",
|
||||
"eslint-plugin-vue": "^7.12.1",
|
||||
"lint-staged": "^9.5.0",
|
||||
"prettier": "^2.3.2",
|
||||
"sass": "^1.35.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"typescript": "^4.3.5",
|
||||
"vue-svg-loader": "^0.17.0-beta.2",
|
||||
"vue-template-compiler": "~2.6.12",
|
||||
"wasm-pack": "~0.9.1"
|
||||
},
|
||||
"gitHooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,js,json,vue}": [
|
||||
"vue-cli-service lint",
|
||||
"git add"
|
||||
]
|
||||
}
|
||||
}
|
||||
BIN
frontend/public/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
frontend/public/android-chrome-384x384.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
frontend/public/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
9
frontend/public/browserconfig.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<TileColor>#f1decd</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
BIN
frontend/public/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
frontend/public/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
frontend/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
24
frontend/public/index.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<link rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700;1,900&family=Inconsolata:wght@400;700">
|
||||
<title>Graphite</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>JavaScript is required</noscript>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
BIN
frontend/public/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
92
frontend/public/safari-pinned-tab.svg
Normal file
@@ -0,0 +1,92 @@
|
||||
<svg version="1.1" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||
<g>
|
||||
<g id="Background_3_">
|
||||
<g>
|
||||
<path style="fill:#473A3A;" d="M3.72,23.41c-0.84,0.02-1.76-0.28-1.75-0.42c0.01-0.09,0.51-0.24,0.93-0.34
|
||||
c0.42-0.11,1.65-0.38,2.59-0.49c0.94-0.11,3.09-0.28,6.44-0.37c1.31-0.03,2.78-0.04,2.78-0.04c0.94,0,1.6,0,2.93,0.03
|
||||
c1.1,0.02,1.66,0.04,1.87,0.06c1.11,0.13,1.9,0.55,2.53,0.72c0.63,0.17,0.93,0.24,0.93,0.24c-0.28,0.23-1.44,0.58-2.28,0.76
|
||||
c-0.84,0.18-1.68,0.3-2.52,0.38c-0.84,0.08-1.68,0.08-2.52,0.01c-0.84-0.07-1.69-0.17-2.53-0.21l-2.53-0.14
|
||||
C7.89,23.53,4.56,23.39,3.72,23.41z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#473A3A;" d="M21.98,8.79L17.48,1c-0.36-0.62-1.02-1-1.73-1h-9C6.04,0,5.38,0.38,5.02,1l-4.5,7.79
|
||||
c-0.36,0.62-0.36,1.38,0,2l4.5,7.79c0.36,0.62,1.02,1,1.73,1h9c0.71,0,1.37-0.38,1.73-1l4.5-7.79
|
||||
C22.34,10.18,22.34,9.41,21.98,8.79z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Inner_Region">
|
||||
<g>
|
||||
<path style="fill:#F1DECD;" d="M16,2.43C15.86,2.19,15.52,2,15.25,2l-8,0C6.97,2,6.64,2.19,6.5,2.43l-4,6.93
|
||||
c-0.14,0.24-0.14,0.63,0,0.87l4,6.93c0.14,0.24,0.48,0.43,0.75,0.43l8,0c0.28,0,0.61-0.19,0.75-0.43l4-6.93
|
||||
c0.14-0.24,0.14-0.63,0-0.87L16,2.43z"/>
|
||||
</g>
|
||||
<line style="fill:none;stroke:#473A3A;stroke-linecap:round;stroke-miterlimit:10;" x1="4.48" y1="9.66" x2="7.98" y2="15.72"/>
|
||||
</g>
|
||||
<g id="Pencil">
|
||||
<g>
|
||||
<defs>
|
||||
<path id="SVGID_1_" d="M20.88,10.27l-4.4,7.62c-0.15,0.26-0.52,0.48-0.82,0.48h-8.8c-0.3,0-0.67-0.21-0.83-0.48l-4.4-7.62
|
||||
c-0.15-0.26-0.15-0.69,0-0.95l4.4-7.62c0.15-0.26,0.52-0.48,0.83-0.48h8.8c0.3,0,0.67,0.21,0.82,0.48l4.4,7.62
|
||||
C21.03,9.58,21.03,10.01,20.88,10.27z"/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_2_">
|
||||
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
|
||||
</clipPath>
|
||||
<g style="clip-path:url(#SVGID_2_);">
|
||||
<polygon style="fill:#3EA8FF;" points="21.12,9.29 17.75,3.47 14.39,-2.36 5.27,2.91 8.64,8.73 12,14.56 "/>
|
||||
<polygon style="fill:#2180CE;" points="16.56,11.93 13.19,6.1 9.83,0.27 5.27,2.91 8.64,8.73 12,14.56 "/>
|
||||
<polygon style="display:none;opacity:0.25;fill:#FFFFFF;" points="21.12,9.29 17.75,3.47 14.39,-2.36 11.81,-0.87 15.17,4.96
|
||||
18.54,10.78 "/>
|
||||
</g>
|
||||
</g>
|
||||
<line style="fill:none;stroke:#473A3A;stroke-width:2;stroke-miterlimit:10;" x1="5.15" y1="2.7" x2="12" y2="14.56"/>
|
||||
<g>
|
||||
<polyline style="fill:#EFB56F;" points="12,14.56 22.37,22 21.12,9.29 "/>
|
||||
<polygon style="fill:#E28E33;" points="12,14.56 21.17,19.92 16.56,11.93 "/>
|
||||
|
||||
<polyline style="fill:none;stroke:#473A3A;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" points="
|
||||
12,14.56 22.37,22 21.12,9.29 "/>
|
||||
<path style="fill:#473A3A;" d="M18.8,18.63L22.37,22l-1.13-4.78c0,0-0.79-0.23-1.52,0.19C18.99,17.83,18.8,18.63,18.8,18.63z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#473A3A;" d="M15.08,13.93l1.48-2.01l2.48-0.28c0,0,0.93-1.69,2.08-2.36
|
||||
l-1-1.73c-1.15,0.67-2.08,2.36-2.08,2.36l-2.48,0.28l-1.48,2.01c0,0-1.93-0.04-3.08,0.62l1,1.73
|
||||
C13.15,13.89,15.08,13.93,15.08,13.93z"/>
|
||||
</g>
|
||||
|
||||
<line style="fill:none;stroke:#473A3A;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:10;" x1="21.12" y1="9.29" x2="16.62" y2="1.5"/>
|
||||
<g>
|
||||
<path style="fill:#473A3A;" d="M22.24,9.64c-0.02-0.29-0.11-0.59-0.26-0.85l-0.4,0.5L22.84,22c0,0,0.56,0.29,0.53-0.1
|
||||
C23.37,21.9,22.25,9.69,22.24,9.64z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Top_Shading">
|
||||
<g id="Pencil_Top_Shading">
|
||||
<defs>
|
||||
<path id="SVGID_3_" d="M20.88,10.27c0.15-0.26,0.15-0.69,0-0.95l-4.4-7.62c-0.15-0.26-0.52-0.48-0.83-0.48h-8.8
|
||||
c-0.3,0-0.67,0.21-0.83,0.48l-4.4,7.62c-0.15,0.26-0.15,0.69,0,0.95l4.4,7.62c0.15,0.26,0.52,0.48,0.83,0.48h8.8
|
||||
c0.3,0,0.67-0.21,0.83-0.48L20.88,10.27z"/>
|
||||
</defs>
|
||||
<clipPath id="SVGID_4_">
|
||||
<use xlink:href="#SVGID_3_" style="overflow:visible;"/>
|
||||
</clipPath>
|
||||
<g style="opacity:0.25;clip-path:url(#SVGID_4_);">
|
||||
<g>
|
||||
|
||||
<image style="overflow:visible;" width="19.22" height="9.91" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsSAAALEgHS3X78AAAA
|
||||
GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAKJJREFUeNpiYEAFDkD8nwLcwIRm
|
||||
YD8DhQDZwAIgNqDUQEYoLQDE96E0CPwF4kNQC/8jqYV57R8OeikLVHE9kmEgcAWIJwPxGyQDkcOK
|
||||
EYsYyNCnIEEFNInvoMAFYg0g5sCC2dEwGxJmBhm4H83AvUDsDsR85IajAzT8QIa9hkaOIsw2UgFI
|
||||
0wMgngjlPwbirUB8F4h/MVABsEIjh5FcAwACDABGnjt8y2PIxQAAAABJRU5ErkJggg==" transform="matrix(1 0 0 1 1.0297 -1)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<polygon style="fill:#F1DECD;" points="11.13,15.06 4.29,3.2 3.19,7.41 "/>
|
||||
<g>
|
||||
<path style="fill:#473A3A;" d="M3.21,8.12L6.75,2h9l3.54,6.13h2.31L17.48,1c-0.36-0.62-1.02-1-1.73-1h-9C6.04,0,5.38,0.38,5.02,1
|
||||
L0.9,8.12H3.21z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
19
frontend/public/site.webmanifest
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "",
|
||||
"short_name": "",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#f1decd",
|
||||
"background_color": "#f1decd",
|
||||
"display": "standalone"
|
||||
}
|
||||
243
frontend/src/App.vue
Normal file
@@ -0,0 +1,243 @@
|
||||
<template>
|
||||
<MainWindow />
|
||||
<div class="unsupported-modal-backdrop" v-if="showUnsupportedModal">
|
||||
<div class="unsupported-modal">
|
||||
<h2>Your browser currently doesn't support Graphite</h2>
|
||||
<p>
|
||||
Unfortunately, some features won't work properly in your browser. Please use a modern browser other than Safari, such as Firefox, Chrome, or Edge. Rest assured, Safari compatibility is
|
||||
planned.
|
||||
</p>
|
||||
<p>
|
||||
Your browser is missing support for the
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt64Array#browser_compatibility" target="_blank"><code>BigInt64Array</code></a> JavaScript
|
||||
API which is required for using the editor. You can still explore the user interface.
|
||||
</p>
|
||||
<LayoutRow> <button class="unsupported-modal-button" @click="closeModal()">I understand, let's just see the interface</button> </LayoutRow>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
:root {
|
||||
--color-0-black: #000;
|
||||
--color-0-black-rgb: 0, 0, 0;
|
||||
--color-1-nearblack: #111;
|
||||
--color-1-nearblack-rgb: 17, 17, 17;
|
||||
--color-2-mildblack: #222;
|
||||
--color-2-mildblack-rgb: 34, 34, 34;
|
||||
--color-3-darkgray: #333;
|
||||
--color-3-darkgray-rgb: 51, 51, 51;
|
||||
--color-4-dimgray: #444;
|
||||
--color-4-dimgray-rgb: 68, 68, 68;
|
||||
--color-5-dullgray: #555;
|
||||
--color-5-dullgray-rgb: 85, 85, 85;
|
||||
--color-6-lowergray: #666;
|
||||
--color-6-lowergray-rgb: 102, 102, 102;
|
||||
--color-7-middlegray: #777;
|
||||
--color-7-middlegray-rgb: 109, 109, 109;
|
||||
--color-8-uppergray: #888;
|
||||
--color-8-uppergray-rgb: 136, 136, 136;
|
||||
--color-9-palegray: #999;
|
||||
--color-9-palegray-rgb: 153, 153, 153;
|
||||
--color-a-softgray: #aaa;
|
||||
--color-a-softgray-rgb: 170, 170, 170;
|
||||
--color-b-lightgray: #bbb;
|
||||
--color-b-lightgray-rgb: 187, 187, 187;
|
||||
--color-c-brightgray: #ccc;
|
||||
--color-c-brightgray-rgb: 204, 204, 204;
|
||||
--color-d-mildwhite: #ddd;
|
||||
--color-d-mildwhite-rgb: 221, 221, 221;
|
||||
--color-e-nearwhite: #eee;
|
||||
--color-e-nearwhite-rgb: 238, 238, 238;
|
||||
--color-f-white: #fff;
|
||||
--color-f-white-rgb: 255, 255, 255;
|
||||
--color-accent: #3194d6;
|
||||
--color-accent-rgb: 49, 148, 214;
|
||||
--color-accent-hover: #49a5e2;
|
||||
--color-accent-hover-rgb: 73, 165, 226;
|
||||
--color-accent-disabled: #416277;
|
||||
--color-accent-disabled-rgb: 65, 98, 119;
|
||||
|
||||
// TODO: Replace with CSS color() function to calculate alpha when browsers support it
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color() and https://caniuse.com/css-color-function
|
||||
// F2 = 95% alpha
|
||||
--floating-menu-opacity-color-2-mildblack: #222222f2;
|
||||
--floating-menu-shadow: rgba(0, 0, 0, 50%);
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
background: var(--color-2-mildblack);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
body,
|
||||
input,
|
||||
textarea,
|
||||
button {
|
||||
font-family: "Source Sans Pro", Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
color: var(--color-e-nearwhite);
|
||||
}
|
||||
|
||||
svg,
|
||||
img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.scrollable,
|
||||
.scrollable-x,
|
||||
.scrollable-y {
|
||||
// Standard
|
||||
scrollbar-width: thin;
|
||||
scrollbar-width: 6px;
|
||||
scrollbar-gutter: 6px;
|
||||
scrollbar-color: var(--color-5-dullgray) transparent;
|
||||
|
||||
&:not(:hover) {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
// WebKit
|
||||
&::-webkit-scrollbar {
|
||||
width: calc(2px + 6px + 2px);
|
||||
}
|
||||
|
||||
&:not(:hover)::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: inset 0 0 0 1px var(--color-5-dullgray);
|
||||
border: 2px solid transparent;
|
||||
border-radius: 10px;
|
||||
|
||||
&:hover {
|
||||
box-shadow: inset 0 0 0 1px var(--color-6-lowergray);
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background-clip: padding-box;
|
||||
background-color: var(--color-5-dullgray);
|
||||
border: 2px solid transparent;
|
||||
border-radius: 10px;
|
||||
margin: 2px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-6-lowergray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
// Standard
|
||||
overflow: auto;
|
||||
// WebKit
|
||||
overflow: overlay;
|
||||
}
|
||||
|
||||
.scrollable-x {
|
||||
// Standard
|
||||
overflow-x: auto;
|
||||
// WebKit
|
||||
overflow-x: overlay;
|
||||
}
|
||||
|
||||
.scrollable-y {
|
||||
// Standard
|
||||
overflow-y: auto;
|
||||
// WebKit
|
||||
overflow-y: overlay;
|
||||
}
|
||||
|
||||
// For placeholder messages (remove eventually)
|
||||
.floating-menu {
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.unsupported-modal-backdrop {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
}
|
||||
.unsupported-modal {
|
||||
background: var(--color-3-darkgray);
|
||||
border-radius: 4px;
|
||||
box-shadow: 2px 2px 5px 0 var(--floating-menu-shadow);
|
||||
padding: 0 16px 16px 16px;
|
||||
border: 1px solid var(--color-4-dimgray);
|
||||
max-width: 500px;
|
||||
|
||||
& a {
|
||||
color: var(--color-accent-hover);
|
||||
}
|
||||
}
|
||||
.unsupported-modal-button {
|
||||
flex: 1;
|
||||
background: var(--color-1-nearblack);
|
||||
border: 0 none;
|
||||
padding: 12px;
|
||||
border-radius: 2px;
|
||||
|
||||
&:hover {
|
||||
background: var(--color-6-lowergray);
|
||||
color: var(--color-f-white);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: var(--color-accent-hover);
|
||||
color: var(--color-f-white);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
import dialog from "@/utilities/dialog";
|
||||
import documents from "@/utilities/documents";
|
||||
import fullscreen from "@/utilities/fullscreen";
|
||||
import MainWindow from "@/components/window/MainWindow.vue";
|
||||
import LayoutRow from "@/components/layout/LayoutRow.vue";
|
||||
|
||||
export default defineComponent({
|
||||
provide: {
|
||||
dialog,
|
||||
documents,
|
||||
fullscreen,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showUnsupportedModal: !("BigInt64Array" in window),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
closeModal() {
|
||||
this.showUnsupportedModal = false;
|
||||
},
|
||||
},
|
||||
components: { MainWindow, LayoutRow },
|
||||
});
|
||||
</script>
|
||||
23
frontend/src/components/layout/LayoutCol.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div :class="['layout-col']">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.layout-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
export default defineComponent({});
|
||||
</script>
|
||||
23
frontend/src/components/layout/LayoutRow.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div :class="['layout-row']">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.layout-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
export default defineComponent({});
|
||||
</script>
|
||||
393
frontend/src/components/panels/Document.vue
Normal file
@@ -0,0 +1,393 @@
|
||||
<template>
|
||||
<LayoutCol :class="'document'">
|
||||
<LayoutRow :class="'options-bar'">
|
||||
<div class="left side">
|
||||
<DropdownInput :menuEntries="documentModeEntries" v-model:selectedIndex="documentModeSelectionIndex" :drawIcon="true" />
|
||||
|
||||
<Separator :type="SeparatorType.Section" />
|
||||
|
||||
<ToolOptions :activeTool="activeTool" />
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<div class="right side">
|
||||
<OptionalInput v-model:checked="snappingEnabled" @update:checked="comingSoon(200)" :icon="'Snapping'" title="Snapping" />
|
||||
<PopoverButton>
|
||||
<h3>Snapping</h3>
|
||||
<p>More snapping options will be here</p>
|
||||
</PopoverButton>
|
||||
|
||||
<Separator :type="SeparatorType.Unrelated" />
|
||||
|
||||
<OptionalInput v-model:checked="gridEnabled" @update:checked="comingSoon(318)" :icon="'Grid'" title="Grid" />
|
||||
<PopoverButton>
|
||||
<h3>Grid</h3>
|
||||
<p>More grid options will be here</p>
|
||||
</PopoverButton>
|
||||
|
||||
<Separator :type="SeparatorType.Unrelated" />
|
||||
|
||||
<OptionalInput v-model:checked="overlaysEnabled" @update:checked="comingSoon(99)" :icon="'Overlays'" title="Overlays" />
|
||||
<PopoverButton>
|
||||
<h3>Overlays</h3>
|
||||
<p>More overlays options will be here</p>
|
||||
</PopoverButton>
|
||||
|
||||
<Separator :type="SeparatorType.Unrelated" />
|
||||
|
||||
<RadioInput :entries="viewModeEntries" v-model:selectedIndex="viewModeIndex" />
|
||||
<PopoverButton>
|
||||
<h3>View Mode</h3>
|
||||
<p>More view mode options will be here</p>
|
||||
</PopoverButton>
|
||||
|
||||
<Separator :type="SeparatorType.Section" />
|
||||
|
||||
<NumberInput @update:value="setRotation" v-model:value="documentRotation" :step="15" :unit="`°`" ref="rotation" />
|
||||
|
||||
<Separator :type="SeparatorType.Section" />
|
||||
|
||||
<IconButton :action="() => this.$refs.zoom.onIncrement(IncrementDirection.Increase)" :icon="'ZoomIn'" :size="24" title="Zoom In" />
|
||||
<IconButton :action="() => this.$refs.zoom.onIncrement(IncrementDirection.Decrease)" :icon="'ZoomOut'" :size="24" title="Zoom Out" />
|
||||
<IconButton :action="() => this.$refs.zoom.updateValue(100)" :icon="'ZoomReset'" :size="24" title="Zoom to 100%" />
|
||||
|
||||
<Separator :type="SeparatorType.Related" />
|
||||
|
||||
<NumberInput
|
||||
v-model:value="documentZoom"
|
||||
@update:value="setZoom"
|
||||
:min="0.000001"
|
||||
:max="1000000"
|
||||
:step="1.25"
|
||||
:stepIsMultiplier="true"
|
||||
:unit="`%`"
|
||||
:displayDecimalPlaces="4"
|
||||
ref="zoom"
|
||||
/>
|
||||
</div>
|
||||
</LayoutRow>
|
||||
<LayoutRow :class="'shelf-and-viewport'">
|
||||
<LayoutCol :class="'shelf'">
|
||||
<div class="tools">
|
||||
<ShelfItemInput icon="LayoutSelectTool" title="Select Tool (V)" :active="activeTool === 'Select'" :action="() => selectTool('Select')" />
|
||||
<ShelfItemInput icon="LayoutCropTool" title="Crop Tool" :active="activeTool === 'Crop'" :action="() => comingSoon(289) && selectTool('Crop')" />
|
||||
<ShelfItemInput icon="LayoutNavigateTool" title="Navigate Tool (Z)" :active="activeTool === 'Navigate'" :action="() => comingSoon(155) && selectTool('Navigate')" />
|
||||
<ShelfItemInput icon="LayoutEyedropperTool" title="Eyedropper Tool (I)" :active="activeTool === 'Eyedropper'" :action="() => selectTool('Eyedropper')" />
|
||||
|
||||
<Separator :type="SeparatorType.Section" :direction="SeparatorDirection.Vertical" />
|
||||
|
||||
<ShelfItemInput icon="ParametricTextTool" title="Text Tool (T)" :active="activeTool === 'Text'" :action="() => comingSoon(153) && selectTool('Text')" />
|
||||
<ShelfItemInput icon="ParametricFillTool" title="Fill Tool (F)" :active="activeTool === 'Fill'" :action="() => selectTool('Fill')" />
|
||||
<ShelfItemInput icon="ParametricGradientTool" title="Gradient Tool (H)" :active="activeTool === 'Gradient'" :action="() => comingSoon() && selectTool('Gradient')" />
|
||||
|
||||
<Separator :type="SeparatorType.Section" :direction="SeparatorDirection.Vertical" />
|
||||
|
||||
<ShelfItemInput icon="RasterBrushTool" title="Brush Tool (B)" :active="activeTool === 'Brush'" :action="() => comingSoon() && selectTool('Brush')" />
|
||||
<ShelfItemInput icon="RasterHealTool" title="Heal Tool (J)" :active="activeTool === 'Heal'" :action="() => comingSoon() && selectTool('Heal')" />
|
||||
<ShelfItemInput icon="RasterCloneTool" title="Clone Tool (C)" :active="activeTool === 'Clone'" :action="() => comingSoon() && selectTool('Clone')" />
|
||||
<ShelfItemInput icon="RasterPatchTool" title="Patch Tool" :active="activeTool === 'Patch'" :action="() => comingSoon() && selectTool('Patch')" />
|
||||
<ShelfItemInput icon="RasterBlurSharpenTool" title="Detail Tool (D)" :active="activeTool === 'BlurSharpen'" :action="() => comingSoon() && selectTool('BlurSharpen')" />
|
||||
<ShelfItemInput icon="RasterRelightTool" title="Relight Tool (O)" :active="activeTool === 'Relight'" :action="() => comingSoon() && selectTool('Relight')" />
|
||||
|
||||
<Separator :type="SeparatorType.Section" :direction="SeparatorDirection.Vertical" />
|
||||
|
||||
<ShelfItemInput icon="VectorPathTool" title="Path Tool (A)" :active="activeTool === 'Path'" :action="() => comingSoon(82) && selectTool('Path')" />
|
||||
<ShelfItemInput icon="VectorPenTool" title="Pen Tool (P)" :active="activeTool === 'Pen'" :action="() => selectTool('Pen')" />
|
||||
<ShelfItemInput icon="VectorFreehandTool" title="Freehand Tool (N)" :active="activeTool === 'Freehand'" :action="() => comingSoon() && selectTool('Freehand')" />
|
||||
<ShelfItemInput icon="VectorSplineTool" title="Spline Tool" :active="activeTool === 'Spline'" :action="() => comingSoon() && selectTool('Spline')" />
|
||||
<ShelfItemInput icon="VectorLineTool" title="Line Tool (L)" :active="activeTool === 'Line'" :action="() => selectTool('Line')" />
|
||||
<ShelfItemInput icon="VectorRectangleTool" title="Rectangle Tool (M)" :active="activeTool === 'Rectangle'" :action="() => selectTool('Rectangle')" />
|
||||
<ShelfItemInput icon="VectorEllipseTool" title="Ellipse Tool (E)" :active="activeTool === 'Ellipse'" :action="() => selectTool('Ellipse')" />
|
||||
<ShelfItemInput icon="VectorShapeTool" title="Shape Tool (Y)" :active="activeTool === 'Shape'" :action="() => selectTool('Shape')" />
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<div class="working-colors">
|
||||
<SwatchPairInput />
|
||||
<div class="swap-and-reset">
|
||||
<IconButton :action="swapWorkingColors" :icon="'Swap'" title="Swap (Shift+X)" :size="16" />
|
||||
<IconButton :action="resetWorkingColors" :icon="'ResetColors'" title="Reset (Ctrl+Shift+X)" :size="16" />
|
||||
</div>
|
||||
</div>
|
||||
</LayoutCol>
|
||||
<LayoutCol :class="'viewport'">
|
||||
<LayoutRow :class="'bar-area'">
|
||||
<CanvasRuler :origin="0" :majorMarkSpacing="100" :direction="RulerDirection.Horizontal" :class="'top-ruler'" />
|
||||
</LayoutRow>
|
||||
<LayoutRow :class="'canvas-area'">
|
||||
<LayoutCol :class="'bar-area'">
|
||||
<CanvasRuler :origin="0" :majorMarkSpacing="100" :direction="RulerDirection.Vertical" />
|
||||
</LayoutCol>
|
||||
<LayoutCol :class="'canvas-area'">
|
||||
<div class="canvas" @mousedown="canvasMouseDown" @mouseup="canvasMouseUp" @mousemove="canvasMouseMove" ref="canvas">
|
||||
<svg v-html="viewportSvg" :style="{ width: canvasSvgWidth, height: canvasSvgHeight }"></svg>
|
||||
</div>
|
||||
</LayoutCol>
|
||||
<LayoutCol :class="'bar-area'">
|
||||
<PersistentScrollbar :direction="ScrollbarDirection.Vertical" :class="'right-scrollbar'" />
|
||||
</LayoutCol>
|
||||
</LayoutRow>
|
||||
<LayoutRow :class="'bar-area'">
|
||||
<PersistentScrollbar :direction="ScrollbarDirection.Horizontal" :class="'bottom-scrollbar'" />
|
||||
</LayoutRow>
|
||||
</LayoutCol>
|
||||
</LayoutRow>
|
||||
</LayoutCol>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.document {
|
||||
height: 100%;
|
||||
|
||||
.options-bar {
|
||||
height: 32px;
|
||||
flex: 0 0 auto;
|
||||
|
||||
.side {
|
||||
height: 100%;
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.shelf-and-viewport {
|
||||
.shelf {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.working-colors .swap-and-reset {
|
||||
font-size: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.viewport {
|
||||
flex: 1 1 100%;
|
||||
|
||||
.canvas-area {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
|
||||
.bar-area {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.top-ruler {
|
||||
padding-left: 16px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.right-scrollbar {
|
||||
margin-top: -16px;
|
||||
}
|
||||
|
||||
.bottom-scrollbar {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.canvas {
|
||||
background: var(--color-1-nearblack);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
// Allows the SVG to be placed at explicit integer values of width and height to prevent non-pixel-perfect SVG scaling
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
svg {
|
||||
background: #ffffff;
|
||||
position: absolute;
|
||||
// Fallback values if JS hasn't set these to integers yet
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
import { makeModifiersBitfield } from "@/utilities/input";
|
||||
import { ResponseType, registerResponseHandler, Response, UpdateCanvas, SetActiveTool, ExportDocument, SetCanvasZoom, SetCanvasRotation } from "@/utilities/response-handler";
|
||||
import { SeparatorDirection, SeparatorType } from "@/components/widgets/widgets";
|
||||
import comingSoon from "@/utilities/coming-soon";
|
||||
|
||||
import LayoutRow from "@/components/layout/LayoutRow.vue";
|
||||
import LayoutCol from "@/components/layout/LayoutCol.vue";
|
||||
import SwatchPairInput from "@/components/widgets/inputs/SwatchPairInput.vue";
|
||||
import { MenuDirection } from "@/components/widgets/floating-menus/FloatingMenu.vue";
|
||||
import ShelfItemInput from "@/components/widgets/inputs/ShelfItemInput.vue";
|
||||
import Separator from "@/components/widgets/separators/Separator.vue";
|
||||
import PersistentScrollbar, { ScrollbarDirection } from "@/components/widgets/scrollbars/PersistentScrollbar.vue";
|
||||
import CanvasRuler, { RulerDirection } from "@/components/widgets/rulers/CanvasRuler.vue";
|
||||
import IconButton from "@/components/widgets/buttons/IconButton.vue";
|
||||
import PopoverButton from "@/components/widgets/buttons/PopoverButton.vue";
|
||||
import RadioInput, { RadioEntries } from "@/components/widgets/inputs/RadioInput.vue";
|
||||
import NumberInput, { IncrementDirection } from "@/components/widgets/inputs/NumberInput.vue";
|
||||
import DropdownInput from "@/components/widgets/inputs/DropdownInput.vue";
|
||||
import OptionalInput from "@/components/widgets/inputs/OptionalInput.vue";
|
||||
import ToolOptions from "@/components/widgets/options/ToolOptions.vue";
|
||||
import { SectionsOfMenuListEntries } from "@/components/widgets/floating-menus/MenuList.vue";
|
||||
|
||||
const documentModeEntries: SectionsOfMenuListEntries = [
|
||||
[
|
||||
{ label: "Design Mode", icon: "ViewportDesignMode" },
|
||||
{ label: "Select Mode", icon: "ViewportSelectMode", action: () => comingSoon(330) },
|
||||
{ label: "Guide Mode", icon: "ViewportGuideMode", action: () => comingSoon(331) },
|
||||
],
|
||||
];
|
||||
const viewModeEntries: RadioEntries = [
|
||||
{ value: "normal", icon: "ViewModeNormal", tooltip: "View Mode: Normal" },
|
||||
{ value: "outline", icon: "ViewModeOutline", tooltip: "View Mode: Outline", action: () => comingSoon(319) },
|
||||
{ value: "pixels", icon: "ViewModePixels", tooltip: "View Mode: Pixels", action: () => comingSoon(320) },
|
||||
];
|
||||
|
||||
const wasm = import("@/../wasm/pkg");
|
||||
|
||||
export default defineComponent({
|
||||
methods: {
|
||||
async viewportResize() {
|
||||
const canvas = this.$refs.canvas as HTMLElement;
|
||||
// Get the width and height rounded up to the nearest even number because resizing is centered and dividing an odd number by 2 for centering causes antialiasing
|
||||
let width = Math.ceil(parseFloat(getComputedStyle(canvas).width));
|
||||
if (width % 2 === 1) width += 1;
|
||||
let height = Math.ceil(parseFloat(getComputedStyle(canvas).height));
|
||||
if (height % 2 === 1) height += 1;
|
||||
|
||||
this.canvasSvgWidth = `${width}px`;
|
||||
this.canvasSvgHeight = `${height}px`;
|
||||
|
||||
const { viewport_resize } = await wasm;
|
||||
viewport_resize(width, height);
|
||||
},
|
||||
async canvasMouseDown(e: MouseEvent) {
|
||||
const { on_mouse_down } = await wasm;
|
||||
const modifiers = makeModifiersBitfield(e.ctrlKey, e.shiftKey, e.altKey);
|
||||
on_mouse_down(e.offsetX, e.offsetY, e.buttons, modifiers);
|
||||
},
|
||||
async canvasMouseUp(e: MouseEvent) {
|
||||
const { on_mouse_up } = await wasm;
|
||||
const modifiers = makeModifiersBitfield(e.ctrlKey, e.shiftKey, e.altKey);
|
||||
on_mouse_up(e.offsetX, e.offsetY, e.buttons, modifiers);
|
||||
},
|
||||
async canvasMouseMove(e: MouseEvent) {
|
||||
const { on_mouse_move } = await wasm;
|
||||
const modifiers = makeModifiersBitfield(e.ctrlKey, e.shiftKey, e.altKey);
|
||||
on_mouse_move(e.offsetX, e.offsetY, modifiers);
|
||||
},
|
||||
async canvasMouseScroll(e: WheelEvent) {
|
||||
e.preventDefault();
|
||||
const { on_mouse_scroll } = await wasm;
|
||||
const modifiers = makeModifiersBitfield(e.ctrlKey, e.shiftKey, e.altKey);
|
||||
on_mouse_scroll(e.deltaX, e.deltaY, e.deltaZ, modifiers);
|
||||
},
|
||||
async setZoom(newZoom: number) {
|
||||
const { set_zoom } = await wasm;
|
||||
set_zoom(newZoom / 100);
|
||||
},
|
||||
async setRotation(newRotation: number) {
|
||||
const { set_rotation } = await wasm;
|
||||
set_rotation(newRotation * (Math.PI / 180));
|
||||
},
|
||||
async selectTool(toolName: string) {
|
||||
const { select_tool } = await wasm;
|
||||
select_tool(toolName);
|
||||
},
|
||||
async swapWorkingColors() {
|
||||
const { swap_colors } = await wasm;
|
||||
swap_colors();
|
||||
},
|
||||
async resetWorkingColors() {
|
||||
const { reset_colors } = await wasm;
|
||||
reset_colors();
|
||||
},
|
||||
download(filename: string, fileData: string) {
|
||||
const svgBlob = new Blob([fileData], { type: "image/svg+xml;charset=utf-8" });
|
||||
const svgUrl = URL.createObjectURL(svgBlob);
|
||||
const element = document.createElement("a");
|
||||
|
||||
element.href = svgUrl;
|
||||
element.setAttribute("download", filename);
|
||||
element.style.display = "none";
|
||||
|
||||
element.click();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
registerResponseHandler(ResponseType.UpdateCanvas, (responseData: Response) => {
|
||||
const updateData = responseData as UpdateCanvas;
|
||||
if (updateData) this.viewportSvg = updateData.document;
|
||||
});
|
||||
registerResponseHandler(ResponseType.ExportDocument, (responseData: Response) => {
|
||||
const updateData = responseData as ExportDocument;
|
||||
if (updateData) this.download("canvas.svg", updateData.document);
|
||||
});
|
||||
registerResponseHandler(ResponseType.SetActiveTool, (responseData: Response) => {
|
||||
const toolData = responseData as SetActiveTool;
|
||||
if (toolData) this.activeTool = toolData.tool_name;
|
||||
});
|
||||
registerResponseHandler(ResponseType.SetCanvasZoom, (responseData: Response) => {
|
||||
const updateData = responseData as SetCanvasZoom;
|
||||
if (updateData) {
|
||||
this.documentZoom = updateData.new_zoom * 100;
|
||||
}
|
||||
});
|
||||
registerResponseHandler(ResponseType.SetCanvasRotation, (responseData: Response) => {
|
||||
const updateData = responseData as SetCanvasRotation;
|
||||
if (updateData) {
|
||||
const newRotation = updateData.new_radians * (180 / Math.PI);
|
||||
this.documentRotation = (360 + (newRotation % 360)) % 360;
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Move event listeners to `main.ts`
|
||||
const canvas = this.$refs.canvas as HTMLDivElement;
|
||||
canvas.addEventListener("wheel", this.canvasMouseScroll, { passive: false });
|
||||
|
||||
window.addEventListener("resize", () => this.viewportResize());
|
||||
window.addEventListener("DOMContentLoaded", () => this.viewportResize());
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
viewportSvg: "",
|
||||
canvasSvgWidth: "100%",
|
||||
canvasSvgHeight: "100%",
|
||||
activeTool: "Select",
|
||||
documentModeEntries,
|
||||
viewModeEntries,
|
||||
documentModeSelectionIndex: 0,
|
||||
viewModeIndex: 0,
|
||||
snappingEnabled: true,
|
||||
gridEnabled: true,
|
||||
overlaysEnabled: true,
|
||||
documentRotation: 0,
|
||||
documentZoom: 100,
|
||||
IncrementDirection,
|
||||
MenuDirection,
|
||||
SeparatorDirection,
|
||||
ScrollbarDirection,
|
||||
RulerDirection,
|
||||
SeparatorType,
|
||||
comingSoon,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
LayoutRow,
|
||||
LayoutCol,
|
||||
SwatchPairInput,
|
||||
ShelfItemInput,
|
||||
Separator,
|
||||
PersistentScrollbar,
|
||||
CanvasRuler,
|
||||
IconButton,
|
||||
PopoverButton,
|
||||
RadioInput,
|
||||
NumberInput,
|
||||
DropdownInput,
|
||||
OptionalInput,
|
||||
ToolOptions,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
369
frontend/src/components/panels/LayerTree.vue
Normal file
@@ -0,0 +1,369 @@
|
||||
<template>
|
||||
<LayoutCol :class="'layer-tree-panel'">
|
||||
<LayoutRow :class="'options-bar'">
|
||||
<DropdownInput v-model:selectedIndex="blendModeSelectedIndex" @update:selectedIndex="setLayerBlendMode" :menuEntries="blendModeEntries" :disabled="blendModeDropdownDisabled" />
|
||||
|
||||
<Separator :type="SeparatorType.Related" />
|
||||
|
||||
<NumberInput v-model:value="opacity" @update:value="setLayerOpacity" :min="0" :max="100" :unit="`%`" :displayDecimalPlaces="2" :label="'Opacity'" :disabled="opacityNumberInputDisabled" />
|
||||
|
||||
<Separator :type="SeparatorType.Related" />
|
||||
|
||||
<PopoverButton>
|
||||
<h3>Compositing Options</h3>
|
||||
<p>More blend and compositing options will be here</p>
|
||||
</PopoverButton>
|
||||
</LayoutRow>
|
||||
<LayoutRow :class="'layer-tree scrollable-y'">
|
||||
<LayoutCol :class="'list'" @click="deselectAllLayers">
|
||||
<div class="layer-row" v-for="layer in layers" :key="layer.path">
|
||||
<div class="layer-visibility">
|
||||
<IconButton
|
||||
:action="(e) => (toggleLayerVisibility(layer.path), e.stopPropagation())"
|
||||
:icon="layer.visible ? 'EyeVisible' : 'EyeHidden'"
|
||||
:size="24"
|
||||
:title="layer.visible ? 'Visible' : 'Hidden'"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="layer"
|
||||
:class="{ selected: layer.layer_data.selected }"
|
||||
@click.shift.exact.stop="handleShiftClick(layer)"
|
||||
@click.ctrl.exact.stop="handleControlClick(layer)"
|
||||
@click.alt.exact.stop="handleControlClick(layer)"
|
||||
@click.exact.stop="handleClick(layer)"
|
||||
>
|
||||
<div class="layer-thumbnail" v-html="layer.thumbnail"></div>
|
||||
<div class="layer-type-icon">
|
||||
<IconLabel :icon="'NodeTypePath'" title="Path" />
|
||||
</div>
|
||||
<div class="layer-name">
|
||||
<span>{{ layer.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</LayoutCol>
|
||||
</LayoutRow>
|
||||
</LayoutCol>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.layer-tree-panel {
|
||||
min-height: 0;
|
||||
|
||||
.options-bar {
|
||||
height: 32px;
|
||||
flex: 0 0 auto;
|
||||
margin: 0 4px;
|
||||
align-items: center;
|
||||
|
||||
.dropdown-input {
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
.dropdown-input,
|
||||
.number-input {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.layer-tree {
|
||||
.layer-row {
|
||||
display: flex;
|
||||
height: 36px;
|
||||
align-items: center;
|
||||
margin: 0 8px;
|
||||
flex: 0 0 auto;
|
||||
|
||||
.layer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: var(--color-5-dullgray);
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin-left: 4px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.selected {
|
||||
background: var(--color-accent);
|
||||
color: var(--color-f-white);
|
||||
}
|
||||
|
||||
& + .layer-row {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.layer-thumbnail {
|
||||
width: 64px;
|
||||
height: 100%;
|
||||
background: white;
|
||||
|
||||
svg {
|
||||
width: calc(100% - 4px);
|
||||
height: calc(100% - 4px);
|
||||
margin: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.layer-type-icon {
|
||||
margin: 0 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
import { ResponseType, registerResponseHandler, Response, BlendMode, ExpandFolder, UpdateLayer, LayerPanelEntry } from "@/utilities/response-handler";
|
||||
import { SeparatorType } from "@/components/widgets/widgets";
|
||||
|
||||
import LayoutRow from "@/components/layout/LayoutRow.vue";
|
||||
import LayoutCol from "@/components/layout/LayoutCol.vue";
|
||||
import Separator from "@/components/widgets/separators/Separator.vue";
|
||||
import NumberInput from "@/components/widgets/inputs/NumberInput.vue";
|
||||
import PopoverButton from "@/components/widgets/buttons/PopoverButton.vue";
|
||||
import { MenuDirection } from "@/components/widgets/floating-menus/FloatingMenu.vue";
|
||||
import IconButton from "@/components/widgets/buttons/IconButton.vue";
|
||||
import IconLabel from "@/components/widgets/labels/IconLabel.vue";
|
||||
import DropdownInput from "@/components/widgets/inputs/DropdownInput.vue";
|
||||
import { SectionsOfMenuListEntries } from "@/components/widgets/floating-menus/MenuList.vue";
|
||||
|
||||
const wasm = import("@/../wasm/pkg");
|
||||
|
||||
const blendModeEntries: SectionsOfMenuListEntries = [
|
||||
[{ label: "Normal", value: BlendMode.Normal }],
|
||||
[
|
||||
{ label: "Multiply", value: BlendMode.Multiply },
|
||||
{ label: "Darken", value: BlendMode.Darken },
|
||||
{ label: "Color Burn", value: BlendMode.ColorBurn },
|
||||
// { label: "Linear Burn", value: "" }, // Not supported by SVG
|
||||
// { label: "Darker Color", value: "" }, // Not supported by SVG
|
||||
],
|
||||
[
|
||||
{ label: "Screen", value: BlendMode.Screen },
|
||||
{ label: "Lighten", value: BlendMode.Lighten },
|
||||
{ label: "Color Dodge", value: BlendMode.ColorDodge },
|
||||
// { label: "Linear Dodge (Add)", value: "" }, // Not supported by SVG
|
||||
// { label: "Lighter Color", value: "" }, // Not supported by SVG
|
||||
],
|
||||
[
|
||||
{ label: "Overlay", value: BlendMode.Overlay },
|
||||
{ label: "Soft Light", value: BlendMode.SoftLight },
|
||||
{ label: "Hard Light", value: BlendMode.HardLight },
|
||||
// { label: "Vivid Light", value: "" }, // Not supported by SVG
|
||||
// { label: "Linear Light", value: "" }, // Not supported by SVG
|
||||
// { label: "Pin Light", value: "" }, // Not supported by SVG
|
||||
// { label: "Hard Mix", value: "" }, // Not supported by SVG
|
||||
],
|
||||
[
|
||||
{ label: "Difference", value: BlendMode.Difference },
|
||||
{ label: "Exclusion", value: BlendMode.Exclusion },
|
||||
// { label: "Subtract", value: "" }, // Not supported by SVG
|
||||
// { label: "Divide", value: "" }, // Not supported by SVG
|
||||
],
|
||||
[
|
||||
{ label: "Hue", value: BlendMode.Hue },
|
||||
{ label: "Saturation", value: BlendMode.Saturation },
|
||||
{ label: "Color", value: BlendMode.Color },
|
||||
{ label: "Luminosity", value: BlendMode.Luminosity },
|
||||
],
|
||||
];
|
||||
|
||||
export default defineComponent({
|
||||
props: {},
|
||||
methods: {
|
||||
async toggleLayerVisibility(path: BigUint64Array) {
|
||||
const { toggle_layer_visibility } = await wasm;
|
||||
toggle_layer_visibility(path);
|
||||
},
|
||||
async setLayerBlendMode() {
|
||||
const blendMode = this.blendModeEntries.flat()[this.blendModeSelectedIndex].value as BlendMode;
|
||||
if (blendMode) {
|
||||
const { set_blend_mode_for_selected_layers } = await wasm;
|
||||
set_blend_mode_for_selected_layers(blendMode);
|
||||
}
|
||||
},
|
||||
async setLayerOpacity() {
|
||||
const { set_opacity_for_selected_layers } = await wasm;
|
||||
set_opacity_for_selected_layers(this.opacity);
|
||||
},
|
||||
async handleControlClick(clickedLayer: LayerPanelEntry) {
|
||||
const index = this.layers.indexOf(clickedLayer);
|
||||
clickedLayer.layer_data.selected = !clickedLayer.layer_data.selected;
|
||||
|
||||
this.selectionRangeEndLayer = undefined;
|
||||
this.selectionRangeStartLayer =
|
||||
this.layers.slice(index).filter((layer) => layer.layer_data.selected)[0] ||
|
||||
this.layers
|
||||
.slice(0, index)
|
||||
.reverse()
|
||||
.filter((layer) => layer.layer_data.selected)[0];
|
||||
|
||||
this.sendSelectedLayers();
|
||||
},
|
||||
async handleShiftClick(clickedLayer: LayerPanelEntry) {
|
||||
// The two paths of the range are stored in selectionRangeStartLayer and selectionRangeEndLayer
|
||||
// So for a new Shift+Click, select all layers between selectionRangeStartLayer and selectionRangeEndLayer (stored in previous Shift+Click)
|
||||
this.clearSelection();
|
||||
|
||||
this.selectionRangeEndLayer = clickedLayer;
|
||||
if (!this.selectionRangeStartLayer) this.selectionRangeStartLayer = clickedLayer;
|
||||
this.fillSelectionRange(this.selectionRangeStartLayer, this.selectionRangeEndLayer, true);
|
||||
|
||||
this.sendSelectedLayers();
|
||||
},
|
||||
async handleClick(clickedLayer: LayerPanelEntry) {
|
||||
this.selectionRangeStartLayer = clickedLayer;
|
||||
this.selectionRangeEndLayer = clickedLayer;
|
||||
|
||||
this.clearSelection();
|
||||
clickedLayer.layer_data.selected = true;
|
||||
|
||||
this.sendSelectedLayers();
|
||||
},
|
||||
async deselectAllLayers() {
|
||||
this.selectionRangeStartLayer = undefined;
|
||||
this.selectionRangeEndLayer = undefined;
|
||||
|
||||
const { deselect_all_layers } = await wasm;
|
||||
deselect_all_layers();
|
||||
},
|
||||
async fillSelectionRange(start: LayerPanelEntry, end: LayerPanelEntry, selected = true) {
|
||||
const startIndex = this.layers.findIndex((layer) => layer.path.join() === start.path.join());
|
||||
const endIndex = this.layers.findIndex((layer) => layer.path.join() === end.path.join());
|
||||
const [min, max] = [startIndex, endIndex].sort();
|
||||
|
||||
if (min !== -1) {
|
||||
for (let i = min; i <= max; i += 1) {
|
||||
this.layers[i].layer_data.selected = selected;
|
||||
}
|
||||
}
|
||||
},
|
||||
async clearSelection() {
|
||||
this.layers.forEach((layer) => {
|
||||
layer.layer_data.selected = false;
|
||||
});
|
||||
},
|
||||
async sendSelectedLayers() {
|
||||
const paths = this.layers.filter((layer) => layer.layer_data.selected).map((layer) => layer.path);
|
||||
|
||||
const length = paths.reduce((acc, cur) => acc + cur.length, 0) + paths.length - 1;
|
||||
const output = new BigUint64Array(length);
|
||||
|
||||
let i = 0;
|
||||
paths.forEach((path, index) => {
|
||||
output.set(path, i);
|
||||
i += path.length;
|
||||
if (index < paths.length) {
|
||||
// eslint-disable-next-line no-bitwise
|
||||
output[i] = (1n << 64n) - 1n;
|
||||
}
|
||||
i += 1;
|
||||
});
|
||||
const { select_layers } = await wasm;
|
||||
select_layers(output);
|
||||
},
|
||||
setBlendModeForSelectedLayers() {
|
||||
const selected = this.layers.filter((layer) => layer.layer_data.selected);
|
||||
|
||||
if (selected.length < 1) {
|
||||
this.blendModeSelectedIndex = 0;
|
||||
this.blendModeDropdownDisabled = true;
|
||||
return;
|
||||
}
|
||||
this.blendModeDropdownDisabled = false;
|
||||
|
||||
const firstEncounteredBlendMode = selected[0].blend_mode;
|
||||
const allBlendModesAlike = !selected.find((layer) => layer.blend_mode !== firstEncounteredBlendMode);
|
||||
|
||||
if (allBlendModesAlike) {
|
||||
this.blendModeSelectedIndex = this.blendModeEntries.flat().findIndex((entry) => entry.value === firstEncounteredBlendMode);
|
||||
} else {
|
||||
// Display a dash when they are not all the same value
|
||||
this.blendModeSelectedIndex = NaN;
|
||||
}
|
||||
},
|
||||
setOpacityForSelectedLayers() {
|
||||
const selected = this.layers.filter((layer) => layer.layer_data.selected);
|
||||
|
||||
if (selected.length < 1) {
|
||||
this.opacity = 100;
|
||||
this.opacityNumberInputDisabled = true;
|
||||
return;
|
||||
}
|
||||
this.opacityNumberInputDisabled = false;
|
||||
|
||||
const firstEncounteredOpacity = selected[0].opacity;
|
||||
const allOpacitiesAlike = !selected.find((layer) => layer.opacity !== firstEncounteredOpacity);
|
||||
|
||||
if (allOpacitiesAlike) {
|
||||
this.opacity = firstEncounteredOpacity;
|
||||
} else {
|
||||
// Display a dash when they are not all the same value
|
||||
this.opacity = NaN;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
registerResponseHandler(ResponseType.ExpandFolder, (responseData: Response) => {
|
||||
const expandData = responseData as ExpandFolder;
|
||||
if (expandData) {
|
||||
const responsePath = expandData.path;
|
||||
const responseLayers = expandData.children as Array<LayerPanelEntry>;
|
||||
if (responsePath.length > 0) console.error("Non root paths are currently not implemented");
|
||||
|
||||
this.layers = responseLayers;
|
||||
|
||||
this.setBlendModeForSelectedLayers();
|
||||
this.setOpacityForSelectedLayers();
|
||||
}
|
||||
});
|
||||
registerResponseHandler(ResponseType.CollapseFolder, (responseData) => {
|
||||
console.log("CollapseFolder: ", responseData);
|
||||
});
|
||||
registerResponseHandler(ResponseType.UpdateLayer, (responseData) => {
|
||||
const updateData = responseData as UpdateLayer;
|
||||
if (updateData) {
|
||||
const responsePath = updateData.path;
|
||||
const responseLayer = updateData.data;
|
||||
|
||||
const index = this.layers.findIndex((layer: LayerPanelEntry) => {
|
||||
const pathLengthsEqual = responsePath.length === layer.path.length;
|
||||
return pathLengthsEqual && responsePath.every((layer_id, i) => layer_id === layer.path[i]);
|
||||
});
|
||||
if (index >= 0) this.layers[index] = responseLayer;
|
||||
|
||||
this.setBlendModeForSelectedLayers();
|
||||
this.setOpacityForSelectedLayers();
|
||||
}
|
||||
});
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
blendModeEntries,
|
||||
blendModeSelectedIndex: 0,
|
||||
blendModeDropdownDisabled: true,
|
||||
opacityNumberInputDisabled: true,
|
||||
layers: [] as Array<LayerPanelEntry>,
|
||||
selectionRangeStartLayer: undefined as undefined | LayerPanelEntry,
|
||||
selectionRangeEndLayer: undefined as undefined | LayerPanelEntry,
|
||||
opacity: 100,
|
||||
MenuDirection,
|
||||
SeparatorType,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
LayoutRow,
|
||||
LayoutCol,
|
||||
Separator,
|
||||
PopoverButton,
|
||||
NumberInput,
|
||||
IconButton,
|
||||
IconLabel,
|
||||
DropdownInput,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
14
frontend/src/components/panels/Minimap.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss"></style>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
components: {},
|
||||
props: {},
|
||||
});
|
||||
</script>
|
||||
14
frontend/src/components/panels/Properties.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<style lang="scss"></style>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
components: {},
|
||||
props: {},
|
||||
});
|
||||
</script>
|
||||