资源
-
Fancyapps UI - Robust JavaScript UI Component Library | Fancyapps 官网。
-
Showcase | Fancyapps 这里有 fancyapp 的使用示例。
正文
Fancybox
引入
从 Releases · fancyapps/ui (github.com) 引入 fancybox.umd.js 和 fancybox.css:
<script src="fancybox.umd.js"></script>
<link rel="stylesheet" href="fancybox.css" />请注意,这种方法的缺点是,每次要将文件更新到最新版本时,都必须执行此操作。
因此,推荐的方法是使用 NPM 等包管理器或使用 CDN 链接,这些链接将自动使用最新的补丁版本而不会影响您的代码。
使用
<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:
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)
一般来说,没啥好设置的……
效果
Carousel
引入
<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:
<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 的样式 :
.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 样式了。
注册对象:
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。
引入
<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"
/>使用
创建对象:
<div class="f-panzoom" id="myPanzoom" style="background: #ff000020;">
<img class="f-panzoom__content" src="665.png" alt="吉恩 · 格雷迈恩"/>
</div>设置 CSS,如果 panzoom 里的元素实际大小大于所设定的大小,则会在渲染的时候自适应大小,而在鼠标移过去时缩放到原大小。
#myPanzoom {
height: 300px;
}注册对象:
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.js 和 panzoom.toolbar.css 并引入。
使用
<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.js 和 panzoom.pins.css 并引入。
使用
<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%" 通过测量得到,案例中将坐标点打在投火无面者的火焰上。
演示
移植一个牛逼的
<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>


