basic drawing of closed shapes

This commit is contained in:
Skyler Lehmkuhl 2024-11-15 00:15:58 -05:00
parent 9491a1006e
commit 36f8c99dd3
8 changed files with 2470 additions and 14 deletions

142
src/assets/draw.svg Normal file
View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="24"
viewBox="0 0 24 24"
id="svg30571"
version="1.1"
inkscape:version="0.91+devel r"
sodipodi:docname="gimp-tool-pencil-24.svg"
inkscape:export-filename="/home/klaus/Bilder/icons/Symbolic/hicolor/24x24/apps/gimp-channel.png"
inkscape:export-xdpi="98.181816"
inkscape:export-ydpi="98.181816">
<defs
id="defs30573">
<linearGradient
id="linearGradient19282-4"
osb:paint="solid"
gradientTransform="matrix(0.34682586,0,0,0.30620888,-482.61525,330.965)">
<stop
style="stop-color:#bebebe;stop-opacity:1;"
offset="0"
id="stop19284-0" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient19282-4"
id="linearGradient10396"
x1="-148.71875"
y1="-36.782017"
x2="-144"
y2="-36.782017"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.4999998,0,0,1.4999998,239.50009,1088.3622)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient19282-4"
id="linearGradient10390"
x1="82.000198"
y1="187"
x2="94.000198"
y2="187"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.4999998,0,0,1.4999998,-122.00028,762.86224)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="11.379883"
inkscape:cy="17.128924"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:snap-page="true"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:object-paths="true"
inkscape:snap-intersection-paths="true"
inkscape:object-nodes="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-midpoints="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
inkscape:snap-text-baseline="true"
showborder="false"
inkscape:window-width="1440"
inkscape:window-height="752"
inkscape:window-x="149"
inkscape:window-y="27"
inkscape:window-maximized="0"
inkscape:snap-global="false">
<inkscape:grid
type="xygrid"
id="grid4369" />
</sodipodi:namedview>
<metadata
id="metadata30576">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Klaus Staedtler</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1028.3622)">
<g
id="g9722">
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path69005"
d="m 19.5,1029.8622 -3,3 c 1.993094,0.039 3.919679,1.6611 4.000124,3.5 l 3,-3 c -0.0831,-1.898 -1.946084,-3.5763 -4.000124,-3.5 z"
style="fill:url(#linearGradient10396);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.49999976" />
<rect
ry="0"
rx="0"
y="1028.3622"
x="1.3463471e-06"
height="23.999996"
width="23.999994"
id="rect63426"
style="fill:none;stroke:none;stroke-width:1.49999976" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc"
id="path2273-6-2"
d="m 4,1046.3622 11,-11.9977 c 2.054034,-0.076 3.916963,1.5997 3.999997,3.4977 L 8,1049.3622 l -7,3 z"
style="fill:url(#linearGradient10390);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.49999976" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

