Skip to content

removeChild not working #1038

Open
Open

Description

@Jaswant99

Issue Details

  • createJs version 1.0.0

if a Tween is added to some timeline on some target.
tween = cjs.Tween.get(target);
timeline.addTween(tween.wait(1));

if target is an instance of createjs.DisplayObject then in below mentioned _resolveState function(MovieClip.js) _addManagedChild(MovieClip.js) adds that target as a child to owner of the timeline.

Consider this.removeChild(target) is called and target is removed from parent
but child is still there because on next tick target again gets added as child in _resolveState function
and it looks like removeChild didn't work.

p._resolveState = function() {
		var tl = this.timeline;
		this.currentFrame = tl.position;
		
		for (var n in this._managed) { this._managed[n] = 1; }

		var tweens = tl.tweens;
		for (var i=0, l=tweens.length; i<l; i++) {
			var tween = tweens[i],  target = tween.target;
			if (target === this || tween.passive) { continue; } // TODO: this assumes the actions tween from Animate has `this` as the target. There's likely a better approach.
			var offset = tween._stepPosition;

			if (target instanceof createjs.DisplayObject) {
				// motion tween.
				this._addManagedChild(target, offset);
			} else {
				// state tween.
				this._setState(target.state, offset);
			}
		}

		var kids = this.children;
		for (i=kids.length-1; i>=0; i--) {
			var id = kids[i].id;
			if (this._managed[id] === 1) {
				this.removeChildAt(i);
				delete(this._managed[id]);
			}
		}
	};

p._addManagedChild = function(child, offset) {
		if (child._off) { return; }
		this.addChildAt(child,0);

		if (child instanceof MovieClip) {
			child._synchOffset = offset;
			// TODO: this does not precisely match Adobe Flash/Animate, which loses track of the clip if it is renamed or removed from the timeline, which causes it to reset.
			// TODO: should also reset when MovieClip loops, though that will be a bit tricky to detect.
			if (child.mode === MovieClip.INDEPENDENT && child.autoReset && (!this._managed[child.id])) { child._reset(); }
		}
		this._managed[child.id] = 2;
	};
  • Mac 10.15.1 Chrome 78.0.3904.108

  • Possible solution:
    setting child._off = true on removing child and
    setting false on adding child.

    this.removeChild(target);
    target._off = true;

    this could be done either outside createjs or can be made part of removeChild and addChild
    functions.

Is this ok or is there any other solution or any other approach to solve this problem?

https://jsfiddle.net/jaswant0709/mocqfj3s/17/

Activity

  1. danzen commented on Aug 8, 2020

    @danzen
    Contributor

    This was mentioned just recently in #1048 (comment)

    So... it sounds like it is not the right behavior to add the clip back again once it is removed.

    Your proposed solution would be to set the _off property to true when removeChild() is used and set the _off property to false when the addChild() is used. I have made a test version of CreateJS here: https://zimjs.org/cdn/1.3.3/createjs_doc_off.js

    The three changes in it can be found by searching:
    #1038

    If you could test it and see if it works, that would be great. If not, then I will set up tests here, etc. Just going out for a swim! (hahaha - funny, the issue is from December and I am hoping for a test by the time I get back from swimming eight months later - I am so used to fixing bugs with developers as soon as they report them.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions