Johnny Kontrolleti Posted May 2, 2020 Share Posted May 2, 2020 That's how I currently load an image as a sprite. As for now, some image are distorted due to a different ration than the sprite's: this.sprite = PIXI.Sprite.from(this.image); this.dimensions = { width: window.innerWidth * 1.05, height: window.innerHeight * 1.05, alpha: 0 }; // later in code getPosition = () => { if (!active) { this.sprite.position.set(window.innerWidth / 2, window.innerHeight / 2); this.sprite.width = this.dimensions.width; this.sprite.height = this.dimensions.height; this.sprite.anchor.set(0.5); this.sprite.alpha = this.dimensions.alpha; } else { const {width, height, top, left} = document.querySelector('.detail__image').getBoundingClientRect(); this.sprite.position.set(left, top); this.sprite.width = width; this.sprite.height = height; this.sprite.anchor.set(0); this.sprite.alpha = this.dimensions.alpha; } }; update = () => { if (!this.sprite) return; this.getPosition(); } As you can see, when active is true, the sprite is bound to a html element, if not it's about the size of the window. How can I make the image cover the sprite, without distorting? Just like `background-size: cover` or `object-fit: cover`. Tried to find something online, but couldn't make it work for me. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 2, 2020 Share Posted May 2, 2020 It shouldn't be distorted. Please make a whole demo and we can help you fix it. ZIP-file or any existing sandbox services are ok. Quote Link to comment Share on other sites More sharing options...
Johnny Kontrolleti Posted May 3, 2020 Author Share Posted May 3, 2020 12 hours ago, ivan.popelyshev said: It shouldn't be distorted. Please make a whole demo and we can help you fix it. ZIP-file or any existing sandbox services are ok. Here's a quick pen: https://codepen.io/magiix/pen/ZEbaKQg?editors=0010 That's how it usually should look like: Image - I want the image to adjust it's size just like `background-size: cover` etc. - it this possible? Thanks for your help again!!! Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 3, 2020 Share Posted May 3, 2020 Oh, that! That's one of basic exercises with transforms, solves with javascript functions "Math.min" and "Math.max", or pair of IF's. sprite.position.set(app.screen.width/2, app.screen.height/2 ); //same as your innerWidth sprite.anchor.set(0.5); sprite.scale.set(Math.min(app.screen.width / sprite.texture.width, app.screen.height / sprite.texture.height); PixiJS does not have its own alignment/reflow system. Dfiferent people write it different way => we supply only basic transforms. Johnny Kontrolleti 1 Quote Link to comment Share on other sites More sharing options...
Johnny Kontrolleti Posted May 4, 2020 Author Share Posted May 4, 2020 (edited) On 5/3/2020 at 2:01 PM, ivan.popelyshev said: Oh, that! That's one of basic exercises with transforms, solves with javascript functions "Math.min" and "Math.max", or pair of IF's. sprite.position.set(app.screen.width/2, app.screen.height/2 ); //same as your innerWidth sprite.anchor.set(0.5); sprite.scale.set(Math.min(app.screen.width / sprite.texture.width, app.screen.height / sprite.texture.height); PixiJS does not have its own alignment/reflow system. Dfiferent people write it different way => we supply only basic transforms. I have another case this unfortunately is not working, because this time the window isn't the container, but a small html element it's supposed to follow on scroll. So if I use the following, the images are not distorted and perfectly scaled to the container's size, but overflowing: const {width, height, top, left} = this.$els.image.getBoundingClientRect(); this.sprite.position.set(left + width / 2, top + height / 2); this.sprite.scale.set(Math.max(width / this.sprite.texture.width, height / this.sprite.texture.height)); this.sprite.anchor.set(0.5) Using this makes the image not overflow, but distort again, since it's stuffed into this little container again: const {width, height, top, left} = this.$els.image.getBoundingClientRect(); this.sprite.position.set(left + width / 2, top + height / 2); this.sprite.scale.set(Math.max(width / this.sprite.texture.width, height / this.sprite.texture.height)); this.sprite.anchor.set(0.5) this.sprite.width = width; this.sprite.height = height; Edited May 4, 2020 by Johnny Kontrolleti Quote Link to comment Share on other sites More sharing options...
Johnny Kontrolleti Posted May 4, 2020 Author Share Posted May 4, 2020 I added an AlphaFilter, which is kind of working - but how do I update it's position? Do I need to redraw the filterArea on update? getMask = () => { const {width, height, top, left} = this.$els.image.getBoundingClientRect(); this.sprite.filters = [new PIXI.filters.AlphaFilter()]; this.sprite.filterArea = new PIXI.Rectangle(left, top, left + width, top + width); }; Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 4, 2020 Share Posted May 4, 2020 no, its calculated automatically in that case, its just a sprite. We needed filterArea-expand-out-of-screen trick only for edge case Quote Link to comment Share on other sites More sharing options...
Johnny Kontrolleti Posted May 4, 2020 Author Share Posted May 4, 2020 22 minutes ago, ivan.popelyshev said: no, its calculated automatically in that case, its just a sprite. We needed filterArea-expand-out-of-screen trick only for edge case What do you mean by that? That I need that trick or that there shouldn't be an overflow for a sprite? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 4, 2020 Share Posted May 4, 2020 (edited) there shouldn't be a problem in case sprite doesnt get out of screen. The problem exists because filter scales everything down -> it needs some info "from beyond the screen" . You should use Sprite bounds and not getBounding stuff if you need it Edited May 4, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
Johnny Kontrolleti Posted May 4, 2020 Author Share Posted May 4, 2020 (edited) 53 minutes ago, ivan.popelyshev said: there shouldn't be a problem in case sprite doesnt get out of screen. The problem exists because filter scales everything down -> it needs some info "from beyond the screen" . You should use Sprite bounds and not getBounding stuff if you need it Thanks the efforts again, but I smh still can't make it run. The sprite is overflowing a normal html container, as you can see in the image below. - All images should be of same width, but some images, probably a different ratio do overflow. const {width, height, top, left} = this.$els.image.getBoundingClientRect(); this.sprite.position.set(left + width / 2, top + height / 2); this.sprite.scale.set(Math.max(width / this.sprite.texture.width, height / this.sprite.texture.height)); this.sprite.anchor.set(0.5); Setting width and height will restrict the sprite's area to my elements width and height, but cramp/distort the images. I need a way to cut/hide that overflow. Edited May 4, 2020 by Johnny Kontrolleti Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 4, 2020 Share Posted May 4, 2020 (edited) oh, you want to use filterArea to clamp sprites! tehre are two more ways: 1. add rect graphics inside sprite that is also its mask, coords local. (anchor=0.5, then 0,0 in graphics is sprite center) 2. modify texture frame. "const frame = sprite.texture.frame; frame.x = ... frame.y = ..." where x,y,width,height is culled the way you want, use JS min/max and positioning here, im sure you can do the math. Dont forget to call "texture.updateUvs()" afterwards. If you have one texture on multiple sprites, i recommend to clone texture before you assign it to sprite (works in >5.2.2) 1 is faster than filter, 2 is significantly faster. But if you need alphaFilter anyway, you can use your trick with filterArea, yep Edited May 4, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
Johnny Kontrolleti Posted May 5, 2020 Author Share Posted May 5, 2020 (edited) 22 hours ago, ivan.popelyshev said: oh, you want to use filterArea to clamp sprites! tehre are two more ways: 1. add rect graphics inside sprite that is also its mask, coords local. (anchor=0.5, then 0,0 in graphics is sprite center) I tried the following, but somehow the sprite completely disappeared - well at least this shows that the mask is working ? const {width, height, top, left} = this.$els.image.getBoundingClientRect(); this.sprite.position.set(left + width / 2, top + height / 2); this.sprite.scale.set(Math.max(width / this.sprite.texture.width, height / this.sprite.texture.height)); this.sprite.anchor.set(0.5); const mask = new PIXI.Graphics(); mask.drawRect(0,0, this.sprite.width, this.sprite.height); this.sprite.mask = mask; Edited May 5, 2020 by Johnny Kontrolleti Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted May 5, 2020 Share Posted May 5, 2020 (edited) right now you are masking (0,0,w,h) in global coords. add mask to sprite as a child - it will be in locals usually its detected as stencil mask, but if you do something like "renderer.mask.enableScissor=true", it will use faster scissor mask Edited May 5, 2020 by ivan.popelyshev 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.