@dolphinweex/weex-vue-render 0.2.114 → 0.2.116

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.common.js +149 -36
  2. package/package.json +1 -1
@@ -11294,49 +11294,137 @@ function detectEvents () {
11294
11294
 
11295
11295
  detectEvents();
11296
11296
 
11297
+ var animationLayerEl = null;
11298
+ var animationLayerRules = {};
11299
+ var animationLayerSeq = 1;
11300
+
11301
+ function flushAnimationLayer () {
11302
+ if (!animationLayerEl) {
11303
+ animationLayerEl = document.createElement('style');
11304
+ animationLayerEl.setAttribute('data-weex-animation-layer', '');
11305
+ (document.head || document.documentElement).appendChild(animationLayerEl);
11306
+ }
11307
+ var css = '@layer weex-animation{';
11308
+ for (var id in animationLayerRules) {
11309
+ css += '[data-weex-ani="' + id + '"]{' + animationLayerRules[id] + '}';
11310
+ }
11311
+ css += '}';
11312
+ animationLayerEl.textContent = css;
11313
+ }
11314
+
11315
+ // 行内样式优先级高于 class。class 变化后再把动画终态降到 layer,
11316
+ // 普通 class 才能盖过 opacity、transform,播放过程中仍由行内样式生效。
11317
+ function demoteAnimationInline (dom, oldClass) {
11318
+ __renderLog('[animation] classChange', {
11319
+ id: dom._weexAniId || '',
11320
+ oldClass: oldClass,
11321
+ nextClass: dom.className,
11322
+ animating: !!dom._activeTransition
11323
+ });
11324
+ if (dom._activeTransition) {
11325
+ __renderLog('[animation] demoteSkip', { reason: 'animating' });
11326
+ return
11327
+ }
11328
+ var locked = dom._ani_lock;
11329
+ if (!locked) {
11330
+ __renderLog('[animation] demoteSkip', { reason: 'noLock' });
11331
+ return
11332
+ }
11333
+ var body = '';
11334
+ var moved = {};
11335
+ var has = false;
11336
+ for (var key in locked) {
11337
+ if (locked[key] == null || locked[key] === '') { continue }
11338
+ body += key + ':' + locked[key] + ';';
11339
+ moved[key] = locked[key];
11340
+ dom.style.removeProperty(key);
11341
+ has = true;
11342
+ }
11343
+ if (!has) {
11344
+ __renderLog('[animation] demoteSkip', { reason: 'emptyLock' });
11345
+ return
11346
+ }
11347
+ if (!dom._weexAniId) {
11348
+ dom._weexAniId = 'weex-ani-' + (animationLayerSeq++);
11349
+ dom.setAttribute('data-weex-ani', dom._weexAniId);
11350
+ }
11351
+ animationLayerRules[dom._weexAniId] = body;
11352
+ flushAnimationLayer();
11353
+ __renderLog('[animation] demote', {
11354
+ id: dom._weexAniId,
11355
+ moved: moved,
11356
+ inlineOpacity: dom.style.opacity,
11357
+ inlineTransform: dom.style.transform
11358
+ });
11359
+ }
11360
+
11361
+ function watchAnimationClass (dom) {
11362
+ if (dom._aniClassObserver || typeof MutationObserver !== 'function') { return }
11363
+ dom._aniClassObserver = new MutationObserver(function (records) {
11364
+ var oldClass = records && records[0] ? records[0].oldValue : '';
11365
+ demoteAnimationInline(dom, oldClass);
11366
+ });
11367
+ dom._aniClassObserver.observe(dom, { attributes: true, attributeFilter: ['class'], attributeOldValue: true });
11368
+ }
11369
+
11370
+ function applyTransitionStyles (dom, config) {
11371
+ if (config.styles && config.styles["transform"]) {
11372
+ // translate 第三参在鸿蒙上无效,收成两参,避免过渡被判定为不合法而中断
11373
+ config.styles["transform"] = config.styles["transform"].replace(/(translate\([^,]+,[^,]+),[^)]+\)/, '$1)');
11374
+ }
11375
+ var styled = utils$2.styleObject2rem(config.styles, DESIGN_ROOT_VALUE) || {};
11376
+ var processed = hyphenateStyleKeys(styled);
11377
+ var toCss = utils$2.toCSSText(processed) || '';
11378
+ dom.animation_style = toCss;
11379
+ watchAnimationClass(dom);
11380
+ for (var key in processed) {
11381
+ if (processed[key] == null || processed[key] === '') { continue }
11382
+ dom.style.setProperty(key, String(processed[key]));
11383
+ }
11384
+ }
11385
+
11297
11386
  function transitionOnce (vnode, config, callback) {
11298
11387
  var nextFrame = utils$2.nextFrame;
11299
- var toCSSText = utils$2.toCSSText;
11300
- var styleObject2rem = utils$2.styleObject2rem;
11301
11388
  var isArray = utils$2.isArray;
11302
11389
 
11303
11390
  if (isArray(vnode)) {
11304
11391
  vnode = vnode[0];
11305
11392
  }
11306
11393
 
11307
- var duration = config.duration || 0; // ms
11394
+ var duration = Number(config.duration) || 0; // ms
11308
11395
  var timing = config.timingFunction || 'linear';
11309
- var delay = config.delay || 0; // ms
11396
+ var delay = Number(config.delay) || 0; // ms
11310
11397
 
11311
11398
  // TODO: parse transition properties
11312
11399
  var transitionValue = "all " + duration + "ms " + timing + " " + delay + "ms";
11313
11400
 
11314
11401
  var dom = vnode instanceof HTMLElement ? vnode : vnode.$el;
11402
+ if (!dom) { return }
11315
11403
  // trigger image lazyloading by force.
11316
- dom && weex.utils.fireLazyload(dom, true);
11317
-
11318
- var ended = false;
11319
- var eventFinishTimer = null;
11320
- var cleanup = function () {
11321
- if (ended) { return }
11322
- ended = true;
11323
- if (eventFinishTimer) {
11324
- clearTimeout(eventFinishTimer);
11325
- eventFinishTimer = null;
11326
- }
11327
- if (endEvent) {
11328
- dom.removeEventListener(endEvent, transitionEndHandler);
11329
- }
11404
+ weex.utils.fireLazyload(dom, true);
11405
+
11406
+ // 同一节点只保留最后一次动画。旧的收尾如果再去清 transition,
11407
+ // 会把已经开始的下一次旋转直接停掉。
11408
+ if (dom._activeTransition) {
11409
+ dom._activeTransition.cancel();
11410
+ dom._activeTransition = null;
11411
+ }
11412
+
11413
+ // 原生 duration 为 0 时是同步改值。这里若拖到下一帧再加 60ms 兜底,
11414
+ // 收尾会落到下一次 800ms 定时器之后,并把角度留在 rotate(360deg)。
11415
+ if (duration + delay <= 0) {
11330
11416
  if (styleName) {
11331
11417
  dom.style[styleName] = '';
11332
11418
  }
11333
- };
11334
- var finish = function () {
11335
- if (ended) { return }
11336
- clearTimeout(timerId);
11337
- cleanup();
11419
+ applyTransitionStyles(dom, config);
11338
11420
  callback && callback();
11339
- };
11421
+ return
11422
+ }
11423
+
11424
+ var ended = false;
11425
+ var replaced = false;
11426
+ var eventFinishTimer = null;
11427
+ var timerId = null;
11340
11428
  var transitionEndHandler = function (event) {
11341
11429
  event && event.stopPropagation();
11342
11430
  // transitionend 会针对 opacity、transform 等属性分别触发。
@@ -11350,28 +11438,53 @@ function transitionOnce (vnode, config, callback) {
11350
11438
  finish();
11351
11439
  }, remaining + 16);
11352
11440
  };
