Customise scaling of height and width
Zian00 opened this issue · comments
Hi,
I was wondering if we can do customise scaling of the height and width for the 3d model indivdually, i have tried adding threefingermove and fourfingermove for customising the width and height respectively. However, it seems like not working due to the scaling calculation for the change of model size.
This is the part for the init:
init: function () {
this.customScaleHorizontal = this.customScaleHorizontal.bind(this);
this.customScaleVertical = this.customScaleVertical.bind(this);
this.handleScale = this.handleScale.bind(this);
this.handleRotation = this.handleRotation.bind(this);
this.initialScale = this.el.object3D.scale.clone();
this.scaleFactor = 1;
},
This is the part for updating the eventlistener:
update: function () {
if (this.data.enabled) {
this.el.sceneEl.addEventListener("onefingermove", this.handleRotation);
this.el.sceneEl.addEventListener("twofingermove", this.handleScale);
this.el.sceneEl.addEventListener("threefingermove", this.customScaleHorizontal);
this.el.sceneEl.addEventListener("fourfingermove",this.customScaleVertical);
} else {
this.el.sceneEl.removeEventListener("onefingermove", this.handleRotation);
this.el.sceneEl.removeEventListener("twofingermove", this.handleScale);
this.el.sceneEl.removeEventListener("threefingermove", this.customScaleHorizontal);
this.el.sceneEl.removeEventListener("fourfingermove", this.customScaleVertical);
}
},
This is the part for removing the eventlistener:
remove: function () {
this.el.sceneEl.removeEventListener("onefingermove", this.handleRotation);
this.el.sceneEl.removeEventListener("twofingermove", this.handleScale);
this.el.sceneEl.removeEventListener("threefingermove", this.customScaleHorizontal);
this.el.sceneEl.removeEventListener("fourfingermove", this.customScaleVertical);
},
This is the part for customizing the width:
customScaleHorizontal: function (event) {
this.scaleFactor *=
1 + event.detail.spreadChange / event.detail.startSpread;
this.scaleFactor = Math.min(
Math.max(this.scaleFactor, this.data.minScale),
this.data.maxScale
);
this.el.object3D.scale.x = this.scaleFactor * this.initialScale.x;
this.el.object3D.scale.y = this.el.object3D.scale.y;
this.el.object3D.scale.z = this.el.object3D.scale.z;
},
This is the part for customizing the height:
customScaleVertical: function (event) {
this.scaleFactor *=
1 + event.detail.spreadChange / event.detail.startSpread;
this.scaleFactor = Math.min(
Math.max(this.scaleFactor, this.data.minScale),
this.data.maxScale
);
this.el.object3D.scale.x = this.el.object3D.scale.x;
this.el.object3D.scale.y = this.scaleFactor * this.initialScale.y;
this.el.object3D.scale.z = this.el.object3D.scale.z;
},
And this is the only part i have changed for gesture-detector part:
getEventPrefix(touchCount) {
const numberNames = ["one", "two", "three", "four"];
return numberNames[Math.min(touchCount, 4) - 1];
}
I'm not sure whether is my logic wrong or what, please help me.
Thank you!
Hi! Sorry for my late response. Did you check if three and four finger events were triggered? What are the results right now? Keep in mind that you could see some weird results if you scale a model on just one axis, and also you should double check which is the axis that corresponds to width and which one corresponds to height since it depends on the marker orientation (this happens to me all the time).
Let me know if you managed to solve it :)
Hi fcor, thanks for your reply. Three and four finger events are triggered, but they are kind of too sensitive.
this.el.object3D.scale.x = this.scaleFactor * this.initialScale.x;
Due to the above line of code, whenever i scales its x-axis, it would recalculate from the initial scale of x, instead of the currently value of x, so i was wondering how to continue scaling from current x, instead of initial x.
I have tried this.el.object3D.scale.x = this.scaleFactor * this.el.object3D.scale.x;
, however it would increase or decrease the x extremely to too oversized or disappear respectively.
I was wondering if there's a way to calculate the current value of x?
thanks in advance .
You are calculating the current value of x correctly: this.el.object3D.scale.x
. Could you try adding the scale factor instead of multiplying it? At least this whay it will always increase x by the same value on each iteration. I'm not sure how good it will be but worth trying :)
Other option could be reducing the impact of finger movement on the scale factor, which could be different depending on how many fingers you use for the gesture event. Something like this.scaleFactor *= 1 + (event.detail.spreadChange/event.detail.startSpread) * 0.5;
.
I think the issue with using the current x value is that if we multiply it by some factor, it will increase or decrease too fast since gesture events are too sensitive and could run multiple times for a single touch.
Finally, just in case you want to dig deeper, in three.js scale is a Vector3, so you have acces to all this properties/functions: https://threejs.org/docs/#api/en/math/Vector3
Hope this helps!
Thanks a lot man!
Just wondering, as the 8th wall demo has the hold and drag model component and I know that their demo doesnt require a marker.
If i want to adapt that to your code, is it do-able? and how could i achieve that ?
Thanks in advance.
Hi!
Unfortunately that is not compatible yet with AR.js :(
Take a look at model-viewer, on WebXR compatible phones AR mode it works pretty well.
Hi, thanks for your fast reply!
May i know which model-viewer are you referring to ? could you link me the url ?
Thanks a lot man.
This one: https://modelviewer.dev/
Hope it helps