139
src/assets/select.svg Normal file
View File

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 23.999999 24"
id="svg7384"
height="24"
width="24"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="gimp-cursor.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1016"
id="namedview1507"
showgrid="true"
inkscape:zoom="14.75"
inkscape:cx="-4.8474576"
inkscape:cy="8.8813559"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg7384">
<inkscape:grid
type="xygrid"
id="grid4149" />
</sodipodi:namedview>
<metadata
id="metadata90">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:contributor>
<cc:Agent>
<dc:title>Barbara Muraus, Jakub Steiner, Klaus Staedtler</dc:title>
</cc:Agent>
</dc:contributor>
<dc:description>Images originally created as the &quot;Art Libre&quot; icon set. Extended and adopted for GIMP</dc:description>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs7386">
<linearGradient
osb:paint="solid"
id="linearGradient8074">
<stop
id="stop8072"
offset="0"
style="stop-color:#be00be;stop-opacity:1;" />
</linearGradient>
<linearGradient
osb:paint="solid"
id="linearGradient7561">
<stop
id="stop7558"
offset="0"
style="stop-color:#a5a5a5;stop-opacity:1;" />
</linearGradient>
<linearGradient
osb:paint="solid"
id="linearGradient7548">
<stop
id="stop7546"
offset="0"
style="stop-color:#ebebeb;stop-opacity:1;" />
</linearGradient>
<linearGradient
osb:paint="solid"
id="linearGradient7542">
<stop
id="stop7538"
offset="0"
style="stop-color:#c9c9c9;stop-opacity:1;" />
</linearGradient>
<linearGradient
gradientTransform="matrix(0,-735328.32,170712.69,0,2464326300,577972450)"
osb:paint="solid"
id="linearGradient19282">
<stop
id="stop19284"
offset="0"
style="stop-color:#b4b4b4;stop-opacity:1;" />
</linearGradient>
<linearGradient
gradientTransform="matrix(0.34682586,0,0,0.30620888,-33.35187,162.03851)"
osb:paint="solid"
id="linearGradient19282-4">
<stop
id="stop19284-0"
offset="0"
style="stop-color:#bebebe;stop-opacity:1;" />
</linearGradient>
<linearGradient
gradientTransform="matrix(1,0,0,1.0064514,523.05932,150.423)"
gradientUnits="userSpaceOnUse"
y2="607.03845"
x2="133.0002"
y1="607.03845"
x1="125.0002"
id="linearGradient7314"
xlink:href="#linearGradient19282-4" />
</defs>
<g
transform="matrix(1.5,0,0,1.5,-97.872258,20.46468)"
style="display:inline"
id="stock">
<g
id="gimp-cursor"
style="display:inline"
transform="translate(-55.752028,-612.64312)">
<path
style="fill:url(#linearGradient7314);fill-opacity:1;stroke:none"
d="m 125.0002,601.85133 0,9.14867 0.82307,-0.0129 1.64616,-3.1742 3.06144,5.1871 2.46933,0 -3.88462,-6 3.88462,0 0,-0.89033 -8,-5.10967 z"
id="path8245"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

200
src/assets/transform.svg Normal file
View File

@ -0,0 +1,200 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24.000006"
height="24"
viewBox="0 0 24.000006 24"
id="svg30571"
version="1.1"
inkscape:version="0.92.2 2405546, 2018-03-11"
sodipodi:docname="gimp-tool-cage-symbolic.svg"
inkscape:export-filename="/home/klaus/Bilder/icons/Symbolic/hicolor/24x24/apps/gimp-channel.png"
inkscape:export-xdpi="98.181816"
inkscape:export-ydpi="98.181816">
<defs
id="defs30573">
<linearGradient
id="linearGradient19282-4"
osb:paint="solid"
gradientTransform="matrix(0.34682586,0,0,0.30620888,-482.61525,330.965)">
<stop
style="stop-color:#bebebe;stop-opacity:1;"
offset="0"
id="stop19284-0" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient19282-4"
id="linearGradient7345-8"
x1="-178.03125"
y1="-39.984375"
x2="-174"
y2="-39.984375"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.4883721,0,0,1.4883721,264.97678,1093.8973)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient19282-4"
id="linearGradient7363-5"
x1="-178.03125"
y1="-39.984375"
x2="-174"
y2="-39.984375"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.4883721,0,0,1.4883721,264.97674,1108.8738)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient19282-4"
id="linearGradient7357-3"
x1="-178.03125"
y1="-39.984375"
x2="-174"
y2="-39.984375"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.488372,0,0,1.4883721,282.97674,1105.8739)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient19282-4"
id="linearGradient7351-7"
x1="-178.03125"
y1="-39.984375"
x2="-174"
y2="-39.984375"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.4883721,0,0,1.4883721,281.97674,1090.8738)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient19282-4"
id="linearGradient7333-2"
x1="82.250198"
y1="225.35899"
x2="95.881874"
y2="225.35899"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.4970767,0,0,1.4999996,-121.2401,702.86229)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient19282-4"
id="linearGradient7339-4"
x1="-178.03125"
y1="-39.984375"
x2="-174"
y2="-39.984375"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.4883721,0,0,1.4883721,273.97674,1101.8738)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="-0.71288204"
inkscape:cy="12.378924"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:snap-page="true"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:object-paths="true"
inkscape:snap-intersection-paths="true"
inkscape:object-nodes="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-midpoints="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
inkscape:snap-text-baseline="true"
showborder="false"
inkscape:window-width="1366"
inkscape:window-height="704"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="0"
inkscape:snap-global="false"
showguides="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
<inkscape:grid
type="xygrid"
id="grid4369"
originx="21.437509"
originy="1.8125" />
</sodipodi:namedview>
<metadata
id="metadata30576">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Klaus Staedtler</dc:title>
</cc:Agent>
</dc:creator>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(21.437509,-1030.1747)">
<g
style="display:inline"
transform="translate(-21.437503,1.8125)"
id="gimp-tool-cage-24">
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient7345-8);fill-opacity:1;stroke:none;stroke-width:1.48837185;marker:none;enable-background:new"
d="m 6.0000274,1034.3856 a 3,3 0 0 1 -3,3 3,3 0 0 1 -2.999999981863,-3 3,3 0 0 1 2.999999981863,-3 3,3 0 0 1 3,3 z"
id="path3908-1" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient7363-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.48837173;marker:none;enable-background:new"
d="m 5.999994,1049.3622 a 3,3 0 0 1 -3,3 3,3 0 0 1 -2.9999999604645,-3 3,3 0 0 1 2.9999999604645,-3 3,3 0 0 1 3,3 z"
id="path3910-5" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient7357-3);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.48837173;marker:none;enable-background:new"
d="m 24,1046.3622 a 3,3 0 0 1 -3,3 3,3 0 0 1 -3,-3 3,3 0 0 1 3,-3 3,3 0 0 1 3,3 z"
id="path3912-2" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient7351-7);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.48837173;marker:none;enable-background:new"
d="m 23,1031.3622 a 3,3 0 0 1 -3,3 3,3 0 0 1 -3,-3 3,3 0 0 1 3,-3 3,3 0 0 1 3,3 z"
id="path3914-1" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient7333-2);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.24780607;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:new"
d="m 21.039062,1030.0371 -19.1621089,3.3828 v 0.9414 17.2989 l 10.2812499,-7.9981 10.087891,4.4844 z m -2.076171,2.6484 0.792968,11.8946 -7.914062,-3.5176 -7.7187501,6.002 v -11.7598 z"
id="rect3916-8"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient7339-4);fill-opacity:1;stroke:none;stroke-width:1.48837173;marker:none;enable-background:new"
d="m 15,1042.3622 a 3,3 0 0 1 -3,3 3,3 0 0 1 -3,-3 3,3 0 0 1 3,-3 3,3 0 0 1 3,3 z"
id="path38587-3" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.7 KiB

