+Shapes, +Background, +Fill/Stroke, +Line Join
4
Ideas
Normal file → Executable file
@ -1,8 +1,8 @@
|
|||||||
Current
|
Current
|
||||||
=======
|
=======
|
||||||
Eraser
|
Eraser
|
||||||
Shapes
|
*Shapes
|
||||||
Fill
|
*Fill
|
||||||
Pen
|
Pen
|
||||||
Chalk
|
Chalk
|
||||||
Board Size
|
Board Size
|
||||||
|
0
Mobile/Sketchy-1.1.zip
Normal file → Executable file
0
Mobile/Sketchy-1.zip
Normal file → Executable file
0
Mobile/css/color-picker.less
Normal file → Executable file
0
Mobile/css/fonts.less
Normal file → Executable file
0
Mobile/css/fonts/MozTT-Bold.ttf
Normal file → Executable file
0
Mobile/css/fonts/MozTT-Light.ttf
Normal file → Executable file
0
Mobile/css/fonts/MozTT-Medium.ttf
Normal file → Executable file
0
Mobile/css/fonts/MozTT-Regular.ttf
Normal file → Executable file
0
Mobile/css/imgs/bg_overlay_pressed_1.png
Normal file → Executable file
Before Width: | Height: | Size: 93 B After Width: | Height: | Size: 93 B |
0
Mobile/css/imgs/bg_overlay_pressed_2.png
Normal file → Executable file
Before Width: | Height: | Size: 94 B After Width: | Height: | Size: 94 B |
0
Mobile/css/imgs/clear.png
Normal file → Executable file
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
0
Mobile/css/imgs/div_line_lg_black.png
Normal file → Executable file
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
0
Mobile/css/imgs/div_line_sm_black.png
Normal file → Executable file
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
0
Mobile/css/imgs/download.png
Normal file → Executable file
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
0
Mobile/css/imgs/header_bg_black.png
Normal file → Executable file
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
0
Mobile/css/imgs/load.png
Normal file → Executable file
Before Width: | Height: | Size: 413 B After Width: | Height: | Size: 413 B |
0
Mobile/css/imgs/menu.png
Normal file → Executable file
Before Width: | Height: | Size: 182 B After Width: | Height: | Size: 182 B |
0
Mobile/css/imgs/redo.png
Normal file → Executable file
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
0
Mobile/css/imgs/settings.png
Normal file → Executable file
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
0
Mobile/css/imgs/undo.png
Normal file → Executable file
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
61
Mobile/css/main.css
Normal file → Executable file
@ -301,7 +301,8 @@ form[role="dialog"][data-type="value-selector"] menu button::-moz-focus-inner {
|
|||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
form[role="dialog"][data-type="value-selector"] menu button {
|
form[role="dialog"][data-type="value-selector"] menu button,
|
||||||
|
.button {
|
||||||
width: calc(49.5%);
|
width: calc(49.5%);
|
||||||
height: 3.8rem;
|
height: 3.8rem;
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
@ -326,13 +327,15 @@ form[role="dialog"][data-type="value-selector"] menu button {
|
|||||||
}
|
}
|
||||||
/* Press (default & affirmative) */
|
/* Press (default & affirmative) */
|
||||||
form[role="dialog"][data-type="value-selector"] menu button:active,
|
form[role="dialog"][data-type="value-selector"] menu button:active,
|
||||||
form[role="dialog"][data-type="value-selector"] menu button.affirmative:active {
|
form[role="dialog"][data-type="value-selector"] menu button.affirmative:active,
|
||||||
|
.button:active {
|
||||||
border-color: #008aaa;
|
border-color: #008aaa;
|
||||||
background: #008aaa;
|
background: #008aaa;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
/* affirmative */
|
/* affirmative */
|
||||||
form[role="dialog"][data-type="value-selector"] menu button.affirmative {
|
form[role="dialog"][data-type="value-selector"] menu button.affirmative,
|
||||||
|
.button.affirmative {
|
||||||
background-image: url(value_selector/images/ui/affirmative.png);
|
background-image: url(value_selector/images/ui/affirmative.png);
|
||||||
background-color: #00caf2;
|
background-color: #00caf2;
|
||||||
border-color: #008eab;
|
border-color: #008eab;
|
||||||
@ -344,7 +347,8 @@ form[role="dialog"][data-type="value-selector"] menu button,
|
|||||||
form[role="dialog"][data-type="value-selector"] menu button:first-child {
|
form[role="dialog"][data-type="value-selector"] menu button:first-child {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
form[role="dialog"][data-type="value-selector"] menu button.full {
|
form[role="dialog"][data-type="value-selector"] menu button.full,
|
||||||
|
.button.full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
/* Right to left tweaks */
|
/* Right to left tweaks */
|
||||||
@ -358,6 +362,8 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
*::-moz-focus-inner {
|
*::-moz-focus-inner {
|
||||||
border: none;
|
border: none;
|
||||||
@ -366,8 +372,8 @@ body {
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none !important;
|
||||||
visibility: none;
|
visibility: none !important;
|
||||||
}
|
}
|
||||||
div#container {
|
div#container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -424,7 +430,8 @@ button {
|
|||||||
left: 97%;
|
left: 97%;
|
||||||
}
|
}
|
||||||
.picker,
|
.picker,
|
||||||
.about {
|
.about,
|
||||||
|
.tour {
|
||||||
font-family: 'MozTT-Light';
|
font-family: 'MozTT-Light';
|
||||||
width: 30rem;
|
width: 30rem;
|
||||||
height: 24.6rem;
|
height: 24.6rem;
|
||||||
@ -435,10 +442,12 @@ button {
|
|||||||
margin-left: -15rem;
|
margin-left: -15rem;
|
||||||
}
|
}
|
||||||
.picker .color-picker,
|
.picker .color-picker,
|
||||||
.about .color-picker {
|
.about .color-picker,
|
||||||
|
.tour .color-picker {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.about {
|
.about,
|
||||||
|
.tour {
|
||||||
background: #262626;
|
background: #262626;
|
||||||
padding: 1rem 2rem;
|
padding: 1rem 2rem;
|
||||||
height: 23rem;
|
height: 23rem;
|
||||||
@ -449,22 +458,35 @@ button {
|
|||||||
box-shadow: 0 0 0.3rem black;
|
box-shadow: 0 0 0.3rem black;
|
||||||
}
|
}
|
||||||
.about a,
|
.about a,
|
||||||
|
.tour a,
|
||||||
.about a:link,
|
.about a:link,
|
||||||
|
.tour a:link,
|
||||||
.about a:visited,
|
.about a:visited,
|
||||||
.about a:active {
|
.tour a:visited,
|
||||||
|
.about a:active,
|
||||||
|
.tour a:active {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
.about .close {
|
.about .close,
|
||||||
|
.tour .close {
|
||||||
background: #262626;
|
background: #262626;
|
||||||
color: white;
|
color: white;
|
||||||
border: 1px solid gray;
|
border: 1px solid gray;
|
||||||
}
|
}
|
||||||
.about p {
|
.about p,
|
||||||
|
.tour p {
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
}
|
}
|
||||||
.about span {
|
.about span,
|
||||||
|
.tour span {
|
||||||
font-size: 8pt;
|
font-size: 8pt;
|
||||||
}
|
}
|
||||||
|
.tour .button {
|
||||||
|
width: 30rem;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 1rem;
|
||||||
|
left: 1.8rem;
|
||||||
|
}
|
||||||
header {
|
header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 5.3rem;
|
height: 5.3rem;
|
||||||
@ -505,8 +527,9 @@ header #title {
|
|||||||
left: -2rem;
|
left: -2rem;
|
||||||
}
|
}
|
||||||
#menu {
|
#menu {
|
||||||
height: 100%;
|
|
||||||
width: 15rem;
|
width: 15rem;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
background: #262626;
|
background: #262626;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -15rem;
|
left: -15rem;
|
||||||
@ -516,7 +539,7 @@ header #title {
|
|||||||
font-size: 8pt;
|
font-size: 8pt;
|
||||||
transition: left 0.2s ease-out;
|
transition: left 0.2s ease-out;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
overflow: hidden;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
#menu.pulled {
|
#menu.pulled {
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -536,6 +559,9 @@ header #title {
|
|||||||
padding: 0 0.6rem;
|
padding: 0 0.6rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
#menu p {
|
||||||
|
width: 65%;
|
||||||
|
}
|
||||||
#menu span {
|
#menu span {
|
||||||
float: right;
|
float: right;
|
||||||
font-size: 7pt;
|
font-size: 7pt;
|
||||||
@ -588,13 +614,14 @@ header #title {
|
|||||||
background-image: url('imgs/redo.png');
|
background-image: url('imgs/redo.png');
|
||||||
}
|
}
|
||||||
#menu .options {
|
#menu .options {
|
||||||
display: block;
|
display: table-row;
|
||||||
|
vertical-align: top;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
#menu .bottom {
|
#menu .bottom {
|
||||||
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 5rem;
|
bottom: 5rem;
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
#menu .bottom button[class^='icon'] {
|
#menu .bottom button[class^='icon'] {
|
||||||
margin-left: 3.5rem;
|
margin-left: 3.5rem;
|
||||||
|
33
Mobile/css/main.less
Normal file → Executable file
@ -3,11 +3,12 @@
|
|||||||
@import 'seekbars';
|
@import 'seekbars';
|
||||||
@import 'value_selector';
|
@import 'value_selector';
|
||||||
|
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
*::-moz-focus-inner {
|
*::-moz-focus-inner {
|
||||||
@ -18,8 +19,8 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none !important;
|
||||||
visibility: none;
|
visibility: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#container {
|
div#container {
|
||||||
@ -82,7 +83,7 @@ button {
|
|||||||
left: 97%;
|
left: 97%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.picker, .about {
|
.picker, .about, .tour {
|
||||||
font-family: 'MozTT-Light';
|
font-family: 'MozTT-Light';
|
||||||
width: 30rem;
|
width: 30rem;
|
||||||
height: 24.6rem;
|
height: 24.6rem;
|
||||||
@ -97,7 +98,7 @@ button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.about {
|
.about, .tour {
|
||||||
background: #262626;
|
background: #262626;
|
||||||
padding: 1rem 2rem;;
|
padding: 1rem 2rem;;
|
||||||
height: 23rem;
|
height: 23rem;
|
||||||
@ -125,6 +126,15 @@ button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tour {
|
||||||
|
.button {
|
||||||
|
width: 30rem;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 1rem;
|
||||||
|
left: 1.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 5.3rem;
|
height: 5.3rem;
|
||||||
@ -172,8 +182,9 @@ header {
|
|||||||
|
|
||||||
|
|
||||||
#menu {
|
#menu {
|
||||||
height: 100%;
|
|
||||||
width: 15rem;
|
width: 15rem;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
background: #262626;
|
background: #262626;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -15rem;
|
left: -15rem;
|
||||||
@ -183,7 +194,7 @@ header {
|
|||||||
font-size: 8pt;
|
font-size: 8pt;
|
||||||
transition: left 0.2s ease-out;
|
transition: left 0.2s ease-out;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
overflow: hidden;
|
overflow-y: auto;
|
||||||
|
|
||||||
&.pulled {
|
&.pulled {
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -202,6 +213,9 @@ header {
|
|||||||
padding: 0 0.6rem;
|
padding: 0 0.6rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
p {
|
||||||
|
width: 65%;
|
||||||
|
}
|
||||||
span {
|
span {
|
||||||
float: right;
|
float: right;
|
||||||
font-size: 7pt;
|
font-size: 7pt;
|
||||||
@ -258,13 +272,14 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.options {
|
.options {
|
||||||
display: block;
|
display: table-row;
|
||||||
|
vertical-align: top;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
.bottom {
|
.bottom {
|
||||||
|
width: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 5rem;
|
bottom: 5rem;
|
||||||
width: 100%;
|
|
||||||
button[class^='icon'] {
|
button[class^='icon'] {
|
||||||
margin-left: 3.5rem;
|
margin-left: 3.5rem;
|
||||||
}
|
}
|
||||||
|
0
Mobile/css/seekbars.less
Normal file → Executable file
0
Mobile/css/seekbars/images/ui/handler.png
Normal file → Executable file
Before Width: | Height: | Size: 636 B After Width: | Height: | Size: 636 B |
0
Mobile/css/seekbars/images/ui/handler@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 960 B After Width: | Height: | Size: 960 B |
0
Mobile/css/seekbars/images/ui/handler@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 938 B After Width: | Height: | Size: 938 B |
0
Mobile/css/seekbars/seekbars.css
Normal file → Executable file
0
Mobile/css/switches.less
Normal file → Executable file
0
Mobile/css/switches/images/check/danger.png
Normal file → Executable file
Before Width: | Height: | Size: 583 B After Width: | Height: | Size: 583 B |
0
Mobile/css/switches/images/check/danger@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 946 B After Width: | Height: | Size: 946 B |
0
Mobile/css/switches/images/check/danger@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
0
Mobile/css/switches/images/check/default.png
Normal file → Executable file
Before Width: | Height: | Size: 583 B After Width: | Height: | Size: 583 B |
0
Mobile/css/switches/images/check/default@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 946 B After Width: | Height: | Size: 946 B |
0
Mobile/css/switches/images/check/default@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
0
Mobile/css/switches/images/radio/danger.png
Normal file → Executable file
Before Width: | Height: | Size: 578 B After Width: | Height: | Size: 578 B |
0
Mobile/css/switches/images/radio/danger@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 893 B After Width: | Height: | Size: 893 B |
0
Mobile/css/switches/images/radio/danger@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
0
Mobile/css/switches/images/radio/default.png
Normal file → Executable file
Before Width: | Height: | Size: 575 B After Width: | Height: | Size: 575 B |
0
Mobile/css/switches/images/radio/default@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 889 B After Width: | Height: | Size: 889 B |
0
Mobile/css/switches/images/radio/default@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
0
Mobile/css/switches/images/switch/background.png
Normal file → Executable file
Before Width: | Height: | Size: 755 B After Width: | Height: | Size: 755 B |
0
Mobile/css/switches/images/switch/background@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
0
Mobile/css/switches/images/switch/background_off.png
Normal file → Executable file
Before Width: | Height: | Size: 475 B After Width: | Height: | Size: 475 B |
0
Mobile/css/switches/images/switch/background_off@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 616 B After Width: | Height: | Size: 616 B |
8
Mobile/css/value_selector.less
Normal file → Executable file
@ -144,7 +144,7 @@ form[role="dialog"][data-type="value-selector"] menu button::-moz-focus-inner {
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
form[role="dialog"][data-type="value-selector"] menu button {
|
form[role="dialog"][data-type="value-selector"] menu button, .button {
|
||||||
width: calc((100% - 1rem) / 2);
|
width: calc((100% - 1rem) / 2);
|
||||||
height: 3.8rem;
|
height: 3.8rem;
|
||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
@ -170,14 +170,14 @@ form[role="dialog"][data-type="value-selector"] menu button {
|
|||||||
|
|
||||||
/* Press (default & affirmative) */
|
/* Press (default & affirmative) */
|
||||||
form[role="dialog"][data-type="value-selector"] menu button:active,
|
form[role="dialog"][data-type="value-selector"] menu button:active,
|
||||||
form[role="dialog"][data-type="value-selector"] menu button.affirmative:active {
|
form[role="dialog"][data-type="value-selector"] menu button.affirmative:active, .button:active {
|
||||||
border-color: #008aaa;
|
border-color: #008aaa;
|
||||||
background: #008aaa;
|
background: #008aaa;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* affirmative */
|
/* affirmative */
|
||||||
form[role="dialog"][data-type="value-selector"] menu button.affirmative {
|
form[role="dialog"][data-type="value-selector"] menu button.affirmative, .button.affirmative {
|
||||||
background-image: url(value_selector/images/ui/affirmative.png);
|
background-image: url(value_selector/images/ui/affirmative.png);
|
||||||
background-color: #00caf2;
|
background-color: #00caf2;
|
||||||
border-color: #008eab;
|
border-color: #008eab;
|
||||||
@ -192,7 +192,7 @@ form[role="dialog"][data-type="value-selector"] menu button:first-child {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
form[role="dialog"][data-type="value-selector"] menu button.full {
|
form[role="dialog"][data-type="value-selector"] menu button.full, .button.full {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
0
Mobile/css/value_selector/images/icons/checked.png
Normal file → Executable file
Before Width: | Height: | Size: 177 B After Width: | Height: | Size: 177 B |
0
Mobile/css/value_selector/images/icons/checked@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 392 B After Width: | Height: | Size: 392 B |
0
Mobile/css/value_selector/images/icons/checked@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 601 B After Width: | Height: | Size: 601 B |
0
Mobile/css/value_selector/images/ui/affirmative.png
Normal file → Executable file
Before Width: | Height: | Size: 101 B After Width: | Height: | Size: 101 B |
0
Mobile/css/value_selector/images/ui/default.png
Normal file → Executable file
Before Width: | Height: | Size: 82 B After Width: | Height: | Size: 82 B |
0
Mobile/css/value_selector/images/ui/gradient.png
Normal file → Executable file
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
0
Mobile/css/value_selector/images/ui/gradient@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
0
Mobile/css/value_selector/images/ui/pattern.png
Normal file → Executable file
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
0
Mobile/css/value_selector/images/ui/shadow-invert.png
Normal file → Executable file
Before Width: | Height: | Size: 83 B After Width: | Height: | Size: 83 B |
0
Mobile/css/value_selector/images/ui/shadow-invert@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 154 B After Width: | Height: | Size: 154 B |
0
Mobile/css/value_selector/images/ui/shadow-invert@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 86 B After Width: | Height: | Size: 86 B |
0
Mobile/css/value_selector/images/ui/shadow.png
Normal file → Executable file
Before Width: | Height: | Size: 82 B After Width: | Height: | Size: 82 B |
0
Mobile/css/value_selector/images/ui/shadow@1.5x.png
Normal file → Executable file
Before Width: | Height: | Size: 154 B After Width: | Height: | Size: 154 B |
0
Mobile/css/value_selector/images/ui/shadow@2x.png
Normal file → Executable file
Before Width: | Height: | Size: 87 B After Width: | Height: | Size: 87 B |
0
Mobile/img/icons/MozillaFXOSIconTemplate1_overlay.png
Normal file → Executable file
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
0
Mobile/img/icons/icon120.png
Normal file → Executable file
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
0
Mobile/img/icons/icon128.png
Normal file → Executable file
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
0
Mobile/img/icons/icon16.png
Normal file → Executable file
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 738 B |
0
Mobile/img/icons/icon2.png
Normal file → Executable file
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
0
Mobile/img/icons/icon2.svg
Normal file → Executable file
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
0
Mobile/img/icons/icon32.png
Normal file → Executable file
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
0
Mobile/img/icons/icon48.png
Normal file → Executable file
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
0
Mobile/img/icons/icon60.png
Normal file → Executable file
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
0
Mobile/img/icons/icon64.png
Normal file → Executable file
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
0
Mobile/img/icons/icon90.png
Normal file → Executable file
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
57
Mobile/index.html
Normal file → Executable file
@ -24,12 +24,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id='menu'>
|
<div id='menu'>
|
||||||
<p class='icon-settings'>Settings</p>
|
|
||||||
<div class='options'>
|
<div class='options'>
|
||||||
|
<p class='icon-settings'>Settings</p>
|
||||||
<div class='general'>
|
<div class='general'>
|
||||||
<button id='settype'>Brush Type<span>Sketch</span></button>
|
<button id='settype'>Brush Type<span>Sketch</span></button>
|
||||||
<button id='setcolor'>Color<span>#000000</span></button>
|
<button id='setcolor'>Color<span>#000000</span></button>
|
||||||
<!--<button id='setlineJoin'>Line Join<span>Round</span></button>-->
|
<button id='setbg'>Background<span>#ffffff</span></button>
|
||||||
|
<button id='setlineJoin'>Line Join<span>Round</span></button>
|
||||||
<button id='setlineCap'>Line Cap<span>Round</span></button>
|
<button id='setlineCap'>Line Cap<span>Round</span></button>
|
||||||
<p id='lineWidth'>Line Width <span>2</span></p>
|
<p id='lineWidth'>Line Width <span>2</span></p>
|
||||||
<div role="slider" class='lineWidth'>
|
<div role="slider" class='lineWidth'>
|
||||||
@ -69,6 +70,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class='line hidden'>
|
||||||
|
<p class='fill'>Fill<span>No</span></p>
|
||||||
|
<p class='stroke'>Stroke<span>Yes</span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='shape hidden'>
|
||||||
|
<p class='icon-settings'>Shape</p>
|
||||||
|
<button id='setshape'>Type<span>Circle</span></button>
|
||||||
|
<p class='fill'>Fill<span>No</span></p>
|
||||||
|
<p class='stroke'>Stroke<span>Yes</span></p>
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='bottom'>
|
<div class='bottom'>
|
||||||
<button id='clear' class='icon-clear'>Clear</button>
|
<button id='clear' class='icon-clear'>Clear</button>
|
||||||
@ -79,14 +94,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<form role='dialog' data-type='value-selector' id='type' class='hidden single'>
|
<form role='dialog' data-type='value-selector' id='type' class='hidden single'>
|
||||||
<section class='scrollable'>
|
<section class='scrollable'>
|
||||||
<h1>Brush Type</h1>
|
<h1>Brush Type</h1>
|
||||||
<ol role='listbox'>
|
<ol role='listbox'>
|
||||||
<li aria-selected='true'><label><span>Sketch</span></label></li>
|
<li aria-selected='true' data-target='sketch'><label><span>Sketch</span></label></li>
|
||||||
<li><label><span>Fur</span></label></li>
|
<li data-target='fur'><label><span>Fur</span></label></li>
|
||||||
<li><label><span>Pen</span></label></li>
|
<li data-target='pencil'><label><span>Pencil</span></label></li>
|
||||||
<li><label><span>Line</span></label></li>
|
<li data-target='line'><label><span>Line</span></label></li>
|
||||||
|
<li data-target='shape'><label><span>Shape</span></label></li>
|
||||||
<!--<li><label><span>Eraser</span></label></li>-->
|
<!--<li><label><span>Eraser</span></label></li>-->
|
||||||
</ol>
|
</ol>
|
||||||
</section>
|
</section>
|
||||||
@ -109,6 +126,22 @@
|
|||||||
</menu>
|
</menu>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<form role='dialog' data-type='value-selector' id='shape' class='hidden single'>
|
||||||
|
<section class='scrollable'>
|
||||||
|
<h1>Shape Type</h1>
|
||||||
|
<ol role='listbox'>
|
||||||
|
<li aria-selected='true' data-target='shape'><label><span>Circle</span></label></li>
|
||||||
|
<li data-target='shape'><label><span>Rectangle</span></label></li>
|
||||||
|
<li data-target='shape'><label><span>Square</span></label></li>
|
||||||
|
<li data-target='shape'><label><span>Triangle</span></label></li>
|
||||||
|
</ol>
|
||||||
|
<menu>
|
||||||
|
<button class='affirmative full'>Cancel</button>
|
||||||
|
</menu>
|
||||||
|
</section>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
<form role='dialog' data-type='value-selector' id='lineCap' class='hidden single'>
|
<form role='dialog' data-type='value-selector' id='lineCap' class='hidden single'>
|
||||||
<section class='scrollable'>
|
<section class='scrollable'>
|
||||||
<h1>Line Cap</h1>
|
<h1>Line Cap</h1>
|
||||||
@ -186,7 +219,7 @@
|
|||||||
<span>Sketchy was found by Mahdi Dibaiee. More info: <a href='http://about.me/mdibaiee'>About.me</a>
|
<span>Sketchy was found by Mahdi Dibaiee. More info: <a href='http://about.me/mdibaiee'>About.me</a>
|
||||||
<br><br>
|
<br><br>
|
||||||
Contact: <br>
|
Contact: <br>
|
||||||
<a href='https://twitter.com/mdibaiee'>Twitter</a><br />
|
<a href='https://twitter.com/mdibaiee'>Twitter</a> •
|
||||||
<a href='mailto:mdibaiee@aol.com'>Email</a>
|
<a href='mailto:mdibaiee@aol.com'>Email</a>
|
||||||
<br><br>
|
<br><br>
|
||||||
<a href='http://mdibaiee.github.io/Sketchy/changelog.html'>Changelog</a>
|
<a href='http://mdibaiee.github.io/Sketchy/changelog.html'>Changelog</a>
|
||||||
@ -194,6 +227,16 @@
|
|||||||
<button class='close'>x</button>
|
<button class='close'>x</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class='tour overlay hidden'>
|
||||||
|
<p>Tips</p>
|
||||||
|
<span>Hey! Let me give you some tips to help you along the way,</span><br /><br />
|
||||||
|
<span>To finish a line, hold your finger for 1 second on mobile, or double click on desktop.</span><br />
|
||||||
|
<span>Line join, fill / stroke are applied when the line is finished.</span><br /><br />
|
||||||
|
<span>If you found something missing, please get in touch with us.</span>
|
||||||
|
<button class='button'>Gotcha!</button>
|
||||||
|
<button class='close'>x</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- PRELOADER -->
|
<!-- PRELOADER -->
|
||||||
<div class='hidden'>
|
<div class='hidden'>
|
||||||
<img src='css/value_selector/images/ui/pattern.png'>
|
<img src='css/value_selector/images/ui/pattern.png'>
|
||||||
|
239
Mobile/js/functions-m.js
Executable file
@ -0,0 +1,239 @@
|
|||||||
|
"use strict";
|
||||||
|
/*** ESSENTIALS ***/
|
||||||
|
|
||||||
|
function sizeAndPos() {
|
||||||
|
|
||||||
|
var data = c.getImageData(0,0, $c.width(), $c.height());
|
||||||
|
var w = $(window).width(),
|
||||||
|
h = $(window).height() - 53;
|
||||||
|
$c.attr('width', w * window.devicePixelRatio);
|
||||||
|
$c.attr('height',h * window.devicePixelRatio);
|
||||||
|
$c.css({
|
||||||
|
'width' : w,
|
||||||
|
'height' : h
|
||||||
|
});
|
||||||
|
c.clearRect(0,0, width(), height());
|
||||||
|
c.putImageData(data, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function relative(x,y, el) {
|
||||||
|
var el = el || $c[0];
|
||||||
|
return {
|
||||||
|
x : x*window.devicePixelRatio - el.offset().left,
|
||||||
|
y : (y - 53) * window.devicePixelRatio - el.offset().top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function threshold(x1, y1, x2, y2, threshold) {
|
||||||
|
var tr = threshold || 5;
|
||||||
|
if( x1 <= x2 + tr && x1 >= x2 - tr && y1 <= y2 + tr && y1 >= y2 - tr ) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw(x1, y1, x2, y2, opts, overlay) {
|
||||||
|
opts = opts || {};
|
||||||
|
var c = window.c;
|
||||||
|
if( overlay ) var c = window.o;
|
||||||
|
c.beginPath();
|
||||||
|
if( settings.type == 'eraser' ) c.globalCompositeOperation = 'destination-out';
|
||||||
|
else c.globalCompositeOperation = opts.composite || settings.composite;
|
||||||
|
c.lineCap = opts.lineCap || settings.lineCap;
|
||||||
|
c.lineJoin = opts.lineJoin || settings.lineJoin;
|
||||||
|
c.strokeStyle = opts.color || settings.color;
|
||||||
|
c.fillStyle = opts.color || settings.color;
|
||||||
|
c.lineWidth = ( opts.lineWidth || settings.lineWidth ) / 10;
|
||||||
|
c.moveTo(x1, y1);
|
||||||
|
c.lineTo(x2, y2);
|
||||||
|
if( !opts.noStroke ) c.stroke();
|
||||||
|
if( opts.fill ) c.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
function shape(opts, overlay) {
|
||||||
|
if(overlay) var c = window.o;
|
||||||
|
else var c = window.c;
|
||||||
|
c.beginPath();
|
||||||
|
c.fillStyle = opts.color || settings.color;
|
||||||
|
switch(opts.type) {
|
||||||
|
|
||||||
|
case 'circle': {
|
||||||
|
c.arc(opts.x, opts.y, opts.radius, 0, 2*Math.PI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'rectangle': {
|
||||||
|
c.rect(opts.x, opts.y, opts.width, opts.height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'square': {
|
||||||
|
c.rect(opts.x, opts.y, opts.width, opts.width);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'triangle': {
|
||||||
|
c.fillStyle = opts
|
||||||
|
c.moveTo(opts.x1, opts.y1);
|
||||||
|
c.lineTo(opts.x2, opts.y2);
|
||||||
|
c.lineTo(opts.x3, opts.y3);
|
||||||
|
c.lineTo(opts.x1, opts.y1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
c.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function undo() {
|
||||||
|
var history = window.points.history;
|
||||||
|
if( history.last > 1 ) {
|
||||||
|
var step = history[history.last-1];
|
||||||
|
c.putImageData(step.data, 0, 0);
|
||||||
|
window.points = step.points.slice(0);
|
||||||
|
window.points.history = history;
|
||||||
|
window.points.history.last = history.last-1;
|
||||||
|
} else {
|
||||||
|
c.clearRect(0,0, width(), height());
|
||||||
|
window.points = [];
|
||||||
|
window.points.history = history;
|
||||||
|
window.points.history.last = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function redo() {
|
||||||
|
var history = window.points.history;
|
||||||
|
if( history.last < history.length-1 ) {
|
||||||
|
var step = history[history.last+1];
|
||||||
|
c.putImageData(step.data, 0, 0);
|
||||||
|
window.points = step.points.slice(0);
|
||||||
|
window.points.history = history;
|
||||||
|
window.points.history.last = history.last+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function width() {
|
||||||
|
return +$c.attr('width');
|
||||||
|
}
|
||||||
|
|
||||||
|
function height() {
|
||||||
|
return +$c.attr('height');
|
||||||
|
}
|
||||||
|
|
||||||
|
function dataToBlob(data) {
|
||||||
|
var binary = atob(data.split(',')[1]), array = [];
|
||||||
|
var type = data.split(',')[0].split(':')[1].split(';')[0];
|
||||||
|
for(var i = 0; i < binary.length; i++) array.push(binary.charCodeAt(i));
|
||||||
|
return new Blob([new Uint8Array(array)], {type: type});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*** END ***/
|
||||||
|
|
||||||
|
function startPoint(x, y) {
|
||||||
|
|
||||||
|
// If no previous point exists, make the first one.
|
||||||
|
if( !points.length ) points.push({x: x, y: y, type: '', start: {x: x, y: y}});
|
||||||
|
|
||||||
|
var old = points[points.length-1],
|
||||||
|
start = old.start,
|
||||||
|
current = {
|
||||||
|
x : x,
|
||||||
|
y : y,
|
||||||
|
start : old.start || {x: x, y: y},
|
||||||
|
type : settings.type
|
||||||
|
}
|
||||||
|
// Line
|
||||||
|
if( old.type !== 'line' && current.type == 'line' ) {
|
||||||
|
window.o.beginPath();
|
||||||
|
window.o.fillStyle = 'red';
|
||||||
|
window.o.arc(x,y, 3, 0, 2*Math.PI);
|
||||||
|
window.o.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( old.type == 'line' && current.type == 'line' ) {
|
||||||
|
if( points[points.indexOf(old)-1].type !== 'line' ) {
|
||||||
|
o.clearRect(old.x-3, old.y-3, 6, 6, true);
|
||||||
|
draw(old.x, old.y, x, y);
|
||||||
|
} else
|
||||||
|
draw(old.x, old.y, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shapes
|
||||||
|
|
||||||
|
if( old.type !== 'shape' && current.type == 'shape' ) {
|
||||||
|
settings.shape.
|
||||||
|
}
|
||||||
|
|
||||||
|
var thresholds = window.mobile ? [10, 5] : [5, 2];
|
||||||
|
if( points.length > 1 && ((start && threshold(start.x, start.y, x, y, thresholds[0])) || threshold(old.x, old.y, x, y, thresholds[1])) ) {
|
||||||
|
window.active = false;
|
||||||
|
points[points.length-1].type = '';
|
||||||
|
points[points.length-1].start = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
points.push(current);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawPoint(x,y) {
|
||||||
|
var capture = points[points.length-1];
|
||||||
|
|
||||||
|
switch(capture.type) {
|
||||||
|
case 'eraser': {
|
||||||
|
capture.type = 'pen';
|
||||||
|
}
|
||||||
|
case 'pen': {
|
||||||
|
draw(capture.x, capture.y, x, y);
|
||||||
|
|
||||||
|
var current = {
|
||||||
|
x : x,
|
||||||
|
y : y,
|
||||||
|
start : capture.start,
|
||||||
|
type : capture.type
|
||||||
|
}
|
||||||
|
|
||||||
|
points.push(current);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'sketch': {
|
||||||
|
draw(capture.x, capture.y, x, y);
|
||||||
|
var current = {
|
||||||
|
x : x,
|
||||||
|
y : y,
|
||||||
|
start : capture.start,
|
||||||
|
type : capture.type
|
||||||
|
}
|
||||||
|
points.push(current);
|
||||||
|
|
||||||
|
for( var i = 0, len = points.length-1; i < len; i++ ) {
|
||||||
|
if(threshold(points[i].x, points[i].y, current.x, current.y, settings.connectTelorance)) {
|
||||||
|
var x = points[i].x - current.x,
|
||||||
|
y = points[i].y - current.y;
|
||||||
|
var w = settings.lineWidth/20 > 0.2 ? settings.lineWidth/20 : 0.2;
|
||||||
|
|
||||||
|
draw(points[i].x - x*0.2, points[i].y - y*0.2, current.x + x*0.2, current.y + y*0.2, {strokeStyle: 'rgba(0,0,0,0.4)', lineWidth: w})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'fur': {
|
||||||
|
draw(capture.x, capture.y, x, y);
|
||||||
|
var current = {
|
||||||
|
x : x,
|
||||||
|
y : y,
|
||||||
|
start : capture.start,
|
||||||
|
type : capture.type
|
||||||
|
}
|
||||||
|
points.push(current);
|
||||||
|
|
||||||
|
for( var i = 0, len = points.length-1; i < len; i++ ) {
|
||||||
|
if(threshold(points[i].x, points[i].y, current.x, current.y, settings.connectTelorance)) {
|
||||||
|
var x = points[i].x - current.x,
|
||||||
|
y = points[i].y - current.y;
|
||||||
|
var l = settings.furLength / 100 || 0.2;
|
||||||
|
var w = settings.lineWidth/20 > 0.2 ? settings.lineWidth/20 : 0.2;
|
||||||
|
|
||||||
|
draw(points[i].x + x*l, points[i].y + y*l, current.x - x*l, current.y - y*l, {strokeStyle: 'rgba(0,0,0,0.4)', lineWidth: w})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
0
Mobile/js/functions.css
Normal file → Executable file
200
Mobile/js/functions.js
Normal file → Executable file
@ -12,15 +12,16 @@ function sizeAndPos() {
|
|||||||
'width' : w,
|
'width' : w,
|
||||||
'height' : h
|
'height' : h
|
||||||
});
|
});
|
||||||
c.clearRect(0,0, width(), height());
|
c.clear();
|
||||||
c.putImageData(data, 0, 0);
|
c.putImageData(data, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function relative(x,y, el) {
|
function relative(x,y, el) {
|
||||||
var el = el || $c[0];
|
var el = el || $c,
|
||||||
|
offset = el.offset();
|
||||||
return {
|
return {
|
||||||
x : x*window.devicePixelRatio - el.offset().left,
|
x : (x - offset.left) *window.devicePixelRatio,
|
||||||
y : (y - 53) * window.devicePixelRatio - el.offset().top
|
y : (y - offset.top) * window.devicePixelRatio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,8 +33,8 @@ function threshold(x1, y1, x2, y2, threshold) {
|
|||||||
|
|
||||||
function draw(x1, y1, x2, y2, opts, overlay) {
|
function draw(x1, y1, x2, y2, opts, overlay) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
var c = window.c;
|
|
||||||
if( overlay ) var c = window.o;
|
if( overlay ) var c = window.o;
|
||||||
|
else var c = window.c;
|
||||||
c.beginPath();
|
c.beginPath();
|
||||||
if( settings.type == 'eraser' ) c.globalCompositeOperation = 'destination-out';
|
if( settings.type == 'eraser' ) c.globalCompositeOperation = 'destination-out';
|
||||||
else c.globalCompositeOperation = opts.composite || settings.composite;
|
else c.globalCompositeOperation = opts.composite || settings.composite;
|
||||||
@ -44,41 +45,76 @@ function draw(x1, y1, x2, y2, opts, overlay) {
|
|||||||
c.lineWidth = ( opts.lineWidth || settings.lineWidth ) / 10;
|
c.lineWidth = ( opts.lineWidth || settings.lineWidth ) / 10;
|
||||||
c.moveTo(x1, y1);
|
c.moveTo(x1, y1);
|
||||||
c.lineTo(x2, y2);
|
c.lineTo(x2, y2);
|
||||||
if( !opts.noStroke ) c.stroke();
|
if( !opts.noStroke || settings.noStroke ) c.stroke();
|
||||||
if( opts.fill ) c.fill();
|
if( opts.fill || settings.fill ) c.fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
function shape(opts, overlay) {
|
function mark(x, y) {
|
||||||
if(overlay) var c = window.o;
|
var o = window.o;
|
||||||
else var c = window.c;
|
o.beginPath();
|
||||||
|
o.fillStyle = 'red';
|
||||||
|
o.arc(x,y, 3, 0, 2*Math.PI);
|
||||||
|
o.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
function erase(x1, y1, x2, y2, opts) {
|
||||||
|
var opts = opts || {};
|
||||||
|
var c = window.c;
|
||||||
c.beginPath();
|
c.beginPath();
|
||||||
|
c.lineWidth = ( opts.lineWidth || settings.lineWidth ) / 10;
|
||||||
|
c.globalCompositeOperation = 'source-out';
|
||||||
|
c.moveTo(x1, y1);
|
||||||
|
c.lineTo(x2, y2);
|
||||||
|
window.points = window.points.filter(function(e, i) {
|
||||||
|
if(!threshold(e.x, e.y, x1, y1, c.lineWidth) &&
|
||||||
|
!threshold(e.x, e.y, x2, y2, c.lineWidth) ) return true;
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function line(x, y, opts) {
|
||||||
|
var opts = opts || {};
|
||||||
|
var o = window.o;
|
||||||
|
o.beginPath();
|
||||||
|
o.lineCap = opts.lineCap || settings.lineCap;
|
||||||
|
o.lineJoin = opts.lineJoin || settings.lineJoin;
|
||||||
|
o.strokeStyle = opts.color || settings.color;
|
||||||
|
o.fillStyle = opts.color || settings.color;
|
||||||
|
o.lineWidth = ( opts.lineWidth || settings.lineWidth ) / 10;
|
||||||
|
var last = settings.drawingLine.length-1;
|
||||||
|
o.moveTo(settings.drawingLine[last].x, settings.drawingLine[last].y);
|
||||||
|
o.lineTo(x,y);
|
||||||
|
settings.drawingLine.push({
|
||||||
|
x: x,
|
||||||
|
y: y
|
||||||
|
})
|
||||||
|
o.stroke();
|
||||||
|
if( opts.fill || settings.fill ) o.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishLine(opts) {
|
||||||
|
var opts = opts || {};
|
||||||
|
var c = window.c;
|
||||||
|
o.clear();
|
||||||
|
c.beginPath();
|
||||||
|
c.strokeStyle = opts.color || settings.color;
|
||||||
c.fillStyle = opts.color || settings.color;
|
c.fillStyle = opts.color || settings.color;
|
||||||
switch(opts.type) {
|
c.lineWidth = ( opts.lineWidth || settings.lineWidth ) / 10;
|
||||||
|
c.lineJoin = opts.lineJoin || settings.lineJoin;
|
||||||
case 'circle': {
|
c.lineCap = opts.lineJoin || settings.lineJoin;
|
||||||
c.arc(opts.x, opts.y, opts.radius, 0, 2*Math.PI);
|
c.moveTo(settings.drawingLine[0].x, settings.drawingLine[0].y);
|
||||||
break;
|
for( var i = 1, len = settings.drawingLine.length; i < len; i++ ) {
|
||||||
|
c.lineTo(settings.drawingLine[i].x, settings.drawingLine[i].y);
|
||||||
}
|
}
|
||||||
case 'rectangle': {
|
if( settings.stroke ) c.stroke();
|
||||||
c.rect(opts.x, opts.y, opts.width, opts.height);
|
if( settings.fill ) c.fill();
|
||||||
break;
|
settings.drawingLine = [];
|
||||||
|
window.points.history.push({
|
||||||
|
data: c.getImageData(0, 0, width(), height()),
|
||||||
|
points: window.points.slice(0)
|
||||||
|
})
|
||||||
|
window.points.history.last = window.points.history.length-1;
|
||||||
}
|
}
|
||||||
case 'square': {
|
|
||||||
c.rect(opts.x, opts.y, opts.width, opts.width);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'triangle': {
|
|
||||||
c.fillStyle = opts
|
|
||||||
c.moveTo(opts.x1, opts.y1);
|
|
||||||
c.lineTo(opts.x2, opts.y2);
|
|
||||||
c.lineTo(opts.x3, opts.y3);
|
|
||||||
c.lineTo(opts.x1, opts.y1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
c.fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function undo() {
|
function undo() {
|
||||||
var history = window.points.history;
|
var history = window.points.history;
|
||||||
@ -89,7 +125,7 @@ function undo() {
|
|||||||
window.points.history = history;
|
window.points.history = history;
|
||||||
window.points.history.last = history.last-1;
|
window.points.history.last = history.last-1;
|
||||||
} else {
|
} else {
|
||||||
c.clearRect(0,0, width(), height());
|
c.clear();
|
||||||
window.points = [];
|
window.points = [];
|
||||||
window.points.history = history;
|
window.points.history = history;
|
||||||
window.points.history.last = 0;
|
window.points.history.last = 0;
|
||||||
@ -139,26 +175,27 @@ function startPoint(x, y) {
|
|||||||
start : old.start || {x: x, y: y},
|
start : old.start || {x: x, y: y},
|
||||||
type : settings.type
|
type : settings.type
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line
|
// Line
|
||||||
if( old.type !== 'line' && current.type == 'line' ) {
|
if( old.type !== 'line' && current.type == 'line' ) {
|
||||||
window.o.beginPath();
|
mark(x, y);
|
||||||
window.o.fillStyle = 'red';
|
settings.drawingLine.push({
|
||||||
window.o.arc(x,y, 3, 0, 2*Math.PI);
|
x: x,
|
||||||
window.o.fill();
|
y: y
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if( old.type == 'line' && current.type == 'line' ) {
|
if( old.type == 'line' && current.type == 'line' ) {
|
||||||
if( points[points.indexOf(old)-1].type !== 'line' ) {
|
if( points[points.indexOf(old)-1].type !== 'line' ) {
|
||||||
o.clearRect(old.x-3, old.y-3, 6, 6, true);
|
o.clear();
|
||||||
draw(old.x, old.y, x, y);
|
}
|
||||||
} else
|
line(x, y);
|
||||||
draw(old.x, old.y, x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shapes
|
// Shapes
|
||||||
|
|
||||||
if( old.type !== 'shape' && current.type == 'shape' ) {
|
if( current.type == 'shape' ) {
|
||||||
settings.shape.
|
settings.shapeStart = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
var thresholds = window.mobile ? [10, 5] : [5, 2];
|
var thresholds = window.mobile ? [10, 5] : [5, 2];
|
||||||
@ -166,6 +203,7 @@ function startPoint(x, y) {
|
|||||||
window.active = false;
|
window.active = false;
|
||||||
points[points.length-1].type = '';
|
points[points.length-1].type = '';
|
||||||
points[points.length-1].start = undefined;
|
points[points.length-1].start = undefined;
|
||||||
|
finishLine();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
points.push(current);
|
points.push(current);
|
||||||
@ -176,9 +214,9 @@ function drawPoint(x,y) {
|
|||||||
|
|
||||||
switch(capture.type) {
|
switch(capture.type) {
|
||||||
case 'eraser': {
|
case 'eraser': {
|
||||||
capture.type = 'pen';
|
erase(capture.x, capture.y, x, y);
|
||||||
}
|
}
|
||||||
case 'pen': {
|
case 'pencil': {
|
||||||
draw(capture.x, capture.y, x, y);
|
draw(capture.x, capture.y, x, y);
|
||||||
|
|
||||||
var current = {
|
var current = {
|
||||||
@ -234,6 +272,74 @@ function drawPoint(x,y) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'shape': {
|
||||||
|
o.clear();
|
||||||
|
o.beginPath();
|
||||||
|
o.fillStyle = settings.color;
|
||||||
|
o.strokeStyle = settings.color;
|
||||||
|
o.lineWidth = settings.lineWidth / 20;
|
||||||
|
var start = settings.shapeStart;
|
||||||
|
switch(settings.shape) {
|
||||||
|
case 'circle': {
|
||||||
|
var di = Math.abs(x - start.x);
|
||||||
|
o.arc(start.x, start.y, di, 0, 2*Math.PI);
|
||||||
|
settings.comShape = {
|
||||||
|
type: 'circle',
|
||||||
|
x: start.x,
|
||||||
|
y: start.y,
|
||||||
|
radius: di
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'rectangle': {
|
||||||
|
var w = x - start.x;
|
||||||
|
var h = y - start.y;
|
||||||
|
o.rect(start.x, start.y, w, h);
|
||||||
|
settings.comShape = {
|
||||||
|
type: 'rectangle',
|
||||||
|
x: start.x,
|
||||||
|
y: start.y,
|
||||||
|
w: w,
|
||||||
|
h: h
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'square': {
|
||||||
|
var w = x - start.x;
|
||||||
|
o.rect(start.x, start.y, w, w);
|
||||||
|
settings.comShape = {
|
||||||
|
type: 'rectangle',
|
||||||
|
x: start.x,
|
||||||
|
y: start.y,
|
||||||
|
w: w,
|
||||||
|
h: w
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'triangle': {
|
||||||
|
var dix = (x - start.x)/2;
|
||||||
|
var diy = (y - start.y)/2;
|
||||||
|
o.moveTo(start.x + dix, start.y);
|
||||||
|
o.lineTo(x, y);
|
||||||
|
o.lineTo(start.x, y);
|
||||||
|
o.lineTo(start.x + dix, start.y);
|
||||||
|
settings.comShape = {
|
||||||
|
type: 'triangle',
|
||||||
|
start: {
|
||||||
|
x: start.x,
|
||||||
|
y: start.y
|
||||||
|
},
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
dix: dix,
|
||||||
|
diy: diy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( settings.fill ) o.fill();
|
||||||
|
if( settings.stroke ) o.stroke();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
0
Mobile/js/less-1.5.0.min.js
vendored
Normal file → Executable file
0
Mobile/js/libs/color-picker-touch.js
Normal file → Executable file
0
Mobile/js/libs/color-picker.js
Normal file → Executable file
0
Mobile/js/libs/mobilebrowsers.js
Normal file → Executable file
0
Mobile/js/libs/stack.js
Normal file → Executable file
0
Mobile/js/libs/touch.js
Normal file → Executable file
0
Mobile/js/libs/yepnope.min.js
vendored
Normal file → Executable file
0
Mobile/js/libs/zepto.min.js
vendored
Normal file → Executable file
31
Mobile/js/main.js
Normal file → Executable file
@ -3,8 +3,12 @@
|
|||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
window.c = $('canvas')[0].getContext('2d');
|
window.c = $('canvas')[0].getContext('2d');
|
||||||
window.o = $('canvas')[1].getContext('2d');
|
window.o = $('canvas')[1].getContext('2d');
|
||||||
|
window.c.clear = window.o.clear = function() {
|
||||||
|
this.clearRect(0, 0, width(), height());
|
||||||
|
}
|
||||||
window.settings = {
|
window.settings = {
|
||||||
|
stroke: true,
|
||||||
|
fill: false,
|
||||||
lineWidth : 2,
|
lineWidth : 2,
|
||||||
color : 'black',
|
color : 'black',
|
||||||
type: 'sketch',
|
type: 'sketch',
|
||||||
@ -12,7 +16,12 @@ $(document).ready(function() {
|
|||||||
lineJoin: 'round',
|
lineJoin: 'round',
|
||||||
furLength: 5,
|
furLength: 5,
|
||||||
connectTelorance: 40,
|
connectTelorance: 40,
|
||||||
composite: 'source-over'
|
composite: 'source-over',
|
||||||
|
shape: 'circle',
|
||||||
|
shapeStart: {},
|
||||||
|
comShape: {},
|
||||||
|
drawingLine: [],
|
||||||
|
version: 1.2
|
||||||
};
|
};
|
||||||
window.points = [];
|
window.points = [];
|
||||||
window.$c = $('canvas');
|
window.$c = $('canvas');
|
||||||
@ -20,19 +29,21 @@ $(document).ready(function() {
|
|||||||
window.points.history.last = 0;
|
window.points.history.last = 0;
|
||||||
|
|
||||||
sizeAndPos();
|
sizeAndPos();
|
||||||
//$(window).resize(sizeAndPos);
|
|
||||||
|
|
||||||
$('.color-picker').change(function() {
|
$('.color-picker').change(function() {
|
||||||
var c = $(this).find('.color').val();
|
var c = $(this).find('.color').val();
|
||||||
settings.color = c;
|
var caller = $(this).parent().attr('data-caller');
|
||||||
$('#setcolor span').html(c);
|
settings[caller] = c;
|
||||||
|
$('#set' + caller + ' span').html(c);
|
||||||
|
if( caller == 'bg' ) {
|
||||||
|
$c.first().css('background', c);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
$('.color').val('#000000');
|
$('.color').val('#000000');
|
||||||
|
|
||||||
/*yepnope({
|
if( localStorage.getItem('sawTips') != settings.version ) {
|
||||||
test: window.mobile,
|
$('.tour').removeClass('hidden');
|
||||||
yep : ['js/libs/touch.js', 'js/mobile.js', 'js/libs/color-picker-touch.js'],
|
localStorage.setItem('sawTips', settings.version);
|
||||||
nope: ['js/desktop.js', 'js/libs/color-picker.js']
|
}
|
||||||
})*/
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
76
Mobile/js/mobile.js
Normal file → Executable file
@ -43,7 +43,7 @@ window.save = function() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'current color': {
|
case 'current color': {
|
||||||
c.fillStyle = settings.color;
|
c.fillStyle = settings.bg;
|
||||||
c.globalCompositeOperation = 'destination-over';
|
c.globalCompositeOperation = 'destination-over';
|
||||||
c.fillRect(0, 0, width(), height());
|
c.fillRect(0, 0, width(), height());
|
||||||
c.globalCompositeOperation = settings.composite;
|
c.globalCompositeOperation = settings.composite;
|
||||||
@ -109,7 +109,7 @@ window.load = function() {
|
|||||||
$(this).attr('aria-selected', 'true');
|
$(this).attr('aria-selected', 'true');
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
$('#pro').click(function() {
|
$('#pro').tap(function() {
|
||||||
$('#save ol:nth-of-type(2) li').each(function() {
|
$('#save ol:nth-of-type(2) li').each(function() {
|
||||||
if( $(this).find('span').html() !== 'Transparent' ) {
|
if( $(this).find('span').html() !== 'Transparent' ) {
|
||||||
$(this).addClass('hidden');
|
$(this).addClass('hidden');
|
||||||
@ -118,7 +118,7 @@ window.load = function() {
|
|||||||
else $(this).attr('aria-selected', 'true');
|
else $(this).attr('aria-selected', 'true');
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
$('#exp').click(function() {
|
$('#exp').tap(function() {
|
||||||
$('#save ol:nth-of-type(2) li').removeClass('hidden');
|
$('#save ol:nth-of-type(2) li').removeClass('hidden');
|
||||||
})
|
})
|
||||||
$c.last().on('touchstart', function(e) {
|
$c.last().on('touchstart', function(e) {
|
||||||
@ -133,6 +133,36 @@ window.load = function() {
|
|||||||
window.active = false;
|
window.active = false;
|
||||||
if( settings.type == 'eraser' ) return;
|
if( settings.type == 'eraser' ) return;
|
||||||
|
|
||||||
|
if( settings.type == 'shape' ) {
|
||||||
|
var s = settings.comShape;
|
||||||
|
o.clear();
|
||||||
|
c.beginPath();
|
||||||
|
c.fillStyle = settings.color;
|
||||||
|
c.strokeStyle = settings.color;
|
||||||
|
c.lineWidth = settings.lineWidth / 20;
|
||||||
|
switch(s.type) {
|
||||||
|
case 'circle': {
|
||||||
|
c.arc(s.x, s.y, s.radius, 0, 2*Math.PI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'rectangle': {
|
||||||
|
c.rect(s.x, s.y, s.w, s.h)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'triangle': {
|
||||||
|
c.moveTo(s.start.x + s.dix, s.start.y);
|
||||||
|
c.lineTo(s.x, s.y);
|
||||||
|
c.lineTo(s.start.x, s.y);
|
||||||
|
c.lineTo(s.start.x + s.dix, s.start.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( settings.fill ) c.fill();
|
||||||
|
if( settings.stroke ) c.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( settings.type == 'line' ) return;
|
||||||
|
|
||||||
if(window.points.history.last < window.points.history.length-1) {
|
if(window.points.history.last < window.points.history.length-1) {
|
||||||
window.points.history.splice(window.points.history.last+1);
|
window.points.history.splice(window.points.history.last+1);
|
||||||
}
|
}
|
||||||
@ -147,6 +177,7 @@ window.load = function() {
|
|||||||
window.active = false;
|
window.active = false;
|
||||||
points[points.length-1].type = '';
|
points[points.length-1].type = '';
|
||||||
points[points.length-1].start = undefined;
|
points[points.length-1].start = undefined;
|
||||||
|
finishLine();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -155,23 +186,23 @@ window.load = function() {
|
|||||||
var $single = $('form[data-type="value-selector"].single');
|
var $single = $('form[data-type="value-selector"].single');
|
||||||
|
|
||||||
$single.find('li').tap(function(e) {
|
$single.find('li').tap(function(e) {
|
||||||
e.preventDefault();
|
|
||||||
$(this).parent().find('li[aria-selected]').removeAttr('aria-selected');
|
$(this).parent().find('li[aria-selected]').removeAttr('aria-selected');
|
||||||
$(this).attr('aria-selected', 'true');
|
$(this).attr('aria-selected', 'true');
|
||||||
var key = $(this).parents('form').attr('id'),
|
var key = $(this).parents('form').attr('id'),
|
||||||
value = $(this).find('label span').html().toLowerCase();
|
value = $(this).find('label span').html().toLowerCase(),
|
||||||
|
target = $(this).attr('data-target');
|
||||||
window.settings[key] = value;
|
window.settings[key] = value;
|
||||||
|
|
||||||
$('button[id="set' + key + '"] span').html(value[0].toUpperCase() + value.substr(1));
|
$('button[id="set' + key + '"] span').html(value[0].toUpperCase() + value.substr(1));
|
||||||
|
if( target ) {
|
||||||
$('#menu div.options > div').addClass('hidden');
|
$('#menu div.options > div').addClass('hidden');
|
||||||
$('#menu div.options > .general, #menu div.options > .'+value).removeClass('hidden');
|
$('#menu div.options > .general, #menu div.options > .'+target).removeClass('hidden');
|
||||||
|
}
|
||||||
$(this).parents('form').addClass('hidden');
|
$(this).parents('form').addClass('hidden');
|
||||||
})
|
})
|
||||||
|
$single.submit(function(e) {
|
||||||
$single.find('button').tap(function(e) {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$(this).parents('form').addClass('hidden');
|
$(this).addClass('hidden');
|
||||||
})
|
})
|
||||||
|
|
||||||
// Confirm
|
// Confirm
|
||||||
@ -180,11 +211,11 @@ window.load = function() {
|
|||||||
|
|
||||||
$confirm.each(function() {
|
$confirm.each(function() {
|
||||||
|
|
||||||
$(this).find('li').click(function(e) {
|
$(this).find('li').tap(function(e) {
|
||||||
$(this).parent().find('li[aria-selected]').removeAttr('aria-selected');
|
$(this).parent().find('li[aria-selected]').removeAttr('aria-selected');
|
||||||
$(this).attr('aria-selected', 'true');
|
$(this).attr('aria-selected', 'true');
|
||||||
})
|
})
|
||||||
$(this).find('button').last().click(function(e) {
|
$(this).find('button').last().tap(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var v = $(this).parents('form').attr('id');
|
var v = $(this).parents('form').attr('id');
|
||||||
$(this).parents('form').find('h1').each(function(i) {
|
$(this).parents('form').find('h1').each(function(i) {
|
||||||
@ -198,7 +229,7 @@ window.load = function() {
|
|||||||
$(this).parents('form').addClass('hidden');
|
$(this).parents('form').addClass('hidden');
|
||||||
window[v]();
|
window[v]();
|
||||||
})
|
})
|
||||||
$(this).find('button').first().click(function(e) {
|
$(this).find('button').first().tap(function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$(this).parents('form').addClass('hidden');
|
$(this).parents('form').addClass('hidden');
|
||||||
})
|
})
|
||||||
@ -210,9 +241,11 @@ window.load = function() {
|
|||||||
var $btn = $('button[id^="set"]');
|
var $btn = $('button[id^="set"]');
|
||||||
$btn.each(function() {
|
$btn.each(function() {
|
||||||
var target = /set(.*)/.exec($(this).attr('id'))[1];
|
var target = /set(.*)/.exec($(this).attr('id'))[1];
|
||||||
if( target == 'color' ) {
|
// Exception for Color
|
||||||
|
if( target == 'color' || target == 'bg' ) {
|
||||||
return $(this).tap(function() {
|
return $(this).tap(function() {
|
||||||
$('.picker').removeClass('hidden');
|
$('.picker').removeClass('hidden');
|
||||||
|
$('.picker').attr('data-caller', target);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
$(this).tap(function(e) {
|
$(this).tap(function(e) {
|
||||||
@ -246,6 +279,21 @@ window.load = function() {
|
|||||||
$(this).removeAttr('data-moving');
|
$(this).removeAttr('data-moving');
|
||||||
})
|
})
|
||||||
|
|
||||||
|
$('.fill, .stroke').tap(function() {
|
||||||
|
var s = $('.'+$(this).attr('class')).find('span');
|
||||||
|
if( s.html() == 'Yes' ) {
|
||||||
|
s.html('No');
|
||||||
|
settings[$(this).attr('class')] = false;
|
||||||
|
} else {
|
||||||
|
s.html('Yes');
|
||||||
|
settings[$(this).attr('class')] = true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$('.close, .tour button').tap(function() {
|
||||||
|
$(this).parent().addClass('hidden');
|
||||||
|
})
|
||||||
|
|
||||||
// Color Picker
|
// Color Picker
|
||||||
|
|
||||||
$('.close').tap(function() {
|
$('.close').tap(function() {
|
||||||
|
0
Mobile/manifest.webapp
Normal file → Executable file
0
Web/cache.appcache
Normal file → Executable file
0
Web/css/color-picker.less
Normal file → Executable file
0
Web/css/fonts.less
Normal file → Executable file
0
Web/css/fonts/MozTT-Bold.ttf
Normal file → Executable file
0
Web/css/fonts/MozTT-Light.ttf
Normal file → Executable file
0
Web/css/fonts/MozTT-Medium.ttf
Normal file → Executable file
0
Web/css/fonts/MozTT-Regular.ttf
Normal file → Executable file
0
Web/css/imgs/bg_overlay_pressed_1.png
Normal file → Executable file
Before Width: | Height: | Size: 93 B After Width: | Height: | Size: 93 B |
0
Web/css/imgs/bg_overlay_pressed_2.png
Normal file → Executable file
Before Width: | Height: | Size: 94 B After Width: | Height: | Size: 94 B |
0
Web/css/imgs/clear.png
Normal file → Executable file
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
0
Web/css/imgs/div_line_lg_black.png
Normal file → Executable file
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |