2
2
< html >
3
3
< head >
4
4
< meta charset = utf-8 >
5
- < meta name = viewport content = 'width=device-width,initial-scale=1 '>
5
+ < meta name = viewport content = 'width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no '>
6
6
< title > CanvasCraft</ title >
7
7
< link rel = icon type = image/x-icon href = logo.ico >
8
8
24
24
background-color : # 000 ;
25
25
height : 100% ;
26
26
overflow : hidden;
27
- color : # fff
27
+ color : # fff;
28
28
}
29
29
30
30
h1 , h2 , h3 , h4 {
68
68
69
69
.contents {
70
70
display : flex;
71
- height : 100%
71
+ height : 100% ;
72
72
}
73
73
74
74
.mainSection {
310
310
311
311
* {
312
312
box-sizing : border-box;
313
- outline : none
313
+ outline : none;
314
314
}
315
315
</ style >
316
316
</ head >
@@ -426,6 +426,7 @@ <h2>Images and shapes</h2>
426
426
if ( ! types [ this . name ] ) types [ this . name ] = 1
427
427
else types [ this . name ] ++
428
428
this . number = types [ this . name ]
429
+ this . initGen = true
429
430
430
431
this . line = false
431
432
if ( brushType == 'line' )
@@ -440,6 +441,8 @@ <h2>Images and shapes</h2>
440
441
this . saved = false
441
442
this . movingHovered = false
442
443
444
+ this . trim = { x : 0 , y : 0 , s : 1 }
445
+
443
446
this . gray = false
444
447
this . color = fill . value
445
448
this . originalColor = this . color
@@ -459,7 +462,7 @@ <h2>Images and shapes</h2>
459
462
elem . children [ 2 ] . appendChild ( this . cell )
460
463
}
461
464
else {
462
- if ( selectedCell . id && game . shapes . length )
465
+ if ( selectedCell . id && game . shapes . length && activeLayer . children [ 2 ] . children . length )
463
466
selectedCell . parentElement . appendChild ( this . cell )
464
467
else activeLayer . children [ 2 ] . appendChild ( this . cell )
465
468
}
@@ -497,9 +500,12 @@ <h2>Images and shapes</h2>
497
500
498
501
let maybeImage = ''
499
502
if ( this . image ) maybeImage = '<span><div id=newRatio>Ratio: ' +
500
- this . image . width + '×' + this . image . height +
503
+ this . image . width + ' × ' + this . image . height +
501
504
'</div>Multiply: <input value=1 oninput=changeRatio(this,' +
502
- this . image . width + ',' + this . image . height + ')></span>'
505
+ this . image . width + ',' + this . image . height + ')></span>' +
506
+ '<span>Offset x: <input type=number oninput=changeTrim(this,' + this . index + ',"y") value="' + this . trim . x + '"></span>' +
507
+ '<span>Offset y: <input type=number oninput=changeTrim(this,' + this . index + ',"x") value="' + this . trim . y + '"></span>' +
508
+ '<span>Offset scale: <input type=number oninput=changeTrim(this,' + this . index + ',"s") value="' + this . trim . s + '"></span>'
503
509
504
510
return '<h2>Textures</h2>' +
505
511
'<span style=color:#bbb;margin-bottom:15px>Change the texture of this shape</span>' +
@@ -509,9 +515,10 @@ <h2>Images and shapes</h2>
509
515
'<option id=default>Default</option>' +
510
516
'<option id=rgb>RGB</option>' +
511
517
'<option id=noise>Noise</option>' +
512
- '<option id=largeNoise >Large noise</option>' +
518
+ '<option id=largenoise >Large noise</option>' +
513
519
'<option id=rotated>Rotated</option>' +
514
520
addedPresets + '</select>' +
521
+ '<button onmousedown=savePresetAsDefault(this)>Save active preset as default</button>' +
515
522
'<span class=codeBoxWrite>function (x, y) {' +
516
523
'<textarea id=codeBox oninput=writeCode(' +
517
524
this . index + ',this)>' + this . codeContent + '</textarea>}</span>' +
@@ -566,7 +573,14 @@ <h2>Images and shapes</h2>
566
573
'<div id=defaultProperties contenteditable oninput="defaultStr=this.textContent">' +
567
574
defaultStr + '</div>'
568
575
569
- if ( ! this . line ) setCodeBoxHeight ( )
576
+ if ( ! this . line ) {
577
+ if ( ! firstTime ) {
578
+ const special = document . getElementById ( 'codeTemplate' )
579
+ special . selectedIndex = defaultPreset
580
+ addTemplateCode ( special , this . index )
581
+ }
582
+ setCodeBoxHeight ( )
583
+ }
570
584
else this . setLineDraw ( )
571
585
572
586
updateScreen = true
@@ -583,8 +597,6 @@ <h2>Images and shapes</h2>
583
597
this . ctx . strokeStyle = this . color
584
598
this . ctx . lineWidth = thick
585
599
this . ctx . beginPath ( )
586
- // this.ctx.moveTo(this.x, this.y)
587
- // this.ctx.lineTo(this.x2, this.y2)
588
600
this . ctx . moveTo (
589
601
thick / 2 - w * ( .5 + Math . sign ( - w ) / 2 ) ,
590
602
thick / 2 - h * ( .5 + Math . sign ( - h ) / 2 ) )
@@ -594,31 +606,42 @@ <h2>Images and shapes</h2>
594
606
this . ctx . stroke ( )
595
607
}
596
608
597
- generateImage ( ) {
609
+ generateImage ( init ) {
598
610
if ( this . line ) return
599
611
if ( this . w > 1 ) this . cvs . width = Math . floor ( this . w )
600
612
if ( this . h > 1 ) this . cvs . height = Math . floor ( this . h )
601
613
602
614
if ( this . image ) {
603
- this . ctx . drawImage ( this . image , 0 , 0 , this . w , this . h )
615
+ const scaleX = ( this . trim . s * this . w ) / this . w
616
+ const scaleY = ( this . trim . s * this . h ) / this . h
617
+ const newX = - ( this . w * this . trim . x ) * scaleX
618
+ const newY = - ( this . h * this . trim . y ) * scaleY
619
+
620
+ this . ctx . drawImage (
621
+ this . image , newX , newY ,
622
+ this . w * scaleX , this . h * scaleY )
604
623
return
605
624
}
606
625
607
626
this . ctx . clearRect ( 0 , 0 , this . w , this . h )
627
+ if ( init ) this . initGen = false
608
628
609
- let fillFunction = ( x , y ) => {
629
+ const errorFill = ( x , y ) => {
610
630
if ( ( x + y ) % 10 < 4 ) return '#ff0'
611
631
return '#000'
612
632
}
613
633
634
+ let fillFunction = ( x , y ) => { return errorFill ( x , y ) }
635
+
614
636
const calculateFillFunction = ( ) => {
615
637
try {
616
- const func = new Function ( 'x' , 'y' , this . codeContent )
638
+ let func = new Function ( 'x' , 'y' , this . codeContent )
617
639
fillFunction = ( x , y ) => {
618
640
try {
619
641
return func ( x , y )
620
642
}
621
643
catch ( error ) {
644
+ func = ( x , y ) => { return errorFill ( x , y ) }
622
645
document . getElementById ( 'errors' ) . innerHTML = 'Error: ' + error . message
623
646
}
624
647
}
@@ -677,6 +700,24 @@ <h2>Images and shapes</h2>
677
700
}
678
701
}
679
702
703
+ function changeTrim ( input , index , name ) {
704
+ const shape = game . shapes [ index ]
705
+ shape . trim [ name ] = Number ( input . value )
706
+ shape . generateImage ( )
707
+ updateScreen = true
708
+ }
709
+
710
+ let defaultPreset = 0
711
+ function savePresetAsDefault ( button ) {
712
+ const special = document . getElementById ( 'codeTemplate' )
713
+
714
+ button . textContent = 'Saved!'
715
+ setTimeout ( ( ) => button . textContent = 'Save active preset as default' , 1000 )
716
+
717
+ const select = document . getElementById ( 'codeTemplate' )
718
+ defaultPreset = select . selectedIndex
719
+ }
720
+
680
721
function changeColorLine ( index , item ) {
681
722
const shape = game . shapes [ index ]
682
723
shape . color = item . value
@@ -805,7 +846,7 @@ <h2>Images and shapes</h2>
805
846
storePresets . push ( { name, code} )
806
847
codeOptions [ name ] = ( e ) => { return code }
807
848
808
- save . innerHTML = 'Done '
849
+ save . innerHTML = 'Saved! '
809
850
setTimeout ( ( ) => save . innerHTML = 'Save' , 1000 )
810
851
}
811
852
@@ -1043,6 +1084,14 @@ <h2>Images and shapes</h2>
1043
1084
'Transform x: <input type=number id=layerTransformX>' +
1044
1085
'Transform y: <input type=number id=layerTransformY>' +
1045
1086
'<button onmousedown=transformLayer(this,"' + div . id + '")>Transform</button>'
1087
+ const upButton = document . createElement ( 'button' )
1088
+ const downButton = document . createElement ( 'button' )
1089
+ upButton . onmousedown = ( ) => moveLayer ( - 1 , div . id )
1090
+ downButton . onmousedown = ( ) => moveLayer ( 1 , div . id )
1091
+ upButton . textContent = 'Move Up'
1092
+ downButton . textContent = 'Move Down'
1093
+ stats . appendChild ( upButton )
1094
+ stats . appendChild ( downButton )
1046
1095
}
1047
1096
layerToExport . appendChild ( option )
1048
1097
@@ -1051,6 +1100,42 @@ <h2>Images and shapes</h2>
1051
1100
return title
1052
1101
}
1053
1102
1103
+ function moveLayer ( dir , layerId ) {
1104
+ const layer = document . getElementById ( layerId )
1105
+ const arr = layer . children [ 2 ] . children
1106
+
1107
+ if ( dir < 0 ) {
1108
+ const prev = layer . previousElementSibling
1109
+ if ( prev && prev . className == 'layer' ) shapes . insertBefore ( layer , prev )
1110
+ }
1111
+ else {
1112
+ const next = layer . nextElementSibling
1113
+ if ( next && next . className == 'layer' ) shapes . insertBefore ( next , layer )
1114
+ }
1115
+
1116
+ reCalcShapes ( )
1117
+
1118
+ updateScreen = true
1119
+ }
1120
+
1121
+ function reCalcShapes ( ) {
1122
+ const gameShapes = [ ]
1123
+ let currIndex = 0
1124
+ for ( let i = 0 ; i < shapes . children . length ; i ++ ) {
1125
+ const lay = shapes . children [ i ]
1126
+ if ( lay . className != 'layer' ) continue
1127
+ for ( let j = 0 ; j < lay . children [ 2 ] . children . length ; j ++ ) {
1128
+ const cell = lay . children [ 2 ] . children [ j ]
1129
+ const shape = game . shapes [ Number ( cell . realId ) ]
1130
+ shape . index = currIndex
1131
+ shape . setStats ( )
1132
+ gameShapes . push ( shape )
1133
+ currIndex ++
1134
+ }
1135
+ }
1136
+ game . shapes = gameShapes
1137
+ }
1138
+
1054
1139
function transformLayer ( button , layerId ) {
1055
1140
const x = document . getElementById ( 'layerTransformX' )
1056
1141
const y = document . getElementById ( 'layerTransformY' )
@@ -1192,6 +1277,7 @@ <h2>Images and shapes</h2>
1192
1277
1193
1278
function loop ( ) {
1194
1279
requestAnimationFrame ( loop )
1280
+
1195
1281
if ( ! updateScreen && ! m . dragZoom && ! m . dragNav ) return
1196
1282
updateScreen = false
1197
1283
@@ -1536,6 +1622,7 @@ <h2>Images and shapes</h2>
1536
1622
}
1537
1623
1538
1624
game . shapes . push ( shape )
1625
+ reCalcShapes ( )
1539
1626
1540
1627
shape . setStats ( )
1541
1628
updateScreen = true
@@ -1593,7 +1680,7 @@ <h2>Images and shapes</h2>
1593
1680
return 'let r = ' + r + ' + Math.random() * ' + amt + ' - ' + amt / 2 + '\nlet g = ' + g + ' + Math' +
1594
1681
'.random() * ' + amt + ' - ' + amt / 2 + '\nlet b = ' + b + ' + Math.random() * ' + amt + ' - ' + amt / 2 + '\nlet a = 1\nreturn ' +
1595
1682
'"rgb("+r+","+g+","+b+","+a+")"' } ,
1596
- largeNoise : ( e ) => {
1683
+ largenoise : ( e ) => {
1597
1684
const [ r , g , b ] = hexToRGB ( e . originalColor )
1598
1685
const amt = 40
1599
1686
return '// Useful 1D random number generator\nfunction random(seed) {\n' +
@@ -1672,11 +1759,11 @@ <h2>Images and shapes</h2>
1672
1759
if ( m . press ) {
1673
1760
if ( m . dragZoom )
1674
1761
zoomSpeed = - ( zoomPadY /
1675
- game . realScale ) * Math . abs ( zoomPadY / 50 ) / 1e3
1762
+ game . realScale ) * Math . abs ( zoomPadY / 50 ) / 5e3
1676
1763
1677
1764
else if ( m . dragNav ) {
1678
- navXSpeed = - ( navPadX / game . scale ) * Math . abs ( navPadX / 20 ) / 20
1679
- navYSpeed = - ( navPadY / game . scale ) * Math . abs ( navPadY / 20 ) / 20
1765
+ navXSpeed = - ( navPadX / game . scale ) * Math . abs ( navPadX / 20 ) / 40
1766
+ navYSpeed = - ( navPadY / game . scale ) * Math . abs ( navPadY / 20 ) / 40
1680
1767
}
1681
1768
1682
1769
else {
@@ -1719,6 +1806,7 @@ <h2>Images and shapes</h2>
1719
1806
else {
1720
1807
m . dragging = new Shape ( val ( mousePos . x ) , val ( mousePos . y ) )
1721
1808
game . shapes . push ( m . dragging )
1809
+ reCalcShapes ( )
1722
1810
}
1723
1811
}
1724
1812
}
@@ -1748,8 +1836,14 @@ <h2>Images and shapes</h2>
1748
1836
if ( ! shape . gray &&
1749
1837
mousePos . x > x && mousePos . y > y &&
1750
1838
mousePos . x < x + w &&
1751
- mousePos . y < y + h )
1752
- focusOnItem = shape . index
1839
+ mousePos . y < y + h ) {
1840
+
1841
+ let onTheRightLayer = true
1842
+ if ( selectedCell . parentElement && selectedCell . parentElement . parentElement . id != shape . cell . parentElement . parentElement . id )
1843
+ onTheRightLayer = false
1844
+
1845
+ if ( onTheRightLayer ) focusOnItem = shape . index
1846
+ }
1753
1847
}
1754
1848
}
1755
1849
@@ -1809,6 +1903,9 @@ <h2>Images and shapes</h2>
1809
1903
game . shapes [ m . dragging . index - 1 ] . setStats ( )
1810
1904
else stats . innerHTML = 'No information available'
1811
1905
}
1906
+
1907
+ if ( ! m . dragging . line && defaultPreset > 0 && m . dragging . initGen )
1908
+ m . dragging . generateImage ( true )
1812
1909
}
1813
1910
m . dragging = false
1814
1911
updateScreen = true
@@ -1826,8 +1923,8 @@ <h2>Images and shapes</h2>
1826
1923
updateScreen = true
1827
1924
}
1828
1925
1829
- onpointermove = e => moveMouse ( e )
1830
- onmousemove = e => moveMouse ( e )
1926
+ cvs . onpointermove = e => moveMouse ( e )
1927
+ cvs . onmousemove = e => moveMouse ( e )
1831
1928
1832
1929
cvs . onpointerdown = e => downMouse ( e )
1833
1930
cvs . onmousedown = e => downMouse ( e )
0 commit comments