如何在swiper滑块中添加覆盖图像以适合所有尺寸屏幕上的图像

时间:2017-01-13 09:03:56

标签: javascript html css slider swiper

我在我的项目中使用swiper slider。我已经将它设置为在大屏幕上有4个图像,在滑块中有一个用于较小屏幕的图像。 这是脚本:

var carousel = function carousel() {
  var mySwiper = new Swiper ('.swiper-container', {
    direction: 'horizontal',
    nextButton: '.next',
    prevButton: '.previous',
    slidesPerView: 4,
    simulateTouch: false,
    spaceBetween: 30,
    breakpoints: {
      640: {
        slidesPerView: 1
      }
    }
  });
};

$(document).ready(function () {
  carousel();
});

我在滑块中添加了带文字的叠加图片

        @foreach($issues as $issue)
          <div class="swiper-slide magazine-image">
            <img
              class="js-magazine-selector"
              src="/imagecache/medium/{{ $issue->first()->image  }}"
              data-id='{{ $issue->first()->magazine->id }}'
              data-name='{{ $issue->first()->magazine->name }}'
              data-summary='{{ $issue->first()->magazine->summary ?: '' }}'
              data-magazine-image='{{ $issue->first()->magazine->image ?: '' }}'
              data-issue-image='{{ $issue->first()->image  }}'
            >
            <div class="magazine-overlay">
              <div class="magazine-overlay-text">
                <p>{{ $issue->first()->magazine->name }}</p>
                <a href="#">Se magasinet</a>
              </div>
            </div>
          </div>
        @endforeach

这是它的css

.carousel {
  margin: $global-margin*8 0;
  padding-left: .3rem;
  padding-right: .3rem;

  .swiper-container {
    z-index: 0;
  }

  .arrows {
    padding: 0;
  }

  button {
    line-height: normal;
    margin-bottom: 0;
  }

  .swiper-slide {
    width: auto;

    img {
      height: 100%;
      cursor: pointer;
    }
  }

  .view-all {
    padding-top:$global-padding*2;
    padding-bottom:$global-padding*2;
  }

  @include breakpoint(medium up) {
    margin: $global-margin*10 0;
  }
}

.container {
  .carousel {
    background: $black;
    margin: 0;
    padding-top: $global-padding*5;
  }
}
.magazine-image {
  position: relative;
}

.magazine-overlay {
  position: absolute;
  top: 50%;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100%;
  opacity: 0;
  transition: .5s ease;
  background-color: $black;
  display: flex;
  align-items: center;
  justify-content: center;
  color: $white!important;
}

.magazine-image:hover .magazine-overlay {
  opacity: 0.8;
}

这在大屏幕上工作正常,但在较小的屏幕上,由于滑动器动态地改变滑块的宽度,并且覆盖采用滑块的大小,它变得更宽,而图像在所有屏幕上具有相同的宽度。因此,覆盖变得比小屏幕上的图像更大。如何设置样式以使其始终与图像的宽度相同?

4 个答案:

答案 0 :(得分:2)

推荐人政策:strict-origin-when-cross-origin / 使用外部来源

pdf 应该位于同一主机上(包括相同的协议)。将 pdf 托管在与您的应用/网站相同的网址上,应该可以解决此问题。

允许在其他页面加载 pdf 会导致各种安全风险。

如果您想在自己的主页上显示外部 pdf 的最新版本,基本上有两种选择。

在您的服务器上托管 PDF

运行服务器脚本 (cron),下载 pdf 并将其托管在您自己的服务器上。

允许跨域

如果您有权访问托管 pdf 的服务器,您可以发送标头以允许跨域。

Access-Control-Allow-Origin: *

如何在yarn/npm中使用pdfjs

这方面的文档非常糟糕,但他们有一个存储库 pdfjs-dist 和一些相关文档。

安装

npm install pdfjs-dist

用法(来自DOC

import * as pdfjsLib from 'pdfjs-dist';
var url = 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf';

// The workerSrc property shall be specified.
pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';

// Asynchronous download of PDF
var loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(function(pdf) {
  console.log('PDF loaded');
  
  // Fetch the first page
  var pageNumber = 1;
  pdf.getPage(pageNumber).then(function(page) {
    console.log('Page loaded');
    
    var scale = 1.5;
    var viewport = page.getViewport({scale: scale});

    // Prepare canvas using PDF page dimensions
    var canvas = document.getElementById('the-canvas');
    var context = canvas.getContext('2d');
    canvas.height = viewport.height;
    canvas.width = viewport.width;

    // Render PDF page into canvas context
    var renderContext = {
      canvasContext: context,
      viewport: viewport
    };
    var renderTask = page.render(renderContext);
    renderTask.promise.then(function () {
      console.log('Page rendered');
    });
  });
}, function (reason) {
  // PDF loading error
  console.error(reason);
});

服务工作者

确实需要 service worker - 没有它 pdfjs 无法工作,所以 reactpdf 也不能。

如果您使用 CRA,并且不想使用 CDN,您可以执行以下步骤:

1) 将 worker 复制到公共文件夹

