danzen / zimjs

ZIM JavaScript Canvas Framework - Code Creativity! Interactive Media For All.
Other
507 stars 47 forks source link

hi, is it possible run on an environment which has no dom bom environment #39

Closed coder-free closed 4 years ago

coder-free commented 4 years ago

hi, is it possible run on an environment which has no dom and bom environment. For example, THREE js that i just provide a context and height , width. it not dependency dom environment.

coder-free commented 4 years ago

you can see this page. maybe need translate. the environment is javascriptCore on ios and v8 on android. both have no dom environment.

danzen commented 4 years ago

Hi @zfavourite99 - thanks for the question. We will look into it tomorrow (1AM here...). I think I recall CreateJS working on a version that runs without DOM. So if they can do it, probably ZIM can do it. Will keep you posted. You are welcome to join us on Slack at https://zimjs.com/slack to discuss more. And please send a reminder if you don't hear back from us. We are working hard right now to launch 10.9.0

coder-free commented 4 years ago

hi, thanks for your reply. Your comments inspired me. now zim works for me. this is my code. image

my document is counterfeit, i just have canvas object, the object have no id, so i adapte getElementById like this:

i get a correct display:

but i drag the Circle. it not worked for me.

the touch event listen use this code, it work fine:

document.addEventListener('touchstart', (e) => {
  console.log('touchstart', e);
})

document.addEventListener('touchend', (e) => {
  console.log('touchend', e);
})

document.addEventListener('touchmove', (e) => {
  console.log('touchmove', e);
})

document.addEventListener('touchcancel', (e) => {
  console.log('touchcancel', e);
})

the event object "e" properties is: image

when i drag the circel, it not worked. how can i do meke it work for me?

danzen commented 4 years ago

Perhaps try some basic events first.

circle.on("mousedown", function(){
  circle.removeFrom();
  stage.update();
});

// or 

circle.on("pressmove", function(){
  circle.x = frame.mouseX;
  circle.y = frame.mouseY;
  stage.update();
});
coder-free commented 4 years ago

this tow event both not response. the environment's target user all is phone. so it only has touch event. have no mouse event. maybe need convert touch event to mouse event. i will try.

coder-free commented 4 years ago

Hello, I need more help. I adapte the touch event to mouse event. this is my code:

var canvas = document.createElement('canvas');
canvas.width = window.innerWidth * window.devicePixelRatio;
canvas.height = window.innerHeight * window.devicePixelRatio;

// my document is counterfeit, my element have no id
document.setElementById(canvas, "myCanvasID");

var stage = new Stage("myCanvasID");
stage.width = canvas.width;
stage.height = canvas.height;

var circle = new Circle(50, "#acd241", "#e472c4", 5) // radius, color, borderColor, borderWidth
    .addTo(stage)
    .center();

circle.on("mousedown", () => {
    circle.removeFrom();
    stage.update();
});

circle.on("pressmove", (e) => {
    circle.x = frame.mouseX;
    circle.y = frame.mouseY;
    stage.update();
});

circle.on("pressup", (e) => {
    console.log('circle pressup');
})

circle.addEventListener("touchstart", (e) => {
    console.log('circle touchstart');
})

circle.addEventListener("mousedown", (e) => {
    console.log('circle mousedown');
})

circle.addEventListener("pressup", (e) => {
    console.log('circle pressup');
})

canvas.addEventListener("touchstart", (e) => {
    console.log('canvas touchstart');
})

canvas.addEventListener("mousedown", (e) => {
    console.log('canvas mousedown');
})

canvas.addEventListener("pressup", (e) => {
    console.log('canvas pressup');
})

document.addEventListener('touchstart', (e) => {
    console.log('document touchstart');
})

document.addEventListener('mousedown', (e) => {
    console.log('document mousedown');
})

document.addEventListener('pressup', (e) => {
    console.log('document pressup');
})

stage.update();

i get the log is:

image

the canvas which i provide to stage, and the document both has event. but circle has no event.

i don't know who i need dispatch the event to?

danzen commented 4 years ago

I see... well if you are not getting the mousedown event, etc. on the circle then it will certainly not drag nor will many interactive things in ZIM work. But the issue is not with ZIM... it will have to be solved in CreateJS where all these events are created. So I would suggest seeing if CreateJS has a version that works without the DOM. It may be that this version could be used and then ZIM will work on top of it as it will get the expected events. Does this help at all? https://github.com/CreateJS/EaselJS-NodeJS

