Last active
April 30, 2020 22:23
-
-
Save nabbynz/a20de82573eb674f88b63e04e8c5c58d to your computer and use it in GitHub Desktop.
TagPro Tiles Mixer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name TagPro Tiles Mixer | |
// @description Mix & match tiles from the different tiles.png textures. | |
// @version 0.6.0 | |
// @include https://tagpro.koalabeast.com/textures/ | |
// @updateURL https://gist.github.com/nabbynz/a20de82573eb674f88b63e04e8c5c58d/raw/TagPro_Tiles_Mixer.user.js | |
// @downloadURL https://gist.github.com/nabbynz/a20de82573eb674f88b63e04e8c5c58d/raw/TagPro_Tiles_Mixer.user.js | |
// @grant none | |
// @author nabby | |
// ==/UserScript== | |
console.log('START: ' + GM_info.script.name + ' (v' + GM_info.script.version + ' by ' + GM_info.script.author + ')'); | |
//Create "Mixer" tab... | |
$('ul.tab-list').append('<li data-target="#TTM_Container"><a>Tiles Mixer</a></li>'); | |
$('div.tab-content').append('<div id="TTM_Container" class="tab-pane" style="padding:0px; text-align:center; font-size:12px; user-select:none"></div>'); | |
$('#TTM_Container').append('<div id="TTM_Tiles_Outer" style="display:inline-block; position:relative; vertical-align:top; margin:10px; padding:0px; border:6px ridge yellow; border-radius:8px;"></div>'); | |
$('#TTM_Tiles_Outer').append('<div id="TTM_Tiles_Header" style="position:relative; display:flex; justify-content:space-between; align-items:center; margin:10px; padding:0px; height:30px; background:#444; border:1px outset #777; border-radius:5px; z-index:3"></div>'); | |
$('#TTM_Tiles_Header').append('<div><select id="TTM_Textures" style="margin:0 5px; color:black; font-size:13px; width:165px; border-radius:8px; outline:none; border:none; background:linear-gradient(#999, #ccc, #777);"></select>' + | |
'<button id="TTM_UpdateCTL" style="color:#000; border-radius:10px; margin:0 5px; background:#999; border:1px outset #ccc; padding:0 3px; outline:none;">Refresh</button></div>'); | |
$('#TTM_Tiles_Header').append('<label style="display:none;">FreeMove:<input type="checkbox" id="TTM_FreeMove"></label>'); | |
$('#TTM_Tiles_Header').append('<select id="TTM_Select_Shape" style="margin:0 5px; color:black; font-size:11px; border-radius:3px; outline:none; border:none;" title="Texture clip size (good for clipping from dragged images, or resizing to pixel perfect)">' + | |
' <option value="square40" data-size="40" data-shape="square" title="40px Square Tile (Default)">Default</option>' + | |
' <option value="circle38" data-size="38" data-shape="circle" title="38px Circle (Balls)">Balls</option>' + | |
' <option value="circle30" data-size="30" data-shape="circle" title="30px Circle (Bombs & Powerups)">Bombs & Powerups</option>' + | |
' <option value="circle28" data-size="28" data-shape="circle" title="28px Circle (Spike)">Spike</option>' + | |
' <option value="circle16" data-size="16" data-shape="circle" title="16px Circle (Button)">Button</option>' + | |
'</select>'); | |
$('#TTM_Tiles_Header').append('<div><button id="TTM_Copy_All" style="color:#fff; border-radius:10px; margin:0 5px; background:#333; border:1px outset #4fa; padding:0 6px; outline:none;">Copy All</button>' + | |
'<button id="TTM_Copy_Walls" style="color:#fff; border-radius:10px; margin:0 5px; background:#333; border:1px outset #4fa; padding:0 6px; outline:none;">Copy Walls</button>' + | |
'<button id="TTM_Copy_Right" style="color:#fff; border-radius:10px; margin:0 5px; background:#333; border:1px outset #4fa; padding:0 6px; outline:none;">Copy Right</button></div>'); | |
$('#TTM_Tiles_Outer').append('<div id="TTM_Tiles" style="position:relative; margin:10px; padding:0px; width:640px; height:440px; text-align:left; overflow:hidden;"></div>'); | |
$('#TTM_Tiles').append('<div id="TTM_Tiles_Cover" style="position:absolute; margin:0; padding:0px; width:640px; height:440px; z-index:2;"></div>'); | |
$('#TTM_Tiles').append('<canvas id="TTM_Tiles_Canvas">'); | |
$('#TTM_Container').append('<div id="TTM_New_Outer" style="display:inline-block; position:relative; vertical-align:top; margin:10px; padding:0px; border:6px ridge chartreuse; border-radius:8px;"></div>'); | |
$('#TTM_New_Outer').append('<div id="TTM_New_Header" style="position:relative; display:flex; justify-content:space-between; align-items:center; margin:10px; padding:0px; height:30px; background:#444; border:1px outset #777; border-radius:5px; z-index:3;"></div>'); | |
$('#TTM_New_Header').append('<div><button id="TTM_Clear_All" style="color:#fff; border-radius:10px; margin:0 5px; background:#333; border:1px outset #f74; padding:0 6px; outline:none;">Clear All</button>' + | |
'<button id="TTM_Clear_Walls" style="color:#fff; border-radius:10px; margin:0 5px; background:#333; border:1px outset #f74; padding:0 6px; outline:none;">Clear Walls</button>' + | |
'<button id="TTM_Clear_Right" style="color:#fff; border-radius:10px; margin:0 5px; background:#333; border:1px outset #f74; padding:0 6px; outline:none;">Clear Right</button></div>'); | |
$('#TTM_New_Header').append('<div id="TTM_ModifyMenu_Container" style="display:none; position:absolute; width:520px; height=200px; top:25px; right:240px; background:#223; border:5px ridge #aab; border-radius:5px;"></div>'); | |
$('#TTM_ModifyMenu_Container').append('<div id="TTM_ModifyMenu_Inner" style="padding:10px; display:flex; flex-flow:column; align-items:center;">' + | |
' <div style="margin:0 0 5px; padding:0 0 5px; width:100%; border-bottom:1px solid #888;">' + | |
' <label title="" style="display:flex; justify-content:center; align-items:center; white-space:nowrap;"><span>Hue Rotate: </span><span style="margin:0 10px"><input type="range" id="TTM_TileHue" value="0" min="0" max="360" style="width:180px"></span><span id="TTM_TileHue_Value">0</span>°</label>' + | |
' <span style="font-size:11px; font-style:italic;">Note: This only affects colors (not greys).</span>' + | |
' </div>' + | |
' <div>' + | |
' <label title="Less than 100 is lower. Over 100 is higher. Unchanged is 100.">Brightness:<input type="number" id="TTM_Brightness" value="100" min="0" max="5000""></label>' + | |
' <label title="Less than 100 is lower. Over 100 is higher. Unchanged is 100.">Contrast:<input type="number" id="TTM_Contrast" value="100" min="0" max="5000""></label>' + | |
' <label title="Less than 100 is lower. Over 100 is higher. Unchanged is 100.">Saturation:<input type="number" id="TTM_Saturation" value="100" min="0" max="5000""></label>' + | |
' <label title="Less than 100 is lower. Over 100 is higher. Unchanged is 100.">Sepia:<input type="number" id="TTM_Sepia" value="0" min="0" max="100""></label>' + | |
' </div>' + | |
' <div style="margin-top:5px; border:1px inset #ccc; border-radius:7px;">' + | |
' <div id="TTM_Presets" style="display:inline-block; border-radius:5px; margin:3px; color:black; background:#c7c7c7; padding:2px 3px;">Presets: </div>' + | |
' <div style="display:flex; flex-flow:column wrap; align-items:center; max-height:320px; width:500px;">' + | |
' <div class="TTM_Add_Container">' + | |
' <label title=""><input type="checkbox" id="TTM_Add_Checkered" data-saveto="checkered" data-group="TTM_Group_Add_Checkered">Add Checkered</label>' + | |
' <div class="TTM_Group_Add_Checkered" style="display:none">' + | |
' <label title="">Size: <input type="number" min="1" max="40" value="20" data-saveto="checkered_size"></label>' + | |
' <label title="">Color: <input type="color" value="#444444" data-saveto="checkered_color"></label>' + | |
' <label title="">Alt: <input type="number" min="-100" max="100" value="-20" data-saveto="checkered_alt"></label>' + | |
' <label title="0=Transparent, 100=Solid Color">Opacity: <input type="number" min="0" max="100" value="100" data-saveto="checkered_opacity"></label>' + | |
' </div>' + | |
' </div>' + | |
' <div class="TTM_Add_Container">' + | |
' <label title=""><input type="checkbox" id="TTM_Add_Pattern" data-saveto="pattern" data-group="TTM_Group_Add_Pattern">Add Pattern</label>' + | |
' <div class="TTM_Group_Add_Pattern" style="display:none">' + | |
' <label title="">Shape: <select data-saveto="pattern_shape">' + | |
' <option value="square">Square</option>' + | |
' <option value="circle">Circle</option>' + | |
' <option value="rightangle">Right Angle</option>' + | |
' <option value="pyramid">Pyramid</option>' + | |
' <option value="corner">Corner</option>' + | |
' </select></label>' + | |
' <label title="">Color: <input type="color" data-saveto="pattern_color"></label>' + | |
' <label title="0=Transparent, 100=Solid Color">Opacity: <input type="number" min="0" max="100" value="100" data-saveto="pattern_opacity"></label>' + | |
' <label title="">Spacing: <input type="number" min="1" max="40" value="10" data-saveto="pattern_size"></label>' + | |
' <label title="">Width: <input type="number" min="1" max="40" value="8" data-saveto="pattern_margin"></label>' + | |
' <label title="">Stroke: <input type="checkbox" data-saveto="pattern_stroke" style="width:11px; height:11px;"></label>' + | |
' <label title="">Fill: <input type="checkbox" data-saveto="pattern_fill" checked style="width:11px; height:11px;"></label>' + | |
' </div>' + | |
' </div>' + | |
' <div class="TTM_Add_Container">' + | |
' <label title=""><input type="checkbox" id="TTM_Add_Stripes" data-saveto="stripes" data-group="TTM_Group_Add_Stripes">Add Stripes</label>' + | |
' <div class="TTM_Group_Add_Stripes" style="display:none">' + | |
' <label title="">Type: <select data-saveto="stripes_direction">' + | |
' <option value="horizontal">Horizontal (-)</option>' + | |
' <option value="vertical">Vertical (|)</option>' + | |
' <option value="diagonal" selected>Diagonal (\\)</option>' + | |
' <option value="diagonalback">Diagonal (/)</option>' + | |
' <option value="plus">Plus (+)</option>' + | |
' <option value="cross">Cross (X)</option>' + | |
' </select></label>' + | |
' <label title="">Size: <input type="number" min="1" max="40" value="10" data-saveto="stripes_size"></label>' + | |
' <label title="">Line Width: <input type="number" min="1" max="40" value="1" data-saveto="stripes_linewidth"></label>' + | |
' <label title="">Color: <input type="color" value="#ffffff" data-saveto="stripes_color"></label>' + | |
' <label title="0=Transparent, 100=Solid Color">Opacity: <input type="number" min="0" max="100" value="40" data-saveto="stripes_opacity"></label>' + | |
' </div>' + | |
' </div>' + | |
' <div class="TTM_Add_Container">' + | |
' <label title=""><input type="checkbox" id="TTM_Add_Specks" data-saveto="specks" data-group="TTM_Group_Add_Specks">Add Randoms</label>' + | |
' <div class="TTM_Group_Add_Specks" style="display:none">' + | |
' <label title="">Color: <input type="color" data-saveto="specks_color"></label>' + | |
' <label title="0=Transparent, 100=Solid Color">Opacity: <input type="number" min="0" max="100" value="50" data-saveto="specks_opacity"></label>' + | |
' <label title="">Length: <input type="number" min="1" max="20" value="7" data-saveto="specks_length"></label>' + | |
' <label title="">Count: <input type="number" min="1" max="300" value="20" data-saveto="specks_count"></label>' + | |
' <label title="0=Random Angles">Angle: <input type="number" min="0" max="360" value="315" data-saveto="specks_angle"></label>' + | |
' </div>' + | |
' </div>' + | |
' <div class="TTM_Add_Container">' + | |
' <label title=""><input type="checkbox" id="TTM_Add_Shine" data-saveto="shine" data-group="TTM_Group_Add_Shine">Add Shine</label>' + | |
' <div class="TTM_Group_Add_Shine" style="display:none">' + | |
' <label title="">X: <input type="number" min="-40" max="40" value="10" data-saveto="shine_x"></label>' + | |
' <label title="">Y: <input type="number" min="-40" max="40" value="10" data-saveto="shine_y"></label>' + | |
' <label title="Radius">R: <input type="number" min="1" max="80" value="50" data-saveto="shine_radius"></label>' + | |
' <label title="">Inner: <input type="color" value="#ffffff" data-saveto="shine_color_inner"></label>' + | |
' <label title="">Outer: <input type="color" value="#ffffff" data-saveto="shine_color_outer"></label>' + | |
' <label title="">Opacity: <input type="number" min="0" max="100" value="25" data-saveto="shine_opacity_inner"></label>' + | |
' <label title="">Opacity: <input type="number" min="0" max="100" value="5" data-saveto="shine_opacity_outer"></label>' + | |
' <label title="">Behind?: <input type="checkbox" data-saveto="shine_behind"></label>' + | |
' </div>' + | |
' </div>' + | |
' <div class="TTM_Add_Container">' + | |
' <label title=""><input type="checkbox" id="TTM_Add_Border" data-saveto="border" data-group="TTM_Group_Add_Border">Add Border</label>' + | |
' <div class="TTM_Group_Add_Border" style="display:none">' + | |
' <label title="">Color: <input type="color" data-saveto="border_color"></label>' + | |
' <label title="0=Transparent, 100=Solid Color">Opacity: <input type="number" min="0" max="100" value="100" data-saveto="border_opacity"></label>' + | |
' <label title="">Circle?: <input type="checkbox" data-saveto="border_circle"></label>' + | |
' <label title="">Size: <input type="number" min="1" max="40" value="40" data-saveto="border_size"></label>' + | |
' <label title="">Width: <input type="number" min="1" max="40" value="1" data-saveto="border_linewidth"></label>' + | |
' <label title="">Dash: <input type="number" min="1" max="40" value="1" data-saveto="border_dash"></label>' + | |
' </div>' + | |
' </div>' + | |
' </div>' + | |
' </div>' + | |
' <div>' + | |
' <label style="font-weight:normal;"><input type="checkbox" id="TTM_Tint">Tint</label>' + | |
' <div id="TTM_Tint_Group" style="display:inline; margin:0 0 2px 5px; background:#555; padding:2px; border-radius:2px;">' + | |
' <label style="font-weight:normal; margin:0;">Color: <input id="TTM_Tint_Color" type="color" value="#ff0000" style="height:17px; border:none;"></label>' + | |
' <select style="margin:0 5px; color:black; font-size:11px; border-radius:5px; outline:none; border:none;" title="Method 1 is usually best, but some images get better results using a different tinting method.">' + | |
' <option value="desaturation" title="Desaturation">Method 1</option>' + | |
' <option value="decomposition" title="Decomposition">Method 2</option>' + | |
' <option value="brightness" title="Brightness">Method 3</option>' + | |
' <option value="simple" title="Simple Overlay">Method 4</option>' + | |
' </select>' + | |
' <div id="TTM_TintMenu_Message" style="font-size:11px; font-style:italic; color:coral;">Hue is also being rotated</div>' + | |
' </div>' + | |
' </div>' + | |
' <div style="display:flex; align-items:center; border:4px groove #999; padding:6px 16px; border-radius:10px;">' + | |
' <canvas id="TTM_ModifySourceTilePreview" width="40" height="40" title="Source Preview"></canvas> <span style="font-size:26px; padding:0 12px;">➠</span> <canvas id="TTM_ModifyDestTilePreview" width="40" height="40" title="Target Preview"></canvas>' + | |
' </div>' + | |
' <label style="font-weight:normal;" title="Applies the filters to the source tile (left)."><input type="checkbox" id="TTM_Modify_CopySource">Source Tile</label>' + | |
' <div id="TTM_Modify_Message" style="color:red; font-style:italic; text-align:center;">No target tile selected</div>' + | |
' <div>' + | |
' <button id="TTM_Reset_Tile" style="color:#fff; border-radius:10px; margin:10px 10px 0; background:#333; border:1px outset #fff; padding:0 6px; outline:none;" title="Resets all the option values to the defaults">Reset</button>' + | |
' <button id="TTM_Apply_Tile" style="color:#fff; border-radius:10px; margin:10px 10px 0; background:#333; border:1px outset #fff; padding:0 6px; outline:none;" title="Apply the changes to the new tile below">Apply</button>' + | |
' </div>' + | |
'</div>'); | |
$('#TTM_New_Header').append('<div><button id="TTM_Show_ModifyMenu" style="color:#fff; border-radius:10px; margin:0 5px; background:#333; border:1px outset #07b; padding:0 6px; outline:none;">Modify</button></div>'); | |
$('#TTM_New_Header').append('<div id="TTM_Preview" style="color:#fff; text-shadow:1px 1px 1px black; margin:0 5px; background:green; border:1px dashed #aaa; padding:0 6px; outline:none; cursor:default;">Preview</div>'); | |
$('#TTM_New_Header').append('<a href="#" id="TTM_Save" style="color:#fff; border-radius:10px; margin:0 5px; background:dodgerblue; border:1px outset #aaa; padding:0 6px; outline:none;" download="tiles.png" title="Save as tiles.png so you can edit them or upload it to imgur later">Save to PNG</a>'); | |
$('#TTM_New_Header').append('<div id="TTM_Imgur_PreviewWindow" style="position:absolute; display:none; top:0; right:0; background:#333; padding:10px; border:1px solid red; border-radius:4px; box-shadow:0 0 10px 1px pink; z-index:1;">' + | |
' <div id="TTM_Imgur_PreviewWindow_Info" style="position:absolute; display:inline-block; top:2px; left:2px; width:16px; height:16px; color:#fff; border:1px outset white; border-radius:50%; cursor:pointer;" title="Info">?</div>' + | |
' <div id="TTM_Imgur_PreviewWindow_Title" style="color:#000; background:#ccc; border-radius:5px; width:90%; margin:0 auto 10px; font-size:14px;"></div>' + | |
' <div id="TTM_Imgur_PreviewWindow_Close" style="position:absolute; display:inline-block; top:2px; right:2px; width:16px; height:16px; color:#fff; border:1px outset red; border-radius:50%; cursor:pointer;" title="Close">X</div>' + | |
' <img id="TTM_Imgur_PreviewWindow_Image" src="" style="background:#000; width:480px; height:330px;" title="">' + | |
' <div style="display:flex; justify-content:space-around; margin:10px 0 0;">' + | |
' <div id="TTM_Imgur_LoadToMixer" class="TTM_Imgur_Button">Load into Mixer</div>' + | |
' <div id="TTM_Imgur_ViewOnImgur" class="TTM_Imgur_Button" title="Opens in new tab...">View on Imgur</div>' + | |
' <div id="TTM_Imgur_SaveToTiles" class="TTM_Imgur_Button" title="Save to the "Import Custom" tab">Save as Game Tiles</div>' + | |
' <div id="TTM_Imgur_Rename" class="TTM_Imgur_Button">Rename</div>' + | |
' <div id="TTM_Imgur_Delete" class="TTM_Imgur_Button">Delete</div>' + | |
' </div>' + | |
'</div>'); | |
$('#TTM_New_Header').append('<div id="TTM_Imgur_MenuContainer" style="display:none; position:absolute; width:200px; max-height:280px; overflow-y:auto; top:25px; right:0px; background:#502222; border:5px ridge #d33; border-radius:5px;">' + | |
' <div id="TTM_Imgur_MenuInner" style="position:relative; padding:10px;">' + | |
' <a href="" id="TTM_Imgur_Upload" style="color:#fff; border-radius:10px; margin:0 5px; background:red; border:1px outset #aaa; padding:0 6px; outline:none;" title="Upload to imgur">Upload to Imgur</a><span id="TTM_Imgur_Spinner"></span>' + | |
' </div>' + | |
'</div>'); | |
$('#TTM_New_Header').append('<div><button id="TTM_Imgur_ShowMenu" style="color:#fff; border-radius:10px; margin:0 5px; background:#d33; border:1px outset #999; padding:0 6px; outline:none;">Imgur</button></div>'); | |
$('#TTM_New_Outer').append('<div id="TTM_New" style="position:relative; margin:10px; padding:0px; width:640px; height:440px; overflow:hidden;"></div>'); | |
$('#TTM_New').append('<div id="TTM_New_Cover" style="position:absolute; margin:0px; padding:0px; width:640px; height:440px; z-index:2;"></div>'); | |
$('#TTM_New').append('<canvas id="TTM_New_Canvas" width="640" height="440">'); | |
$('#TTM_New_Outer').append('<div id="TTM_New_Footer" style="position:relative; display:flex; justify-content:center; align-items:center; margin:10px; padding:0px; background:#444; border:1px outset #777; border-radius:5px;"></div>'); //width:640px; height:30px; | |
$('#TTM_New_Footer').append('<button id="TTM_QuickSave" style="color:#fff; border-radius:10px; margin:5px; background:#333; border:1px outset dodgerblue; padding:0px 6px; outline:none;">Quick Save</button>'); | |
$('#TTM_New_Footer').append('<div id="TTM_QuickSaves" style="position:relative; display:flex; flex-flow:row; justify-content:flex-start; width:536px; margin:0 5px; padding:5px 0; overflow-x:auto; overflow-y:hidden;"></div>'); | |
$('#TTM_Tiles').append('<div id="TTM_Tiles_MouseSquare" style="position:absolute; display:inline-block; left:-9999px; top:-9999px; width:40px; height:40px; border:1px solid white; z-index:1;"></div>'); | |
$('#TTM_New').append('<div id="TTM_New_MouseSquare" style="position:absolute; display:inline-block; left:-9999px; top:-9999px; width:40px; height:40px; border:1px dashed white; z-index:1;"></div>'); | |
$('#TTM_New').append('<div id="TTM_New_MouseSquareFixed" style="position:absolute; display:inline-block; left:-9999px; top:-9999px; width:40px; height:40px; border:1px solid chartreuse; box-shadow:0px 0px 18px 7px #fff"></div>'); | |
addStyle('#TTM_ModifyMenu_Inner input, #TTM_ModifyMenu_Inner select, TTM_ModifyMenu_Inner label { margin:2px; color:black; font-weight:normal; }'); | |
addStyle('#TTM_ModifyMenu_Inner label { font-weight:normal; margin:1px; }'); | |
addStyle('.TTM_Saved { position:relative; margin:3px; padding:1px 5px; color:#bbb; background:#333; font-size:11px; border:1px inset #555; border-radius:5px; cursor:pointer; white-space:nowrap; }'); | |
addStyle('.TTM_DeleteSaved { display:inline-block; margin:0 0 0 3px; width:12px; height:12px; top:0px; right:14px; color:white; background:red; opacity:0.5; font-size:9px; text-align:center; border-radius:50%; cursor:pointer; }'); | |
addStyle('.TTM_ViewImage { display:inline-block; margin:0 0 0 3px; width:12px; height:12px; top:0px; right:0px; color:white !important; background:green; font-size:9px; text-align:center; border-radius:50%; cursor:pointer; }'); | |
addStyle('.TTM_Imgur_Button { background:#555; border-radius:3px; padding:0 5px; color:white !important; cursor:pointer; }'); | |
addStyle('.TTM_Imgur_Button:hover { background:#777; }'); | |
addStyle('.TTM_SetLinkToTiles { display:inline-block; margin:0 0 0 3px; width:12px; height:12px; top:0px; right:0px; color:white; background:orange; font-size:9px; text-align:center; border-radius:50%; cursor:pointer; }'); | |
addStyle('.TTM_Add_Container { display:flex; flex-flow:column wrap; width:245px; border:1px outset #ccc; margin:2px; border-radius:5px; }'); | |
addStyle('.TTM_Preset { display:inline-block; width:18px; font:10px Arial; background:#eee; border:1px solid #777; border-radius:3px; box-shadow:1px 1px 1px #555; margin:1px 2px 1px 0; padding:1px 0; cursor:pointer; }'); | |
addStyle('.TTM_Preset:hover { background:#f00; color:#fff; }'); | |
addStyle('@keyframes TTM_Spinner { to {transform:rotate(360deg);} }'); | |
addStyle('.TTM_Loading:after { content: ""; box-sizing:border-box; position:absolute; width:20px; height:20px; margin-top:-3px; margin-left:4px; border-radius:50%; border-top:2px solid #f70; border-right:2px solid transparent; animation:TTM_Spinner .6s linear infinite; }'); | |
let tilesTarget = {x:null, y:null}; | |
let tilesCtx; | |
let newCtx = $("#TTM_New_Canvas").get(0).getContext("2d"); | |
let newCtxDataUrl; | |
let tilesImg = document.createElement('img'); | |
let speedpadImg = document.createElement('img'); | |
let portalImg = document.createElement('img'); | |
let newImg = document.createElement('img'); | |
let randomPup = Math.floor(Math.random()*3); | |
let fixedTarget = false; | |
let freeMove = false; | |
let selectorSize = 40; | |
let tilesHover = $('#TTM_Tiles_MouseSquare'); | |
let newHover = $('#TTM_New_MouseSquare'); | |
let newHoverFixed = $('#TTM_New_MouseSquareFixed'); | |
let draggedData; | |
let previewCanvas = document.createElement('canvas'); | |
let tempCanvas = document.createElement('canvas'); | |
let imgurClientId = '1feeb5b9d9cb0c5'; //don't steal my client-id! get your own very quickly from here: https://api.imgur.com/oauth2/addclient | |
const tileNames = { | |
'4800': { name:'Spike', tx:480, ty:0 }, | |
'5200': { name:'Gravity Well', tx:520, ty:0 }, | |
'5600': { name:'Red Ball', tx:560, ty:0 }, | |
'6000': { name:'Blue Ball', tx:600, ty:0 }, | |
'48040': { name:'Bomb', tx:480, ty:40 }, | |
'52040': { name:'Yellow Flag', tx:520, ty:40 }, | |
'56040': { name:'Red Flag', tx:560, ty:40 }, | |
'60040': { name:'Blue Flag', tx:600, ty:40 }, | |
'48080': { name:'Bomb (Detonated)', tx:480, ty:80 }, | |
'52080': { name:'Yellow Flag (Taken)', tx:520, ty:80 }, | |
'56080': { name:'Red Flag (Taken)', tx:560, ty:80 }, | |
'60080': { name:'Blue Flag (Taken)', tx:600, ty:80 }, | |
'480120': { name:'Neutral Gate', tx:480, ty:120 }, | |
'520120': { name:'Green Gate', tx:520, ty:120 }, | |
'560120': { name:'Red Gate', tx:560, ty:120 }, | |
'600120': { name:'Blue Gate', tx:600, ty:120 }, | |
'480160': { name:'Juke Juice', tx:480, ty:160 }, | |
'520160': { name:'Floor Tile', tx:520, ty:160 }, | |
'560160': { name:'Red TeamTile', tx:560, ty:160 }, | |
'600160': { name:'Blue TeamTile', tx:600, ty:160 }, | |
'480200': { name:'Rolling Bomb', tx:480, ty:200 }, | |
'520200': { name:'[Empty]', tx:520, ty:200 }, | |
'560200': { name:'Red Endzone', tx:560, ty:200 }, | |
'600200': { name:'Blue Endzone', tx:600, ty:200 }, | |
'480240': { name:'TagPro', tx:480, ty:240 }, | |
'520240': { name:'Button', tx:520, ty:240 }, | |
'560240': { name:'Yellow Potato', tx:560, ty:240 }, | |
'600240': { name:'Yellow Potato (Taken)', tx:600, ty:240 }, | |
'480280': { name:'Top Speed', tx:480, ty:280 }, | |
'520280': { name:'[Empty]', tx:520, ty:280 }, | |
'560280': { name:'Red Potato', tx:560, ty:280 }, | |
'600280': { name:'Red Potato (Taken)', tx:600, ty:280 }, | |
'480320': { name:'Powerup (Taken)', tx:480, ty:320 }, | |
'520320': { name:'[Empty]', tx:520, ty:320 }, | |
'560320': { name:'Blue Potato', tx:560, ty:320 }, | |
'600320': { name:'Blue Potato (Taken)', tx:600, ty:320 }, | |
'480360': { name:'Mars Ball (Top Left)', tx:480, ty:360 }, | |
'520360': { name:'Mars Ball (Top Right)', tx:520, ty:360 }, | |
'560360': { name:'[Empty]', tx:560, ty:360 }, | |
'600360': { name:'[Empty]', tx:600, ty:360 }, | |
'480400': { name:'Mars Ball (Bottom Left)', tx:480, ty:400 }, | |
'520400': { name:'Mars Ball (Bottom Right)', tx:520, ty:400 }, | |
'560400': { name:'[Empty]', tx:560, ty:400 }, | |
'600400': { name:'[Empty]', tx:600, ty:400 }, | |
}; | |
//Bind events... | |
$('.tab-list').on('click', 'li', function() { | |
$(this).parents('.tab-list').find('li').removeClass('active'); | |
$(this).parents('.tab-list').parent().find('.tab-pane').removeClass('active'); | |
$(this).addClass('active'); | |
$( $(this).data('target') ).addClass('active'); | |
}); | |
$('#TTM_Tiles_Cover').on('mousemove', function(e) { | |
let x; | |
let y; | |
let mouseOffset = 40; | |
let sourceTileName = ''; | |
let title = ''; | |
if (freeMove) { | |
x = e.offsetX - mouseOffset; | |
y = e.offsetY - mouseOffset; | |
} else { | |
let sizeOffset = (40 - selectorSize) / 2; | |
x = Math.floor(e.offsetX/40)*40 + sizeOffset; | |
y = Math.floor(e.offsetY/40)*40 + sizeOffset; | |
let sourceKey = ''+(x-sizeOffset)+(y-sizeOffset); | |
if (tileNames.hasOwnProperty(sourceKey)) sourceTileName = tileNames[sourceKey].name; | |
else sourceTileName = 'Wall Tile'; | |
if (fixedTarget) { | |
let fx = parseInt(newHoverFixed.css('left')); | |
let fy = parseInt(newHoverFixed.css('top')); | |
let targetKey = ''+fx+fy; | |
let targetTileName = 'Wall Tile'; | |
if (tileNames.hasOwnProperty(targetKey)) targetTileName = tileNames[targetKey].name; | |
title += 'Copy to FIXED target...\n'; | |
title += sourceTileName + ' -> ' + targetTileName; | |
title += '\n[x:'+x+', y:'+y+']'; | |
} else { | |
title += 'Copy...\n'; | |
title += sourceTileName; | |
title += '\n[x:'+x+', y:'+y+']'; | |
} | |
} | |
//tilesHover.css({ 'left':x, 'top':y, 'border-color':fixedTarget?'rgba(255,0,0,0.5)':'white' }); | |
tilesHover.css({ 'left':x, 'top':y, 'border':fixedTarget?'2px dashed rgba(0,255,255,0.8)':'1px solid white' }); | |
$(this).attr('title', title); | |
}).on('mouseenter', function() { | |
tilesHover.show(); | |
}).on('mouseleave', function() { | |
tilesHover.hide(); | |
}); | |
$('#TTM_Tiles_Cover').on('click', function(e) { | |
let x = parseInt( tilesHover.css('left') ); | |
let y = parseInt( tilesHover.css('top') ); | |
let isCircle = ( $('#TTM_Select_Shape').find(':selected').data('shape') === 'circle' ? true : false ); | |
copyTiles(x, y, selectorSize, selectorSize, (fixedTarget ? tilesTarget.x : x), (fixedTarget ? tilesTarget.y : y), selectorSize, selectorSize, isCircle); | |
}); | |
$('#TTM_New_Cover').on('mousemove', function(e) { | |
let x = Math.floor(e.offsetX/40)*40; | |
let y = Math.floor(e.offsetY/40)*40; | |
let key = ''+x+y; | |
let title = 'Click to set as target tile.'; | |
let tileName = ''; | |
if (tileNames.hasOwnProperty(key)) tileName = tileNames[key].name; | |
else tileName = 'Wall Tile'; | |
if (fixedTarget && (x === parseInt(newHoverFixed.css('left'))) && (y === parseInt(newHoverFixed.css('top'))) ) title = 'Click to unset target tile.'; | |
newHover.css({'left':x, 'top':y}); | |
$(this).attr('title', title + '\n' + tileName + ' [x:'+x+', y:'+y +']'); | |
}).on('mouseenter', function() { | |
newHover.show(); | |
}).on('mouseleave', function() { | |
newHover.hide(); | |
}); | |
$('#TTM_New_Cover').on('click', function(e) { | |
let x = parseInt( newHover.css('left') ); | |
let y = parseInt( newHover.css('top') ); | |
let mx = parseInt( newHoverFixed.css('left') ); | |
let my = parseInt( newHoverFixed.css('top') ); | |
if ((x === mx) && (y === my)) { | |
tilesTarget.x = null; | |
tilesTarget.y = null; | |
fixedTarget = false; | |
newHoverFixed.css({'left':-9999, 'top':-9999}); | |
} else { | |
tilesTarget.x = x; | |
tilesTarget.y = y; | |
fixedTarget = true; | |
newHoverFixed.css({'left':x, 'top':y}); | |
} | |
let sx = x; | |
let sy = y; | |
let sw = 40; | |
let sh = 40; | |
if (x < 480) { | |
sx = 0; | |
sy = 0; | |
sw = 480; | |
sh = 440; | |
} | |
tempCanvas.width = sw; | |
tempCanvas.height = sh; | |
let tempCtx = tempCanvas.getContext("2d"); | |
tempCtx.drawImage($('#TTM_Modify_CopySource').is(':checked') ? tilesCtx.canvas : newCtx.canvas, sx,sy,sw,sh, 0,0,sw,sh); | |
updateModifyTilePreviews(); | |
}); | |
$('#TTM_FreeMove').on('click', function() { | |
if (this.checked) { | |
freeMove = true; | |
} else { | |
freeMove = false; | |
} | |
}); | |
$('#TTM_Select_Shape').on('change', function() { | |
selectorSize = $(this).find(':selected').data('size'); | |
let borderRadius = ( $(this).find(':selected').data('shape') === 'circle' ? '50%' : '0' ); | |
tilesHover.css({ 'width':selectorSize+'px', 'height':selectorSize+'px', 'border-radius':borderRadius }); | |
}); | |
$('#TTM_Show_ModifyMenu').on('click', function() { | |
$('#TTM_ModifyMenu_Container').slideToggle(); | |
}); | |
$('#TTM_Tint').on('click', function() { | |
$('#TTM_Tint_Group').fadeToggle(); | |
if ($('#TTM_Tint').is(':checked') && $('#TTM_TileHue').val() > 0) $('#TTM_TintMenu_Message').show(); | |
else $('#TTM_TintMenu_Message').hide(); | |
}); | |
$('#TTM_TileHue').on('input', function() { | |
$('#TTM_TileHue_Value').text(this.value); | |
if ($('#TTM_Tint').is(':checked') && $('#TTM_TileHue').val() > 0) $('#TTM_TintMenu_Message').show(); | |
else $('#TTM_TintMenu_Message').hide(); | |
}); | |
$('#TTM_ModifyMenu_Inner').find('input, select').on('click', function() { | |
let group = this.dataset.group; | |
if (group) { | |
if ( $(this).is(':checked') || ($(this).val() > 0) ) $('#TTM_ModifyMenu_Inner').find('.'+group).fadeIn(); | |
else $('#TTM_ModifyMenu_Inner').find('.'+group).fadeOut(); | |
} | |
updateModifyTilePreviews(false); | |
}); | |
$('#TTM_Reset_Tile').on('click', function() { | |
$('#TTM_TileHue').val('0'); | |
$('#TTM_TileHue_Value').text('0'); | |
$('#TTM_Sepia').val('0'); | |
$('#TTM_Brightness').val('100'); | |
$('#TTM_Contrast').val('100'); | |
$('#TTM_Saturation').val('100'); | |
$('#TTM_Add_Checkered').prop('checked', false); | |
$('#TTM_ModifyMenu_Inner').find('.TTM_Group_Add_Checkered').hide(); | |
$('#TTM_Add_Pattern').prop('checked', false); | |
$('#TTM_ModifyMenu_Inner').find('.TTM_Group_Add_Pattern').hide(); | |
$('#TTM_Add_Stripes').prop('checked', false); | |
$('#TTM_ModifyMenu_Inner').find('.TTM_Group_Add_Stripes').hide(); | |
$('#TTM_Add_Specks').prop('checked', false); | |
$('#TTM_ModifyMenu_Inner').find('.TTM_Group_Add_Specks').hide(); | |
$('#TTM_Add_Shine').prop('checked', false); | |
$('#TTM_ModifyMenu_Inner').find('.TTM_Group_Add_Shine').hide(); | |
$('#TTM_Add_Border').prop('checked', false); | |
$('#TTM_ModifyMenu_Inner').find('.TTM_Group_Add_Border').hide(); | |
$('#TTM_Tint').prop('checked', false); | |
$('#TTM_Tint_Group').hide(); | |
$('#TTM_Modify_CopySource').prop('checked', false); | |
$('#TTM_Tint_Color').val('#FF0000'); | |
updateModifyTilePreviews(); | |
}); | |
$('#TTM_Apply_Tile').on('click', function() { | |
let x = parseInt( newHoverFixed.css('left') ); | |
let y = parseInt( newHoverFixed.css('top') ); | |
if (x < 480) { | |
tintTiles(0, 0, 480, 440, true, true); | |
} else { | |
tintTiles(x, y, 40, 40, true, false); | |
} | |
//updateModifyTilePreviews(false); | |
}); | |
$('#TTM_Modify_CopySource').on('click', function() { | |
if (!fixedTarget) return; | |
let x = parseInt( newHoverFixed.css('left') ); | |
let y = parseInt( newHoverFixed.css('top') ); | |
let w = 40; | |
let h = 40; | |
if (x < 480) { | |
x = 0; | |
y = 0; | |
w = 480; | |
h = 440; | |
} | |
tempCanvas.width = w; | |
tempCanvas.height = h; | |
let tempCtx = tempCanvas.getContext("2d"); | |
tempCtx.drawImage(this.checked ? tilesCtx.canvas : newCtx.canvas, x,y,w,h, 0,0,w,h); | |
updateModifyTilePreviews(); | |
}); | |
$('#TTM_Textures').on('change', function() { | |
let value = this.value; | |
if (value === 'customtileslink') { | |
value = $('#tiles').val(); | |
$('#TTM_UpdateCTL').fadeIn(); | |
} else if (value === 'dragged') { | |
value = draggedData; | |
} else { | |
$('#TTM_Tiles').scrollTop('0'); | |
$('#TTM_UpdateCTL').hide(); | |
} | |
loadImage(value); | |
}); | |
$('#TTM_UpdateCTL').on('click', function() { | |
loadImage($('#tiles').val()); | |
}); | |
$('#TTM_Copy_Walls').on('click', function() { | |
copyTiles(0, 0, 480, 440); | |
}); | |
$('#TTM_Copy_All').on('click', function() { | |
copyTiles(0, 0, tilesCtx.canvas.width, tilesCtx.canvas.height); | |
}); | |
$('#TTM_Copy_Right').on('click', function() { | |
copyTiles(480, 0, 160, tilesCtx.canvas.height); | |
}); | |
$('#TTM_Clear_Walls').on('click', function() { | |
newCtx.clearRect(0, 0, 480, 440); | |
}); | |
$('#TTM_Clear_All').on('click', function() { | |
newCtx.clearRect(0, 0, newCtx.canvas.width, newCtx.canvas.height); | |
}); | |
$('#TTM_Clear_Right').on('click', function() { | |
newCtx.clearRect(480, 0, 160, newCtx.canvas.height); | |
}); | |
$('#TTM_Save').on('click', function() { | |
this.href = newCtx.canvas.toDataURL('image/png'); | |
}); | |
let myImgurs = JSON.parse(localStorage.getItem('myImgurs') || '{}'); | |
$('#TTM_Imgur_ShowMenu').on('click', function() { | |
$('#TTM_Imgur_MenuContainer').slideToggle(200); | |
}); | |
$('#TTM_Imgur_Upload').on('click', function(e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
let url = 'https://api.imgur.com/3/image'; | |
let title = prompt('Enter a name for these tiles:'); | |
if (title === null) return; | |
let image = newCtx.canvas.toDataURL('image/png').replace('data:image/png;base64,', ''); | |
let data = { | |
'image': image, | |
'title': title | |
}; | |
$('#TTM_Imgur_Spinner').addClass('TTM_Loading'); | |
$.ajax({ | |
url: url, | |
headers: { | |
'Authorization': 'Client-ID '+imgurClientId | |
}, | |
type: 'POST', | |
data: data | |
}).done(function(data) { | |
if (data.success === true) { | |
let myImgurs = JSON.parse(localStorage.getItem('myImgurs') || '{}'); | |
myImgurs[data.data.id] = data.data; | |
localStorage.setItem('myImgurs', JSON.stringify(myImgurs)); | |
createNewIcon(title, '#TTM_Imgur_MenuInner', myImgurs[data.data.id]); | |
} else { | |
alert('Upload to Imgur failed :(\n\nError: '+data.status); | |
} | |
}).fail(function(data) { | |
alert('Upload to Imgur failed :(\n\nError: '+data.status + ' ' + data.statusText); | |
}).always(function() { | |
removeSpinner(); | |
}); | |
}); | |
$('#TTM_Imgur_MenuInner').on('click', '.TTM_Saved', function() { | |
let imgurId = $(this).data('name'); | |
let myImgurs = JSON.parse(localStorage.getItem('myImgurs') || '{}'); | |
if (imgurId && myImgurs.hasOwnProperty(imgurId)) { | |
$('#TTM_Imgur_PreviewWindow').data('name', imgurId); | |
$('#TTM_Imgur_PreviewWindow_Title').text(myImgurs[imgurId].title || myImgurs[imgurId].id); | |
$('#TTM_Imgur_PreviewWindow_Image').attr('src', myImgurs[imgurId].link); | |
$('#TTM_Imgur_PreviewWindow').fadeIn(200); | |
} | |
}).on('mouseenter', '.TTM_Saved', function() { | |
$(this).css('border', '1px outset #fff'); | |
}).on('mouseleave', '.TTM_Saved', function() { | |
$(this).css('border', '1px inset #555'); | |
}); | |
$('#TTM_Imgur_PreviewWindow_Info').on('click', function() { | |
let imgurId = $('#TTM_Imgur_PreviewWindow').data('name'); | |
let myImgurs = JSON.parse(localStorage.getItem('myImgurs') || '{}'); | |
if (imgurId && myImgurs.hasOwnProperty(imgurId)) { | |
$.ajax({ | |
url: 'https://api.imgur.com/3/image/'+imgurId, | |
headers: { | |
'Authorization': 'Client-ID '+imgurClientId | |
}, | |
type: 'GET' | |
}).done(function(data) { | |
data = data.data; | |
$('#TTM_Imgur_PreviewWindow_Title').append('<div id="TTM_Imgur_PreviewWindow_TitleInfo" style="font-size:11px; font-style:italic;">' + | |
' Uploaded: ' + new Date(data.datetime*1000).toDateString() + ' | Size: ' + (data.size / 1024).toFixed(0) + 'KB' + ' | #Views: '+ data.views + ' | Bandwidth: ' + (data.bandwidth / 1024/1024).toFixed(1) + 'MB' + | |
'</div>'); | |
}); | |
} | |
}); | |
$('#TTM_Imgur_PreviewWindow_Close').on('click', function() { | |
closeImgurPreviewWindow(); | |
}); | |
$('#TTM_Imgur_LoadToMixer').on('click', function() { | |
let imgurId = $('#TTM_Imgur_PreviewWindow').data('name'); | |
let myImgurs = JSON.parse(localStorage.getItem('myImgurs') || '{}'); | |
if (imgurId && myImgurs.hasOwnProperty(imgurId)) { | |
let img = document.createElement('img'); | |
img.onload = function() { | |
newCtx.clearRect(0, 0, 640, 440); | |
newCtx.drawImage(img, 0,0,640,440, 0,0,640,440); | |
img.onload = null; | |
img = null; | |
}; | |
img.crossOrigin = 'Anonymous'; | |
img.src = myImgurs[imgurId].link; | |
$('#TTM_Imgur_MenuContainer').hide(); | |
closeImgurPreviewWindow(); | |
} | |
}); | |
$('#TTM_Imgur_ViewOnImgur').on('click', function(e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
let imgurId = $('#TTM_Imgur_PreviewWindow').data('name'); | |
let myImgurs = JSON.parse(localStorage.getItem('myImgurs') || '{}'); | |
if (imgurId && myImgurs.hasOwnProperty(imgurId)) { | |
window.open(myImgurs[imgurId].link.replace('i.','').replace('.png',''), '_blank'); | |
} | |
}); | |
$('#TTM_Imgur_Rename').on('click', function(e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
let imgurId = $('#TTM_Imgur_PreviewWindow').data('name'); | |
let myImgurs = JSON.parse(localStorage.getItem('myImgurs') || '{}'); | |
if (imgurId && myImgurs.hasOwnProperty(imgurId)) { | |
let newName = prompt('Enter new name for these tiles:\n\n', myImgurs[imgurId].title === null ? '' : myImgurs[imgurId].title); | |
if (!newName) return true; | |
let url = 'https://api.imgur.com/3/image/'+myImgurs[imgurId].deletehash; | |
$('#TTM_Imgur_Rename').addClass('TTM_Loading'); | |
$.ajax({ | |
url: url, | |
headers: { | |
'Authorization': 'Client-ID '+imgurClientId | |
}, | |
type: 'POST', | |
data: { 'title':newName } | |
}).done(function(data) { | |
if (data.success === true) { | |
myImgurs[imgurId].title = newName; | |
localStorage.setItem('myImgurs', JSON.stringify(myImgurs)); | |
$('#TTM_Imgur_MenuInner').find('.TTM_Saved[data-name="'+imgurId+'"]').text(newName).attr('title', newName + ' ('+imgurId+')'); | |
$('#TTM_Imgur_PreviewWindow_Title').text(newName); | |
} else { | |
alert('Failed to Rename on Imgur :(\n\nError: '+data.status); | |
} | |
}).fail(function(data) { | |
alert('Failed to Rename on Imgur :(\n\nError: '+data.status); | |
}).always(function() { | |
removeSpinner(); | |
}); | |
} | |
}); | |
$('#TTM_Imgur_Delete').on('click', function(e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
let $this = $(this).parent(); | |
let imgurId = $('#TTM_Imgur_PreviewWindow').data('name'); | |
let myImgurs = JSON.parse(localStorage.getItem('myImgurs') || '{}'); | |
if (imgurId && myImgurs.hasOwnProperty(imgurId)) { | |
let response1 = confirm('Are you sure you want to remove these tiles from this list?\n\n'); | |
if (response1) { | |
$('#TTM_Imgur_Delete').addClass('TTM_Loading'); | |
let response2 = confirm('Delete it from Imgur too?\n\n'); | |
if (response2) { | |
let url = 'https://api.imgur.com/3/image/'+myImgurs[imgurId].deletehash; | |
$.ajax({ | |
url: url, | |
headers: { | |
'Authorization': 'Client-ID '+imgurClientId | |
}, | |
type: 'DELETE' | |
}).done(function(data) { | |
if (data.success === true) { | |
closeImgurPreviewWindow(); | |
} else { | |
alert('Failed to Delete on Imgur :(\n\nError: '+data.status); | |
} | |
}).fail(function(data) { | |
alert('Failed to Delete on Imgur :(\n\nError: '+data.status); | |
}); | |
} | |
delete myImgurs[imgurId]; | |
localStorage.setItem('myImgurs', JSON.stringify(myImgurs)); | |
$('#TTM_Imgur_MenuInner').find('.TTM_Saved[data-name="'+imgurId+'"]').remove(); | |
removeSpinner(); | |
} | |
} | |
}); | |
$('#TTM_Imgur_SaveToTiles').on('click', function() { | |
let imgurId = $('#TTM_Imgur_PreviewWindow').data('name'); | |
let myImgurs = JSON.parse(localStorage.getItem('myImgurs') || '{}'); | |
$('#TTM_Imgur_SaveToTiles').addClass('TTM_Loading'); | |
if (imgurId && myImgurs.hasOwnProperty(imgurId)) { | |
$('#tiles').val(myImgurs[imgurId].link); | |
$('#custom-textures-btn').trigger('click'); | |
setTimeout(removeSpinner, 1000); | |
} | |
}); | |
$('#TTM_QuickSave').on('click', function() { | |
let name = prompt('Texture pack name:'); | |
if (!name) return; | |
let savedTemps = JSON.parse(localStorage.getItem('savedTemps') || '{}'); | |
let isNewPack = true; | |
if (savedTemps.hasOwnProperty(name)) { | |
if (!confirm('"'+name+'" already exists - OK to overwrite?\n\n')) return; | |
isNewPack = false; | |
} | |
savedTemps[name] = newCtx.canvas.toDataURL('image/png'); | |
localStorage.setItem('savedTemps', JSON.stringify(savedTemps)); | |
if (isNewPack) createNewIcon(name, '#TTM_QuickSaves'); | |
}).on('mouseenter', function() { | |
$(this).css('background', '#555'); | |
}).on('mouseleave', function() { | |
$(this).css('background', '#333'); | |
}); | |
$('#TTM_QuickSaves').on('click', '.TTM_Saved', function() { | |
let name = $(this).data('name'); | |
let savedTemps = JSON.parse(localStorage.getItem('savedTemps') || '{}'); | |
if (savedTemps.hasOwnProperty(name)) { | |
let img = document.createElement('img'); | |
img.onload = function() { | |
newCtx.clearRect(0, 0, 640, 440); | |
newCtx.drawImage(img, 0,0,640,440, 0,0,640,440); | |
img.onload = null; | |
img = null; | |
}; | |
img.crossOrigin = 'Anonymous'; | |
img.src = savedTemps[name]; | |
} | |
}).on('mouseenter', '.TTM_Saved', function() { | |
$(this).css('border', '1px outset #fff'); | |
}).on('mouseleave', '.TTM_Saved', function() { | |
$(this).css('border', '1px inset #555'); | |
}); | |
$('#TTM_QuickSaves').on('click', '.TTM_DeleteSaved', function(e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
let name = $(this).parent().data('name'); | |
let savedTemps = JSON.parse(localStorage.getItem('savedTemps') || '{}'); | |
if (name && savedTemps.hasOwnProperty(name)) { | |
if (!confirm('Delete saved pack "'+name+'?\n\n')) return; | |
delete savedTemps[name]; | |
localStorage.setItem('savedTemps', JSON.stringify(savedTemps)); | |
let $this = $(this).parent(); | |
$this.fadeOut(600, function() { $this.remove(); }); | |
} | |
}).on('mouseenter', '.TTM_DeleteSaved', function() { | |
$(this).css('opacity', '1'); | |
}).on('mouseleave', '.TTM_DeleteSaved', function() { | |
$(this).css('opacity', '0.5'); | |
}); | |
$('#TTM_Preview').hoverIntent(function() { | |
newCtxDataUrl = newCtx.canvas.toDataURL('image/png'); | |
newImg.onload = function() { | |
$('#TTM_Previewer').remove(); | |
$('#TTM_New_Outer').append('<div id="TTM_Previewer" style="position:absolute; display:inline-block; top:45px; right:-20px; padding:10px; background:#111; box-shadow:0px 0px 20px 6px #444; border:8px ridge #ccc; border-radius:10px; z-index:9999;"></div>'); | |
if (newCtxDataUrl.length > 8000) { | |
let bg = createPreview(newCtxDataUrl, previewCanvas).toDataURL('image/png'); | |
$('#TTM_Previewer').append('<canvas id="TTM_BG_Preview" width="640" height="440" style="background-image: url('+bg+');"></canvas>'); | |
animatePreview(); | |
speedpadImg.crossOrigin = 'Anonymous'; | |
speedpadImg.src = $('#speedpad').val(); | |
portalImg.crossOrigin = 'Anonymous'; | |
portalImg.src = $('#portal').val(); | |
} else { | |
$('#TTM_Previewer').append('<div>No Tiles?</div>'); | |
} | |
}; | |
newImg.crossOrigin = 'Anonymous'; | |
newImg.src = newCtxDataUrl; | |
}, function() { | |
$('#TTM_Previewer').remove(); | |
}); | |
$(window).on('resize', trySideBySide); | |
//start it... | |
setTimeout(function() { | |
loadCustomValues(); | |
$('#TTM_Tint_Group').hide(0); | |
if ($('#tiles').val()) { | |
loadImage($('#tiles').val()); | |
$('#TTM_Textures').val('customtileslink'); | |
} else { | |
loadImage('/textures/classic/tiles.png'); | |
} | |
trySideBySide(); | |
//createNewIcons(); | |
}, 800); | |
//functions... | |
let drawPop = 0; | |
let popStartSize = 100; | |
let popStep = 10; | |
let extraAnimFramePos = 0; | |
let frameCount = 0; | |
let animObjects = { | |
rball: { p0:{x:840, y:-200}, p1:{x:40, y:40}, p2:{x:40, y:400}, p3:{x:540, y:390}, tx:560, ty:0, speed:0.003, t:0 }, | |
bball: { p0:{x:680, y:-160}, p1:{x:-40, y:130}, p2:{x:0, y:540}, p3:{x:405, y:270}, tx:600, ty:0, speed:0.003, t:0 }, | |
yflag: { p0:{x:120, y:94}, p1:{x:352, y:346}, p2:{x:352, y:346}, p3:{x:352, y:346}, tx:520, ty:40, speed:0.0015, t:0, offx:13, offy:-32 }, | |
}; | |
function animatePreview() { | |
if (!$('#TTM_BG_Preview').length) return; | |
let bgCtx = document.getElementById('TTM_BG_Preview').getContext('2d'); | |
bgCtx.clearRect(0, 0, previewCanvas.width, previewCanvas.height); | |
bgCtx.fillStyle = 'rgba(255,128,0,0.1)'; | |
for (let key in animObjects) { | |
let value = animObjects[key]; | |
let draw = true; | |
let pt; | |
if (key === 'yflag') { | |
pt = { x:animObjects.bball.x + value.offx, y:animObjects.bball.y + value.offy }; | |
if ((value.speed < 0 && value.t < 0.5) || (value.speed > 0 && value.t > 0.5)) draw = false; | |
if (draw && pt.x > 370 && pt.y > 230) draw = false; | |
} else { | |
pt = calcBezierPoint(value.t, value.p0, value.p1, value.p2, value.p3); | |
value.x = pt.x; | |
value.y = pt.y; | |
if (key === 'rball') { | |
if (value.speed < 0) draw = false; | |
if (drawPop === 0 && pt.x+39 > value.p3.x && pt.y > 230 && value.speed < 0) drawPop = popStartSize; | |
} | |
} | |
if (draw) { | |
if (key === 'rball') { | |
bgCtx.save(); | |
bgCtx.translate(pt.x, pt.y); | |
bgCtx.rotate(200+(50*value.t)); | |
bgCtx.drawImage(newImg, value.tx,value.ty,40,40, -20,-20,40,40); | |
bgCtx.translate(-pt.x, -pt.y); | |
bgCtx.restore(); | |
} else { | |
bgCtx.drawImage(newImg, value.tx,value.ty,40,40, pt.x,pt.y,40,40); | |
} | |
} | |
value.t += value.speed; | |
if (value.t > 1 || value.t < 0) value.speed *= -1; | |
} | |
if (drawPop > 0) { | |
bgCtx.beginPath(); | |
bgCtx.arc(540,390,popStartSize-drawPop, 0, Math.PI*2, false); | |
bgCtx.fill(); | |
drawPop-=popStep; | |
} else { | |
drawPop = 0; | |
} | |
if (speedpadImg) { | |
bgCtx.drawImage(speedpadImg, extraAnimFramePos,0,40,40, 160,80,40,40); | |
bgCtx.drawImage(speedpadImg, extraAnimFramePos,0,40,40, 80,160,40,40); | |
} | |
if (portalImg) { | |
bgCtx.drawImage(portalImg, extraAnimFramePos,0,40,40, 600,320,40,40); | |
bgCtx.drawImage(portalImg, extraAnimFramePos,0,40,40, 600,360,40,40); | |
bgCtx.drawImage(portalImg, extraAnimFramePos,0,40,40, 600,400,40,40); | |
} | |
if (frameCount % 8 === 0) extraAnimFramePos+=40; | |
if (extraAnimFramePos >= 160) extraAnimFramePos = 0; | |
frameCount++; | |
window.requestAnimationFrame(animatePreview); | |
} | |
function closeImgurPreviewWindow() { | |
$('#TTM_Imgur_PreviewWindow').fadeOut(200, function() { | |
$('#TTM_Imgur_PreviewWindow_Image').attr('src', ''); | |
}); | |
} | |
function removeSpinner() { | |
$('#TTM_Container').find('.TTM_Loading').removeClass('TTM_Loading'); | |
} | |
function loadCustomValues() { | |
let texturePacks = JSON.parse($('#texture-pack-data').text()); | |
let savedTemps = JSON.parse(localStorage.getItem('savedTemps') || '{}'); | |
let myImgurs = JSON.parse(localStorage.getItem('myImgurs') || '{}'); | |
let extraPacks = {}; | |
//sort default packs... | |
texturePacks.sort(function(a, b) { | |
if (a.name.toLowerCase() < b.name.toLowerCase()) return -1; | |
if (a.name.toLowerCase() > b.name.toLowerCase()) return 1; | |
return 0; | |
}); | |
for (let i=0; i<texturePacks.length; i++) { | |
if (texturePacks[i].name === 'Classic') { //put this one at the start :) | |
texturePacks.splice(0, 0, texturePacks.splice(i, 1)[0]); | |
} | |
} | |
//some extra packs... | |
let message = '(Note: this texture is not part of the official TagPro texture packs collection)'; | |
extraPacks['88 Electric'] = { author:'Rob Flagetti'+message, tiles:'PzZ5u57', speedpad:'5i2b07D', speedpadRed:'WwQ70DK', speedpadBlue:'fIeILub', portal:'RFQgPXz', splats:'dSGptD4' }; | |
extraPacks['Aperture Laboratories'] = { author:'SuperSans'+message, tiles:'Fg9GIN2', speedpad:'CPoMTrR', speedpadRed:'Az9vhYO', speedpadBlue:'nMVO8KV', portal:'nPdqzJ2', splats:'HSufen1' }; | |
extraPacks['Brioche Light Diagonal'] = { author:'Brioche'+message, tiles:'GCVOxf0', speedpad:'HCTWYrI', speedpadRed:'PnFxbGc', speedpadBlue:'BxhPCj6', portal:'8hUe7G0', splats:'kbkOC6x' }; | |
extraPacks['Brioche Light Square'] = { author:'Brioche'+message, tiles:'h29Pa4P', speedpad:'HCTWYrI', speedpadRed:'PnFxbGc', speedpadBlue:'BxhPCj6', portal:'8hUe7G0', splats:'kbkOC6x' }; | |
extraPacks['Brioche Light None'] = { author:'Brioche'+message, tiles:'Z7aauqp', speedpad:'HCTWYrI', speedpadRed:'PnFxbGc', speedpadBlue:'BxhPCj6', portal:'8hUe7G0', splats:'kbkOC6x' }; | |
extraPacks['Candyland'] = { author:'-salt- (e:nabby)'+message, tiles:'EHCbMS0', speedpad:'hPpsrSI', speedpadRed:'EXqQbpF', speedpadBlue:'if3qEp0', portal:'lfczV8G', splats:'M5TMzBO' }; | |
extraPacks['Catalyst'] = { author:'Catalyst'+message, tiles:'Jpx6FP1', speedpad:'5Z5KC2x', speedpadRed:'kwn7wLk', speedpadBlue:'Z8YlL8e', portal:'hr1zffY', splats:'mGxI0zl' }; | |
extraPacks['Derezzed'] = { author:'-salt- (e:nabby)'+message, tiles:'L0V5dx8', speedpad:'/textures/sparkle/speedpad.png', speedpadRed:'/textures/sparkle/speedpadred.png', speedpadBlue:'if3qEp0', portal:'vJDZam9', splats:'WXHAA3I' }; | |
extraPacks['Doodle'] = { author:'turtlemansam'+message, tiles:'W0anL7u', speedpad:'aLs3qyH', speedpadRed:'uObyeQ2', speedpadBlue:'Ko9Rea2', portal:'bFYUxzA', splats:'KillvgL' }; | |
extraPacks['Doodle Dark'] = { author:'turtlemansam (e:nabby)'+message, tiles:'UeAOeLb', speedpad:'22t8hoV', speedpadRed:'EfQFr4G', speedpadBlue:'hPMDhD5', portal:'H1cHH5w', splats:'KillvgL' }; | |
extraPacks['Dyslexia'] = { author:'MagicPigeon'+message, tiles:'bhNV6LS', speedpad:'nUakHFN', speedpadRed:'3I745gq', speedpadBlue:'LEB9Wfw', portal:'5Z5Yrhu', splats:'u5kzgws' }; | |
extraPacks['Glow'] = { author:'MagicPigeon'+message, tiles:'ciiB8Pw', speedpad:'IB95nd5', speedpadRed:'8RgHd1Y', speedpadBlue:'E3gqIdZ', portal:'H1e5f5X', splats:'yMbLHLT' }; | |
extraPacks['Halloween'] = { author:'TagPro'+message, tiles:'DqpxNyk', speedpad:'/images/events/halloween/speedpad.png', speedpadRed:'/images/events/halloween/speedpadred.png', speedpadBlue:'/images/events/halloween/speedpadblue.png', portal:'/images/events/halloween/portal.png', splats:'/images/events/halloween/splats.png' }; | |
extraPacks['Jar Jar Pinks'] = { author:'Borgen'+message, tiles:'OMvtZnn', speedpad:'/textures/electric/speedpad.png', speedpadRed:'/textures/electric/speedpadred.png', speedpadBlue:'/textures/electric/speedpadblue.png', portal:'/textures/electric/portal.png', splats:'wxJ2ImS' }; | |
extraPacks['Jar Jar R/B'] = { author:'Borgen (e:nabby)'+message, tiles:'auGwfdD', speedpad:'/textures/crystal/speedpad.png', speedpadRed:'/textures/crystal/speedpadred.png', speedpadBlue:'/textures/crystal/speedpadblue.png', portal:'BHltUAU', splats:'/textures/sparkle/splats.png' }; | |
extraPacks['Kindergarten'] = { author:'Clydas'+message, tiles:'Zr1881o', speedpad:'UEpX1wb', speedpadRed:'tUC9CMG', speedpadBlue:'5yA3IOx', portal:'6Lbd9Aw', splats:'ZGSTp2s' }; | |
extraPacks['Mario'] = { author:'MagicPigeon'+message, tiles:'0ErN4Be', speedpad:'zImnW1i', speedpadRed:'AXEDaAv', speedpadBlue:'mH8Qww0', portal:'BLIVace', splats:'9dAtpMy' }; | |
extraPacks['Minima'] = { author:'Canvas'+message, tiles:'KAk9TN9', speedpad:'pJEZKnh', speedpadRed:'OlDPpdM', speedpadBlue:'HgmJ9yg', portal:'DeevRGe', splats:'ytIIuQS' }; | |
extraPacks['Next Classic'] = { author:'TagPro (e:MagicPigeon)'+message, tiles:'ulQFpn7', speedpad:'w7pW8SC', speedpadRed:'FHjSv04', speedpadBlue:'SSK4Hno', portal:'gdJfGV9', splats:'GObCQoT' }; | |
extraPacks['Nilla'] = { author:'Dotsarecool'+message, tiles:'kuPdAXV', speedpad:'39zXNPL', speedpadRed:'bo4m727', speedpadBlue:'EFk5IgL', portal:'KdEHGtf', splats:'kHUlTwP' }; | |
extraPacks['Pixelated'] = { author:'iso'+message, tiles:'vmnTlEK', speedpad:'ZfS3vb1', speedpadRed:'Ao8vGcn', speedpadBlue:'MW7K5PV', portal:'JXTmmen', splats:'LFoPM44' }; | |
extraPacks['Seaweed G/B'] = { author:'Borgen'+message, tiles:'Kh4jUfE', speedpad:'ONxlcFL', speedpadRed:'y3MZi7c', speedpadBlue:'DpJS96w', portal:'44fPSBq', splats:'ipV54ze' }; | |
extraPacks['Seaweed R/B'] = { author:'Borgen'+message, tiles:'RslLcen', speedpad:'A6cNVb3', speedpadRed:'DwUHM2I', speedpadBlue:'DpJS96w', portal:'44fPSBq', splats:'ZrimG2x' }; | |
extraPacks['Starlight R/B'] = { author:'MagicPigeon (e:nabby)'+message, tiles:'j0el5Tn', speedpad:'22t8hoV', speedpadRed:'EfQFr4G', speedpadBlue:'hPMDhD5', portal:'rGEEQ2s', splats:'IIFG2nS' }; | |
extraPacks['Star Wars'] = { author:'Moosen'+message, tiles:'1GQnONe', speedpad:'WgeuDEz', speedpadRed:'cqY1LTe', speedpadBlue:'bCUoqXq', portal:'FtLHfuz', splats:'XIndyGS' }; | |
extraPacks['TagPro Ultra'] = { author:'MuscleCups'+message, tiles:'qTjavFh', speedpad:'dLPehvN', speedpadRed:'U9eQnIa', speedpadBlue:'CtRmTaF', portal:'yiLdTR9', splats:'TTuhrS5' }; | |
extraPacks['Tranquility Dark'] = { author:'R e t r o'+message, tiles:'fb8ueHE', speedpad:'tZE7l6b', speedpadRed:'AGMgt6S', speedpadBlue:'nokGBIr', portal:'gFC1dUu', splats:'tDsbgPv' }; | |
extraPacks['Ultra Smooth'] = { author:'ProfessorTag'+message, tiles:'Nw0EqWH', speedpad:'zxubWbQ', speedpadRed:'yJGhLPt', speedpadBlue:'K02G9jE', portal:'hffUZ2J', splats:'xMMkRce' }; | |
extraPacks['Vanilla Pro'] = { author:'ProfessorTag'+message, tiles:'ZKAwVRG', speedpad:'6h2Fna8', speedpadRed:'pF4l9SO', speedpadBlue:'NlepAuW', portal:'qpg0wCt', splats:'ABTYq4t' }; | |
extraPacks['Vortex'] = { author:'MagicPigeon'+message, tiles:'CLgkyxU', speedpad:'hL1YlFu', speedpadRed:'gxQeYTw', speedpadBlue:'pbXh4b1', portal:'H1cHH5w', splats:'36fUJG2' }; | |
extraPacks['Whix Grey'] = { author:'Nabby'+message, tiles:'E9Qjdw6', speedpad:'22t8hoV', speedpadRed:'EfQFr4G', speedpadBlue:'hPMDhD5', portal:'lfczV8G', splats:'F799BFp' }; | |
extraPacks['Whix Light'] = { author:'Nabby'+message, tiles:'Z05ydSW', speedpad:'22t8hoV', speedpadRed:'EfQFr4G', speedpadBlue:'hPMDhD5', portal:'lfczV8G', splats:'F799BFp' }; | |
extraPacks['Whix Dark'] = { author:'Nabby'+message, tiles:'xw3lN2o', speedpad:'22t8hoV', speedpadRed:'EfQFr4G', speedpadBlue:'hPMDhD5', portal:'lfczV8G', splats:'F799BFp' }; | |
extraPacks['Yin-Yang'] = { author:'Browncoat'+message, tiles:'kTVchxk', speedpad:'NVPIQ1y', speedpadRed:'e18kH49', speedpadBlue:'lv8pcWF', portal:'DZried3', splats:'0GTWyyW' }; | |
extraPacks['YYRB'] = { author:'Browncoat (e:nabby)'+message, tiles:'nDW1Tip', speedpad:'sTqwM4n', speedpadRed:'7tZjFli', speedpadBlue:'pF3xUlZ', portal:'Qb4iyjY', splats:'TqJKyQR' }; | |
extraPacks['YYRB Light'] = { author:'Browncoat (e:nabby)'+message, tiles:'qkaeirQ', speedpad:'sTqwM4n', speedpadRed:'7tZjFli', speedpadBlue:'pF3xUlZ', portal:'Qb4iyjY', splats:'TqJKyQR' }; | |
extraPacks['YYRB Dark'] = { author:'Browncoat (e:nabby)'+message, tiles:'4RMaqMn', speedpad:'sTqwM4n', speedpadRed:'7tZjFli', speedpadBlue:'pF3xUlZ', portal:'Qb4iyjY', splats:'TqJKyQR' }; | |
$('#TTM_Textures').append('<optgroup label="Default Packs..." style="color:#d00; text-decoration:underline; font-weight:bold;">'); | |
$.each(texturePacks, function(key, value) { | |
$('#TTM_Textures').append(' <option value="'+value.tiles+'"'+(value.author?' title="Created by '+value.author+'"':'')+'>'+value.name+'</option>'); | |
}); | |
$('#TTM_Textures').append('</optgroup>'); | |
$('#TTM_Textures').append('<optgroup label="Extra Packs..." style="color:#d00; text-decoration:underline; font-weight:bold;">'); | |
$.each(extraPacks, function(key, value) { | |
let url = value.tiles.startsWith('/') ? value.tiles : 'https://i.imgur.com/' + value.tiles + '.png'; | |
$('#TTM_Textures').append('<option value="' + url + '"' + (value.author ? ' title="Created by ' + value.author + '"' : '') + '>' + key + '</option>'); | |
}); | |
$('#TTM_Textures').append('</optgroup>'); | |
$('#TTM_Textures').append('<optgroup id="TTM_OptGroup_CustomTilesLink" label="Custom Tiles Link..." style="color:#d00; text-decoration:underline; font-weight:bold;">'); | |
$('#TTM_Textures').append(' <option value="customtileslink" title="This is the link from "Tiles" on the "Import Custom" tab">Custom Tiles Link</option>'); | |
$('#TTM_Textures').append('</optgroup>'); | |
//my quick saved... | |
$.each(savedTemps, function(key, value) { | |
createNewIcon(key, '#TTM_QuickSaves'); | |
}); | |
//my imgur uploads... | |
$.each(myImgurs, function(key, value) { | |
createNewIcon(myImgurs[key].title, '#TTM_Imgur_MenuInner', myImgurs[key]); | |
}); | |
} | |
function loadImage(newCtxDataUrl, isDragged=false) { | |
tilesImg.onload = function() { | |
let width = tilesImg.naturalWidth; | |
let height = tilesImg.naturalHeight; | |
if ((width !== 640) || (height !== 440)) { | |
$('#TTM_FreeMove').prop('checked', true); | |
$('#TTM_FreeMove').parent().show(); | |
freeMove = true; | |
} else { | |
$('#TTM_FreeMove').prop('checked', false); | |
$('#TTM_FreeMove').parent().hide(); | |
freeMove = false; | |
} | |
tilesCtx = $("#TTM_Tiles_Canvas").get(0).getContext("2d"); | |
tilesCtx.canvas.width = width; | |
tilesCtx.canvas.height = height; | |
tilesCtx.clearRect(0, 0, width, height); | |
tilesCtx.drawImage(tilesImg, 0,0,width,height, 0,0,width,height); | |
if (width > 640) $("#TTM_Tiles").css({ 'overflow-x':'auto' }); | |
else $("#TTM_Tiles").css({ 'overflow':'hidden' }); | |
if (height > 440) $("#TTM_Tiles").css({ 'overflow-y':'auto' }); | |
else $("#TTM_Tiles").css({ 'overflow':'hidden' }); | |
$("#TTM_Tiles_Cover").css({ 'width':width+'px', 'height':height+'px' }); | |
if (isDragged) { | |
if (!$('#TTM_OptGroup_Dragged').length) $('#TTM_Textures').append('<optgroup id="TTM_OptGroup_Dragged" label="Drag\'n\'Dropped..." style="color:#d00; text-decoration:underline; font-weight:bold;"></optgroup>'); | |
$('#TTM_Option_Dragged').remove(); | |
$('#TTM_OptGroup_Dragged').after('<option id="TTM_Option_Dragged" value="dragged" title="Dragged: '+isDragged+'">Drag\'n\'Dropped</option>'); | |
$('#TTM_Textures').val('dragged'); | |
$('#TTM_UpdateCTL').hide(); | |
} | |
tilesImg.onload = null; | |
}; | |
tilesImg.onerror = function() { | |
alert('Could not load the image at...\n\n ' + newCtxDataUrl + '\n\nCross-origin access may have been denied by the server?\n\n\n'); | |
}; | |
tilesImg.crossOrigin = 'Anonymous'; | |
tilesImg.src = newCtxDataUrl; | |
} | |
function createNewIcon(name, element, imgurData) { | |
let loadTitle = 'LOAD these saved tiles'; | |
let dataName = name; | |
if (imgurData) { | |
if (!name) name = imgurData.id; | |
dataName = imgurData.id; | |
let date = new Date(imgurData.datetime*1000); | |
loadTitle = (imgurData.title ? imgurData.title + ' (' + imgurData.id + ')' : imgurData.id) + | |
'\n - ' + date.toDateString() + ' (' + date.toLocaleTimeString() + ')' + | |
'\n - ' + imgurData.width + 'x' + imgurData.height + 'px (' + (imgurData.size / 1024).toFixed(0) + 'KB)'; | |
} | |
$(element).append('<div class="TTM_Saved" data-name="'+dataName+'" style="" title="'+loadTitle+'">' + name + | |
(!imgurData ? '<div class="TTM_DeleteSaved" style="" title="DELETE these saved tiles">x</div>' : '') + | |
'</div>'); | |
} | |
function updateModifyTilePreviews(updateSource=true) { | |
let sourceCtx = $('#TTM_ModifySourceTilePreview').get(0).getContext('2d'); | |
if (updateSource) sourceCtx.clearRect(0, 0, 40, 40); | |
if (fixedTarget) { | |
let x = parseInt( newHoverFixed.css('left') ); | |
let y = parseInt( newHoverFixed.css('top') ); | |
$('#TTM_Modify_Message').hide(); | |
if (updateSource) sourceCtx.drawImage($('#TTM_Modify_CopySource').is(':checked') ? tilesCtx.canvas : newCtx.canvas, x,y,40,40, 0,0,40,40); | |
if (x < 480) { | |
tintTiles(0, 0, 480, 440, false, true); | |
} else { | |
tintTiles(x, y, 40, 40, false, false); | |
} | |
} else { | |
$('#TTM_Modify_Message').show(); | |
} | |
} | |
function tintTiles(sx, sy, sw=40, sh=40, updateNew=false, isWalls=false) { | |
let tintedCanvas = new OffscreenCanvas(sw, sh); | |
let tintedCtx = tintedCanvas.getContext('2d'); | |
let tempCtx = tempCanvas.getContext('2d'); | |
let destCtx = $('#TTM_ModifyDestTilePreview').get(0).getContext('2d'); | |
let applyFilters = function() { | |
let filters = ''; | |
filters += 'hue-rotate(' + $('#TTM_TileHue').val() + 'deg) '; | |
if ($('#TTM_Sepia').val() > 0) filters += 'sepia('+$('#TTM_Sepia').val()+'%) '; | |
if (($('#TTM_Brightness').val() !== '100')) filters += 'brightness('+$('#TTM_Brightness').val()+'%) '; | |
if (($('#TTM_Contrast').val() != '100')) filters += 'contrast('+$('#TTM_Contrast').val()+'%) '; | |
if (($('#TTM_Saturation').val() !== '100')) filters += 'saturate('+$('#TTM_Saturation').val()+'%) '; | |
if ($('#TTM_Add_Checkered').is(':checked')) addCheckered(tintedCtx); | |
if ($('#TTM_Add_Pattern').is(':checked')) addPattern(tintedCtx); | |
if ($('#TTM_Add_Stripes').is(':checked')) addStripes(tintedCtx); | |
if ($('#TTM_Add_Specks').is(':checked')) addSpecks(tintedCtx); | |
if ($('#TTM_Add_Shine').is(':checked')) addShine(tintedCtx); | |
if ($('#TTM_Add_Border').is(':checked')) addBorder(tintedCtx); | |
destCtx.clearRect(0, 0, 40, 40); | |
destCtx.filter = filters; | |
destCtx.drawImage(tintedCanvas, 0,0,sw,sh, 0,0,sw,sh); | |
if (updateNew) { | |
newCtx.clearRect(sx, sy, sw, sh); | |
newCtx.filter = filters; | |
newCtx.drawImage(tintedCanvas, 0,0,sw,sh, sx,sy,sw,sh); | |
newCtx.filter = 'none'; | |
} | |
tintedCanvas = null; | |
}; | |
let px = 0; | |
let py = 0; | |
if (!updateNew) { | |
if (isWalls) { | |
px = parseInt( newHoverFixed.css('left') ); | |
py = parseInt( newHoverFixed.css('top') ); | |
} | |
} | |
tintedCtx.drawImage(tempCtx.canvas, px,py,sw,sh, 0,0,sw,sh); | |
if ($('#TTM_Tint').is(':checked')) { | |
let method = $('#TTM_Tint_Group').find(':selected').val(); | |
if (method === 'simple') { | |
setTint(tintedCanvas, $('#TTM_Tint_Color').val(), 0.5); | |
applyFilters(); | |
} else { | |
generateTintedImage(tintedCtx, $('#TTM_Tint_Color').val(), method); | |
applyFilters(); | |
} | |
} else { | |
applyFilters(); | |
} | |
} | |
function copyTiles(sx, sy, sw=40, sh=40, dx=sx, dy=sy, dw=sw, dh=sh, isCircle=false) { | |
let size = selectorSize; | |
let xOffset = 0; | |
let yOffset = 0; | |
if (freeMove && !fixedTarget) { | |
alert('You need to first select a target tile...'); | |
return; | |
} | |
if (size < 40) { | |
xOffset = 20-(size/2); | |
yOffset = 20-(size/2); | |
} | |
if ((dw > 40) || (dh > 40)) { | |
newCtx.clearRect(dx, dy, dw, dh); | |
newCtx.drawImage(tilesCtx.canvas, sx,sy,sw,sh, dx,dy,dw,dh); | |
} else { | |
let canvas = new OffscreenCanvas(size, size); | |
let ctx = canvas.getContext('2d'); | |
ctx.beginPath(); | |
if (isCircle) { | |
ctx.arc(size/2, size/2, sw/2, 0, Math.PI*2); | |
} else { | |
ctx.rect(0, 0, sw, sh); | |
} | |
ctx.clip(); | |
ctx.drawImage(tilesCtx.canvas, sx,sy,size,size, 0,0,size,size); | |
if (fixedTarget) { | |
newCtx.clearRect(dx, dy, 40, 40); | |
newCtx.drawImage(ctx.canvas, 0,0,sw,sh, dx+xOffset,dy+yOffset,dw,dh); | |
} else { | |
if (!freeMove) newCtx.clearRect(dx-xOffset, dy-yOffset, 40, 40); | |
newCtx.drawImage(ctx.canvas, 0,0,sw,sh, dx,dy,dw,dh); | |
} | |
canvas = null; | |
} | |
} | |
function trySideBySide() { | |
if ($('body').width() > 1410) { | |
$('#TTM_Container').css({ 'width':'1400px', 'margin-left':'-130px' }); //try for side-by-side if enough room | |
} else { | |
$('#TTM_Container').css({ 'width':'', 'margin-left':'' }); | |
} | |
} | |
function setTint(targetCanvas, color, opacity) { | |
let tintCanvas = new OffscreenCanvas(targetCanvas.width, targetCanvas.height); | |
let ctintCtxtx = tintCanvas.getContext('2d'); | |
tintCtx.globalCompositeOperation = "destination-atop"; | |
tintCtx.fillStyle = hexToRgbA(color || "#000000", opacity); | |
tintCtx.fillRect(0, 0, tintCanvas.width, tintCanvas.height); | |
tintCtx.drawImage(targetCanvas, 0, 0); | |
let imageCtx = targetCanvas.getContext("2d"); | |
imageCtx.drawImage(tintCanvas, 0, 0); | |
tintCanvas = null; | |
} | |
//From: http://www.playmycode.com/blog/2011/06/realtime-image-tinting-on-html5-canvas/ | |
function generateRGBKs(ctx, method) { | |
let width = ctx.canvas.width; | |
let height = ctx.canvas.height; | |
let rgbks = []; | |
let pixels = ctx.getImageData(0, 0, width, height).data; | |
let to = ctx.getImageData(0, 0, width, height); | |
let toData = to.data; | |
let gray; | |
for (let rgbI=0; rgbI<4; rgbI++) { | |
for (let i=0, len=pixels.length; i<len; i+=4) { | |
if (method === 'desaturation') { | |
gray = ( Math.max(pixels[i], pixels[i+1], pixels[i+2]) + Math.min(pixels[i], pixels[i+1], pixels[i+2]) ) / 2; //simple desaturation | |
} else if (method === 'decomposition') { | |
gray = Math.max(pixels[i], pixels[i+1], pixels[i+2]); //simple decomposition | |
} else { | |
gray = (0.3 * pixels[i] + 0.59 * pixels[i + 1] + 0.11 * pixels[i + 2]); //simple brightness | |
} | |
pixels[i ] = gray; | |
pixels[i + 1] = gray; | |
pixels[i + 2] = gray; | |
toData[i ] = (rgbI === 0) ? pixels[i ] : 0; | |
toData[i+1] = (rgbI === 1) ? pixels[i+1] : 0; | |
toData[i+2] = (rgbI === 2) ? pixels[i+2] : 0; | |
toData[i+3] = pixels[i+3] ; | |
} | |
ctx.putImageData(to, 0, 0); | |
let imgComp = document.createElement('img'); | |
imgComp.src = ctx.canvas.toDataURL(); | |
rgbks.push(imgComp); | |
imgComp = null; | |
} | |
return rgbks; | |
} | |
function generateTintedImage(ctx, color, method) { | |
let rgbks = generateRGBKs(ctx, method); | |
let tintRgbs = hexToRgb(color); | |
let red = tintRgbs[0]; | |
let green = tintRgbs[1]; | |
let blue = tintRgbs[2]; | |
ctx.globalAlpha = 1; | |
ctx.globalCompositeOperation = 'copy'; | |
ctx.drawImage(rgbks[3], 0, 0); | |
ctx.globalCompositeOperation = 'lighter'; | |
if (red > 0) { | |
ctx.globalAlpha = red / 255.0; | |
ctx.drawImage( rgbks[0], 0, 0 ); | |
} | |
if (green > 0) { | |
ctx.globalAlpha = green / 255.0; | |
ctx.drawImage( rgbks[1], 0, 0 ); | |
} | |
if (blue > 0) { | |
ctx.globalAlpha = blue / 255.0; | |
ctx.drawImage( rgbks[2], 0, 0 ); | |
} | |
ctx.globalAlpha = 1; | |
ctx.globalCompositeOperation = 'source-over'; | |
} | |
function createPreview(url, canvas) { | |
let map = {"info":{"width":16,"height":11},"data":{"0_5":{"id":9.1,"x":0,"y":5,"tx":520,"ty":120},"0_6":{"id":9.1,"x":0,"y":6,"tx":520,"ty":120},"1_1":{"id":2,"x":1,"y":1,"tx":520,"ty":160},"1_2":{"id":2,"x":1,"y":2,"tx":520,"ty":160},"1_3":{"id":2,"x":1,"y":3,"tx":520,"ty":160},"1_4":{"id":2,"x":1,"y":4,"tx":520,"ty":160},"1_5":{"id":2,"x":1,"y":5,"tx":520,"ty":160},"1_6":{"id":2,"x":1,"y":6,"tx":520,"ty":160},"1_7":{"id":2,"x":1,"y":7,"tx":520,"ty":160},"1_8":{"id":2,"x":1,"y":8,"tx":520,"ty":160},"1_9":{"id":2,"x":1,"y":9,"tx":520,"ty":160},"1_10":{"id":2,"x":1,"y":10,"tx":520,"ty":160},"2_1":{"id":2,"x":2,"y":1,"tx":520,"ty":160},"2.2":{"id":2,"x":2,"y":2,"tx":520,"ty":160},"2_3":{"id":2,"x":2,"y":3,"tx":520,"ty":160},"2_4":{"id":23,"x":2,"y":4,"tx":520,"ty":200},"2_5":{"id":23,"x":2,"y":5,"tx":520,"ty":200},"2_6":{"id":23,"x":2,"y":6,"tx":520,"ty":200},"2_7":{"id":23,"x":2,"y":7,"tx":520,"ty":200},"2_8":{"id":2,"x":2,"y":8,"tx":520,"ty":160},"2.9":{"id":2,"x":2,"y":9,"tx":520,"ty":160},"2_10":{"id":2,"x":2,"y":10,"tx":520,"ty":160},"3_0":{"id":9.2,"x":3,"y":0,"tx":560,"ty":120},"3_1":{"id":2,"x":3,"y":1,"tx":520,"ty":160},"3_2":{"id":2,"x":3,"y":2,"tx":520,"ty":160},"3_3":{"id":2,"x":3,"y":3,"tx":520,"ty":160},"3_4":{"id":2,"x":3,"y":4,"tx":520,"ty":160},"3_5":{"id":2,"x":3,"y":5,"tx":520,"ty":160},"3_6":{"id":2,"x":3,"y":6,"tx":520,"ty":160},"3_7":{"id":2,"x":3,"y":7,"tx":520,"ty":160},"3_8":{"id":2,"x":3,"y":8,"tx":520,"ty":160},"3_9":{"id":2,"x":3,"y":9,"tx":520,"ty":160},"3_10":{"id":2,"x":3,"y":10,"tx":520,"ty":160},"4_0":{"id":9.2,"x":4,"y":0,"tx":560,"ty":120},"4_1":{"id":2,"x":4,"y":1,"tx":520,"ty":160},"4_2":{"id":2,"x":4,"y":2,"tx":520,"ty":160},"4_3":{"id":2,"x":4,"y":3,"tx":520,"ty":160},"4_4":{"id":2,"x":4,"y":4,"tx":520,"ty":160},"4_5":{"id":2,"x":4,"y":5,"tx":520,"ty":160},"4_6":{"id":2,"x":4,"y":6,"tx":520,"ty":160},"4_7":{"id":2,"x":4,"y":7,"tx":520,"ty":160},"4_8":{"id":2,"x":4,"y":8,"tx":520,"ty":160},"4_9":{"id":2,"x":4,"y":9,"tx":520,"ty":160},"4_10":{"id":2,"x":4,"y":10,"tx":520,"ty":160},"5_1":{"id":2,"x":5,"y":1,"tx":520,"ty":160},"5_2":{"id":2,"x":5,"y":2,"tx":520,"ty":160},"5_3":{"id":2,"x":5,"y":3,"tx":520,"ty":160},"5_4":{"id":2,"x":5,"y":4,"tx":520,"ty":160},"5_5":{"id":2,"x":5,"y":5,"tx":520,"ty":160},"5_6":{"id":2,"x":5,"y":6,"tx":520,"ty":160},"5_7":{"id":2,"x":5,"y":7,"tx":520,"ty":160},"5_8":{"id":2,"x":5,"y":8,"tx":520,"ty":160},"5_9":{"id":2,"x":5,"y":9,"tx":520,"ty":160},"5_10":{"id":2,"x":5,"y":10,"tx":520,"ty":160},"6_1":{"id":2,"x":6,"y":1,"tx":520,"ty":160},"6_2":{"id":2,"x":6,"y":2,"tx":520,"ty":160},"6_3":{"id":2,"x":6,"y":3,"tx":520,"ty":160},"6_4":{"id":2,"x":6,"y":4,"tx":520,"ty":160},"6.5":{"id":2,"x":6,"y":5,"tx":520,"ty":160},"6_5":{"id":7,"x":6,"y":5,"tx":480,"ty":0},"6.6":{"id":2,"x":6,"y":6,"tx":520,"ty":160},"6_6":{"id":7,"x":6,"y":6,"tx":480,"ty":0},"6_7":{"id":2,"x":6,"y":7,"tx":520,"ty":160},"6_8":{"id":2,"x":6,"y":8,"tx":520,"ty":160},"6_9":{"id":2,"x":6,"y":9,"tx":520,"ty":160},"6_10":{"id":2,"x":6,"y":10,"tx":520,"ty":160},"7_0":{"id":2,"x":7,"y":0,"tx":520,"ty":160},"7_1":{"id":2,"x":7,"y":1,"tx":520,"ty":160},"7_2":{"id":2,"x":7,"y":2,"tx":520,"ty":160},"7.3":{"id":2,"x":7,"y":3,"tx":520,"ty":160},"7_3":{"id":8,"x":7,"y":3,"tx":520,"ty":240},"7_4":{"id":2,"x":7,"y":4,"tx":520,"ty":160},"7_6":{"id":11,"x":7,"y":6,"tx":560,"ty":160},"7_7":{"id":11,"x":7,"y":7,"tx":560,"ty":160},"7_8":{"id":2,"x":7,"y":8,"tx":520,"ty":160},"7_9":{"id":2,"x":7,"y":9,"tx":520,"ty":160},"7_10":{"id":2,"x":7,"y":10,"tx":520,"ty":160},"8_0":{"id":2,"x":8,"y":0,"tx":520,"ty":160},"8_1":{"id":2,"x":8,"y":1,"tx":520,"ty":160},"8_2":{"id":9,"x":8,"y":2,"tx":480,"ty":120},"8_3":{"id":9,"x":8,"y":3,"tx":480,"ty":120},"8_4":{"id":9,"x":8,"y":4,"tx":480,"ty":120},"8_6":{"id":11,"x":8,"y":6,"tx":560,"ty":160},"8_7":{"id":11,"x":8,"y":7,"tx":560,"ty":160},"8_8":{"id":11,"x":8,"y":8,"tx":560,"ty":160},"8_9":{"id":2,"x":8,"y":9,"tx":520,"ty":160},"8_10":{"id":2,"x":8,"y":10,"tx":520,"ty":160},"9_0":{"id":2,"x":9,"y":0,"tx":520,"ty":160},"9_1":{"id":2,"x":9,"y":1,"tx":520,"ty":160},"9_2":{"id":12,"x":9,"y":2,"tx":600,"ty":160},"9_3":{"id":9,"x":9,"y":3,"tx":480,"ty":120},"9_4":{"id":9,"x":9,"y":4,"tx":480,"ty":120},"9_6":{"id":18,"x":9,"y":6,"tx":600,"ty":200},"9_7":{"id":11,"x":9,"y":7,"tx":560,"ty":160},"9_8":{"id":11,"x":9,"y":8,"tx":560,"ty":160},"9_9":{"id":11,"x":9,"y":9,"tx":560,"ty":160},"9_10":{"id":2,"x":9,"y":10,"tx":520,"ty":160},"10_0":{"id":2,"x":10,"y":0,"tx":520,"ty":160},"10_1":{"id":2,"x":10,"y":1,"tx":520,"ty":160},"10_2":{"id":12,"x":10,"y":2,"tx":600,"ty":160},"10_3":{"id":12,"x":10,"y":3,"tx":600,"ty":160},"10_4":{"id":9,"x":10,"y":4,"tx":480,"ty":120},"10_6":{"id":18,"x":10,"y":6,"tx":600,"ty":200},"10_7":{"id":18,"x":10,"y":7,"tx":600,"ty":200},"10_8":{"id":11,"x":10,"y":8,"tx":560,"ty":160},"10_9":{"id":11,"x":10,"y":9,"tx":560,"ty":160},"10_10":{"id":11,"x":10,"y":10,"tx":560,"ty":160},"11_0":{"id":2,"x":11,"y":0,"tx":520,"ty":160},"11_1":{"id":2,"x":11,"y":1,"tx":520,"ty":160},"11_2":{"id":2,"x":11,"y":2,"tx":520,"ty":160},"11_3":{"id":12,"x":11,"y":3,"tx":600,"ty":160},"11_4":{"id":12,"x":11,"y":4,"tx":600,"ty":160},"11_7":{"id":18,"x":11,"y":7,"tx":600,"ty":200},"11_8":{"id":18,"x":11,"y":8,"tx":600,"ty":200},"11_9":{"id":11,"x":11,"y":9,"tx":560,"ty":160},"11_10":{"id":11,"x":11,"y":10,"tx":560,"ty":160},"12_0":{"id":2,"x":12,"y":0,"tx":520,"ty":160},"12_1":{"id":2,"x":12,"y":1,"tx":520,"ty":160},"12_2":{"id":2,"x":12,"y":2,"tx":520,"ty":160},"12_3":{"id":2,"x":12,"y":3,"tx":520,"ty":160},"12_4":{"id":2,"x":12,"y":4,"tx":520,"ty":160},"12.5":{"id":2,"x":12,"y":5,"tx":520,"ty":160},"12_5":{"id":10,"x":12,"y":5,"tx":480,"ty":40},"12_7":{"id":18,"x":12,"y":7,"tx":600,"ty":200},"12_8":{"id":18,"x":12,"y":8,"tx":600,"ty":200},"12_9":{"id":18,"x":12,"y":9,"tx":600,"ty":200},"12_10":{"id":18,"x":12,"y":10,"tx":600,"ty":200},"13_0":{"id":2,"x":13,"y":0,"tx":520,"ty":160},"13_1":{"id":2,"x":13,"y":1,"tx":520,"ty":160},"13_2":{"id":2,"x":13,"y":2,"tx":520,"ty":160},"13_3":{"id":2,"x":13,"y":3,"tx":520,"ty":160},"13_4":{"id":2,"x":13,"y":4,"tx":520,"ty":160},"13_5":{"id":2,"x":13,"y":5,"tx":520,"ty":160},"13.6":{"id":2,"x":13,"y":6,"tx":520,"ty":160},"13_6":{"id":10.1,"x":13,"y":6,"tx":480,"ty":80},"13_8":{"id":18,"x":13,"y":8,"tx":600,"ty":200},"13_9":{"id":18,"x":13,"y":9,"tx":600,"ty":200},"13_10":{"id":18,"x":13,"y":10,"tx":600,"ty":200},"14.0":{"id":2,"x":14,"y":0,"tx":520,"ty":160},"14_0":{"id":7,"x":14,"y":0,"tx":480,"ty":0},"14.1":{"id":2,"x":14,"y":1,"tx":520,"ty":160},"14_2":{"id":2,"x":14,"y":2,"tx":520,"ty":160},"14_3":{"id":2,"x":14,"y":3,"tx":520,"ty":160},"14_4":{"id":2,"x":14,"y":4,"tx":520,"ty":160},"14_5":{"id":2,"x":14,"y":5,"tx":520,"ty":160},"14_6":{"id":2,"x":14,"y":6,"tx":520,"ty":160},"14_8":{"id":9.3,"x":14,"y":8,"tx":600,"ty":120},"14_9":{"id":9.3,"x":14,"y":9,"tx":600,"ty":120},"14_10":{"id":9.3,"x":14,"y":10,"tx":600,"ty":120},"15.0":{"id":2,"x":15,"y":0,"tx":520,"ty":160},"15.1":{"id":2,"x":15,"y":1,"tx":520,"ty":160},"15_1":{"id":7,"x":15,"y":1,"tx":480,"ty":0},"15_2":{"id":2,"x":15,"y":2,"tx":520,"ty":160},"15_3":{"id":17,"x":15,"y":3,"tx":560,"ty":200},"15_4":{"id":17,"x":15,"y":4,"tx":560,"ty":200},"15_5":{"id":17,"x":15,"y":5,"tx":560,"ty":200},"15_6":{"id":2,"x":15,"y":6,"tx":520,"ty":160},"15_8":{"id":2,"x":15,"y":8,"tx":520,"ty":160},"15_9":{"id":2,"x":15,"y":9,"tx":520,"ty":160},"15_10":{"id":2,"x":15,"y":10,"tx":520,"ty":160}}}; | |
let pups = {"jukejuice":{"id":6.1,"x":14,"y":1,"tx":480,"ty":160}, "rollingbomb":{"id":6.2,"x":2,"y":2,"tx":480,"ty":200}, "tagpro":{"id":6.3,"x":15,"y":0,"tx":480,"ty":240}, "placeholder":{"id":6,"x":2,"y":9,"tx":480,"ty":320} }; | |
let walls = {"0":{"q":0,"x":0,"y":0,"tx":0,"ty":280},"1":{"q":1,"x":0,"y":0,"tx":220,"ty":200},"2":{"q":2,"x":0,"y":0,"tx":220,"ty":220},"3":{"q":3,"x":0,"y":0,"tx":0,"ty":220},"4":{"q":0,"x":0,"y":1,"tx":0,"ty":200},"5":{"q":1,"x":0,"y":1,"tx":220,"ty":240},"6":{"q":2,"x":0,"y":1,"tx":300,"ty":340},"7":{"q":3,"x":0,"y":1,"tx":0,"ty":220},"8":{"q":0,"x":0,"y":2,"tx":0,"ty":200},"9":{"q":1,"x":0,"y":2,"tx":300,"ty":360},"10":{"q":2,"x":0,"y":2,"tx":460,"ty":220},"11":{"q":3,"x":0,"y":2,"tx":0,"ty":220},"12":{"q":0,"x":0,"y":3,"tx":0,"ty":200},"13":{"q":1,"x":0,"y":3,"tx":460,"ty":200},"14":{"q":2,"x":0,"y":3,"tx":460,"ty":220},"15":{"q":3,"x":0,"y":3,"tx":0,"ty":220},"16":{"q":0,"x":0,"y":4,"tx":0,"ty":200},"17":{"q":1,"x":0,"y":4,"tx":460,"ty":200},"18":{"q":2,"x":0,"y":4,"tx":460,"ty":300},"19":{"q":3,"x":0,"y":4,"tx":0,"ty":300},"20":{"q":0,"x":0,"y":7,"tx":0,"ty":280},"21":{"q":1,"x":0,"y":7,"tx":460,"ty":280},"22":{"q":2,"x":0,"y":7,"tx":460,"ty":220},"23":{"q":3,"x":0,"y":7,"tx":0,"ty":220},"24":{"q":0,"x":0,"y":8,"tx":0,"ty":200},"25":{"q":1,"x":0,"y":8,"tx":460,"ty":200},"26":{"q":2,"x":0,"y":8,"tx":460,"ty":220},"27":{"q":3,"x":0,"y":8,"tx":0,"ty":220},"28":{"q":0,"x":0,"y":9,"tx":0,"ty":200},"29":{"q":1,"x":0,"y":9,"tx":460,"ty":200},"30":{"q":2,"x":0,"y":9,"tx":60,"ty":340},"31":{"q":3,"x":0,"y":9,"tx":0,"ty":220},"32":{"q":0,"x":0,"y":10,"tx":0,"ty":200},"33":{"q":1,"x":0,"y":10,"tx":60,"ty":360},"34":{"q":2,"x":0,"y":10,"tx":220,"ty":220},"35":{"q":3,"x":0,"y":10,"tx":0,"ty":220},"36":{"q":0,"x":0,"y":11,"tx":0,"ty":200},"37":{"q":1,"x":0,"y":11,"tx":220,"ty":240},"38":{"q":2,"x":0,"y":11,"tx":340,"ty":420},"39":{"q":3,"x":0,"y":11,"tx":0,"ty":300},"40":{"q":0,"x":1,"y":0,"tx":240,"ty":200},"41":{"q":1,"x":1,"y":0,"tx":220,"ty":200},"42":{"q":2,"x":1,"y":0,"tx":340,"ty":300},"43":{"q":3,"x":1,"y":0,"tx":240,"ty":220},"44":{"q":0,"x":1,"y":1,"tx":240,"ty":400},"45":{"q":1,"x":1,"y":1,"tx":340,"ty":320},"46":{"q":3,"x":1,"y":1,"tx":320,"ty":340},"47":{"q":0,"x":1,"y":10,"tx":80,"ty":360},"48":{"q":2,"x":1,"y":10,"tx":100,"ty":380},"49":{"q":3,"x":1,"y":10,"tx":240,"ty":340},"50":{"q":0,"x":1,"y":11,"tx":240,"ty":240},"51":{"q":1,"x":1,"y":11,"tx":100,"ty":400},"52":{"q":2,"x":1,"y":11,"tx":340,"ty":420},"53":{"q":3,"x":1,"y":11,"tx":360,"ty":420},"54":{"q":0,"x":2,"y":0,"tx":240,"ty":200},"55":{"q":1,"x":2,"y":0,"tx":460,"ty":280},"56":{"q":2,"x":2,"y":0,"tx":460,"ty":300},"57":{"q":3,"x":2,"y":0,"tx":360,"ty":300},"58":{"q":0,"x":2,"y":11,"tx":120,"ty":400},"59":{"q":1,"x":2,"y":11,"tx":220,"ty":200},"60":{"q":2,"x":2,"y":11,"tx":340,"ty":420},"61":{"q":3,"x":2,"y":11,"tx":360,"ty":420},"62":{"q":0,"x":3,"y":11,"tx":240,"ty":200},"63":{"q":1,"x":3,"y":11,"tx":220,"ty":200},"64":{"q":2,"x":3,"y":11,"tx":340,"ty":420},"65":{"q":3,"x":3,"y":11,"tx":360,"ty":420},"66":{"q":0,"x":4,"y":11,"tx":240,"ty":200},"67":{"q":1,"x":4,"y":11,"tx":220,"ty":200},"68":{"q":2,"x":4,"y":11,"tx":340,"ty":420},"69":{"q":3,"x":4,"y":11,"tx":360,"ty":420},"70":{"q":0,"x":5,"y":0,"tx":0,"ty":280},"71":{"q":1,"x":5,"y":0,"tx":220,"ty":200},"72":{"q":2,"x":5,"y":0,"tx":340,"ty":420},"73":{"q":3,"x":5,"y":0,"tx":0,"ty":300},"74":{"q":0,"x":5,"y":11,"tx":240,"ty":200},"75":{"q":1,"x":5,"y":11,"tx":220,"ty":200},"76":{"q":2,"x":5,"y":11,"tx":340,"ty":420},"77":{"q":3,"x":5,"y":11,"tx":360,"ty":420},"78":{"q":0,"x":6,"y":0,"tx":240,"ty":200},"79":{"q":1,"x":6,"y":0,"tx":220,"ty":200},"80":{"q":2,"x":6,"y":0,"tx":380,"ty":420},"81":{"q":3,"x":6,"y":0,"tx":360,"ty":420},"82":{"q":0,"x":6,"y":11,"tx":240,"ty":200},"83":{"q":1,"x":6,"y":11,"tx":220,"ty":200},"84":{"q":2,"x":6,"y":11,"tx":340,"ty":420},"85":{"q":3,"x":6,"y":11,"tx":360,"ty":420},"86":{"q":0,"x":7,"y":0,"tx":280,"ty":200},"87":{"q":1,"x":7,"y":0,"tx":300,"ty":200},"88":{"q":3,"x":7,"y":0,"tx":400,"ty":420},"89":{"q":0,"x":7,"y":5,"tx":0,"ty":280},"90":{"q":1,"x":7,"y":5,"tx":220,"ty":200},"91":{"q":2,"x":7,"y":5,"tx":340,"ty":300},"92":{"q":3,"x":7,"y":5,"tx":0,"ty":220},"93":{"q":0,"x":7,"y":6,"tx":0,"ty":240},"94":{"q":1,"x":7,"y":6,"tx":340,"ty":320},"95":{"q":3,"x":7,"y":6,"tx":200,"ty":300},"96":{"q":0,"x":7,"y":11,"tx":240,"ty":200},"97":{"q":1,"x":7,"y":11,"tx":220,"ty":200},"98":{"q":2,"x":7,"y":11,"tx":340,"ty":420},"99":{"q":3,"x":7,"y":11,"tx":360,"ty":420},"100":{"q":0,"x":8,"y":5,"tx":240,"ty":200},"101":{"q":1,"x":8,"y":5,"tx":220,"ty":200},"102":{"q":2,"x":8,"y":5,"tx":340,"ty":420},"103":{"q":3,"x":8,"y":5,"tx":360,"ty":300},"104":{"q":0,"x":8,"y":11,"tx":240,"ty":200},"105":{"q":1,"x":8,"y":11,"tx":220,"ty":200},"106":{"q":2,"x":8,"y":11,"tx":340,"ty":420},"107":{"q":3,"x":8,"y":11,"tx":360,"ty":420},"108":{"q":0,"x":9,"y":5,"tx":240,"ty":200},"109":{"q":1,"x":9,"y":5,"tx":220,"ty":200},"110":{"q":2,"x":9,"y":5,"tx":340,"ty":420},"111":{"q":3,"x":9,"y":5,"tx":360,"ty":420},"112":{"q":0,"x":9,"y":11,"tx":240,"ty":200},"113":{"q":1,"x":9,"y":11,"tx":220,"ty":200},"114":{"q":2,"x":9,"y":11,"tx":340,"ty":420},"115":{"q":3,"x":9,"y":11,"tx":360,"ty":420},"116":{"q":0,"x":10,"y":5,"tx":240,"ty":200},"117":{"q":1,"x":10,"y":5,"tx":220,"ty":200},"118":{"q":2,"x":10,"y":5,"tx":380,"ty":300},"119":{"q":3,"x":10,"y":5,"tx":360,"ty":420},"120":{"q":0,"x":10,"y":11,"tx":240,"ty":200},"121":{"q":1,"x":10,"y":11,"tx":220,"ty":200},"122":{"q":2,"x":10,"y":11,"tx":340,"ty":420},"123":{"q":3,"x":10,"y":11,"tx":360,"ty":420},"124":{"q":0,"x":11,"y":5,"tx":240,"ty":200},"125":{"q":1,"x":11,"y":5,"tx":460,"ty":280},"126":{"q":2,"x":11,"y":5,"tx":300,"ty":380},"127":{"q":3,"x":11,"y":5,"tx":400,"ty":300},"128":{"q":0,"x":11,"y":6,"tx":400,"ty":320},"129":{"q":1,"x":11,"y":6,"tx":300,"ty":400},"130":{"q":2,"x":11,"y":6,"tx":100,"ty":300},"131":{"q":3,"x":11,"y":6,"tx":0,"ty":300},"132":{"q":0,"x":11,"y":11,"tx":240,"ty":200},"133":{"q":1,"x":11,"y":11,"tx":220,"ty":200},"134":{"q":2,"x":11,"y":11,"tx":340,"ty":420},"135":{"q":3,"x":11,"y":11,"tx":360,"ty":420},"136":{"q":0,"x":12,"y":6,"tx":320,"ty":400},"137":{"q":1,"x":12,"y":6,"tx":460,"ty":280},"138":{"q":2,"x":12,"y":6,"tx":300,"ty":380},"139":{"q":3,"x":12,"y":6,"tx":120,"ty":300},"140":{"q":0,"x":12,"y":7,"tx":120,"ty":320},"141":{"q":1,"x":12,"y":7,"tx":380,"ty":160},"142":{"q":2,"x":12,"y":7,"tx":60,"ty":420},"143":{"q":0,"x":12,"y":11,"tx":240,"ty":200},"144":{"q":1,"x":12,"y":11,"tx":220,"ty":200},"145":{"q":2,"x":12,"y":11,"tx":340,"ty":420},"146":{"q":3,"x":12,"y":11,"tx":360,"ty":420},"147":{"q":0,"x":13,"y":7,"tx":320,"ty":400},"148":{"q":1,"x":13,"y":7,"tx":220,"ty":200},"149":{"q":2,"x":13,"y":7,"tx":340,"ty":420},"150":{"q":3,"x":13,"y":7,"tx":80,"ty":420},"151":{"q":0,"x":13,"y":11,"tx":240,"ty":200},"152":{"q":1,"x":13,"y":11,"tx":220,"ty":200},"153":{"q":2,"x":13,"y":11,"tx":340,"ty":420},"154":{"q":3,"x":13,"y":11,"tx":360,"ty":420},"155":{"q":0,"x":14,"y":7,"tx":240,"ty":200},"156":{"q":1,"x":14,"y":7,"tx":220,"ty":200},"157":{"q":2,"x":14,"y":7,"tx":340,"ty":420},"158":{"q":3,"x":14,"y":7,"tx":360,"ty":420},"159":{"q":0,"x":14,"y":11,"tx":240,"ty":200},"160":{"q":1,"x":14,"y":11,"tx":220,"ty":200},"161":{"q":2,"x":14,"y":11,"tx":340,"ty":420},"162":{"q":3,"x":14,"y":11,"tx":360,"ty":420},"163":{"q":0,"x":15,"y":7,"tx":240,"ty":200},"164":{"q":1,"x":15,"y":7,"tx":220,"ty":200},"165":{"q":2,"x":15,"y":7,"tx":380,"ty":300},"166":{"q":3,"x":15,"y":7,"tx":360,"ty":420},"167":{"q":0,"x":15,"y":11,"tx":240,"ty":200},"168":{"q":1,"x":15,"y":11,"tx":140,"ty":400},"169":{"q":2,"x":15,"y":11,"tx":340,"ty":420},"170":{"q":3,"x":15,"y":11,"tx":360,"ty":420},"171":{"q":0,"x":16,"y":7,"tx":240,"ty":200},"172":{"q":1,"x":16,"y":7,"tx":460,"ty":280},"173":{"q":2,"x":16,"y":7,"tx":460,"ty":220},"174":{"q":3,"x":16,"y":7,"tx":400,"ty":300},"175":{"q":0,"x":16,"y":8,"tx":400,"ty":320},"176":{"q":1,"x":16,"y":8,"tx":460,"ty":200},"177":{"q":2,"x":16,"y":8,"tx":460,"ty":220},"178":{"q":3,"x":16,"y":8,"tx":0,"ty":220},"179":{"q":0,"x":16,"y":9,"tx":0,"ty":200},"180":{"q":1,"x":16,"y":9,"tx":460,"ty":200},"181":{"q":2,"x":16,"y":9,"tx":460,"ty":220},"182":{"q":3,"x":16,"y":9,"tx":0,"ty":220},"183":{"q":0,"x":16,"y":10,"tx":0,"ty":200},"184":{"q":1,"x":16,"y":10,"tx":460,"ty":200},"185":{"q":2,"x":16,"y":10,"tx":460,"ty":220},"186":{"q":3,"x":16,"y":10,"tx":160,"ty":380},"187":{"q":0,"x":16,"y":11,"tx":160,"ty":400},"188":{"q":1,"x":16,"y":11,"tx":460,"ty":200},"189":{"q":2,"x":16,"y":11,"tx":460,"ty":300},"190":{"q":3,"x":16,"y":11,"tx":360,"ty":420}}; | |
canvas.width = map.info.width * 40; | |
canvas.height = map.info.height * 40; | |
let ctx = canvas.getContext("2d"); | |
let img = document.createElement('img'); | |
img.crossOrigin = 'Anonymous'; | |
img.src = url; | |
//floor, objects.. | |
$.each(map.data, function(key, value) { | |
ctx.drawImage(img, value.tx, value.ty, 40, 40, value.x*40, value.y*40, 40, 40); | |
}); | |
//pups.. | |
$.each(pups, function(key, value) { | |
ctx.drawImage(img, value.tx, value.ty, 40, 40, value.x*40, value.y*40, 40, 40); | |
}); | |
//walls... | |
$.each(walls, function(key, value) { | |
if (value.q >= 0) { | |
let xoffset = 0, yoffset = 0; | |
if ((value.q === 1) || (value.q === 2)) xoffset = 20; | |
if ((value.q === 0) || (value.q === 1)) yoffset = -20; | |
ctx.drawImage(img, value.tx, value.ty, 20, 20, value.x*40+xoffset, value.y*40+yoffset+20, 20, 20); | |
} | |
}); | |
img = null; | |
return canvas; | |
} | |
// Drag/Drop events... | |
$(document).on('dragover', function(e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
$('#TTM_Tiles').css({ 'border':'2px dashed red' }); | |
$('#TTM_Tiles').css({ 'box-shadow':'0 0 10px 4px red' }); | |
}).on('dragleave', function(e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
$('#TTM_Tiles').css({ 'border':'2px solid transparent' }); | |
$('#TTM_Tiles').css({ 'box-shadow':'' }); | |
}); | |
$('#TTM_Tiles').on('dragover', function(e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
$(this).css({ 'border':'2px dashed chartreuse' }); | |
$(this).css({ 'box-shadow':'0 0 10px 4px chartreuse' }); | |
}).on('dragleave', function(e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
$(this).css({ 'border':'2px dashed red' }); | |
$(this).css({ 'box-shadow':'0 0 10px 4px red' }); | |
}).on('drop', function(e) { | |
e.stopPropagation(); | |
e.preventDefault(); | |
$(this).css({ 'border':'' }); | |
$(this).css({ 'box-shadow':'' }); | |
handleDrop(e); | |
}); | |
function handleDrop(e) { | |
let data = e.originalEvent.dataTransfer; | |
if (data.files[0]) { // Handle as a file... | |
let reader = new FileReader(); | |
let filename = data.files[0].name; | |
reader.onload = function(file) { | |
draggedData = file.target.result; | |
setTimeout(function() { | |
loadImage(draggedData, filename); | |
}, 100); | |
}; | |
reader.readAsDataURL(data.files[0]); | |
} else { // Handle as a URL... | |
data.items[0].getAsString(function(url) { | |
if (!url.startsWith('http')) url = 'http://' + url; | |
setTimeout(function() { | |
loadImage(url, url); | |
}, 100); | |
}); | |
} | |
} | |
const presets = { | |
'W1':{ | |
title: 'Good for: Walls (apply over existing tile)', | |
data: { | |
'shine':false,'border':false,'checkered':false,'pattern':false, | |
'specks':true, 'specks_color':'#00ccaa', 'specks_opacity':18, 'specks_length':20, 'specks_count':10, 'specks_angle':0, | |
'stripes':true, 'stripes_color':'#ffffff', 'stripes_opacity':6, 'stripes_size':5, 'stripes_linewidth':1, 'stripes_direction':'diagonal' | |
} | |
}, | |
'T1':{ | |
title: 'Good for: TeamTiles (apply over existing tile)', | |
data: { | |
'shine':false,'border':false,'checkered':false,'stripes':false, | |
'specks':true, 'specks_color':'#ffffff', 'specks_opacity':30, 'specks_length':15, 'specks_count':15, 'specks_angle':315, | |
'pattern':true, 'pattern_shape':'circle', 'pattern_color':'#ff0000', 'pattern_opacity':40, 'pattern_size':10, 'pattern_margin':5, 'pattern_stroke':true, 'pattern_fill':true | |
} | |
}, | |
'T2':{ | |
title: 'Good for: TeamTiles (new tile - change base color accordingly)', | |
data: { | |
'specks':false,'border':false, | |
'checkered':true, 'checkered_size':20, 'checkered_color':'#bb0000', 'checkered_alt':14, | |
'pattern':true, 'pattern_shape':'square', 'pattern_color':'#ffffff', 'pattern_opacity':12, 'pattern_size':20, 'pattern_margin':8, 'pattern_stroke':false, 'pattern_fill':true, | |
'stripes':true, 'stripes_direction':'plus', 'stripes_color':'#000000', 'stripes_opacity':16, 'stripes_size':40, 'stripes_linewidth':21, | |
'shine':true, 'shine_x':20, 'shine_y':20, 'shine_radius':24, 'shine_color_inner':'#ffffff', 'shine_color_outer':'#000000', 'shine_opacity_inner':14, 'shine_opacity_outer':1, 'shine_behind':false | |
} | |
}, | |
'T3':{ | |
title: 'Good for: TeamTiles or EndZones (apply over existing tile)', | |
data: { | |
'stripes':false,'border':false,'checkered':false,'pattern':false, | |
'specks':true, 'specks_color':'#ffffff', 'specks_opacity':20, 'specks_length':16, 'specks_count':16, 'specks_angle':315, | |
'shine':true, 'shine_x':10, 'shine_y':10, 'shine_radius':50, 'shine_color_inner':'#ffffff', 'shine_color_outer':'#ffffff', 'shine_opacity_inner':40, 'shine_opacity_outer':1, 'shine_behind':false | |
} | |
}, | |
'E1':{ | |
title: 'Good for: EndZones (new tile - change base color accordingly)', | |
data: { | |
'shine':false,'border':false,'specks':false,'pattern':false, | |
'checkered':true, 'checkered_size':10, 'checkered_color':'#0067ce', 'checkered_alt':-50, | |
'stripes':true, 'stripes_direction':'cross', 'stripes_color':'#ffffff', 'stripes_opacity':7, 'stripes_size':5, 'stripes_linewidth':1 | |
} | |
}, | |
'G1':{ | |
title: 'Good for: Gates (new tile - change base color accordingly)', | |
data: { | |
'shine':false,'border':false,'specks':false,'stripes':false, | |
'checkered':true, 'checkered_size':40, 'checkered_color':'#00ee00', 'checkered_alt':0, //plain green base tile | |
'pattern':true, 'pattern_shape':'corner', 'pattern_color':'#009900', 'pattern_opacity':100, 'pattern_size':10, 'pattern_margin':8, 'pattern_stroke':true, 'pattern_fill':false | |
} | |
}, | |
'G2':{ | |
title: 'Good for: Gates (new tile - change base color accordingly)', | |
data: { | |
'specks':false, | |
'checkered':true, 'checkered_size':40, 'checkered_color':'#00ee00', 'checkered_alt':0, //plain blue base tile | |
'stripes':true, 'stripes_direction':'cross', 'stripes_color':'#000000', 'stripes_opacity':20, 'stripes_size':40, 'stripes_linewidth':7, | |
'pattern':true, 'pattern_shape':'pyramid', 'pattern_color':'#00ee00', 'pattern_opacity':40, 'pattern_size':5, 'pattern_margin':40, 'pattern_stroke':true, 'pattern_fill':true, | |
'border':true, 'border_color':'#000000', 'border_opacity':50, 'border_circle':false, 'border_size':37, 'border_width':1, 'border_dash':1, | |
'shine':true, 'shine_x':20, 'shine_y':20, 'shine_radius':30, 'shine_color_inner':'#ffffff', 'shine_color_outer':'#000000', 'shine_opacity_inner':30, 'shine_opacity_outer':10, 'shine_behind':false | |
} | |
}, | |
'G3':{ | |
title: 'Good for: Gates (new tile - change base color accordingly)', | |
data: { | |
'shine':false,'border':false,'stripes':false,'specks':false, | |
'checkered':true, 'checkered_size':40, 'checkered_color':'#000000', 'checkered_alt':0, //plain black base tile | |
'pattern':true, 'pattern_shape':'pyramid', 'pattern_color':'#77ff00', 'pattern_opacity':100, 'pattern_size':20, 'pattern_margin':18, 'pattern_stroke':false, 'pattern_fill':true | |
} | |
}, | |
'G4':{ | |
title: 'Good for: Gates (apply over existing tile)', | |
data: { | |
'checkered':false,'stripes':false,'specks':false, | |
'shine':true, 'shine_x':10, 'shine_y':10, 'shine_radius':24, 'shine_color_inner':'#ffffff', 'shine_color_outer':'#000000', 'shine_opacity_inner':20, 'shine_opacity_outer':1, 'shine_behind':false, | |
'border':true, 'border_color':'#000000', 'border_opacity':100, 'border_circle':false, 'border_size':32, 'border_width':1, 'border_dash':1, | |
'pattern':true, 'pattern_shape':'corner', 'pattern_color':'#ffffff', 'pattern_opacity':100, 'pattern_size':40, 'pattern_margin':30, 'pattern_stroke':false, 'pattern_fill':true | |
} | |
}, | |
'F1':{ | |
title: 'Good for: Floors (new tile)', | |
data: { | |
'shine':false,'border':false,'stripes':false,'pattern':false, | |
'checkered':true, 'checkered_size':40, 'checkered_color':'#000000', 'checkered_alt':0, //plain black base tile | |
'specks':true, 'specks_color':'#ffffff', 'specks_opacity':15, 'specks_length':1, 'specks_count':75, 'specks_angle':360, | |
} | |
}, | |
'F2':{ | |
title: 'Good for: Floors (new tile)', | |
data: { | |
'shine':false,'stripes':false,'specks':false, | |
'checkered':true, 'checkered_size':40, 'checkered_color':'#000000', 'checkered_alt':0, //plain black base tile | |
'border':true, 'border_color':'#777777', 'border_opacity':10, 'border_circle':false, 'border_size':39, 'border_width':1, 'border_dash':1, | |
'pattern':true, 'pattern_shape':'corner', 'pattern_color':'#ffffff', 'pattern_opacity':15, 'pattern_size':13, 'pattern_margin':10, 'pattern_stroke':false, 'pattern_fill':true | |
} | |
}, | |
}; | |
$.each(presets, function(key, value) { | |
$('#TTM_Presets').append('<div class="TTM_Preset" data-preset="'+key+'" title="'+value.title+'">'+key+'</div>'); | |
}); | |
let loadPreset = function(preset) { | |
if (!preset || !presets.hasOwnProperty(preset)) return; | |
$.each(presets[preset].data, function(k, v) { | |
let element = $('#TTM_ModifyMenu_Inner').find('[data-saveto="'+k+'"]'); | |
if ((v === true) || (v === false)) { | |
element.prop('checked', v); | |
} else { | |
element.val(v); | |
} | |
let group = $(element).data('group'); | |
if (group) { | |
if ((v === true) || (v > 0)) $('.' + group).slideDown(400); | |
else $('.' + group).slideUp(400); | |
} | |
}); | |
updateModifyTilePreviews(); | |
}; | |
$('.TTM_Preset').on('click', function() { | |
loadPreset(this.dataset.preset); | |
}); | |
function addCheckered(ctx) { | |
if (!ctx) return; | |
let canvasWidth = ctx.canvas.width; | |
let canvasHeight = ctx.canvas.height; | |
let size = $('div.TTM_Group_Add_Checkered').find('input[data-saveto="checkered_size"]').val(); | |
let color = $('div.TTM_Group_Add_Checkered').find('input[data-saveto="checkered_color"]').val(); | |
let opacity = $('div.TTM_Group_Add_Checkered').find('input[data-saveto="checkered_opacity"]').val() / 100; | |
let altColor = colorLuminance(color, $('div.TTM_Group_Add_Checkered').find('input[data-saveto="checkered_alt"]').val() / 100); | |
ctx.globalCompositeOperation = 'source-atop'; | |
let pattern = new OffscreenCanvas(size * 2, size * 2); | |
let pctx = pattern.getContext('2d'); | |
pctx.globalAlpha = opacity; | |
pctx.beginPath(); | |
pctx.fillStyle = color; | |
pctx.fillRect(0, 0, size, size); | |
pctx.fillStyle = altColor; | |
pctx.fillRect(size, 0, size, size); | |
pctx.fillStyle = altColor; | |
pctx.fillRect(0, size, size, size); | |
pctx.fillStyle = color; | |
pctx.fillRect(size, size, size, size); | |
pctx.closePath(); | |
let patt = ctx.createPattern(pattern, "repeat"); | |
ctx.fillStyle = patt; | |
ctx.fillRect(0, 0, canvasWidth, canvasHeight); | |
ctx.globalCompositeOperation = "source-over"; | |
pattern = null; | |
} | |
function addSpecks(ctx) { //, count, color, opacity, specks, lines, circles, width=1 | |
if (!ctx) return; | |
let canvasWidth = ctx.canvas.width; | |
let canvasHeight = ctx.canvas.height; | |
let color = $('div.TTM_Group_Add_Specks').find('input[data-saveto="specks_color"]').val(); | |
let opacity = $('div.TTM_Group_Add_Specks').find('input[data-saveto="specks_opacity"]').val() / 100; | |
let count = $('div.TTM_Group_Add_Specks').find('input[data-saveto="specks_count"]').val(); | |
if (canvasWidth > 40) count = count * 132; //walls | |
let length = $('div.TTM_Group_Add_Specks').find('input[data-saveto="specks_length"]').val(); | |
let angle = $('div.TTM_Group_Add_Specks').find('input[data-saveto="specks_angle"]').val() * Math.PI / 180; | |
let a = angle; | |
ctx.globalCompositeOperation = 'source-atop'; | |
ctx.fillStyle = hexToRgbA(color, opacity); | |
ctx.strokeStyle = hexToRgbA(color, opacity); | |
for (let i=0; i<count; i++) { | |
if (angle === 0) a = Math.random() * Math.PI * 2; | |
let sx = Math.random()*canvasWidth; | |
let sy = Math.random()*canvasHeight; | |
let d = Math.random()*length; | |
let dx = sx + Math.cos(a) * d; | |
let dy = sy + Math.sin(a) * d; | |
ctx.lineWidth = 1; | |
ctx.beginPath(); | |
ctx.moveTo(sx, sy); | |
ctx.lineTo(dx, dy); | |
ctx.closePath(); | |
ctx.stroke(); | |
} | |
ctx.globalCompositeOperation = "source-over"; | |
} | |
function addPattern(ctx) { | |
if (!ctx) return; | |
let canvasWidth = ctx.canvas.width; | |
let canvasHeight = ctx.canvas.height; | |
let color = $('div.TTM_Group_Add_Pattern').find('input[data-saveto="pattern_color"]').val(); | |
let opacity = $('div.TTM_Group_Add_Pattern').find('input[data-saveto="pattern_opacity"]').val() / 100; | |
let size = $('div.TTM_Group_Add_Pattern').find('input[data-saveto="pattern_size"]').val() || 20; | |
let margin = $('div.TTM_Group_Add_Pattern').find('input[data-saveto="pattern_margin"]').val(); | |
let shape = $('div.TTM_Group_Add_Pattern').find('select[data-saveto="pattern_shape"]').val(); | |
let stroke = $('div.TTM_Group_Add_Pattern').find('input[data-saveto="pattern_stroke"]').is(':checked'); | |
let fill = $('div.TTM_Group_Add_Pattern').find('input[data-saveto="pattern_fill"]').is(':checked'); | |
ctx.globalCompositeOperation = 'source-atop'; | |
let pattern = new OffscreenCanvas(size, size); | |
let pctx = pattern.getContext('2d'); | |
pctx.lineWidth = 1; | |
//pctx.translate(-0.5, -0.5); | |
if (shape === 'corner') { | |
let p1 = size / 2 - margin / 2; | |
let p2 = size / 2 + margin / 2; | |
let width = margin; | |
pctx.beginPath(); | |
pctx.moveTo(p2, p1); | |
pctx.lineTo(p2, p2); | |
pctx.lineTo(p1, p2); | |
pctx.moveTo(p1, p2); | |
pctx.closePath(); | |
if (stroke) { | |
pctx.strokeStyle = hexToRgbA(color, opacity); | |
pctx.stroke(); | |
} | |
if (fill) { | |
pctx.beginPath(); | |
pctx.moveTo(p1, p2); | |
pctx.lineTo(p1, p1); | |
pctx.lineTo(p2, p1); | |
pctx.moveTo(p2, p1); | |
pctx.closePath(); | |
pctx.strokeStyle = hexToRgbA(colorLuminance(color, -0.35), opacity); | |
pctx.stroke(); | |
} | |
} else if (shape === 'rightangle') { | |
let p1 = size / 2 - margin / 2; | |
let p2 = size / 2 + margin / 2; | |
let width = margin; | |
pctx.beginPath(); | |
pctx.moveTo(p1, p2); | |
pctx.lineTo(p1, p1); | |
pctx.lineTo(p2, p1); | |
pctx.closePath(); | |
if (stroke) { | |
pctx.strokeStyle = hexToRgbA(color, opacity); | |
pctx.stroke(); | |
} | |
if (fill) { | |
pctx.fillStyle = hexToRgbA(color, opacity); | |
pctx.fill(); | |
} | |
} else if (shape === 'pyramid') { | |
let p1 = size / 2 - margin / 2; | |
let p2 = size / 2 + margin / 2; | |
let c = size / 2; | |
let width = margin; | |
//1-------------------- | |
pctx.beginPath(); | |
pctx.strokeStyle = hexToRgbA(colorLuminance(color, 0.2), opacity); | |
pctx.fillStyle = hexToRgbA(colorLuminance(color, 0.3), opacity); | |
pctx.moveTo(p1, p1); | |
pctx.lineTo(p2, p1); | |
pctx.lineTo(c, c); | |
pctx.lineTo(p1, p1); | |
pctx.moveTo(p1, p1); | |
if (stroke) pctx.stroke(); | |
if (fill) pctx.fill(); | |
pctx.closePath(); | |
//2-------------------- | |
pctx.beginPath(); | |
pctx.strokeStyle = hexToRgbA(color, opacity); | |
pctx.fillStyle = hexToRgbA(colorLuminance(color, 0.1), opacity); | |
pctx.moveTo(p2, p1); | |
pctx.lineTo(p2, p2); | |
pctx.lineTo(c, c); | |
pctx.lineTo(p2, p1); | |
pctx.moveTo(p2, p1); | |
if (stroke) pctx.stroke(); | |
if (fill) pctx.fill(); | |
pctx.closePath(); | |
//3-------------------- | |
pctx.beginPath(); | |
pctx.strokeStyle = hexToRgbA(colorLuminance(color, -0.1), opacity); | |
pctx.fillStyle = hexToRgbA(colorLuminance(color, -0.2), opacity); | |
pctx.moveTo(p2, p2); | |
pctx.lineTo(p1, p2); | |
pctx.lineTo(c, c); | |
pctx.lineTo(p2, p2); | |
pctx.moveTo(p2, p2); | |
if (stroke) pctx.stroke(); | |
if (fill) pctx.fill(); | |
pctx.closePath(); | |
//4-------------------- | |
pctx.beginPath(); | |
pctx.strokeStyle = hexToRgbA(colorLuminance(color, -0.2), opacity); | |
pctx.fillStyle = hexToRgbA(colorLuminance(color, -0.3), opacity); | |
pctx.moveTo(p1, p2); | |
pctx.lineTo(p1, p1); | |
pctx.lineTo(c, c); | |
pctx.lineTo(p1, p2); | |
pctx.moveTo(p1, p2); | |
if (stroke) pctx.stroke(); | |
if (fill) pctx.fill(); | |
pctx.closePath(); | |
} else if (shape === 'square') { | |
let p1 = size / 2 - margin / 2; | |
let p2 = size / 2 + margin / 2; | |
let width = margin; | |
if (stroke) { | |
pctx.strokeStyle = hexToRgbA(color, opacity); | |
pctx.rect(p1, p1, width, width); | |
pctx.stroke(); | |
} | |
if (fill) { | |
pctx.fillStyle = hexToRgbA(color, opacity); | |
pctx.fillRect(p1, p1, width, width); | |
} | |
} else if (shape === 'circle') { | |
let radius = margin/2; | |
if (stroke) { | |
pctx.strokeStyle = hexToRgbA(color, opacity); | |
pctx.arc(size/2, size/2, radius, 0, Math.PI*2); | |
pctx.stroke(); | |
} | |
if (fill) { | |
pctx.fillStyle = hexToRgbA(color, opacity); | |
pctx.arc(size/2, size/2, radius, 0, Math.PI*2); | |
pctx.fill(); | |
} | |
} | |
let patt = ctx.createPattern(pattern, "repeat"); | |
ctx.fillStyle = patt; | |
ctx.fillRect(0, 0, canvasWidth, canvasHeight); | |
ctx.globalCompositeOperation = "source-over"; | |
pattern = null; | |
} | |
function addStripes(ctx) { | |
if (!ctx) return; | |
let canvasWidth = ctx.canvas.width; | |
let canvasHeight = ctx.canvas.height; | |
let color = $('div.TTM_Group_Add_Stripes').find('input[data-saveto="stripes_color"]').val(); | |
let opacity = $('div.TTM_Group_Add_Stripes').find('input[data-saveto="stripes_opacity"]').val() / 100; | |
let direction = $('div.TTM_Group_Add_Stripes').find('select[data-saveto="stripes_direction"]').val(); | |
let size = $('div.TTM_Group_Add_Stripes').find('input[data-saveto="stripes_size"]').val(); | |
let lineWidth = $('div.TTM_Group_Add_Stripes').find('input[data-saveto="stripes_linewidth"]').val(); | |
let dashed = false; | |
let translate = false; | |
ctx.globalCompositeOperation = 'source-atop'; | |
let startX = 0; | |
let startY = 0; | |
let endX = 0; | |
let endY = 0; | |
if (direction === 'horizontal') { | |
endX = size; | |
endY = 0; | |
} else if (direction === 'vertical') { | |
endX = 0; | |
endY = size; | |
} else if (direction === 'diagonal') { | |
endX = size; | |
endY = size; | |
} else if (direction === 'diagonalback') { | |
startX = size; | |
startY = 0; | |
endX = 0; | |
endY = size; | |
} else if (direction === 'plus') { | |
startX = size/2; | |
endX = size/2; | |
endY = size; | |
} else if (direction === 'cross') { | |
endX = size; | |
endY = size; | |
} | |
let pattern = new OffscreenCanvas(size, size); | |
let pctx = pattern.getContext('2d'); | |
pctx.lineWidth = lineWidth; | |
pctx.strokeStyle = hexToRgbA(color, opacity); | |
if (dashed) pctx.setLineDash([2, 2]); | |
if (translate) pctx.translate(-0.5, -0.5); | |
pctx.beginPath(); | |
pctx.moveTo(startX, startY); | |
pctx.lineTo(endX, endY); | |
if (direction === 'plus') { | |
pctx.moveTo(startY, startX); | |
pctx.lineTo(endY, endX); | |
} else if (direction === 'cross') { | |
pctx.moveTo(endX, startY); | |
pctx.lineTo(startX, endY); | |
} | |
pctx.closePath(); | |
pctx.stroke(); | |
let patt = ctx.createPattern(pattern, "repeat"); | |
ctx.fillStyle = patt; | |
ctx.fillRect(0, 0, canvasWidth, canvasHeight); | |
pattern = null; | |
ctx.globalCompositeOperation = "source-over"; | |
} | |
function addShine(ctx) { | |
if (!ctx) return; | |
let x = $('div.TTM_Group_Add_Shine').find('input[data-saveto="shine_x"]').val(); | |
let y = $('div.TTM_Group_Add_Shine').find('input[data-saveto="shine_y"]').val(); | |
let size = $('div.TTM_Group_Add_Shine').find('input[data-saveto="shine_radius"]').val(); | |
let c1 = $('div.TTM_Group_Add_Shine').find('input[data-saveto="shine_color_inner"]').val(); | |
let c2 = $('div.TTM_Group_Add_Shine').find('input[data-saveto="shine_color_outer"]').val(); | |
let o1 = $('div.TTM_Group_Add_Shine').find('input[data-saveto="shine_opacity_inner"]').val() / 100; | |
let o2 = $('div.TTM_Group_Add_Shine').find('input[data-saveto="shine_opacity_outer"]').val() / 100; | |
let gco = $('div.TTM_Group_Add_Shine').find('input[data-saveto="shine_behind"]').is(':checked') ? 'destination-over' : 'source-atop'; | |
ctx.globalCompositeOperation = gco; | |
let pattern = new OffscreenCanvas(40, 40); | |
let pctx = pattern.getContext('2d'); | |
let gradient = pctx.createRadialGradient(x,y,0, x,y,size); | |
gradient.addColorStop(0, hexToRgbA(c1, o1)); | |
gradient.addColorStop(1, hexToRgbA(c2, o2)); | |
pctx.fillStyle = gradient; | |
pctx.beginPath(); | |
pctx.arc(x, y, size, 0, 2*Math.PI); | |
pctx.fill(); | |
pctx.closePath(); | |
let patt = ctx.createPattern(pattern, "repeat"); | |
ctx.fillStyle = patt; | |
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); | |
ctx.globalCompositeOperation = "source-over"; | |
pattern = null; | |
} | |
function addBorder(ctx) { | |
if (!ctx) return; | |
let canvasWidth = ctx.canvas.width; | |
let canvasHeight = ctx.canvas.height; | |
let color = $('div.TTM_Group_Add_Border').find('input[data-saveto="border_color"]').val(); | |
let opacity = $('div.TTM_Group_Add_Border').find('input[data-saveto="border_opacity"]').val() / 100; | |
let linewidth = $('div.TTM_Group_Add_Border').find('input[data-saveto="border_linewidth"]').val(); | |
let size = $('div.TTM_Group_Add_Border').find('input[data-saveto="border_size"]').val(); | |
let circle = $('div.TTM_Group_Add_Border').find('input[data-saveto="border_circle"]').is(':checked'); | |
let dash = $('div.TTM_Group_Add_Border').find('input[data-saveto="border_dash"]').val(); | |
//ctx.globalCompositeOperation = 'source-over'; | |
ctx.lineWidth = linewidth; | |
ctx.strokeStyle = hexToRgbA(color, opacity); | |
if (dash > 1) ctx.setLineDash([dash, dash]); | |
ctx.beginPath(); | |
if (circle) { | |
ctx.arc(20,20,size/2,0,Math.PI*2, false); | |
} else { | |
let p1 = 20 - size / 2; | |
ctx.rect(p1, p1, size, size); | |
} | |
ctx.closePath(); | |
ctx.stroke(); | |
ctx.setLineDash([]); | |
//ctx.globalCompositeOperation = "source-over"; | |
} | |
//helpers... | |
const hexToRgb = hex => | |
hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (m, r, g, b) => '#' + r + r + g + g + b + b) | |
.substring(1).match(/.{2}/g) | |
.map(x => parseInt(x, 16)); | |
function hexToRgbA(hex, alpha=1){ | |
if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) { | |
let c = hex.substring(1).split(''); | |
if (c.length === 3) c = [c[0], c[0], c[1], c[1], c[2], c[2]]; | |
c = '0x' + c.join(''); | |
if (!$.isNumeric(alpha) || (alpha < 0) || (alpha > 1)) alpha = 1; | |
return 'rgba(' + [(c>>16)&255, (c>>8)&255, c&255].join(', ') + ', ' + alpha + ')'; | |
} | |
} | |
function colorLuminance(hex, lum) { | |
hex = String(hex).replace(/[^0-9a-f]/gi, ''); | |
if (hex.length < 6) { | |
hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]; | |
} | |
lum = lum || 0; | |
let rgb = "#", c, i; | |
for (i = 0; i < 3; i++) { | |
c = parseInt(hex.substr(i*2,2), 16); | |
c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16); | |
rgb += ("00"+c).substr(c.length); | |
} | |
return rgb; | |
} | |
function calcBezierPoint(t, p0, p1, p2, p3) { | |
let data = [p0, p1, p2, p3]; | |
let at = 1 - t; | |
for (let i = 1; i < data.length; i++) { | |
for (let k = 0; k < data.length - i; k++) { | |
data[k] = { | |
x: data[k].x * at + data[k + 1].x * t, | |
y: data[k].y * at + data[k + 1].y * t | |
}; | |
} | |
} | |
return data[0]; | |
} | |
function addStyle(css) { | |
let s = document.createElement('style'); | |
s.appendChild(document.createTextNode(css)); | |
document.getElementsByTagName('head')[0].appendChild(s); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment