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;