diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f5e0fcc..26d0c3e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ ## History +* 2023/09/24 ver 3.0.9 + * New options in Screenshot to include Author and Rules for png and jpeg. svg support not included. + * Use new clipboard API when able. (Fixes Copy on iOS.) + * Minor bug fixes and code refactoring. * 2023/07/28 ver 3.0.8 * Updated jquery, sweetalert to latest. * Fixed the bug of correctly deleteing cagearrays. diff --git a/docs/branding.js b/docs/branding.js index 7f00c3aa..1644cf62 100644 --- a/docs/branding.js +++ b/docs/branding.js @@ -16,7 +16,9 @@ const Branding = { // Usage Button Amendments addUsageButtons: { // "Submission Rules for GMPuzzles": "https://tinyurl.com/GMPuzzlesFormatting" - } + }, + + googleTag: 'G-2WQYM10ZE7' }; (function () { @@ -29,4 +31,17 @@ const Branding = { button.textContent = buttonName; usageButtons.appendChild(button); } + + if (Branding.googleTag) { + let script = document.createElement("script"); + script.type = "text/javascript"; + script.src = "https://www.googletagmanager.com/gtag/js?id=" + Branding.googleTag; + script.async = true; + document.head.appendChild(script); + + window.dataLayer = window.dataLayer || []; + function gtag() { dataLayer.push(arguments); } + gtag('js', new Date()); + gtag('config', Branding.googleTag); + } })(); \ No newline at end of file diff --git a/docs/css/base-structure.css b/docs/css/base-structure.css index c962d282..365818c7 100644 --- a/docs/css/base-structure.css +++ b/docs/css/base-structure.css @@ -1145,6 +1145,25 @@ h4 { display: inline; } +#modal-save-content textarea, +#modal-save-content input[type=text] { + padding: 2pt 5pt; +} + +#modal-save-content button, +#modal-save-content input[type=button] { + border-radius: 3px; +} + +textarea { + background-color: inherit; + transition: ease 0.3s all; +} + +.copied { + transition: ease 0.8s all; +} + #savetextarea_pp { min-width: 200px; min-height: 40px; diff --git a/docs/css/dark_theme.css b/docs/css/dark_theme.css index 3984b5cf..14eedf35 100644 --- a/docs/css/dark_theme.css +++ b/docs/css/dark_theme.css @@ -198,6 +198,31 @@ header, color: var(--white); } +#modal-save-content textarea, +#modal-save-content input[type=text] { + border: 1px solid var(--greyDark); + background: var(--greyDarkVery); + color: var(--white); +} + +#modal-save-content button, +#modal-save-content input[type=button] { + border: 1px solid var(--greyDark); + background: var(--black); + color: var(--white); +} + +#modal-save-content button:hover, +#modal-save-content input[type=button]:hover { + background: var(--greyDarkVery); +} + +.copied { + color: var(--greenLightVery) !important; + border-color: var(--greenLightVery) !important; + background: var(--green) !important; +} + #save3texttitle, #nb_note { color: var(--white); diff --git a/docs/css/light_theme.css b/docs/css/light_theme.css index ca3723f9..6a6bd581 100644 --- a/docs/css/light_theme.css +++ b/docs/css/light_theme.css @@ -193,6 +193,31 @@ header, background: var(--greyLight); } +#modal-save-content textarea, +#modal-save-content input[type=text] { + border: 1px solid var(--greyLight); + background: var(--greyLightVery); + color: var(--black); +} + +#modal-save-content button, +#modal-save-content input[type=button] { + border: 1px solid var(--greyLight); + background: var(--white); + color: var(--black); +} + +#modal-save-content button:hover, +#modal-save-content input[type=button]:hover { + background: var(--greyLightVery); +} + +.copied { + color: var(--green) !important; + border-color: var(--green) !important; + background: var(--greenLightVery) !important; +} + #save3texttitle, #nb_note { color: var(--black); diff --git a/docs/index.html b/docs/index.html index bf6a99f9..3d2b7018 100644 --- a/docs/index.html +++ b/docs/index.html @@ -31,7 +31,7 @@ - - - - - - @@ -942,6 +926,18 @@

