Skip to content

Addon Events API and User Defined Functions access #7947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: dev-2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/parameterData.json
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@
"windowResized": {
"overloads": [
[
"UIEvent?"
"Event?"
]
]
},
Expand Down
22 changes: 17 additions & 5 deletions src/core/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import * as C from './constants';
import { Vector } from '../math/p5.Vector';

function environment(p5, fn){
function environment(p5, fn, lifecycles){
const standardCursors = [C.ARROW, C.CROSS, C.HAND, C.MOVE, C.TEXT, C.WAIT];

fn._frameRate = 0;
Expand All @@ -19,6 +19,19 @@ function environment(p5, fn){
const _windowPrint = window.print;
let windowPrintDisabled = false;

lifecycles.presetup = function(){
const events = [
'resize'
];

for(const event of events){
window.addEventListener(event, this[`_on${event}`].bind(this), {
passive: false,
signal: this._removeSignal
});
}
};

/**
* Displays text in the web browser's console.
*
Expand Down Expand Up @@ -715,7 +728,7 @@ function environment(p5, fn){
* can be used for debugging or other purposes.
*
* @method windowResized
* @param {UIEvent} [event] optional resize Event.
* @param {Event} [event] optional resize Event.
* @example
* <div class="norender">
* <code>
Expand Down Expand Up @@ -770,10 +783,9 @@ function environment(p5, fn){
fn._onresize = function(e) {
this.windowWidth = getWindowWidth();
this.windowHeight = getWindowHeight();
const context = this._isGlobal ? window : this;
let executeDefault;
if (typeof context.windowResized === 'function') {
executeDefault = context.windowResized(e);
if (this.userDefinedFunctions.windowResized) {
executeDefault = this.userDefinedFunctions.windowResized(e);
if (executeDefault !== undefined && !executeDefault) {
e.preventDefault();
}
Expand Down
81 changes: 27 additions & 54 deletions src/core/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,37 +64,16 @@ class p5 {
this._startListener = null;
this._initializeInstanceVariables();
this._events = {
// keep track of user-events for unregistering later
pointerdown: null,
pointerup: null,
pointermove: null,
dragend: null,
dragover: null,
click: null,
dblclick: null,
mouseover: null,
mouseout: null,
keydown: null,
keyup: null,
keypress: null,
wheel: null,
resize: null,
blur: null
};
this._removeAbortController = new AbortController();
this._removeSignal = this._removeAbortController.signal;
this._millisStart = -1;
this._recording = false;

// States used in the custom random generators
this._lcg_random_state = null; // NOTE: move to random.js
this._gaussian_previous = false; // NOTE: move to random.js

if (window.DeviceOrientationEvent) {
this._events.deviceorientation = null;
}
if (window.DeviceMotionEvent && !window._isNodeWebkit) {
this._events.devicemotion = null;
}

// ensure correct reporting of window dimensions
this._updateWindowSize();

Expand Down Expand Up @@ -156,16 +135,6 @@ class p5 {
p5._checkForUserDefinedFunctions(this);
}

// Bind events to window (not using container div bc key events don't work)
for (const e in this._events) {
const f = this[`_on${e}`];
if (f) {
const m = f.bind(this);
window.addEventListener(e, m, { passive: false });
this._events[e] = m;
}
}

const focusHandler = () => {
this.focused = true;
};
Expand Down Expand Up @@ -208,6 +177,20 @@ class p5 {
}
}

_userDefinedFunctions = {};
userDefinedFunctions = new Proxy({}, {
get: (target, prop) => {
if(!this._userDefinedFunctions[prop]){
const context = this._isGlobal ? window : this;
if(typeof context[prop] === 'function'){
this._userDefinedFunctions[prop] = context[prop].bind(this);
}
}

return this._userDefinedFunctions[prop];
}
})

async #_start() {
if (this.hitCriticalError) return;
// Find node if id given
Expand Down Expand Up @@ -247,18 +230,13 @@ class p5 {
}
if (this.hitCriticalError) return;

// unhide any hidden canvases that were created
const canvases = document.getElementsByTagName('canvas');

// Apply touchAction = 'none' to canvases if pointer events exist
if (Object.keys(this._events).some(event => event.startsWith('pointer'))) {
for (const k of canvases) {
k.style.touchAction = 'none';
}
}


for (const k of canvases) {
// Apply touchAction = 'none' to canvases to prevent scrolling
// when dragging on canvas elements
k.style.touchAction = 'none';

// unhide any hidden canvases that were created
if (k.dataset.hidden === 'true') {
k.style.visibility = '';
delete k.dataset.hidden;
Expand Down Expand Up @@ -380,19 +358,14 @@ class p5 {
window.cancelAnimationFrame(this._requestAnimId);
}

// unregister events sketch-wide
for (const ev in this._events) {
window.removeEventListener(ev, this._events[ev]);
}
// Send sketch remove signal
this._removeAbortController.abort();

// remove DOM elements created by p5, and listeners
// remove DOM elements created by p5
for (const e of this._elements) {
if (e.elt && e.elt.parentNode) {
e.elt.parentNode.removeChild(e.elt);
}
for (const elt_ev in e._events) {
e.elt.removeEventListener(elt_ev, e._events[elt_ev]);
}
}

// Run `remove` hooks
Expand Down Expand Up @@ -422,9 +395,9 @@ class p5 {
}

async _runLifecycleHook(hookName) {
for(const hook of p5.lifecycleHooks[hookName]){
await hook.call(this);
}
await Promise.all(p5.lifecycleHooks[hookName].map(hook => {
return hook.call(this);
}));
}

_initializeInstanceVariables() {
Expand Down
22 changes: 12 additions & 10 deletions src/dom/p5.Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,22 @@ class Element {
// `_elements` array. But when an element lives inside an off-screen
// `p5.Graphics` layer, `this._pInst` is that wrapper Graphics object
// instead. The wrapper keeps a back–pointer (`_pInst`) to the real
// sketch but has no `_elements` array of its own.
let sketch = this._pInst;
// sketch but has no `_elements` array of its own.

let sketch = this._pInst;

// If `sketch` doesn’t own an `_elements` array it means
// we’re still at the graphics-layer “wrapper”.
// we’re still at the graphics-layer “wrapper”.
// Jump one level up to the real p5 sketch stored in sketch._pInst.

if (sketch && !sketch._elements && sketch._pInst) {
sketch = sketch._pInst; // climb one level up
sketch = sketch._pInst; // climb one level up
}

if (sketch && sketch._elements) { // only if the array exists
const i = sketch._elements.indexOf(this);
if (i !== -1) sketch._elements.splice(i, 1);
}


// deregister events
for (let ev in this._events) {
Expand Down Expand Up @@ -1865,7 +1864,7 @@ class Element {
return this;
}

/**
/**
* Calls a function when a file is dragged over the element.
*
* Calling `myElement.dragOver(false)` disables the function.
Expand Down Expand Up @@ -2416,7 +2415,10 @@ class Element {
Element._detachListener(ev, ctx);
}
const f = fxn.bind(ctx);
ctx.elt.addEventListener(ev, f, false);
ctx.elt.addEventListener(ev, f, {
capture: false,
signal: ctx._pInst._removeSignal
});
ctx._events[ev] = f;
}

Expand Down
53 changes: 35 additions & 18 deletions src/events/acceleration.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,21 @@
* @main Events
*/

function acceleration(p5, fn){
function acceleration(p5, fn, lifecycles){
lifecycles.presetup = function(){
const events = [
'deviceorientation',
'devicemotion'
];

for(const event of events){
window.addEventListener(event, this[`_on${event}`].bind(this), {
passive: false,
signal: this._removeSignal
});
}
};

/**
* The system variable deviceOrientation always contains the orientation of
* the device. The value of this variable will either be set 'landscape'
Expand Down Expand Up @@ -449,9 +463,7 @@ function acceleration(p5, fn){
* </code>
* </div>
*/

fn.setMoveThreshold = function (val) {
// p5._validateParameters('setMoveThreshold', arguments);
move_threshold = val;
};

Expand Down Expand Up @@ -491,9 +503,7 @@ function acceleration(p5, fn){
* </code>
* </div>
*/

fn.setShakeThreshold = function (val) {
// p5._validateParameters('setShakeThreshold', arguments);
shake_threshold = val;
};

Expand Down Expand Up @@ -614,7 +624,6 @@ function acceleration(p5, fn){
* </code>
* </div>
*/

fn._ondeviceorientation = function (e) {
this._updatePRotations();

Expand All @@ -624,33 +633,41 @@ function acceleration(p5, fn){
this.rotationZ = this._fromDegrees(e.alpha);
this._handleMotion();
};

fn._ondevicemotion = function (e) {
this._updatePAccelerations();
this.accelerationX = e.acceleration.x * 2;
this.accelerationY = e.acceleration.y * 2;
this.accelerationZ = e.acceleration.z * 2;
this._handleMotion();
};

fn._handleMotion = function () {
if (window.orientation === 90 || window.orientation === -90) {
if (
screen.orientation.type === 'landscape-primary' ||
screen.orientation.type === 'landscape-secondary'
) {
this.deviceOrientation = 'landscape';
} else if (window.orientation === 0) {
} else if (
screen.orientation.type === 'portrait-primary' ||
screen.orientation.type === 'portrait-secondary'
) {
this.deviceOrientation = 'portrait';
} else if (window.orientation === undefined) {
} else {
this.deviceOrientation = 'undefined';
}
const context = this._isGlobal ? window : this;
if (typeof context.deviceMoved === 'function') {

if (this.userDefinedFunctions.deviceMoved) {
if (
Math.abs(this.accelerationX - this.pAccelerationX) > move_threshold ||
Math.abs(this.accelerationY - this.pAccelerationY) > move_threshold ||
Math.abs(this.accelerationZ - this.pAccelerationZ) > move_threshold
) {
context.deviceMoved();
this.userDefinedFunctions.deviceMoved();
}
}

if (typeof context.deviceTurned === 'function') {
if (this.userDefinedFunctions.deviceTurned) {
// The angles given by rotationX etc is from range [-180 to 180].
// The following will convert them to [0 to 360] for ease of calculation
// of cases when the angles wrapped around.
Expand All @@ -671,7 +688,7 @@ function acceleration(p5, fn){
if (Math.abs(wRX - wSAX) > 90 && Math.abs(wRX - wSAX) < 270) {
wSAX = wRX;
this.turnAxis = 'X';
context.deviceTurned();
this.userDefinedFunctions.deviceTurned();
}
this.pRotateDirectionX = rotateDirectionX;
startAngleX = wSAX - 180;
Expand All @@ -691,7 +708,7 @@ function acceleration(p5, fn){
if (Math.abs(wRY - wSAY) > 90 && Math.abs(wRY - wSAY) < 270) {
wSAY = wRY;
this.turnAxis = 'Y';
context.deviceTurned();
this.userDefinedFunctions.deviceTurned();
}
this.pRotateDirectionY = rotateDirectionY;
startAngleY = wSAY - 180;
Expand Down Expand Up @@ -720,12 +737,12 @@ function acceleration(p5, fn){
) {
startAngleZ = rotZ;
this.turnAxis = 'Z';
context.deviceTurned();
this.userDefinedFunctions.deviceTurned();
}
this.pRotateDirectionZ = rotateDirectionZ;
this.turnAxis = undefined;
}
if (typeof context.deviceShaken === 'function') {
if (this.userDefinedFunctions.deviceShaken) {
let accelerationChangeX;
let accelerationChangeY;
// Add accelerationChangeZ if acceleration change on Z is needed
Expand All @@ -734,7 +751,7 @@ function acceleration(p5, fn){
accelerationChangeY = Math.abs(this.accelerationY - this.pAccelerationY);
}
if (accelerationChangeX + accelerationChangeY > shake_threshold) {
context.deviceShaken();
this.userDefinedFunctions.deviceShaken();
}
}
};
Expand Down
Loading
Loading