专栏首页蚂蚁开源社区碉堡了,基于HTML5 WebGL的图像扭曲变形动画开源特效

碉堡了,基于HTML5 WebGL的图像扭曲变形动画开源特效

简要说明

这是一款基于HTML5 WebGL的图像扭曲变形动画特效。该特效中,通过Three.js来制作从一幅缩略图,扭曲变形为全屏大图的动画特效,共有6种炫酷的动画效果。

该特效提供了一个控制面板来控制图像扭曲的动画,你可以自行调节效果。

实现方法

HTML结构

<div id="app"></div>
<div id="itemsWrapper">
    <figure class="grid__item">
        <img class="grid__item-img" src="img/1.jpg" alt="An image" />
        <img class="grid__item-img grid__item-img--large" src="img/1_large.jpg" />
        <figcaption class="grid__item-caption">
            <h2 class="grid__item-title">Our Item Title</h2>
            <p class="grid__item-text">
                Our Item Description
            </p>
        </figcaption>
    </figure>
    ...
</div>

引入base.css

#cdawrap .carbon-text {
    --cda-text-color: #aba1a6;
    padding: 0.25rem 0 0.75rem;
    display: block;
    line-height: 1.4;
    font-weight: 700;
    font-weight: var(--cda-text-weight);
    text-decoration: none;
    text-transform: none;
    letter-spacing: 0px;
    border: 0;
}

body #cdawrap {
        --cda-left: 2rem;
    --cda-right: auto;
    --cda-top: auto;
    --cda-bottom: 6rem;
    z-index: 1;
}

*,
*::after,
*::before {
        box-sizing: border-box;
}

:root {
        font-size: 15px;
}

body {
        margin: 0;
        --color-text: #615d5d;
    --color-bg: #121217;
    --color-link: #aba1a6;
    --color-link-hover: #fff;
    --color-info: #f58a4e;
        color: var(--color-text);
        background-color: var(--color-bg);
        font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
        font-weight: 600;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        overflow: hidden;
}

.dg .title {
    transition: background-color 300ms ease-out;
}

.shine {
        transition: background-color 100ms ease-out !important;
    background-color: #fff !important; 
}

#app {
        top: 0;
        left: 0;
        position: fixed;
        width: 100vw;
        height: 100vh;
        overflow: hidden;
}

#app:hover {
        cursor: pointer;
}

.dg.ac {
        z-index: 99999 !important;
}

/* Page Loader */
.js .loading::before {
        content: '';
        position: fixed;
        z-index: 100000;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: var(--color-bg);
}

.js .loading::after {
        content: '';
        position: fixed;
        z-index: 100000;
        top: 50%;
        left: 50%;
        width: 60px;
        height: 60px;
        margin: -30px 0 0 -30px;
        pointer-events: none;
        border-radius: 50%;
        opacity: 0.4;
        background: var(--color-link);
        animation: loaderAnim 0.7s linear infinite alternate forwards;
}

@keyframes loaderAnim {
        to {
                opacity: 1;
                transform: scale3d(0.5,0.5,1);
        }
}

a {
        text-decoration: none;
        color: var(--color-link);
        outline: none;
}

a:hover,
a:focus {
        color: var(--color-link-hover);
        outline: none;
}

.frame {
        padding: 3rem 5vw;
        text-align: center;
        position: relative;
        z-index: 1000;
}

.frame__title {
        font-size: 1rem;
        margin: 0 0 1rem;
}

.frame__tagline {
        color: var(--color-info);
}

.frame__links {
        display: inline;
}

.frame a {
        text-transform: lowercase;
}

.frame__links a:not(:last-child),
.frame__demos a:not(:last-child) {
        margin-right: 1rem;
}

.frame__demos {
        margin: 1rem 0;
}

.frame__demo--current,
.frame__demo--current:hover {
        color: var(--color-text);
}

.content {
        display: flex;
        flex-direction: column;
        width: 100vw;
        height: calc(100vh - 13rem);
        position: relative;
        justify-content: flex-start;
        align-items: center;
}

.content__img {
        width: 500px;
        max-width: 100%;
        display: block;
        cursor: pointer;
}

.content__img--large {
        pointer-events: none;
        position: fixed;
        opacity: 0;
}

@media screen and (min-width: 53em) {
        .frame {
                position: fixed;
                text-align: left;
                z-index: 10000;
                top: 0;
                left: 0;
                display: grid;
                align-content: space-between;
                width: 100%;
                max-width: none;
                height: 100vh;
                padding: 3rem;
                pointer-events: none;
                grid-template-columns: 50% 50%;
                grid-template-rows: auto auto auto;
                grid-template-areas: 'title ...'
                                                        '... ...'
                                                        'links demos';
        }
        .frame__title-wrap {
                grid-area: title;
                display: flex;
        }
        .frame__title {
                margin: 0;
        }
        .frame__tagline {
                position: relative;
                margin: 0 0 0 1rem;
                padding: 0 0 0 1rem;
                opacity: 0.5;
        }
        .frame__demos {
                margin: 0;
                grid-area: demos;
                justify-self: end;
        }
        .frame__links {
                grid-area: links;
                padding: 0;
                justify-self: start;
        }
        .frame a {
                pointer-events: auto;
        }
        .content {
                height: 100vh;
                justify-content: center;
        }
}

引入javascript

 <script src="js/imagesloaded.pkgd.min.js"></script>
 <script src="js/three.min.js"></script>
 <script src="js/TweenLite.min.js"></script>
 <script src="js/CSSPlugin.min.js"></script>
 <script src="js/EasePack.min.js"></script>
 <script src="js/dat-gui.min.js"></script>
 <script src="js/Configurator.js"></script>
 <script src="js/GridToFullscreenEffect.js"></script>
 <script src="js/basicDemo.js"></script>
  <script>
                        const itemsWrapper = document.getElementById('items-wrap');

                        const configurator = createDemoConfigurator({
                                activation: { type: "side", props: { top: true, bottom: true} },
                                timing: {
                                        type: "sections",
                                        props: {
                                                sections: 4,
                                        }
                                },
                                transformation: {type: 'simplex'},        
                                duration: 1.8,
                                easings: {
                                        toFullscreen: Cubic.easeInOut,
                                        toGrid: Cubic.easeInOut
                                }
                                
                        })
                imagesLoaded(document.querySelectorAll("img"), instance => {

                        //https://www.techrepublic.com/article/preloading-and-the-javascript-image-object/
                        document.body.classList.remove("loading");
                        let images = [];
                                for (var i = 0, imageSet = {}; i < instance.elements.length; i++) {
                                        let image = {
                                                element: instance.elements[i],
                                                image: instance.images[i].isLoaded ? instance.images[i].img : null
                                        };
                                        if (i % 2 === 0) {
                                                imageSet = {};
                                                imageSet.small = image;
                                        }

                                        if (i % 2 === 1) {
                                                imageSet.large = image;
                                                images.push(imageSet);
                                        }
                                }
                                configurator.effect.createTextures(images);
                        });
</script>

作者 | 思齐 | 蚂蚁开源社区大神,资深开发工程师

本文分享自微信公众号 - 蚂蚁开源社区(mayi_zzfriend),作者:思齐大神

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 又到公司年会时,给公司写的年会抽奖程序!

    用户5997198
  • 基于WebGL的超逼真仿透明液体流动变形效果教程

    这是一款基于WebGL的超逼真液体流动变形效果。该效果使用PixiJS和GSAP来制作,以轮播图的方式来展现不同类型的液体流动变形效果。液体流动变形效果共5组...

    用户5997198
  • 如何使用JavaScript来判断是否为移动设备?

      由于移动设备的显示屏幕相对于桌面显示器来说小很多,在桌面显示器上能够正常显示的内容,到了移动设备中就不正常了。为了实现移动端和桌面端的相互跳转,我们可以通过...

    用户5997198
  • 学前端这个事儿,你是怎么个打算呢?

    这是我和一个同学的聊天截图,聊天内容很有代表性,就是知道要学习,知道要努力,但是,然后会怎么样?并不是很清楚。图中的这个哥们已经毕业有一些年头了,但他在面对跨行...

    web前端教室
  • 一:打包JS

    创建vendor文件夹,其中minus.js、multi.js和sum.js分别用 CommonJS、AMD 和 ES6 规范编写。

    心谭博客
  • 算法一看就懂之「 选择排序 」

    上一篇文章咱们已经聊过「 冒泡排序 」和「 插入排序 」了,今天我们来看一看「 选择排序 」。「 选择排序 」虽然在实际应用中没有「 插入排序 」广泛,但它也是...

    奎哥
  • 八:JS Tree Shaking

    是的,在webpack v4中,不再需要配置UglifyjsWebpackPlugin。(详情请见:文档) 取而代之的是,更加方便的配置方法。

    心谭博客
  • 前端必备javascript书籍测评【含红宝书和绿皮书】

    大家好,我是大圣,今天给大家带来期待已久的javascript书籍测评,工作者9年多看过的js书大部分都在这了,会分成这几个部分来推荐

    若川
  • 小白要学好Web前端,要从哪里入手?

    要说目前IT行业需求量最大的岗位是什么,Web前端工程师一定有姓名。Web前端工程师绝对是近几年火爆而且高薪的职业之一,当然,不同的公司也有不同的叫法,比如:网...

    用户5827212
  • Ionic4兼容IE浏览器处理

    在一般场合,Ionic4运行在手机端,没必要去兼容IE,但还是可以了解一下,以免有这样的需求。 Ionic4,它更趋向于一个UI框架,然后可配套Angular...

    IT晴天

扫码关注云+社区

领取腾讯云代金券