+
+

+ + + + +
+

+ + + +

File name: diff --git a/docs/js/class_p.js b/docs/js/class_p.js index d840991c..0eab1385 100644 --- a/docs/js/class_p.js +++ b/docs/js/class_p.js @@ -162,7 +162,7 @@ class Puzzle { ["\"__a\"", "z_"], ["null", "zO"], ]; - this.version = [3, 0, 8]; // Also defined in HTML Script Loading in header tag to avoid Browser Cache Problems + this.version = [3, 0, 9]; // Also defined in HTML Script Loading in header tag to avoid Browser Cache Problems this.undoredo_disable = false; this.comp = false; this.multisolution = false; @@ -2094,8 +2094,14 @@ class Puzzle { resizedContext.drawImage(this.canvas, 0, 0, resizedCanvas.width, resizedCanvas.height); if (document.getElementById("nb_type1").checked) { + if (document.getElementById("nb_title1").checked || document.getElementById("nb_rules1").checked) { + resizedCanvas = this.canvaswithinfo(); + } var canvastext = resizedCanvas.toDataURL("image/png"); } else if (document.getElementById("nb_type2").checked) { + if (document.getElementById("nb_title1").checked || document.getElementById("nb_rules1").checked) { + resizedCanvas = this.canvaswithinfo(); + } var canvastext = resizedCanvas.toDataURL("image/jpeg"); } else if (document.getElementById("nb_type3").checked) { var svg_canvas = new C2S(this.canvasx, this.canvasy); @@ -2160,6 +2166,70 @@ class Puzzle { return canvastext; } + canvaswithinfo() { + //put the title text on the top + let main_c = $('#canvas')[0]; + let main_ctx = main_c.getContext("2d"); + + let gif_c = document.createElement('canvas'); + let gif_ctx = gif_c.getContext("2d"); + + let fontSize = 16; + let fontLineSize = fontSize * 1.2; + gif_ctx.font = "bold " + fontSize + "px sans-serif"; + let puzzleTitle = 'Title: ' + document.getElementById("saveinfotitle").value; + let puzzleRules = document.getElementById("saveinforules").value; + let puzzleTitleLines = this.splitTextLines(gif_ctx, puzzleTitle, main_c.offsetWidth); + let puzzleRulesLines = this.splitTextLines(gif_ctx, puzzleRules, main_c.offsetWidth); + let puzzleAuthor = ('Author: ' + document.getElementById("saveinfoauthor").value).split(","); + if (document.getElementById("nb_title1").checked && document.getElementById("nb_rules1").checked) { + let puzzletext = puzzleTitleLines.concat(puzzleAuthor.concat(puzzleRulesLines)); + } else if (document.getElementById("nb_title1").checked) { + let puzzletext = puzzleTitleLines.concat(puzzleAuthor); + } else { + let puzzletext = puzzleRulesLines; + } + + let gif_vertical_offset = puzzletext.length * fontLineSize; + gif_c.width = main_c.offsetWidth; + gif_c.height = main_c.offsetHeight + gif_vertical_offset; + gif_ctx.font = "bold " + fontSize + "px sans-serif"; + + //clear the gif canvas + gif_ctx.fillStyle = "#fff"; + gif_ctx.fillRect(0, 0, gif_c.width, gif_c.height); + + //draw the title text. + gif_ctx.fillStyle = "#0000ff"; + let textY = fontSize; + for (let textLine of puzzletext) { + gif_ctx.fillText(textLine, (gif_c.width - gif_ctx.measureText(textLine).width) / 2, textY); + textY += fontLineSize; + } + + gif_ctx.drawImage(main_c, 0, 0, main_c.width, main_c.height, 0, gif_vertical_offset, gif_c.width, gif_c.height - gif_vertical_offset); + return gif_c; + } + + splitTextLines(ctx, text, maxWidth) { + var words = text.split(" "); + var lines = []; + var currentLine = words[0]; + + for (var i = 1; i < words.length; i++) { + var word = words[i]; + var width = ctx.measureText(currentLine + " " + word).width; + if (width < maxWidth) { + currentLine += " " + word; + } else { + lines.push(currentLine); + currentLine = word; + } + } + lines.push(currentLine); + return lines; + } + gridspace_calculate() { this.redraw(); // ピクセルデータから計算 @@ -13134,16 +13204,20 @@ class Puzzle { // Sanity check if (outputstring.length === size * size) { - document.getElementById("iostring").value = outputstring; let textarea = document.getElementById("iostring"); - textarea.select(); - let range = document.createRange(); - range.selectNodeContents(textarea); - let sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - textarea.setSelectionRange(0, 1e5); - document.execCommand("copy"); + if (navigator.clipboard) { + navigator.clipboard.writeText(textarea.value); + } else { + document.getElementById("iostring").value = outputstring; + textarea.select(); + let range = document.createRange(); + range.selectNodeContents(textarea); + let sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + textarea.setSelectionRange(0, 1e5); + document.execCommand("copy"); + } } else { document.getElementById("iostring").value = "Error: Some cells have more than 1 digit"; } diff --git a/docs/js/general.js b/docs/js/general.js index bb3b4613..a0af91f5 100644 --- a/docs/js/general.js +++ b/docs/js/general.js @@ -1658,15 +1658,26 @@ function make_gmpfile() { function savetext_copy() { infoMsg('