coder-free commented 4 years ago

Hello, after my further adaptation, zim now works properly in my development environment. I commented out the two lines of code in zim.js. At the moment everything seems to be working, but I don't know if this will cause any problems in the future.

my image always upload fail. in my environment Window and Blob is not defined. this tow lines i commented. the code is:

//+83.35
var ignore;
function zimplify(exclude) {
    z_d("83.35");

    // document.window = Window;
    document.window = window;
    // document.Blob = Blob;
    ignore = "ignore";
    if (zot(exclude)) exclude = [];
    if (!Array.isArray(exclude)) exclude = [exclude];
    var methods = zimify(null, true); // get list of zim methods
    var exceptions = ["loop", "stopAnimate", "pauseAnimate", "animate", "wiggle"]
    for (var command in zim) {
        if ((methods.indexOf(command) == -1 || exceptions.indexOf(command) >= 0) && exclude.indexOf(command) == -1) {
            window[command] = zim[command];
        }
    }
    window["KEYFOCUS"] = zim.KEYFOCUS;
    window["OPTIMIZE"] = zim.OPTIMIZE;
    window["ACTIONEVENT"] = zim.ACTIONEVENT;
    window["STYLE"] = zim.STYLE;
}//-83.35
coder-free commented 4 years ago

and i found another problem. in zim stage.on('drawend', function) called anytime. in createjs stage.on('drawend', function) called after stage.update(). i hope called after stage.update(). how can i do?

danzen commented 4 years ago

Hi @zfavourite99 - very cool. Glad you got most of it to work. The Blob and Window issue probably will not affect anything as there is no Window... not sure about Blob. That can be handled in other ways too if need be - anyway, make sure that the ZIM Blob is working - if not, we can discuss further.

For the stage.on("drawend", function) I don't think we are doing anything different than createjs - do you say that it is firing all the time? In the browser, the drawend is firing only when stage.update() is firing - which also happens on window resize... I wonder if something is constantly trying to draw because of a missing window size or something.

coder-free commented 4 years ago

@danzen the ZIM Blob is worked fine after i commented the document.Blob = Blob;.

I notice that if I add a window object to the stage, the drawend call anytime, else drawend call after stage.update(). This problem also exists in the chrome browser.

This is my html code:

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>ZIM Demo</title>

<script src="https://zimjs.org/cdn/1.3.0/createjs.js"></script>
<script src="https://zimjs.org/cdn/10.9.0/zim.js"></script>

</head>

<body>

    <canvas id="canvas" style="width: 100%; height: 100%;" ></canvas>

</body>

<script >
    function initZim() {

        var canvas = document.getElementById('canvas');

        // canvas.width = window.innerWidth;
        // canvas.height = window.innerHeight;

        var stage = new Stage(canvas);

        stage.width = canvas.width;
        stage.height = canvas.height;

        // var background = new Rectangle(canvas.width, canvas.height, 'rgba(255,0,0,0.5)');
        // background.center(stage);

        var width = window.innerWidth * 0.5;

        var height = window.innerHeight * 0.5;

        var win = new Window({
            width: width,
            height: height,
        });

        win.center(stage);

        stage.on('drawend', (e) => {
            console.log("drawend");
        });

        stage.update();

    }
    initZim();
</script>
</html>

In my environment Frame always throw an exception canvas.setAttribute is not a function. And I adapt the canvas.setAttribute like this:

    canvas.attribute = canvas.attribute || {};
    canvas.setAttribute = function(key, value) {
        canvas.attribute[key] = value;
    }
    canvas.getAttribute = function(key) {
        return canvas.attribute[key];
    }

The canvas.setAttribute is not a function exception gone and come another zog is not defined; . I don't know my adaption is really fine? so I use Stage. Use Stage has no error.

danzen commented 4 years ago

okay - zog binds the console.log so maybe there is no console. Frame is what is setting up the canvas and scales it to the browser window and adds a stage - so maybe you do not need it. It would probably be easier with stage. But... a lot of parts expect a zimDefaultFrame. So you might want to get the latest ZIM 10.9.0 and use the fastFrame - https://zimjs.com/docs.html?item=fastFrame

