Web-fancyapps

Robust JavaScript UI Component Library.

资源

正文

Fancybox

引入

Releases · fancyapps/ui (github.com) 引入 fancybox.umd.jsfancybox.css

html
<script src="fancybox.umd.js"></script>
<link rel="stylesheet" href="fancybox.css" />

请注意,这种方法的缺点是,每次要将文件更新到最新版本时,都必须执行此操作。

因此,推荐的方法是使用 NPM 等包管理器或使用 CDN 链接,这些链接将自动使用最新的补丁版本而不会影响您的代码。

使用

html
<a href="222.png" data-fancybox="gallery" data-caption="青玉之爪">
  <img alt="青玉之爪" src="222.png" />
</a>
 
<a href="653.png" data-fancybox="gallery" data-caption="艾雅 · 黑掌">
  <img alt="艾雅 · 黑掌" src="653.png" />
</a>

即在传统 <img> 显示图片上外包一层 <a>

  • <a>href 应与 <img>src 保持一致;
  • <a>data-caption 应与 <img>alt 保持一致。

最后在网页的尾部(或是其它合适位置)注册 fancybox:

javascript
Fancybox.bind(document.getElementById("gallery-wrap"), "[data-fancybox]", {
  // Your custom options
});

可以从 Options | Fancybox - best JavaScript lightbox alternative (fancyapps.com) 获取想要修改的设置 API。

控制 fancybox 的函数:Methods | Fancybox - best JavaScript lightbox alternative (fancyapps.com)

一些执行后的派发事件:Events | Fancybox - best JavaScript lightbox alternative (fancyapps.com)

一般来说,没啥好设置的……

效果

青玉之爪 艾雅 · 黑掌

引入

html
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/carousel/carousel.umd.js"></script>
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/carousel/carousel.css"
/>

使用

Parallax Slider - StackBlitz 抄一个牛逼的!

创建一个轮播对象 #myCarousel

html
<div class="f-carousel" id="myCarousel" style="background: #ff000020;">
  <div class="f-carousel__slide"><img alt="图腾魔像" src="234.png" /><center>当你把一堆图腾绑在一起时,图腾魔像就诞生了。</center></div>
  <div class="f-carousel__slide"><img alt="阴燃电鳗" src="223.png" /><center>用来做鳗鱼饭最合适不过了!</center></div>
  <div class="f-carousel__slide"><img alt="投火无面者" src="477.png" /><center>他的手感热得发烫,百步穿杨技惊四座!</center></div>
  <div class="f-carousel__slide"><img alt="艾雅 · 黑掌" src="653.png" /><center>别看艾雅年纪轻,她可是玉莲帮的实际掌权者。看似天真活泼的少女,转眼之间便能召唤出魔像大军,将敌人统统碾碎!</center></div>
  <div class="f-carousel__slide"><img alt="深渊魔物" src="655.png" /><center>深渊魔物有一奇怪的癖好,就是收集各式各样的萨满祭司图腾。</center></div>
  <div class="f-carousel__slide"><img alt="吉恩 · 格雷迈恩" src="665.png" /><center>“希尔瓦娜斯杀了偶的儿子,偶一定要为他报仇!”</center></div>
  <div class="f-carousel__slide"><img alt="海巨人" src="1088.png" /><center>嗨,巨人!</center></div>
</div>

<div class="f-carousel__slide"> 中可以不只是 <img>


设置好 #myCarousel 的样式 :

css
.f-carousel__dots>li:before{
    display: none;
}
 
span.f-carousel__dot {
    color: var(--text-primary);
    transition: color 0.5s ease-in-out;
}
 