URL is copied to clipboard

'); - var textarea = document.getElementById("savetextarea"); - textarea.select(); - var range = document.createRange(); - range.selectNodeContents(textarea); - var sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - textarea.setSelectionRange(0, 1e5); - document.execCommand("copy"); + + const textarea = document.getElementById("savetextarea"); + + textarea.classList.add('copied'); + setTimeout(() => { + textarea.classList.remove('copied'); + }, 2500); + + if (navigator.clipboard) { + navigator.clipboard.writeText(textarea.value); + } else { + textarea.select(); + let range = document.createRange(); + range.selectNodeContents(textarea); + let sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + textarea.setSelectionRange(0, 1e5); + document.execCommand("copy"); + } } function savetext_download() { @@ -1722,15 +1733,21 @@ function savetext_window() { } function shorturl_tab() { - var textarea = document.getElementById("savetextarea"); - textarea.select(); - var range = document.createRange(); - range.selectNodeContents(textarea); - var sel = window.getSelection(); - sel.removeAllRanges(); - sel.addRange(range); - textarea.setSelectionRange(0, 1e5); - document.execCommand("copy"); + const textarea = document.getElementById("savetextarea"); + + if (navigator.clipboard) { + navigator.clipboard.writeText(textarea.value); + } else { + textarea.select(); + let range = document.createRange(); + range.selectNodeContents(textarea); + let sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + textarea.setSelectionRange(0, 1e5); + document.execCommand("copy"); + } + window.open('https://tinyurl.com/app', '_blank'); } diff --git a/docs/js/main.js b/docs/js/main.js index 47b8ca88..97b0aaa0 100644 --- a/docs/js/main.js +++ b/docs/js/main.js @@ -1750,25 +1750,6 @@ onload = function() { document.getElementById("replay_message").innerHTML = "Preparing your download"; setTimeout(function() { - function splitTextLines(ctx, text, maxWidth) { - var words = text.split(" "); - var lines = []; - var currentLine = words[0]; - - for (var i = 1; i < words.length; i++) { - var word = words[i]; - var width = ctx.measureText(currentLine + " " + word).width; - if (width < maxWidth) { - currentLine += " " + word; - } else { - lines.push(currentLine); - currentLine = word; - } - } - lines.push(currentLine); - return lines; - } - //put the title text on the top let main_c = $('#canvas')[0]; let main_ctx = main_c.getContext("2d"); @@ -1876,6 +1857,25 @@ onload = function() { } } + function splitTextLines(ctx, text, maxWidth) { + var words = text.split(" "); + var lines = []; + var currentLine = words[0]; + + for (var i = 1; i < words.length; i++) { + var word = words[i]; + var width = ctx.measureText(currentLine + " " + word).width; + if (width < maxWidth) { + currentLine += " " + word; + } else { + lines.push(currentLine); + currentLine = word; + } + } + lines.push(currentLine); + return lines; + } + //panel(drag_window) var x_window; var y_window;