11441
+ var clearWatchers = function () {
11442
+ if (eventFinishTimer) {
11443
+ clearTimeout(eventFinishTimer);
11444
+ eventFinishTimer = null;
11445
+ }
11446
+ if (timerId) {
11447
+ clearTimeout(timerId);
11448
+ timerId = null;
11449
+ }
11450
+ if (endEvent) {
11451
+ dom.removeEventListener(endEvent, transitionEndHandler);
11452
+ }
11453
+ };
11454
+ var session = {
11455
+ cancel: function () {
11456
+ if (ended) { return }
11457
+ ended = true;
11458
+ replaced = true;
11459
+ clearWatchers();
11460
+ }
11461
+ };
11462
+ var finish = function () {
11463
+ if (ended) { return }
11464
+ ended = true;
11465
+ clearWatchers();
11466
+ if (dom._activeTransition === session) {
11467
+ if (styleName) {
11468
+ dom.style[styleName] = '';
11469
+ }
11470
+ dom._activeTransition = null;
11471
+ }
11472
+ callback && callback();
11473
+ };
11353
11474
  var startTime = Date.now();
11475
+ dom._activeTransition = session;
11354
11476
  if (endEvent) {
11355
11477
  dom.style[styleName] = transitionValue;
11356
11478
  dom.addEventListener(endEvent, transitionEndHandler);
11357
11479
  }
11358
11480
  var totalMs = (duration + delay) + 60; // 兜底计时器,避免不触发 transitionend 时卡死
11359
- var timerId = setTimeout(function () {
11481
+ timerId = setTimeout(function () {
11360
11482
  if (ended) { return }
11361
11483
  finish();
11362
11484
  }, totalMs);
11363
11485
  nextFrame(function () {
11364
- // 修改 transform:translate让它支持传3个参数,且第三个参数无效
11365
- if (config.styles["transform"]) {
11366
- config.styles["transform"] = config.styles["transform"].replace(/(translate\([^,]+,[^,]+),[^)]+\)/, '$1)')
11367
- }
11368
- var toCss = toCSSText(styleObject2rem(config.styles, DESIGN_ROOT_VALUE) || {})
11369
-
11370
- // 给dom上标记是动画修改的style
11371
- if(!dom.animation_style) { dom.animation_style = "" }
11372
- dom.animation_style += toCss
11373
-
11374
- dom.style.cssText += toCss;
11486
+ if (ended || replaced) { return }
11487
+ applyTransitionStyles(dom, config);
11375
11488
  });
11376
11489
  }
11377
11490
 
package/package.json CHANGED
@@ -49,5 +49,5 @@
49
49
  "type": "git",
50
50
  "url": "git+ssh://git@github.com/weexteam/weex-vue-render.git"
51
51
  },
52
- "version": "0.2.114"
52
+ "version": "0.2.116"
53
53
  }