JavaScript hands-on practice: SVG-based picture switching effect

I have been too busy recently. After I came to rjxy automatically, I don’t know what’s going on.

Yesterday another classmate told me that you haven't updated your blog for a long time. .

Very ashamed~~

It just happened in December, and I opened an article today.

I recently talked about SVG in class, but I don’t know if the students understand it. -_-!!!

There are too many picture carousels. Today I wrote a picture carousel in SVG. The effect is as follows.

Effect requirements

Click the control block to switch the picture. When switching, use a circle as a mask, which changes from small to large. Every time you switch, the position of the circle is randomly generated.

Main knowledge points

1. SVG cropping (masking), the use of clip-path .

2. SVG uses JS to change the hierarchy. Because SVG does not support CSS z-index to change the level, it will always only let the back tags cover the front tags.

Therefore, I use the appendChild method of JS to move the displayed image to the end of the SVG every time I am so smart.

 // 更改当前图片的层级为最顶层,也就是放到 SVG 的最后,它会覆盖前面的图片。
bannerSvg.appendChild( pic[index ]);

3. To enlarge the circle, I use the  requestAnimationFrame method. It saves too much resources than traditional timers setInterval and setTimeout. You can download it on Baidu.

4. Control block, the DOM used is dynamically generated according to the number of pictures displayed.

HTML code

<svg width="700" height="393" id="banner">
    <defs>
       <clipPath id="c1">
           <circle id="circle"  cx="350" cy="196" r="20"></circle>
       </clipPath >
    </defs>
    <a class="banner_img"  xlink:href="https://www.baidu.com">
        <image x="0" y="0" xlink:href="images/1.jpg"></image>
    </a>
    <a class="banner_img" xlink:href="https://www.sina.com.cn">
        <image  x="0" y="0" xlink:href="images/2.jpg"></image>
    </a>
    <a class="banner_img" xlink:href="https://www.sohu.com.cn">
        <image x="0" y="0"  xlink:href="images/3.jpg"></image>
    </a>
</svg>
<ul id="ul" class="ul">
 <!-- 空着,等 js 动态生成 -->
</ul>

CSS code

.ul {
    display: flex;
    list-style: none;
}
.ul li{
    background: #eee;
    padding-left: 20px;
    padding-right: 20px;
    margin-left: 4px;
    margin-right: 4px;
}
.ul .on{
    background: #f30;
    color: #fff;
}

JavaScript code

let nowpic = 0 ;
let myani = null;
let radius = 0;
// 找标签
let bannerSvg = document.getElementById("banner");
let circle = document.getElementById("circle");
let ul = document.getElementById("ul");
let li = [];
let pic = bannerSvg.querySelectorAll(".banner_img");
// 控制块初始化。
for( let i=0 ; i <= pic.length-1 ; i++ ){
    // 生成 li 标签
    let childLi = document.createElement("li");
    // 添加 li 内容,为当前数字
    childLi.innerHTML = i+1 ;
    // 把 li 分别放入 ul 标签 和 数组 li 中。
    ul.appendChild(childLi);
    li.push(childLi);
}
li[0].classList.add("on");
// 遮罩圆动画
let circleAni = function(){
    console.info(radius);
    radius += 20;
    radius = Math.min(800, radius);
    circle.style.r = radius +"px";
    myani = requestAnimationFrame(circleAni);
    if( radius >= 800 ){
        cancelAnimationFrame( myani );
    }
};
// 显示图片的函数
let showPic = function(index){
    for(let i=0 ; i<=pic.length-1 ; i++ ){
        // 控制块变化
        li[i].classList.remove("on");
        // 不显示的图片不需要遮罩。
        pic[i].children[0].setAttribute("clip-path","");
    }
    // 更改当前图片的层级为最顶层,也就是放到 SVG 的最后,它会覆盖前面的图片。
    bannerSvg.appendChild( pic[index ]);
    // 退出上一步动画
    cancelAnimationFrame( myani );
    // 遮罩圆半径初始化为 0
    radius = 0 ;
    circle.style.r = radius+"px";
    // 遮罩圆的圆心(也就是位置)随机。
    circle.setAttribute("cx",Math.random()*700);
    circle.setAttribute("cy",Math.random()*303);
    // 给指定的图片添加遮罩 clip-path
    pic[index].children[0].setAttribute("clip-path","url(#c1)");
    // 执行 circle 动画
    myani = requestAnimationFrame(circleAni);  // circle 动画

    // 控制块的变化
    li[index].classList.add("on");
}

showPic(0); //  默认显示第一张
for( let i=0 ; i<= li.length-1 ; i++ ){
    li[i].addEventListener("click",function(){
        showPic(i);
    });
}

 

Guess you like

Origin blog.csdn.net/weixin_42703239/article/details/111126451