PIXI.JS - смещение, влияющее на границы - PullRequest
0 голосов
/ 03 ноября 2019

Я использую Pixi для создания шаблона страницы блога, который использует текстуру смещения для искажения изображений поста (при загрузке, при наведении курсора и при нажатии).

Моя проблема в том, что я не могу понять, как повлиять на границы моей текстуры, поэтому, когда вы, например, наводите на нее курсор, границы также перемещаются (теперь они статичны). Я знаю, это может показаться простым, но по какой-то причине я не могу понять, чего мне здесь не хватает ...

Я создал jsfiddle для живого кода.

вот мой html

<div class="section">
  <div class="section__image" data-index="1" data-src="https://source.unsplash.com/random/">
  </div>
  <div class="section__content">
    <h2>Lorem ipsum dolor.</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis, rem. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium assumenda atque distinctio eos illo minima, mollitia officiis pariatur provident! Architecto cum facilis nostrum sit voluptate. Dignissimos dolores enim quidem totam?</p>
  </div>
</div>

<div class="section">
  <div class="section__image" data-index="2" data-src="https://source.unsplash.com/random">
  </div>
  <div class="section__content">
    <h2>Lorem ipsum dolor.</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis, rem. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto asperiores dicta eius, est eum itaque magnam officia perspiciatis porro sequi. Autem ea ipsa sed ullam.</p>
  </div>
</div>

<div class="section">

  <div class="section__image"  data-index="3" data-src="https://source.unsplash.com/random">
  </div>
  <div class="section__content">
    <h2>Lorem ipsum dolor.</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis, rem. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad autem est incidunt iusto obcaecati provident quod sequi ut veritatis. At atque aut blanditiis consequatur distinctio dolor, et, ipsa iste nam numquam officia pariatur perferendis possimus provident quibusdam quod repellendus vitae!</p>
  </div>
</div>

<div class="section">
  <div class="section__image" data-index="4" data-src="https://source.unsplash.com/random">
  </div>
  <div class="section__content">
    <h2>Lorem ipsum dolor.</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Debitis, rem. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur eius nemo perspiciatis quia sit temporibus.</p>
  </div>
</div>

вот мой css

* {
  box-sizing: border-box; 
}

html, body {
  height: 100%; 
}

body {
  margin: 0; 
  font-family: 'Helvetica', serif;
}

.section {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0 auto;
  padding: 50px 0;
  max-width: 960px; 
}

.section__image {
    position: relative;
    overflow: hidden;
    flex-shrink: 0;
    width: 100%;
    height: 100%;
}

.section__image > img {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
}

.section__content {
    padding: 10px 0 0; 
}

а вот мой javascript

// Note : Resize logic to fit the textures with canvas => https://github.com/pixijs/pixi.js/wiki/v4-Tips,-Tricks,-and-Pitfalls#resizing-renderer

class ImageLoader {
  constructor(element) {
    this.wrapper = element;
    this.width = element.getBoundingClientRect().width;
    this.height = element.getBoundingClientRect().height;
    this.src = element.dataset.src;
    this.mouseOn = false;
    this.animated = false;

    this.app = new PIXI.Application(this.width, this.height, {transparent: true});
    this.wrapper.append(this.app.view);
    this.container = new PIXI.Container();
    const parent = this.app.view.parentNode;
    this.app.renderer.resize(parent.clientWidth, parent.clientHeight);
    this.app.stage.addChild(this.container);

    this.load(this.startAnimation.bind(this));
  }

  load(afterLoad) {
    let tmpImg = new Image();
    tmpImg.src = this.src;
    tmpImg.addEventListener('load', () => {
      afterLoad();
    });
  }

  startAnimation() {
    const that = this;
    // create pixi image and add it to container
    this.bg = PIXI.Sprite.fromImage(this.src);
    //this.bg.width = this.app.screen.width;
    this.bg.width = this.width;
    // this.bg.height = this.height;
    this.bg.position.x = 0;
    this.bg.position.y = 0;
    this.container.addChild(this.bg);
    // create filter
    this.displacementSprite = PIXI.Sprite.fromImage('https://s3-us-west-2.amazonaws.com/s.cdpn.io/123024/disp5.jpg');
    this.displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT; // cover with filter all image
    this.displacementFilter = new PIXI.filters.DisplacementFilter(this.displacementSprite);
    // set filter scale
    this.displacementFilter.scale.set(1e4 + Math.random()*1000);
    this.displacementSprite.scale.set(0.4 + 0.6*Math.random());
    // add filter to container & stage (for waves effect on hover)
    this.app.stage.addChild(this.displacementSprite);
    this.container.filters = [this.displacementFilter];

    this.click();

    // animate displacementFilter on image
    let tl = new TimelineMax({onComplete:function() {that.animated = true;}});
    tl.to(that.displacementFilter.scale,1,{x:1,y:1});

    this.hover();
  }

  click() {
    let that = this;
    this.wrapper.addEventListener('click',() => {
        let tl = new TimelineMax(
          {onComplete:function() {that.animated = true;}}
          );
        tl.to(that.displacementFilter.scale,1,{x:1,y:1});
    });
  }

  hover() {
      let that = this;

    this.wrapper.addEventListener('mouseenter',function() {
      if(!that.mouseOn && that.animated) {
        that.mouseOn = true;
        TweenMax.ticker.addEventListener('tick',that.doWaves, that); // same as requestAnimationFrame
        let tl = new TimelineMax();
        tl.to(that.displacementFilter.scale,0.5,{x:20,y:10});
      }

    });

    this.wrapper.addEventListener('mouseleave',function() {
      if(that.mouseOn && that.animated) {
        that.mouseOn = false;
        TweenMax.ticker.removeEventListener('tick',that.doWaves, that);
        let tl = new TimelineMax();
        tl.to(that.displacementFilter.scale,0.5,{x:1,y:1});
      }
    });
  }

  doWaves() {
    this.displacementSprite.x += 1;
  }
}

const imageNodeList = document.querySelectorAll( '.section__image');
Array.prototype.forEach.call(imageNodeList, function (node) {
  const img = new ImageLoader(node);
});
...