目前沒有Camera,故請教一個縮放物件的計算方式 (圖片說明)

因為目前沒有Camrea可以用來縮放畫面,
所以我自已實作計算縮放畫面的相關算式,
但…因為目前在計算座標時遇到困難,希望有大神能幫忙解惑

(以下的圖片為示意圖,不是畫的非常準確。)

已知的情況如下…

我有一個原始方形,長100px高100px,
我將它放大2倍,所以長為200px,高也為200px,

當使用者點擊正中間 ( 50px 位置 )
我要把新的方形的正中間、對齊到原始方形的正中間,
那麼我要求得需偏移的X軸,
算法就會如下…

思路大概是,
因為使用者點擊的是,原始方形的50px的位置,
我們把它想像成50%的位置,正好就是原始方形的寬度除以2,
那麼,新方形的50%的位置,就會是減去原始方形長度

那現在問題來了,
如果使用者點的是25的位置,如下圖…

請問那麼我該如何計算出X軸需偏移多少,才能保持原本的位置?

希望有大神能幫幫忙,感激不盡 :smiley:

第一个问题:

你的正方形锚点在什么位置?从你第一幅图来看,锚点在0,0,也就是左下角,放大后的正方形的左下角和原生正方形的左下角重合(因为缩放是不会改变正方形的位置的)

第二个问题:

到底是先点击再放大还是先放大再点击?或者说是点击原始正方形还是点击放大后的正方形?

第三个问题

位置是由锚点决定的,不知道你说的原本位置是什么位置?

最后,我还是没搞懂你想干啥?可能是我理解能力不行,能不能举个例子或者弄个简单的示例项目并说明目的:joy:

1赞

题目没看懂,

点击和把新正方形放到中间什么关系?
或者说点击应该的效果是什么?
这个点击时获取的坐标是新正方形的还是旧正方形的?

1赞

锚点的位置,就在0,0沒錯,
是我說明的不夠清楚,

具體應該是像下面這樣,先點擊、再放大,接著往左邊移動

  1. 原始的位置

  2. 放大後的位置

  3. 減掉x軸偏移量,讓它對齊原本點擊的點

簡單的說,
我就是要讓使用者覺得,
該圖片是從他點擊的那個位置開始放大的

不曉得這樣說明有沒有清楚一些 :blush:

感謝您的回覆

在舊方形點擊的位置,就是新方形應該對齊的位置

點擊的效果就是,
用戶點在哪個位置,物件就由它點的位置進行縮放,

圖片說明…

這感覺有點像是:
用戶點的位置,锚点就設在那個位置,然後放大,就會達成這個效果

感謝您的回覆 :blush:

最简单的办法就是你点击的时候,把锚点的位置设置在你点击位置的X坐标,这样不管你点哪里都是从点击的地方放大:sweat_smile:

如果非要计算偏移量的话,公式就是 (放大后的scale - 原始scale) * 点击位置距离锚点的偏移

也就是像你说的放大两倍后的情况就是 (2-1)* 25

当然x的偏移方向是往左边,所以结果要取反

别问我怎么知道的,反正我试过应该是对的:joy:

1赞

1你直接把锚点设置在这里不就好了,
2我的理解应该是
假设点击获取的X为x1,那么结果应该是 -2 * x1 + x1,所以应该就是-x1
这里的2是你放大了2倍
这种问题实在理解不清楚可以多尝试。
希望可以帮到你。

1赞

我也觉得直接设置锚点简单粗暴还不会算错

你图画的很棒,不过我还没来得及细看。
你可以试着参考下这个实验性的脚本:

cc.Class({
    extends: cc.Component,

    editor: {
        executeInEditMode: false,
        playOnFocus: true,
    },

    properties: {
        previewOnFocus: {
            default: true,
            notify () {
                this.enabled = this.previewOnFocus;
            },
            tooltip: 'Enable to preview in editor when you select the camera',
            editorOnly: true
        },

        world: {
            default: null,
            type: cc.Node,
            tooltip: 'The root object which contains all the object rendering in camera.'
        },

        // ...
    },

    onFocusInEditor : /*CC_EDITOR &&*/ function () {
        if (this.previewOnFocus) {
            this.enabled = true;
        }
    },

    onLostFocusInEditor : /*CC_EDITOR &&*/ function () {
        this.enabled = false;
    },

    //onEnable () {
    //    if (this.world) {
    //        if ( !this.world.position.equals(cc.Vec2.ZERO) ) {
    //            cc.error('The position of your camera\'s world node should be (0, 0)');
    //        }
    //        if ( this.world.rotation !== 0 ) {
    //            cc.error('The rotation of your camera\'s world node should be 0');
    //        }
    //        if ( this.world.scaleX !== 1 || this.world.scaleY !== 1) {
    //            cc.error('The scale of your camera\'s world node should be 1');
    //        }
    //    }
    //},

    onDisable () {
        // revert world's transform so that the editor's scene view can be reset
        this.world.position = cc.Vec2.ZERO;
        this.world.scale = cc.Vec2.ONE;
        this.world.rotation = 0;

        if (CC_EDITOR  && !cc.engine.isPlaying) {
            cc.engine.repaintInEditMode();
        }
    },

    lateUpdate (dt) {
        var node = this.node;
        var world = this.world;
        if ( !world ) {
            return;
        }
        var screenCenter;
        if (cc.Canvas.instance) {
            screenCenter = cc.Canvas.instance.node.position;
        }

        // compute position
        var position = screenCenter.sub(node.position);

        // compute scale
        var scale = node.scaleX;
        var offset = position.subSelf(screenCenter);
        offset.mulSelf(scale);
        position = screenCenter.add(offset);

        // compute rotation
        var rotation = -node.rotation;
        if (rotation !== 0) {
            position = screenCenter.add(offset.rotate(-rotation * cc.RAD));
        }

        world.position = position;
        world.rotation = rotation;
        world.scale = scale;
    },
});
1赞

我今天驗證過直接設置anchor,
但是因為我是要控制一群Node,所以我設置的是父級Node的Anchor
( 可以想像我有一個world Node,用來控制整個世界的移動、縮放 )

所以直接設置該Node、並進行縮放後,並無法連動的將子物件也都正確的縮放,
因為該父級Node只是一個空Node,

謝謝您提供的算式,我等等實際將它運用到程式中試試看,
感謝您的回覆

如果是正确的话希望告知一下哦:wink:

因為我是控制一個父級空節點,來控制整個世界的縮放、移動,
我也實際測試過設置該節點的Anchor來測試,但是並無法正確的像我想要的方式縮放。

謝謝您提供的算式,

我自已有點搞混了,不好意思,

我會再把您的公式,套上實際Scale來試試看,

感謝您的回覆,我會再多嘗試看看 :smiley:

这里应该是你自己算错了吧?你都说20%了,点击坐标就是20啊,你这里的25哪来的啊?:joy:

過獎了 :smile:

感謝Jare大神,
因為小弟才疏學淺,若有錯誤請不吝告知,
這個看起來,是一個自動更新的腳本,
我應該只要把它附加到我的 world 節點上,應該就能正常運作。

小弟回頭馬上來試試看,謝謝大神 :smile:

對不起,寫錯了 :stuck_out_tongue_closed_eyes:

馬上更正

而且

这个公式在缩放两倍的情况下是正确的哦,的确是往左偏移20,只是其他scale就需要你自己计算了

好的,小弟愚昧,頭腦一時間之轉不過來,

我會再套用到實際程式中測試的,感謝兩位熱心的前輩 :slightly_smiling:

其实还有个公式,比较容易理解

就是,假设有两个正方形,一个是原始正方形,一个是放大后的正方形

如果照你描述的,放大后的正方形的最小偏移量是0(如果锚点在左下角,我点击原始正方形的X轴的0这个坐标,放大后的正方形就不需要偏移)

最大偏移量是放大后的正方形的宽减去原始正方形的宽(我点击原始正方形x为100的坐标,这时就需要让放大后的正方形的右边和原始正方形的右边重合,重合后,放大后的正方形的宽比原始正方形的宽多出的部分就是最大偏移量)

这个时候再计算点击位置在原始正方形的哪里,假设是x=30,那么算出相对于原始正方形的原点的偏移百分比就是30%,计算出来后用放大后的正方形的最大偏移量乘偏移百分比就行了

计算公式就是:最大偏移量 * 偏移百分比

最大偏移量 = 放大后的宽 - 原始的宽

偏移百分比 = 点击位置 / 宽度

这样就求出来了,当然往左边偏移的话要取反

1赞

还有,别叫前辈啊,你才是前辈,我比你后来的,你应该叫我同学才对:joy:

1赞