#myCarousel {
  --f-carousel-slide-width: calc((100% - 60px) / 4);
  --f-carousel-spacing: 20px;
 
  --f-button-next-pos: 1rem;
  --f-button-prev-pos: 1rem;
 
  --f-button-width: 44px;
  --f-button-height: 44px;
  --f-button-border-radius: 50%;
 
  --f-button-color: #fff;
  --f-button-hover-color: #fff;
  --f-button-active-color: #fff;
 
  --f-button-bg: rgba(0, 0, 0, 0.5);
  --f-button-hover-bg: rgba(0, 0, 0, 0.8);
  --f-button-active-bg: rgba(0, 0, 0, 0.8);
 
  --f-button-svg-width: 22px;
  --f-button-svg-height: 22px;
  --f-button-svg-stroke-width: 3;
}
  • --f-carousel-slide-width: calc((100% - 60px) / 4); 可以让一个页面显示中间 3 个页,左右两边显示 2 个半页。

其它的都是设置 UI 样式了。


注册对象:

javascript
const mapRange = (inputLower, inputUpper, outputLower, outputUpper, value) => {
  const INPUT_RANGE = inputUpper - inputLower;
  const OUTPUT_RANGE = outputUpper - outputLower;
  return (
    outputLower + (((value - inputLower) / INPUT_RANGE) * OUTPUT_RANGE || 0)
  );
};
 
new Carousel(document.getElementById('myCarousel'), {
  slidesPerPage: 1,
  dragFree: true,
 
  Dots: false,
  Panzoom: {
    decelFriction: 0.08,
  },
 
  on: {
    'Panzoom.beforeTransform': (carousel) => {
      carousel.slides.map((slide) => {
        const progress = carousel.getProgress(slide.index, true);
 
        const progress1 = mapRange(-4, 4, 50, -50, progress);
        slide.el.style.setProperty('--f-progress1', `${progress1}%`);
    
        const progress2 = mapRange(-4, 4, 50, -50, 1 - progress);
        slide.el.style.setProperty('--f-progress2', `${progress2}%`);
      });
    },
  },
});

这段代码可以让每次翻页只翻一个页面宽度。


可以从 Options | Carousel from Fancyapps UI 获取想要修改的设置 API。

控制 carousel 的函数:Methods | Carousel from Fancyapps UI

一些执行后的派发事件:Events | Carousel from Fancyapps UI

效果

目前看来,这好像跟懒加载 Troy-Yang/hexo-lazyload-image: lazyload image plugin for Hexo. (github.com) 会有点冲突……或许可以在使用 carousel 的时候把懒加载关了。

我说婷婷!这个插件貌似自带懒加载功能,将 src 属性改为 data-lazy-src 属性即可。

Panzoom

感觉像是非全屏的 fancybox。

引入

html
<script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/panzoom/panzoom.umd.js"></script>
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/panzoom/panzoom.css"
/>

使用

创建对象:

html
<div class="f-panzoom" id="myPanzoom" style="background: #ff000020;">
  <img class="f-panzoom__content" src="665.png" alt="吉恩 · 格雷迈恩"/>
</div>

设置 CSS,如果 panzoom 里的元素实际大小大于所设定的大小,则会在渲染的时候自适应大小,而在鼠标移过去时缩放到原大小。

css
#myPanzoom {
  height: 300px;
}

注册对象:

javascript
const container = document.getElementById("myPanzoom");
const instance = new Panzoom(container, {
  panMode: 'mousemove',
  mouseMoveFactor: 1.25,
    click: false,
    wheel: false
});
 
container.addEventListener("mouseenter", (event) => {
  if (!event.buttons) {
    instance.zoomToCover(event);
  }
});
 
container.addEventListener("mouseleave", () => {
  instance.zoomToFit();
});

演示

吉恩 · 格雷迈恩

Panzoom-Toolbar

引入

@fancyapps/ui CDN by jsDelivr - A free, fast, and reliable Open Source CDN 获取 panzoom.toolbar.esm.jspanzoom.toolbar.css 并引入。

使用

html
<div class="f-panzoom" id="myPanzoomToolbar" style="background: #ff000020;">
  <img class="f-panzoom__content" src="1088.png" alt="海巨人"/>
</div>
 