danzen commented 4 years ago

Oh... and the window is probably calling a continuous stage.update() for easing the scroll.

coder-free commented 4 years ago

@danzen Thank you very mach. Thank you for enduring my poor english. Thank you for your patience in answering my questions. I think it is better to call the stage update when the window is scrolled. Maybe this need some work. And I update ZIM 10.8.0 to 10.9.0. The same code show me different result. By 10.8.0 result is correct:

By 10.9.0 the result is not what I want:

My code is:


  var stage = new Stage(uiCanvas);

  stage.width = uiCanvas.width;
  stage.height = uiCanvas.height;

  // OR add custom label (needed to change label color for instance)
  var label = new Label({
    text:"POWER OPTION",
    size:40,
    backgroundColor:"violet",
    fontOptions:"bold"
  });
  var button = new Button({
    label:label,
    width:390,
    height:110,
    backgroundColor:"purple",
    rollBackgroundColor:"MediumOrchid",
    borderWidth:8,
    borderColor:"violet",
    gradient:.3,
    corner:0
  });
  button.center(stage);

  stage.update();

  stage.on('drawend', (e) => {
    console.log("drawend");
  });

And if possible, please update zimjs source code to 10.9.0. In my environment all third-party libraries are prone to problems. Sometimes I need debug them. So I need a not minified js source code. ZIM really is a great project. It brought me many surprises. Hope I can use it to build an amazing project. look forward to. Thank you very much again.

coder-free commented 4 years ago

I notice that no matter where I click, the button's click event always fires. According to my observations, where may zim get the incorrect size.

coder-free commented 4 years ago

My environment is indeed a headache. But there is no way, I can only use it in such an environment. The host of this environment has a large user base.

coder-free commented 4 years ago

Wechat in china like facebook in world. Too many users.

danzen commented 4 years ago

Hi @zfavourite99 - the window has damping so it glides to a stop. In many cases, we track to see if it has stopped moving and then stop the update. I will check to see if we missed that and add a bug/request on our Slack channel - which is where we usually deal with issues.

Could you please try adding fastFrame() to the start of your code. We updated many things in ZIM 10.9.0 that relate to having a stage or not so now require non-frame/non-ZIM Shim code to have fastFrame() run. Let me know if that works. If not, we can dig into it.

Is the click issue in 10.8.0 or in 10.9.0 with the button placement issue?

The non-minified code is always kept up to date at https://zimjs.org/cdn/10.9.0/zim_doc.js for instance. So add _doc - we will update GitHub, NPM, TypeScript, etc. once we settle the 10.9.0 code. We have made about 10 patches to it in the last day or two. That might go on for a week or so from launch and when ready, we update the updates page at https://zimjs.com/updates.html and let folks know on Slack - https://zimjs.com/slack (and thanks for the nice comments about ZIM!)

coder-free commented 4 years ago

Hi, when i try to use fastFrame, I got Uncaught ReferenceError: fastFrame is not defined. I change the zim source code:

--*///+83.355
if (typeof zimDefaultFrame == "undefined") var zimDefaultFrame;
function fastFrame(cjs, stage) {
    z_d("83.355");
    createjs = cjs;

    if (zot(zimDefaultFrame)) {
        stage.frame = new zim.Frame({shim:{stage:stage, canvas:stage.canvas}});
        zimDefaultFrame = stage.frame;
        zim.scaX = createjs.stageTransformable ? 1 : stage.scaleX;
        zim.scaY = createjs.stageTransformable ? 1 : stage.scaleY;
        return stage.frame;
    }
}//-83.355

change to:

--*///+83.355
if (typeof zimDefaultFrame == "undefined") var zimDefaultFrame;
zim.fastFrame = function (cjs, stage) {
    z_d("83.355");
    createjs = cjs;

    if (zot(zimDefaultFrame)) {
        stage.frame = new zim.Frame({shim:{stage:stage, canvas:stage.canvas}});
        zimDefaultFrame = stage.frame;
        zim.scaX = createjs.stageTransformable ? 1 : stage.scaleX;
        zim.scaY = createjs.stageTransformable ? 1 : stage.scaleY;
        return stage.frame;
    }
}//-83.355

The fastFrame now worked for me. And after using fastFrame, all elements are in the correct position.

After using the Window component, my FPS became very low. I looked at the specific data and drawcall was called too many times.

