如何解决JS 3D图像轮播SVG /画布
我想创建像这样的图像轮播https://throwbacks-music.com/,我尝试了许多解决方案,但看起来效果不佳... :(我尝试在具有3d变换,svg路径的css中进行绘制,并在画布上绘制,但是在每种解决方案上我的结果是如此平坦。 也许有人对此有想法吗?也许有人知道一些图书馆/框架?我应该使用css,svg还是canvas?
谢谢
示例:https://jsfiddle.net/ars001/erzgvotd/9/
配合使用:
- https://cdn.jsdelivr.net/npm/animejs@3.2.0/lib/anime.min.js
- https://code.jquery.com/jquery-3.5.0.min.js
CSS
body {
margin: 0;
padding: 0;
min-width: 900px;
}
.carousel {
display: flex;
justify-content: space-between;
margin: 0 -33px 0 -14px;
padding: 0;
}
.carousel svg:nth-child(2) {
margin-left: -21px;
}
JS
class AdvImagesCarousel{
constructor(id){
this.animationFrameTime;
this.id = id;
this.slides = [];
this.default_slide_width = 649;
this.default_slide_height = 900;
this.mouse_start_move = 0;
this.mouse_is_down = false;
this.wrapper;
}
addSlide(img_src,title,url){
var key = this.slides.length;
this.slides[key] = new AdvImagesCarouselImageSlide(img_src,url);
}
calcSizeByWindowWidth(size){
return $(window).width() * (size / 19.20 / 100);
}
setLayout(){
for(var k in this.slides){
this.slides[k].setLayout( this.calcSizeByWindowWidth(this.default_slide_width),this.calcSizeByWindowWidth(this.default_slide_height) );
}
}
init(){
var k;
var that = this;
this.wrapper = $("#" + this.id);
for(k in this.slides){
this.wrapper.append( this.slides[k].getCode(this.id + "_" + k) );
this.slides[k].init(k);
}
this.setLayout();
$(window).resize(function(){
that.setLayout();
});
$("#" + this.id).mousedown(function(ev){
that.mouse_is_down = true;
that.mouse_start_move = ev.clientX;
});
$("#" + this.id).mouseup(function(ev){
that.mouse_is_down = false;
that.mouse_start_move = 0;
});
$("#" + this.id).mousemove(function(ev){
if(that.mouse_is_down){
var move = ev.clientX - that.mouse_start_move;
if(move > 50){
that.mouse_is_down = false;
that.mouse_start_move = 0;
that.moveSlide(1);
}else if(move < -50){
that.mouse_is_down = false;
that.mouse_start_move = 0;
that.moveSlide(-1);
}
}
});
}
moveSlide(move){
var k,slide;
for(k in this.slides){
slide = this.slides[k];
slide.animetoShape( (slide.current_pos + move) );
}
}
}
class AdvImagesCarouselImageSlide{
constructor(img_src,url,parent_id){
this.parent_id = parent_id;
this.img_src = img_src;
this.title = title;
this.url = url;
this.current_pos = 0;
this.shapesValues = [7,14,642,630,634,320,20,622,480,613,714,464,718,265,725,760,356,649,637,272,706,712,27,390,616,305,326,727];
this.default_shapes = [
"M 14 0 L 613 0 C 634 320,622 480,613 714 C 464 718,265 725,14 760 C 14 356,14 356,14 0","M 7 0 L 642 0 C 630 356,630 356,642 712 C 265 706,265 706,7 712 C 20 356,20 356,7 0","M 14 0 L 616 0 C 616 390,616 390,616 760 C 305 727,326 727,14 714 C 0 356,0 356,];
this.shapes = [
"M 14 0 L 613 0 C 634 320,];
this.key;
this.slide_id;
this.image_id;
this.width;
this.height;
}
getCode(key){
if(!key){
key = this.key;
}
this.key = key;
this.slide_id = "slide_"+key;
return '<svg width="1" height="1" id="'+this.slide_id+'">' +
'<defs>' +
'<pattern class="img" id="img_'+this.slide_id+'" patternUnits="userSpaceOnUse" width="1" height="1" x="0" y="0">' +
'<image href="'+this.img_src+'" x="0" y="0" width="100%" height="100%" preserveAspectRatio="xMidYMin slice" />' +
'</pattern>' +
'</defs> ' +
'<path class="shape" fill="url(#img_'+this.slide_id+')" d=""/>' +
'</svg>';
}
calcSizeByWindowWidth(size){
return Math.round($(window).width() * (size / 19.20 / 100));
}
recalculateShapeValues(string){
var k,val;
for(k in this.shapesValues){
val = this.shapesValues[k];
string = string.replace(new RegExp(' '+val,'g'),' '+this.calcSizeByWindowWidth(val));
}
return string;
}
recalculateShapes(){
for(var k in this.default_shapes){
this.shapes[k] = this.recalculateShapeValues(this.default_shapes[k]);
}
}
setLayout(width,height){
this.width = width;
this.height = height;
$('#' + this.slide_id).attr('width',width);
$('#' + this.slide_id).attr('height',height);
$('#' + this.slide_id + ' .img').attr('width',width);
$('#' + this.slide_id + ' .img').attr('height',height);
this.recalculateShapes();
this.setShape(this.current_pos);
}
init(position){
this.setShape(position);
}
setShape(position){
if(this.shapes[position]){
$('#' + this.slide_id + ' .shape').attr('d',this.shapes[position]);
this.current_pos = parseInt(position);
}
}
animetoShape(position){
var that = this;
if(this.shapes[position]){
anime({
targets: '#'+that.slide_id+' .shape',d: [
{ value: that.shapes[position] },],easing: 'cubicBezier(.28,1.43,.52,.99)',duration: 1500,loop: false
});
}
anime({
targets: '#'+that.slide_id,translateX: that.width+20+'px',loop: false
});
this.current_pos = parseInt(position);
}
}
var carousel = new AdvImagesCarousel("carousel");
carousel.addSlide("https://upload.wikimedia.org/wikipedia/commons/9/99/InsSight_spacecraft_appendix_gallery_Image_55-full.jpg","Title 1","#url_1");
carousel.addSlide("https://www.w3schools.com/w3css/img_forest.jpg","Title 2","#url_2");
carousel.addSlide("https://www.gettyimages.pt/gi-resources/images/Homepage/Hero/PT/PT_hero_42_153645159.jpg","Title 3","#url_3");
carousel.init();
HTML
<!DOCTYPE html>
<html>
<head>
<Meta name="viewport" content="width=device-width,initial-scale=1">
<Meta charset="UTF-8" />
<title>svg anim</title>
</head>
<body>
<div class="carousel" id="carousel"></div>
</body>
</html>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。