如何使用PIXI.JS创建具有液体失真的响应式背景图像

时间:2019-11-13 23:56:16

标签: javascript pixi.js

我正在尝试复制与使用CSS width相同的结果:50vw;高度:100vh;但使用Javascript。我的代码当前无法产生理想的效果。

const logicalWidth = window.innerWidth / 2;
const logicalHeight = window.innerHeight;

我可以看到在做出响应时会遇到一些问题,因为它将在ipad / mobile上全屏显示。我想可能是处理此问题的最佳方法是使用CSS background-image渲染图像:这样,我就可以通过媒体查询来控制宽度,高度和背景位置

我尝试了这个,但是没有用

.js-canvas {
  background-image: url('https://raw.githubusercontent.com/codrops/LiquidDistortion/master/img/13.jpg');
  width: 50vw;
  height: 100%;
  background-position: center center;
}

有人可以提出解决方案吗?很高兴用JS做到这一切,但不确定从哪里开始

// Declare all vars
let bgSprite,
    displacementSprite,
    displacementFilter,
    pointerSprite,
    pointerFilter;

// Images used
const images = [
  { 
    name: 'bg', 
    url: 'https://raw.githubusercontent.com/codrops/LiquidDistortion/master/img/13.jpg'
  },
  { 
    name: 'clouds', 
    url: 'https://raw.githubusercontent.com/pixijs/examples/gh-pages/examples/assets/pixi-filters/displacement_map_repeat.jpg'
  }
];

const logicalWidth = 1800;
const logicalHeight = 1080;



// Determine & create the PIXI App instance
const canvasEl = document.querySelector('.js-canvas');
const canvasElOptions = {
  autoDensity: true,
  backgroundColor: 0xFFFFFF,
  resizeTo: window,
  resolution: window.devicePixelRatio || 1,
  view: canvasEl
};

const resizeHandler = () => {
  const scaleFactor = Math.min(
    window.innerWidth / logicalWidth,
    window.innerHeight / logicalHeight
  );
  const newWidth = Math.ceil(logicalWidth * scaleFactor);
  const newHeight = Math.ceil(logicalHeight * scaleFactor);
  app.renderer.view.style.width = `${newWidth}px`;
  app.renderer.view.style.height = `${newHeight}px`;

  app.renderer.resize(newWidth, newHeight);
  mainContainer.scale.set(scaleFactor); 
};

let app = new PIXI.Application(canvasElOptions);
let mainContainer = new PIXI.Container();

app.loader
  .add(images)
  .on('progress', loadProgressHandler)
  .load(setup);

app.renderer.plugins.interaction.moveWhenInside = true;

function loadProgressHandler(loader, resource) {
  //Display the percentage of files currently loaded
  console.log("progress: " + loader.progress + "%");

  //If you gave your files names as the first argument 
  //of the `add` method, you can access them like this
  console.log("loading: " + resource.name);
}

function setup(loader, resources){
  console.log("All files loaded");
  resizeHandler();
  
  app.stage.addChild(mainContainer);
  
  window.addEventListener('resize', resizeHandler);
  
  bgSprite = new PIXI.Sprite(resources.bg.texture);
  bgSprite.interactive = true;
  displacementSprite = new PIXI.Sprite(resources.clouds.texture);
  // Make sure the sprite is wrapping.
  displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
  displacementFilter = new PIXI.filters.DisplacementFilter(displacementSprite);
  pointerSprite = new PIXI.Sprite(resources.clouds.texture);
  pointerFilter = new PIXI.filters.DisplacementFilter(pointerSprite);
  
  displacementSprite.width = bgSprite.height;
  displacementSprite.height = bgSprite.height;
  
  pointerSprite.anchor.set(0.5);
  pointerFilter.scale.x = 7;
  pointerFilter.scale.y = 7;
  
  mainContainer.addChild(bgSprite);
  mainContainer.addChild(displacementSprite);
  mainContainer.addChild(pointerSprite);
  mainContainer.filters = [displacementFilter, pointerFilter];
  
  pointerSprite.visible = false;
  

  
  app.ticker.add((delta) => {
    // Offset the sprite position to make vFilterCoord update to larger value. 
    // Repeat wrapping makes sure there's still pixels on the coordinates.
    displacementSprite.x += 3.5 * delta;
    displacementSprite.y += 3.5 * delta;
    // Reset x & y to 0 when x > width to keep values from going to very huge numbers.
    if (displacementSprite.x > displacementSprite.width) { 
      displacementSprite.x = 0;
      displacementSprite.y = 0;
    }
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.0.3/pixi.min.js"></script>

<canvas class="test js-canvas"></canvas>

0 个答案:

没有答案