<script>
  const options = {
    Toolbar: {
      display: ["zoomIn", "zoomOut", "toggle1to1", "toggleZoom", "panLeft", "panRight", "panUp", "panDown", "rotateCCW", "rotateCW", "flipX", "flipY", "fitX", "fitY", "reset", "toggleFS"],
    },
  };
  new Panzoom(document.getElementById("myPanzoomToolbar"), options, { Toolbar });
</script>

可以在 Toolbar 下的 display 中设置想要显示的工具栏按钮。

演示

海巨人

Panzoom-Pins

引入

@fancyapps/ui CDN by jsDelivr - A free, fast, and reliable Open Source CDN 获取 panzoom.pins.esm.jspanzoom.pins.css 并引入。

使用

html
<div class="f-panzoom" id="myPanzoomPins">
  <div class="f-panzoom__viewport">
    <div data-panzoom-pin data-x="48.8%" data-y="16.02%">
      <div title="You Are Here">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 0a7.2 7.2 0 0 0-7.27 7.14C4.73 11.08 12 24 12 24s7.27-12.92 7.27-16.86A7.2 7.2 0 0 0 12 0Z"></path></svg>
      </div>
    </div>
    <img class="f-panzoom__content" src="477.png" alt="投火无面者" />
  </div>
</div>
 
<script>
  new Panzoom(document.getElementById("myPanzoomPins"), {
    // Custom options
  }, {
    Pins
  });
</script>

data-panzoom-pin 给图片上打一个 svg,感觉作用不大……

data-x="48.8%" data-y="16.02%" 通过测量得到,案例中将坐标点打在投火无面者的火焰上。

演示

投火无面者

移植一个牛逼的

html
<div class="f-carousel" id="parcelSandbox">
  <div class="f-carousel__slide"><img no-lazy alt="图腾魔像" data-lazy-src="234.png" /></div>
  <div class="f-carousel__slide"><img no-lazy alt="阴燃电鳗" data-lazy-src="223.png" /></div>
  <div class="f-carousel__slide"><img no-lazy alt="投火无面者" data-lazy-src="477.png" /></div>
  <div class="f-carousel__slide"><img no-lazy alt="艾雅 · 黑掌" data-lazy-src="653.png" /></div>
  <div class="f-carousel__slide"><img no-lazy alt="深渊魔物" data-lazy-src="655.png" /></div>
  <div class="f-carousel__slide"><img no-lazy alt="吉恩 · 格雷迈恩" data-lazy-src="665.png" /></div>
  <div class="f-carousel__slide"><img no-lazy alt="海巨人" data-lazy-src="1088.png" /></div>
</div>
 
<style>
  #parcelSandbox {
    height: 450px;
  }
  #parcelSandbox .f-carousel__slide {
    display: flex;
    justify-content: center;
    align-items: center;
    width: clamp(100px, 30vw, 200px);
    height: clamp(100px, 40vw, 300px);
  }
  #parcelSandbox img {
    --x: calc(var(--progress) * 100%);
    --y: calc((var(--progress) + 0.15) * 200%);
    --rot: calc(var(--progress) * 60deg);
    object-fit: cover;
    transform: translate(var(--x), var(--y)) rotate(var(--rot));
    transform-origin: 0% 100%;
    filter: drop-shadow(10px 10px 10px #888);
  }
</style>
 
<script>
  const mapRange = (inputLower, inputUpper, outputLower, outputUpper, value) => {
    const INPUT_RANGE = inputUpper - inputLower;
    const OUTPUT_RANGE = outputUpper - outputLower;
    return (
    outputLower + (((value - inputLower) / INPUT_RANGE) * OUTPUT_RANGE || 0)
    );
  };
  new Carousel(document.getElementById('parcelSandbox'), {
    Dots: false,
    slidesPerPage: 1,
    friction: 0.08,
    on: {
      'refresh Panzoom.beforeTransform': (carousel) => {
        carousel.slides.map((slide) => {
          let slide_progress = carousel.getProgress(slide.index, true);
          slide_progress = mapRange(-1, 1, 1 / 6, -(1 / 6), slide_progress);
          slide.el.style.setProperty('--progress', `${slide_progress}`);
        });
      },
    },
  });
</script>