577
src/coloris.css Normal file
View File

@ -0,0 +1,577 @@
.clr-picker {
display: none;
flex-wrap: wrap;
position: absolute;
width: 200px;
z-index: 1000;
border-radius: 10px;
background-color: #fff;
justify-content: flex-end;
direction: ltr;
box-shadow: 0 0 5px rgba(0,0,0,.05), 0 5px 20px rgba(0,0,0,.1);
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
}
.clr-picker.clr-open,
.clr-picker[data-inline="true"] {
display: flex;
}
.clr-picker[data-inline="true"] {
position: relative;
}
.clr-gradient {
position: relative;
width: 100%;
height: 100px;
margin-bottom: 15px;
border-radius: 3px 3px 0 0;
background-image: linear-gradient(rgba(0,0,0,0), #000), linear-gradient(90deg, #fff, currentColor);
cursor: pointer;
}
.clr-marker {
position: absolute;
width: 12px;
height: 12px;
margin: -6px 0 0 -6px;
border: 1px solid #fff;
border-radius: 50%;
background-color: currentColor;
cursor: pointer;
}
.clr-picker input[type="range"]::-webkit-slider-runnable-track {
width: 100%;
height: 16px;
}
.clr-picker input[type="range"]::-webkit-slider-thumb {
width: 16px;
height: 16px;
-webkit-appearance: none;
}
.clr-picker input[type="range"]::-moz-range-track {
width: 100%;
height: 16px;
border: 0;
}
.clr-picker input[type="range"]::-moz-range-thumb {
width: 16px;
height: 16px;
border: 0;
}
.clr-hue {
background-image: linear-gradient(to right, #f00 0%, #ff0 16.66%, #0f0 33.33%, #0ff 50%, #00f 66.66%, #f0f 83.33%, #f00 100%);
}
.clr-hue,
.clr-alpha {
position: relative;
width: calc(100% - 40px);
height: 8px;
margin: 5px 20px;
border-radius: 4px;
}
.clr-alpha span {
display: block;
height: 100%;
width: 100%;
border-radius: inherit;
background-image: linear-gradient(90deg, rgba(0,0,0,0), currentColor);
}
.clr-hue input[type="range"],
.clr-alpha input[type="range"] {
position: absolute;
width: calc(100% + 32px);
height: 16px;
left: -16px;
top: -4px;
margin: 0;
background-color: transparent;
opacity: 0;
cursor: pointer;
appearance: none;
-webkit-appearance: none;
}
.clr-hue div,
.clr-alpha div {
position: absolute;
width: 16px;
height: 16px;
left: 0;
top: 50%;
margin-left: -8px;
transform: translateY(-50%);
border: 2px solid #fff;
border-radius: 50%;
background-color: currentColor;
box-shadow: 0 0 1px #888;
pointer-events: none;
}
.clr-alpha div:before {
content: '';
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
border-radius: 50%;
background-color: currentColor;
}
.clr-format {
display: none;
order: 1;
width: calc(100% - 40px);
margin: 0 20px 20px;
}
.clr-segmented {
display: flex;
position: relative;
width: 100%;
margin: 0;
padding: 0;
border: 1px solid #ddd;
border-radius: 15px;
box-sizing: border-box;
color: #999;
font-size: 12px;
}
.clr-segmented input,
.clr-segmented legend {
position: absolute;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
border: 0;
left: 0;
top: 0;
opacity: 0;
pointer-events: none;
}
.clr-segmented label {
flex-grow: 1;
margin: 0;
padding: 4px 0;
font-size: inherit;
font-weight: normal;
line-height: initial;
text-align: center;
cursor: pointer;
}
.clr-segmented label:first-of-type {
border-radius: 10px 0 0 10px;
}
.clr-segmented label:last-of-type {
border-radius: 0 10px 10px 0;
}
.clr-segmented input:checked + label {
color: #fff;
background-color: #666;
}
.clr-swatches {
order: 2;
width: calc(100% - 32px);
margin: 0 16px;
}
.clr-swatches div {
display: flex;
flex-wrap: wrap;
padding-bottom: 12px;
justify-content: center;
}
.clr-swatches button {
position: relative;
width: 20px;
height: 20px;
margin: 0 4px 6px 4px;
padding: 0;
border: 0;
border-radius: 50%;
color: inherit;
text-indent: -1000px;
white-space: nowrap;
overflow: hidden;
cursor: pointer;
}
.clr-swatches button:after {
content: '';
display: block;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
border-radius: inherit;
background-color: currentColor;
box-shadow: inset 0 0 0 1px rgba(0,0,0,.1);
}
input.clr-color {
order: 1;
width: calc(100% - 80px);
height: 32px;
margin: 15px 20px 20px auto;
padding: 0 10px;
border: 1px solid #ddd;
border-radius: 16px;
color: #444;
background-color: #fff;
font-family: sans-serif;
font-size: 14px;
text-align: center;
box-shadow: none;
}
input.clr-color:focus {
outline: none;
border: 1px solid #1e90ff;
}
.clr-close,
.clr-clear {
display: none;
order: 2;
height: 24px;
margin: 0 20px 20px;
padding: 0 20px;
border: 0;
border-radius: 12px;
color: #fff;
background-color: #666;
font-family: inherit;
font-size: 12px;
font-weight: 400;
cursor: pointer;
}
.clr-close {
display: block;
margin: 0 20px 20px auto;
}
.clr-preview {
position: relative;
width: 32px;
height: 32px;
margin: 15px 0 20px 20px;
border-radius: 50%;
overflow: hidden;
}
.clr-preview:before,
.clr-preview:after {
content: '';
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
border: 1px solid #fff;
border-radius: 50%;
}
.clr-preview:after {
border: 0;
background-color: currentColor;
box-shadow: inset 0 0 0 1px rgba(0,0,0,.1);
}
.clr-preview button {
position: absolute;
width: 100%;
height: 100%;
z-index: 1;
margin: 0;
padding: 0;
border: 0;
border-radius: 50%;
outline-offset: -2px;
background-color: transparent;
text-indent: -9999px;
cursor: pointer;
overflow: hidden;
}
.clr-marker,
.clr-hue div,
.clr-alpha div,
.clr-color {
box-sizing: border-box;
}
.clr-field {
display: inline-block;
position: relative;
color: transparent;
}
.clr-field input {
margin: 0;
direction: ltr;
}
.clr-field.clr-rtl input {
text-align: right;
}
.clr-field button {
position: absolute;
width: 30px;
height: 100%;
right: 0;
top: 50%;
transform: translateY(-50%);
margin: 0;
padding: 0;
border: 0;
color: inherit;
text-indent: -1000px;
white-space: nowrap;
overflow: hidden;
pointer-events: none;
}
.clr-field.clr-rtl button {
right: auto;
left: 0;
}
.clr-field button:after {
content: '';
display: block;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
border-radius: inherit;
background-color: currentColor;
box-shadow: inset 0 0 1px rgba(0,0,0,.5);
}
.clr-alpha,
.clr-alpha div,
.clr-swatches button,
.clr-preview:before,
.clr-field button {
background-image: repeating-linear-gradient(45deg, #aaa 25%, transparent 25%, transparent 75%, #aaa 75%, #aaa), repeating-linear-gradient(45deg, #aaa 25%, #fff 25%, #fff 75%, #aaa 75%, #aaa);
background-position: 0 0, 4px 4px;
background-size: 8px 8px;
}
.clr-marker:focus {
outline: none;
}
.clr-keyboard-nav .clr-marker:focus,
.clr-keyboard-nav .clr-hue input:focus + div,
.clr-keyboard-nav .clr-alpha input:focus + div,
.clr-keyboard-nav .clr-segmented input:focus + label {
outline: none;
box-shadow: 0 0 0 2px #1e90ff, 0 0 2px 2px #fff;
}
.clr-picker[data-alpha="false"] .clr-alpha {
display: none;
}
.clr-picker[data-minimal="true"] {
padding-top: 16px;
}
.clr-picker[data-minimal="true"] .clr-gradient,
.clr-picker[data-minimal="true"] .clr-hue,
.clr-picker[data-minimal="true"] .clr-alpha,
.clr-picker[data-minimal="true"] .clr-color,
.clr-picker[data-minimal="true"] .clr-preview {
display: none;
}
/** Dark theme **/
.clr-dark {
background-color: #444;
}
.clr-dark .clr-segmented {
border-color: #777;
}
.clr-dark .clr-swatches button:after {
box-shadow: inset 0 0 0 1px rgba(255,255,255,.3);
}
.clr-dark input.clr-color {
color: #fff;
border-color: #777;
background-color: #555;
}
.clr-dark input.clr-color:focus {
border-color: #1e90ff;
}
.clr-dark .clr-preview:after {
box-shadow: inset 0 0 0 1px rgba(255,255,255,.5);
}
.clr-dark .clr-alpha,
.clr-dark .clr-alpha div,
.clr-dark .clr-swatches button,
.clr-dark .clr-preview:before {
background-image: repeating-linear-gradient(45deg, #666 25%, transparent 25%, transparent 75%, #888 75%, #888), repeating-linear-gradient(45deg, #888 25%, #444 25%, #444 75%, #888 75%, #888);
}
/** Polaroid theme **/
.clr-picker.clr-polaroid {
border-radius: 6px;
box-shadow: 0 0 5px rgba(0,0,0,.1), 0 5px 30px rgba(0,0,0,.2);
}
.clr-picker.clr-polaroid:before {
content: '';
display: block;
position: absolute;
width: 16px;
height: 10px;
left: 20px;
top: -10px;
border: solid transparent;
border-width: 0 8px 10px 8px;
border-bottom-color: currentColor;
box-sizing: border-box;
color: #fff;
filter: drop-shadow(0 -4px 3px rgba(0,0,0,.1));
pointer-events: none;
}
.clr-picker.clr-polaroid.clr-dark:before {
color: #444;
}
.clr-picker.clr-polaroid.clr-left:before {
left: auto;
right: 20px;
}
.clr-picker.clr-polaroid.clr-top:before {
top: auto;
bottom: -10px;
transform: rotateZ(180deg);
}
.clr-polaroid .clr-gradient {
width: calc(100% - 20px);
height: 120px;
margin: 10px;
border-radius: 3px;
}
.clr-polaroid .clr-hue,
.clr-polaroid .clr-alpha {
width: calc(100% - 30px);
height: 10px;
margin: 6px 15px;
border-radius: 5px;
}
.clr-polaroid .clr-hue div,
.clr-polaroid .clr-alpha div {
box-shadow: 0 0 5px rgba(0,0,0,.2);
}
.clr-polaroid .clr-format {
width: calc(100% - 20px);
margin: 0 10px 15px;
}
.clr-polaroid .clr-swatches {
width: calc(100% - 12px);
margin: 0 6px;
}
.clr-polaroid .clr-swatches div {
padding-bottom: 10px;
}
.clr-polaroid .clr-swatches button {
width: 22px;
height: 22px;
}
.clr-polaroid input.clr-color {
width: calc(100% - 60px);
margin: 10px 10px 15px auto;
}
.clr-polaroid .clr-clear {
margin: 0 10px 15px 10px;
}
.clr-polaroid .clr-close {
margin: 0 10px 15px auto;
}
.clr-polaroid .clr-preview {
margin: 10px 0 15px 10px;
}
/** Large theme **/
.clr-picker.clr-large {
width: 275px;
}
.clr-large .clr-gradient {
height: 150px;
}
.clr-large .clr-swatches button {
width: 22px;
height: 22px;
}
/** Pill (horizontal) theme **/
.clr-picker.clr-pill {
width: 380px;
padding-left: 180px;
box-sizing: border-box;
}
.clr-pill .clr-gradient {
position: absolute;
width: 180px;
height: 100%;
left: 0;
top: 0;
margin-bottom: 0;
border-radius: 3px 0 0 3px;
}
.clr-pill .clr-hue {
margin-top: 20px;
}

1263
src/coloris.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,8 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="stylesheet" href="styles.css" /> <link rel="stylesheet" href="styles.css" />
<link rel="stylesheet" href="coloris.css"/>
<script src="coloris.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tauri App</title> <title>Tauri App</title>
<script type="module" src="/main.js" defer></script> <script type="module" src="/main.js" defer></script>

View File

@ -8,25 +8,43 @@ let canvases = [];
let mode = "draw" let mode = "draw"
let minSegmentSize = 5;
let tools = { let tools = {
select: { select: {
icon: "/assets/select.png", icon: "/assets/select.svg",
},
transform: {
icon: "/assets/transform.svg",
}, },
draw: { draw: {
icon: "/assets/pen.png" icon: "/assets/draw.svg"
}, },
rectangle: { rectangle: {
icon: "/assets/rectangle.png" icon: "/assets/rectangle.svg"
}, },
polygon: { polygon: {
icon: "assets/polygon.png" icon: "assets/polygon.svg"
} }
} }
let mouseEvent; let mouseEvent;
let context = {} let context = {
mouseDown: false,
swatches: [
"#000000",
"#FFFFFF",
"#FF0000",
"#FFFF00",
"#00FF00",
"#00FFFF",
"#0000FF",
"#FF00FF",
]
}
function uuidv4() { function uuidv4() {
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
@ -34,6 +52,10 @@ function uuidv4() {
); );
} }
function vectorDist(a, b) {
return Math.sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y))
}
function getMousePos(canvas, evt) { function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect(); var rect = canvas.getBoundingClientRect();
return { return {
@ -69,6 +91,9 @@ class Shape {
this.filled = filled; this.filled = filled;
this.stroked = stroked; this.stroked = stroked;
} }
addCurve(curve) {
this.curves.push(curve)
}
} }
class GraphicsObject { class GraphicsObject {
@ -121,8 +146,9 @@ class GraphicsObject {
let root = new GraphicsObject(); let root = new GraphicsObject();
let shp = new Shape(100,100,'blue', 'black') let shp = new Shape(100,100,'blue', 'black')
shp.curves.push(new Curve(150,150,150,150,200,100)) shp.addCurve(new Curve(150,150,150,150,200,100))
root.addShape(shp) root.addShape(shp)
context.activeObject = root
async function greet() { async function greet() {
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/ // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
@ -155,6 +181,60 @@ function stage() {
scroller.className = "scroll" scroller.className = "scroll"
canvases.push(stage) canvases.push(stage)
scroller.appendChild(stage) scroller.appendChild(stage)
stage.addEventListener("mousedown", (e) => {
let mouse = getMousePos(stage, e)
switch (mode) {
case "draw":
context.mouseDown = true
context.activeShape = new Shape(mouse.x, mouse.y, context.fillStyle, context.strokeStyle, true, true)
context.activeObject.addShape(context.activeShape)
context.lastMouse = mouse
console.log(stage)
break;
default:
break;
}
context.lastMouse = mouse
updateUI()
})
stage.addEventListener("mouseup", (e) => {
context.mouseDown = false
let mouse = getMousePos(stage, e)
switch (mode) {
case "draw":
if (context.activeShape) {
if (vectorDist(mouse, context.lastMouse) > minSegmentSize) {
let midpoint = {x: (mouse.x+context.lastMouse.x)/2, y: (mouse.y+context.lastMouse.y)/2}
context.activeShape.addCurve(new Curve(midpoint.x, midpoint.y, midpoint.x, midpoint.y, mouse.x, mouse.y))
}
context.activeShape = undefined
}
break;
default:
break;
}
context.lastMouse = mouse
updateUI()
})
stage.addEventListener("mousemove", (e) => {
let mouse = getMousePos(stage, e)
switch (mode) {
case "draw":
if (context.activeShape) {
if (vectorDist(mouse, context.lastMouse) > minSegmentSize) {
let midpoint = {x: (mouse.x+context.lastMouse.x)/2, y: (mouse.y+context.lastMouse.y)/2}
context.activeShape.addCurve(new Curve(midpoint.x, midpoint.y, midpoint.x, midpoint.y, mouse.x, mouse.y))
}
}
break;
default:
break;
}
context.lastMouse = mouse
updateUI()
})
return scroller return scroller
} }
@ -170,6 +250,52 @@ function toolbar() {
toolbtn.appendChild(icon) toolbtn.appendChild(icon)
tools_scroller.appendChild(toolbtn) tools_scroller.appendChild(toolbtn)
} }
let tools_break = document.createElement("div")
tools_break.className = "horiz_break"
tools_scroller.appendChild(tools_break)
let fillColor = document.createElement("input")
let strokeColor = document.createElement("input")
fillColor.className = "color-field"
strokeColor.className = "color-field"
fillColor.value = "#ffffff"
strokeColor.value = "#000000"
fillColor.addEventListener('click', e => {
Coloris({
el: ".color-field",
selectInput: true,
focusInput: true,
theme: 'default',
swatches: context.swatches,
defaultColor: '#ffffff',
onChange: (color) => {
context.fillStyle = color;
}
})
})
strokeColor.addEventListener('click', e => {
Coloris({
el: ".color-field",
selectInput: true,
focusInput: true,
theme: 'default',
swatches: context.swatches,
defaultColor: '#000000',
onChange: (color) => {
context.strokeStyle = color;
}
})
})
// Fill and stroke colors use the same set of swatches
fillColor.addEventListener("change", e => {
context.swatches.unshift(fillColor.value)
if (context.swatches.length>12) context.swatches.pop();
})
strokeColor.addEventListener("change", e => {
context.swatches.unshift(strokeColor.value)
if (context.swatches.length>12) context.swatches.pop();
})
tools_scroller.appendChild(fillColor)
tools_scroller.appendChild(strokeColor)
return tools_scroller return tools_scroller
} }
@ -249,13 +375,13 @@ function updateUI() {
context.ctx = ctx; context.ctx = ctx;
root.draw(context) root.draw(context)
let mouse; // let mouse;
if (mouseEvent) { // if (mouseEvent) {
mouse = getMousePos(canvas, mouseEvent); // mouse = getMousePos(canvas, mouseEvent);
} else { // } else {
mouse = {x: 0, y: 0} // mouse = {x: 0, y: 0}
} // }
ctx.fillRect(mouse.x, mouse.y, 50,50) // ctx.fillRect(mouse.x, mouse.y, 50,50)
} }
requestAnimationFrame(updateUI) // requestAnimationFrame(updateUI)
} }

View File

@ -192,3 +192,10 @@ button {
height: var(--lineheight); */ height: var(--lineheight); */
background-color: #2f2f2f; background-color: #2f2f2f;
} }
.horiz_break {
width: 100%;
height: 5px;
background-color: #2f2f2f;
}