Skip to content

Commit

Permalink
Add new fullScreenMode settings (auto/force/allow/disable).
Browse files Browse the repository at this point in the history
Add global "small screen mode" state to change UI behaviour on mobiles

Fix dragging of palettes on mobile toggled visibility
  • Loading branch information
thenickdude committed Jul 14, 2021
1 parent efb1081 commit 39a0592
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 79 deletions.
20 changes: 20 additions & 0 deletions example/index-mobile.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>ChickenPaint testbed</title>

<script src="../resources/js/chickenpaint.js"></script>
<link rel="stylesheet" type="text/css" href="../resources/css/chickenpaint.css">

<script src="index-mobile.js"></script>

</head>
<body>
<h1>ChickenPaint testbed</h1>
<div id="chickenpaint-parent"></div>
<p></p>
</body>
</html>
14 changes: 14 additions & 0 deletions example/index-mobile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
document.addEventListener("DOMContentLoaded", function() {
new ChickenPaint({
uiElem: document.getElementById("chickenpaint-parent"),
//loadImageUrl: "./uploaded.png",
//loadChibiFileUrl: "./uploaded.chi",
saveUrl: "save.php",
postUrl: "posting.php",
exitUrl: "forum.php",
allowDownload: true,
resourcesRoot: "../resources/",
disableBootstrapAPI: true,
fullScreenMode: "force"
});
});
3 changes: 2 additions & 1 deletion example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ document.addEventListener("DOMContentLoaded", function() {
exitUrl: "forum.php",
allowDownload: true,
resourcesRoot: "../resources/",
disableBootstrapAPI: true
disableBootstrapAPI: true,
fullScreenMode: "auto"
});
});
103 changes: 72 additions & 31 deletions js/ChickenPaint.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ function checkBrowserSupport() {
return true;
}

function isSmallScreen() {
return $(window).width() < 400 || $(window).height() < 768;
}

