istoica Posted October 2, 2017 Share Posted October 2, 2017 Hi, The code is available here https://jsbin.com/hazogar/edit?html,js,output What I do not understand is that initial behavior is not correct, past the first zoom, it will jump/jag then be proper to zoom to a point of the object. I am zooming content inside container, so what am I missing ? var initZoom = function(app, objectDocument) { var inZoomMode = true; var content = objectDocument.view; var container = objectDocument.board; var scale = { x: content.scale.x, y: content.scale.y }; var zoom = function(x, y, isZoomIn) { var globalPosition = app.renderer.plugins.interaction.eventData.data.global; if (!globalPosition) { return; } var containerPosition = container.toLocal(globalPosition, app.stage); var contentPosition = content.toLocal(containerPosition, container); var direction = isZoomIn ? 1 : -1; var factor = (1 + direction * 0.01); var nextScaleX = content.scale.x * factor; var nextScaleY = content.scale.y * factor; var p = contentPosition; console.debug('>> P', p.x, p.y); var mat = new PIXI.Matrix(); mat.translate(-p.x, -p.y); mat.scale(nextScaleX, nextScaleY); mat.translate(p.x, p.y); content.transform.setFromMatrix(mat); content.updateTransform(); }; documentView.on('mousewheel', function(e, delta) { if (!inZoomMode) { return; } zoom(e.clientX, e.clientY, delta > 0); }); }; Thank you! ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted October 2, 2017 Share Posted October 2, 2017 content.pivot.set(0, 0); That one helps if you put it before calculation of contentMousePosition . We also need to add something to compensate pivot change. This is code from one of my projects. I fix the global point that wont move in local coords - push it, and then pop it. class CameraMover extends PIXI.Container { memCoord = new PIXI.Point(); memCoord2 = new PIXI.Point(); pushPivot(pos) { this.toLocal(pos, null, this.memCoord); } popPivot(pos) { this.toLocal(pos, null, this.memCoord2); this.pivot.x -= this.memCoord2.x - this.memCoord.x; this.pivot.y -= this.memCoord2.y - this.memCoord.y; } } //somewhere else camera.pushPivot(mousePos); camera.scale.set(...); camera.popPivot(mousePos); You can do the same thing, and in that case you wont need to set pivot to zero. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted October 2, 2017 Share Posted October 2, 2017 Btw, that's not a beginner question in general, if only all newbies had those kind of questions You've certainly have experience with 2d stage, may be from flash or something like that. Quote Link to comment Share on other sites More sharing options...
istoica Posted October 3, 2017 Author Share Posted October 3, 2017 absolute beginner with PIXI, yes, had solid flash background a while ago, miss it very much! I love PIXI so far, but how I arrived at this is through known patterns, I wanted to try CreateJS but the community of PIXI is unbeatable, these two projects should actually join hands! Coming back, why can't one do this directly on display objects ? node.pivot.set(downLocation.x, downLocation.y); node.scale.set(scaleX, scaleY); node.pivot.set(0, 0); I have tried with transformation matrix, but it was still not working after introducing the content.pivot.set(0, 0) Thank you Ivan, very useful information, I do not use ES6 so I had to extend that container a bit different, hopefully nothing wrong with it: var ZoomableContainer = (function() { var ct = function() { PIXI.Container.call(this); }; ct.prototype.constructor = ct; ct.prototype = Object.create(PIXI.Container.prototype); ct.prototype.pushPivot = function(pos) { if (!this.memCoordinates) { this.memCoordinates = new PIXI.Point(); } this.toLocal(pos, null, this.memCoordinates); }; ct.prototype.popPivot = function(pos) { var coordinates = new PIXI.Point(); this.toLocal(pos, null, coordinates); this.pivot.x -= coordinates.x - this.memCoordinates.x; this.pivot.y -= coordinates.y - this.memCoordinates.y; }; return ct; })(); And then I use it as you instructed, in the end I have managed to have this code working, I was unable to compute the new positions, but found a formula to get the delta according to zoom level: var inZoomMode = true; var initZoom = function(app, content ) { var level = 1; var amount = 1.1; var zoomTo = function(level, p) { content.scale.x *= level; content.scale.y *= level; content.x -= (p.x - content.x) * (level - 1); content.y -= (p.y - content.y) * (level - 1); }; documentView.on('mousewheel', function(e, delta) { if (!inZoomMode) { return; } var globalData = app.renderer.plugins.interaction.eventData.data; if (!globalData || !globalData.global) { return; } var zoomIn = delta > 0; var zoomFactor = zoomIn ? amount : (1 / amount); zoomTo(zoomFactor * level, globalData.global); }); }; The zoomTo function inside the init zoom is all there is (I am using jquery-mousewheel to normalize mouse delta) PS: The forum does not let me save code as JavaScript Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.