When I replace Window to many other component (like ten Circle). The drawcall is 3 times. And FPS is 60.

danzen commented 4 years ago

Thanks for the digging @zfavourite99 - we have updated the CDN with the fastFrame fix! We do see the window calling the update constantly so will try and figure that within the week. We are racing on teaching projects at the moment. Keep in touch!

coder-free commented 4 years ago

Hi, when I use fastFrame like this:

  var stage = new createjs.Stage(uiCanvas);
  fastFrame(createjs, stage);
  stage.frame.loadAssets("images/over_bg.png");
  var background = stage.frame.asset("images/over_bg.png");;
  background.center();

I got an error:

Failed to execute 'createObjectURL' on 'URL':

this code in createjs:

    /**
     * The asynchronous image formatter function. This is required because images have
     * a short delay before they are ready.
     * @method _formatImage
     * @param {Function} successCallback The method to call when the result has finished formatting
     * @param {Function} errorCallback The method to call if an error occurs during formatting
     * @private
     */
    p._formatImage = function (successCallback, errorCallback) {
        var tag = this._tag;
        var URL = window.URL || window.webkitURL;

        if (!this._preferXHR) {

            //document.body.removeChild(tag);
        } else if (URL) {
            var objURL = URL.createObjectURL(this.getResult(true));
            tag.src = objURL;

            tag.addEventListener("load", this._cleanUpURL, false);
            tag.addEventListener("error", this._cleanUpURL, false);
        } else {
            tag.src = this._item.src;
        }

        if (tag.complete) {
            successCallback(tag);
        } else {
            tag.onload = createjs.proxy(function() {
                successCallback(this._tag);
                tag.onload = tag.onerror = null;
            }, this);

            tag.onerror = createjs.proxy(function(event) {
                errorCallback(new createjs.ErrorEvent('IMAGE_FORMAT', null, event));
                tag.onload = tag.onerror = null;
            }, this);
        }
    };

I console the URL, it show me: URL: ƒ URL() { [native code] } I think maybe it is not a normal URL like browser. So i change the code var URL = window.URL || window.webkitURL; to var URL = undefined;. And I get another error: Cannot set property 'images/over_bg.png' of undefined the code in zim is (at line 51512):

} else if (type == "image") {
    if (e.result.width) asset = that.assets[item.id] = new zim.Bitmap(e.result, e.result.width, e.result.height, item.id);
} else {
    asset = that.assets[item.id] = e.result;
}

I console that.assets, it is undefined. Is it URL is undefined, that.assets has some problem?

danzen commented 4 years ago

Hmmm... @zfavourite99 - in the end, we just want a Bitmap(). We used all this preload stuff to turn an HTML image tag into a Bitmap. ZIM has a Bitmap class that receives data in various ways including just passing an image url into it. Maybe you do not need the preloading through CreateJS - perhaps try the Bitmap class directly.

coder-free commented 4 years ago

Yes, it works. I just noticed the examples, but ignored the documentation. Sorry. And looking forward to improving the performance of the window component. Window's scroll able is very useful to me. Some features (such as rank list) can greatly improve the user experience by using scroll.

coder-free commented 4 years ago

@danzen Hi, when i use the fastFrame, call the stage.frame.loadAssets(["image.png"], "images/"); get Cannot set property 'image.png' of undefined. i change the code line 50844-50851:

var initCheck = false;
if (!shim) {
    if (document.readyState === 'interactive' || document.readyState === 'complete' ) { // DOM has loaded
        setTimeout(function() {init();}, 200); // can't dispatch directly from a constructor
    } else {
        document.addEventListener('DOMContentLoaded', init);
    }
}

change to:

var initCheck = false;
if (!shim) {
    if (document.readyState === 'interactive' || document.readyState === 'complete' ) { // DOM has loaded
        setTimeout(function() {init();}, 200); // can't dispatch directly from a constructor
    } else {
        document.addEventListener('DOMContentLoaded', init);
    }
} else {
    this.assets = {};
    this.assetIDs = {};
}

the error gone. And assets worked fine. when use fastFrame, the init function not call. so assets and assetIDs is undefined. I don't know is the change cause some other bug?

danzen commented 1 year ago

We have now updated our npm to be more robust https://www.npmjs.com/package/zimjs