Skip to content

Commit

Permalink
feat(mvc.$): update methods for better backwards compatibility (#2471)
Browse files Browse the repository at this point in the history
  • Loading branch information
kumilingus authored Jan 12, 2024
1 parent 0e6d464 commit 229672e
Show file tree
Hide file tree
Showing 10 changed files with 471 additions and 36 deletions.
2 changes: 1 addition & 1 deletion packages/joint-core/src/mvc/Dom/Dom.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ $.event.dispatch = function(nativeEvent) {
}

return event.result;
},
};

$.event.handlers = function(event, handlers) {

Expand Down
122 changes: 122 additions & 0 deletions packages/joint-core/src/mvc/Dom/animations.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import $ from './Dom.mjs';
import { dataPriv } from './vars.mjs';

const animationKey = 'animationFrameId';
const cssReset = {};

cssReset['transition-property'] =
cssReset['transition-duration'] =
cssReset['transition-delay'] =
cssReset['transition-timing-function'] =
cssReset['animation-name'] =
cssReset['animation-duration'] =
cssReset['animation-delay'] =
cssReset['animation-timing-function'] = '';

export function animate(properties, opt = {}) {
this.stop();
for (let i = 0; i < this.length; i++) {
animateNode(this[i], properties, opt);
}
return this;
}

function animateNode(el, properties, opt = {}) {

let {
duration = 400,
easing = 'ease-in-out',
delay = 0,
complete
} = opt;

const delayId = setTimeout(function() {

const $el = $(el);
let fired = false;
let endEvent = 'transitionend';

// Convert milliseconds to seconds for CSS
duration = duration / 1000;
delay = delay / 1000;

// Set up CSS values for transition or keyframe animation
const cssValues = {};
if (typeof properties === 'string') {
// Keyframe animation
cssValues['animation-name'] = properties;
cssValues['animation-duration'] = duration + 's';
cssValues['animation-delay'] = delay + 's';
cssValues['animation-timing-function'] = easing;
endEvent = 'animationend';
} else {
// CSS transitions
const transitionProperties = [];
for (var key in properties) {
if (properties.hasOwnProperty(key)) {
cssValues[key] = properties[key];
transitionProperties.push(key);
}
}

if (duration > 0) {
cssValues['transition-property'] = transitionProperties.join(', ');
cssValues['transition-duration'] = duration + 's';
cssValues['transition-delay'] = delay + 's';
cssValues['transition-timing-function'] = easing;
}
}

const wrappedCallback = function(event){
if (event) {
if (event.target !== event.currentTarget) return; // makes sure the event didn't bubble from "below"
event.target.removeEventListener(endEvent, wrappedCallback);
} else {
el.removeEventListener(endEvent, wrappedCallback); // triggered by setTimeout
}
fired = true;
$el.css(cssReset);
complete && complete.call(el);
};

if (duration > 0){
el.addEventListener(endEvent, wrappedCallback);
// transitionEnd is not always firing on older Android phones
// so make sure it gets fired
const callbackId = setTimeout(function() {
if (fired) return;
wrappedCallback(null);
}, ((duration + delay) * 1000) + 25);

dataPriv.set(el, animationKey, {
id: callbackId,
stop: () => {
clearTimeout(callbackId);
el.removeEventListener(endEvent, wrappedCallback);
}
});
}

$el.css(cssValues);

if (duration <= 0) {
wrappedCallback(null);
}
});

dataPriv.set(el, animationKey, {
stop: () => clearTimeout(delayId)
});
}

export function stop() {
for (let i = 0; i < this.length; i++) {
const el = this[i];
const animation = dataPriv.get(el, animationKey);
if (!animation) continue;
animation.stop();
dataPriv.remove(el, animationKey);
}
this.css(cssReset);
return this;
}
4 changes: 3 additions & 1 deletion packages/joint-core/src/mvc/Dom/events.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import $ from './Dom.mjs';

// Special events

export const special = Object.create(null);
const special = Object.create(null);

export default special;

special.load = {
// Prevent triggered image.load events from bubbling to window.load
Expand Down
6 changes: 5 additions & 1 deletion packages/joint-core/src/mvc/Dom/index.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { default as $ } from './Dom.mjs';
import * as methods from './methods.mjs';
import { special } from './events.mjs';
import * as animations from './animations.mjs';
import { default as props } from './props.mjs';
import { default as special } from './events.mjs';

Object.assign($.fn, methods);
Object.assign($.fn, animations);
Object.assign($.fn, props);
Object.assign($.event.special, special);

export default $;
Expand Down
Loading

0 comments on commit 229672e

Please sign in to comment.