cp ./node_modules/pdfjs-dist/build/pdf.worker.js public/scripts

2) 注册 Service Worker

pdfjsLib.GlobalWorkerOptions.workerSrc = `${process.env.PUBLIC_URL}/scripts/pdf.worker.js`

答案 1 :(得分:2)

这是带有 Mozilla 的查看器和您的 pdf 的有效 codesandbox

注意事项:

  1. 您的 pdf 必须通过 HTTPS 提供,否则您会收到此错误:
<块引用>

混合内容:“https://codesandbox.io/”页面已加载 HTTPS,但请求了不安全的资源 'http://www.africau.edu/images/default/sample.pdf'。这个请求有 被封锁;内容必须通过 HTTPS 提供。

  1. 托管 pdf 的服务器应允许您的应用域使用 Access-Control-Allow-Origin,或者属于同一来源,否则您会收到此错误:
<块引用>

访问获取 'https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf' 来自“https://lchyv.csb.app”的来源已被 CORS 政策阻止: 请求中不存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式为 'no-cors' 以在禁用 CORS 的情况下获取资源。

  1. 出于演示目的,我使用了 https://cors-anywhere.herokuapp.com/<URL_TO_PDF>,它为您设置了 Access-Control-Allow-Origin: *,但不应在生产中使用!

总之,由于浏览器的限制,您的 pdf 没有加载。直接在您的应用中导入 pdfjs 并从头开始构建查看器(这需要大量工作)并不能解决这些问题。

答案 2 :(得分:0)

我对您的示例进行了更改,以便它接受一个 URL

我的代码如下

import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
const pdfjsLib = import("pdfjs-dist/build/pdf");

export default class PDFJs {
  init = (source, element) => {
    pdfjsLib.then((pdfjs) => {
      pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
      var loadingTask = pdfjs.getDocument(`${source}`);
      loadingTask.promise.then((pdf) => {
        pdf.getPage(1).then((page) => {
          var scale = 1.5;
          var viewport = page.getViewport({ scale: scale });
          var canvas = document.createElement("canvas");
          var context = canvas.getContext("2d");
          canvas.height = viewport.height;
          canvas.width = viewport.width;
          element.appendChild(canvas);
          var renderContext = {
            canvasContext: context,
            viewport: viewport
          };
          page.render(renderContext);
        });
      });
    });
  };
}

你可以看到结果here

答案 3 :(得分:0)

注意:正如其他人已经说过的,仅使用 react(或任何客户端库),在不解决 CORS 问题的情况下无法获取外部资源(在您的情况下为 PDF)。您需要某种服务器端技术来解决它。 (除非您拥有/有权访问外部资源服务器)


查看您提供的沙箱代码,您似乎已经在使用 node js,但该解决方案适用于所有人。

基本上,您会请求您的服务器为您获取文件,然后将该文件作为响应负载返回。 例如节点服务器侦听 fetchPdf 上的请求并将文件本身作为响应返回

app.post('/fetchPdf', asyncMiddleware(async (req, res, next) => {
    const pdfPath = await downloadFile(req.body.url);
    if (pdfPath) {
        res.type('application/pdf');
        res.sendFile(pdfPath);
        res.on('finish', function () {
            try {
                fs.unlinkSync(pdfPath);
            } catch (e) {
                console.error(e);
                console.log(`Unable to delete file ${pdfPath}`);
            }
        });
    } else
        res.status(404).send('Not found');
}));

function downloadFile(url) {
    return new Promise((resolve, reject) => {
        const absoluteFilePath = path.join(__dirname, `public/${crypto.randomBytes(20).toString('hex')}.pdf`);
        const file = fs.createWriteStream(absoluteFilePath);
        console.log(`Requested url ${url}`);
        const request = http.get(url, function (downloadResponse) {
            downloadResponse.pipe(file).on('finish', () => {
                resolve(absoluteFilePath);
            });
        }).on('error', function (err) {
            fs.unlink(absoluteFilePath);
            resolve(null);
        });
    });
}

注意:出于教育和学习目的,这会奏效,但以这种方式将代码部署到生产环境存在各种安全问题。

首先,您的服务器应该能够向任何 Internet 上的站点发出请求
其次,如果没有某种身份验证,您的站点将成为任何希望下载被 CORS 阻止的外部资源的人的热点 (类似于 [https://cors-anywhere.herokuapp.com])


至于您的第二个问题,是的,可以将 pdfjs 库与 react & npm 一起使用。
您可以参考 yurydelendik's 存储库,取自官方 pdf.js mozilla 存储库。
我还创建了一个与上述服务器端解决方案相同的 here 分支。