function createDrawingTools() {
let
tools = new Array(ChickenPaint.T_MAX);
Expand Down Expand Up @@ -268,40 +272,45 @@ function createDrawingTools() {
/**
* @typedef {Object} ChickenPaintOptions
*
* @property {Element} uiElem - DOM element to insert ChickenPaint into (required)
* @property {Element} uiElem - DOM element to insert ChickenPaint into
*
* @property {Function} onLoaded - Callback to call when artwork loading completes
* @property {Function} [onLoaded] - Callback to call when artwork loading completes
*
* @property {int} canvasWidth - Width in pixels to use when creating blank canvases (defaults to 800)
* @property {int} canvasHeight - Height in pixels to use when creating blank canvases (defaults to 600)
* @property {int} rotation - Integer from [0..3], number of 90 degree right rotations that should be applied to
* @property {int} [canvasWidth] - Width in pixels to use when creating blank canvases (defaults to 800)
* @property {int} [canvasHeight] - Height in pixels to use when creating blank canvases (defaults to 600)
* @property {int} [rotation] - Integer from [0..3], number of 90 degree right rotations that should be applied to
* the canvas after loading
*
* @property {string} saveUrl - URL to POST the drawing to to save it
* @property {string} postUrl - URL to navigate to after saving is successful and the user chooses to see/publish
* @property {string} [saveUrl] - URL to POST the drawing to to save it
* @property {string} [postUrl] - URL to navigate to after saving is successful and the user chooses to see/publish
* their finished product
* @property {string} exitUrl - URL to navigate to after saving is successful and the user chooses to exit (optional)
* @property {string} testUrl - URL that ChickenPaint can simulate a drawing upload to to test the user's
* @property {string} [exitUrl] - URL to navigate to after saving is successful and the user chooses to exit (optional)
* @property {string} [testUrl] - URL that ChickenPaint can simulate a drawing upload to to test the user's
* permissions/connection (optional)
*
* @property {string} loadImageUrl - URL of PNG/JPEG image to load for editing (optional)
* @property {string} loadChibiFileUrl - URL of .chi file to load for editing (optional). Used in preference to loadImage.
* @property {string} loadSwatchesUrl - URL of an .aco palette to load (optional)
* @property {CPArtwork} artwork - Artwork to load into ChickenPaint (if you've already created one)
* @property {string} [loadImageUrl] - URL of PNG/JPEG image to load for editing (optional)
* @property {string} [loadChibiFileUrl] - URL of .chi file to load for editing (optional). Used in preference to loadImage.
* @property {string} [loadSwatchesUrl] - URL of an .aco palette to load (optional)
* @property {CPArtwork} [artwork] - Artwork to load into ChickenPaint (if you've already created one)
*
* @property {boolean} allowMultipleSends - Allow the drawing to be sent to the server multiple times (saving does not
* @property {boolean} [allowMultipleSends] - Allow the drawing to be sent to the server multiple times (saving does not
* immediately end drawing session).
* @property {boolean} allowDownload - Allow the drawing to be saved to the user's computer
* @property {boolean} allowFullScreen - Allow the drawing tool to enter "full screen" mode, where the rest of the page
* contents will be hidden
* @property {boolean} [allowDownload] - Allow the drawing to be saved to the user's computer
*
* @property {boolean} disableBootstrapAPI - Disable Bootstrap's data API on the root of the document. This speeds up
* @property {"allow"|"auto"|"force"|"disable"} [fullScreenMode] - Control the behaviour of the full screen option:
* allow - Don't automatically enter full screen mode, but allow it to be
* chosen manually (default)
* auto - Automatically enter full screen mode on startup on small screens
* force - Enter full screen mode at startup and do not provide option to leave
* disable - Don't allow full screen mode at all
*
* @property {boolean} [disableBootstrapAPI] - Disable Bootstrap's data API on the root of the document. This speeds up
* things considerably.
*
* @property {string} resourcesRoot - URL to the directory that contains the gfx/css etc directories (relative to the
* page that ChickenPaint is loaded on)
*
* @property {string} language - Provide an explicit ISO language code here (e.g. "ja_JP") to override the guessed browser language
* @property {string} [language] - Provide an explicit ISO language code here (e.g. "ja_JP") to override the guessed browser language
* Unsupported languages will fall back to English.
* Currently only "en" and "ja" are available.
*/
Expand Down Expand Up @@ -349,7 +358,8 @@ export default function ChickenPaint(options) {
preTransformMode = curMode,
curGradient = [0xFF000000, 0xFFFFFFFF],

fullScreenMode = false,
smallScreenMode = false,
isFullScreen = false,

tools = createDrawingTools(),

Expand All @@ -360,17 +370,10 @@ export default function ChickenPaint(options) {

CPFullScreen: {
action: function () {
fullScreenMode = !fullScreenMode;

$("body").toggleClass("chickenpaint-full-screen", fullScreenMode);
$(uiElem).toggleClass("chickenpaint-full-screen", fullScreenMode);

setTimeout(function () {
mainGUI.setFullScreenMode(fullScreenMode);
}, 200);
that.setFullScreen(!isFullScreen);
},
isSupported: function() {
return options.allowFullScreen !== false;
return !(options.fullScreenMode === "disable" || options.fullScreenMode === "force");
},
modifies: {gui: true}
},
Expand Down Expand Up @@ -1231,7 +1234,31 @@ export default function ChickenPaint(options) {

// callCPEventListeners(); TODO
};

this.setSmallScreenMode = function(small) {
if (smallScreenMode !== small) {
smallScreenMode = small;

$(uiElem).toggleClass("chickenpaint-small-screen", smallScreenMode);
that.emitEvent("smallScreen", [smallScreenMode]);
}
};

this.getSmallScreenMode = function() {
return smallScreenMode;
};

this.setFullScreen = function(newVal) {
if (isFullScreen !== newVal) {
isFullScreen = newVal;

$("body").toggleClass("chickenpaint-full-screen", isFullScreen);
$(uiElem).toggleClass("chickenpaint-full-screen", isFullScreen);

that.emitEvent("fullScreen", [isFullScreen]);
}
};

function installUnsavedWarning() {
if (isEventSupported("onbeforeunload")) {
window.addEventListener("beforeunload", function(e) {
Expand All @@ -1256,11 +1283,14 @@ export default function ChickenPaint(options) {
if (!uiElem) {
return;
}

that.artwork.on("editModeChanged", onEditModeChanged);

mainGUI = new CPMainGUI(that, uiElem);


that.emitEvent("fullScreen", [isFullScreen]);
that.emitEvent("smallScreen", [smallScreenMode]);

setTool(ChickenPaint.T_PEN);
mainGUI.arrangePalettes();

Expand Down Expand Up @@ -1296,6 +1326,17 @@ export default function ChickenPaint(options) {
if (options.disableBootstrapAPI) {
$(document).off('.data-api');
}

this.setSmallScreenMode(isSmallScreen());

switch (options.fullScreenMode) {
case "force":
this.setFullScreen(true);
break;
case "auto":
this.setFullScreen(smallScreenMode);
break;
}

if (options.loadImageUrl || options.loadChibiFileUrl) {
let
Expand Down
8 changes: 5 additions & 3 deletions js/gui/CPMainGUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ export default function CPMainGUI(controller, uiElem) {
};

this.setFullScreenMode = function(value) {
fullScreenMode = value;
if (fullScreenMode !== value) {
fullScreenMode = value;

that.resize();
that.arrangePalettes();
that.resize();
that.arrangePalettes();
}
};

this.resize = function() {
Expand Down
61 changes: 50 additions & 11 deletions js/gui/CPPalette.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,15 @@ import $ from "jquery";
import EventEmitter from "wolfy87-eventemitter";
import {_} from "../languages/lang";

const isInLowResolutionMode = window.innerHeight < 820 || window.innerWidth < 400;
const
DRAG_START_THRESHOLD = 5;

function distanceGreaterThan(a, b, threshold) {
let
dist = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);

return dist > threshold * threshold;
}

export default function CPPalette(cpController, className, title, resizeVert, resizeHorz) {
this.title = _(title);
Expand All @@ -41,6 +49,7 @@ export default function CPPalette(cpController, className, title, resizeVert, re
vertHandle = null,
horzHandle = null,

dragStartPos,
dragAction,
dragOffset,

Expand Down Expand Up @@ -88,15 +97,29 @@ export default function CPPalette(cpController, className, title, resizeVert, re
this.setHeight(height);
};

this.toggleBodyElementVisibility = function() {
if (isInLowResolutionMode) {
$(containerElement).toggleClass("collapsed");
}
/**
* @param {boolean} [collapse]
*/
this.toggleCollapse = function(collapse) {
$(containerElement).toggleClass("collapsed", collapse);
};

function paletteHeaderPointerMove(e) {
if (e.buttons != 0 && dragAction == "move") {
that.setLocation(e.pageX - dragOffset.x, e.pageY - dragOffset.y);
if (e.buttons != 0) {
let
newX = e.pageX - dragOffset.x,
newY = e.pageY - dragOffset.y

if (dragAction == "dragStart") {
if (distanceGreaterThan({x: newX, y: newY}, dragStartPos, DRAG_START_THRESHOLD)) {
// Recognise this as a drag rather than a clink
dragAction = "dragging";
}
}

if (dragAction == "dragging") {
that.setLocation(newX, newY);
}
}
}

Expand All @@ -108,17 +131,33 @@ export default function CPPalette(cpController, className, title, resizeVert, re
} else {
headElement.setPointerCapture(e.pointerId);

dragStartPos = {
x: parseInt(containerElement.style.left, 10),
y: parseInt(containerElement.style.top, 10),
};
dragOffset = {x: e.pageX - $(containerElement).position().left, y: e.pageY - $(containerElement).position().top};
dragAction = "move";

if (cpController.getSmallScreenMode()) {
// Wait for the cursor to move a certain amount before we classify this as a drag
dragAction = "dragStart";
} else {
dragAction = "dragging";
}
}
}
}

function paletteHeaderPointerUp(e) {
if (dragAction == "move") {
if (dragAction === "dragging" || dragAction === "dragStart") {
headElement.releasePointerCapture(e.pointerId);

if (dragAction === "dragStart") {
// We clicked the header. Cancel the drag and toggle the palette instead
that.setLocation(dragStartPos.x, dragStartPos.y);
that.toggleCollapse();
}

dragAction = false;
that.toggleBodyElementVisibility();
}
}

Expand Down Expand Up @@ -197,7 +236,7 @@ export default function CPPalette(cpController, className, title, resizeVert, re
titleElem.appendChild(document.createTextNode(_(this.title)));

titleContainer.appendChild(titleElem);
if (!isInLowResolutionMode) titleContainer.appendChild(closeButton);
titleContainer.appendChild(closeButton);

headElement.appendChild(titleContainer);

Expand Down
Loading

0 comments on commit 39a0592

Please sign in to comment.