Javascript JS 3d图像旋转svg/canvas
我想创建这样的图像旋转木马我尝试了许多解决方案,但看起来不太好…:(我试着用css制作3d变换、svg路径和画布上的绘图,但在每个解决方案中,我的结果都很平淡。 也许这里有人对此有什么想法?也许有人知道一些库/框架?我应该使用css、svg或画布 谢谢大家 例如: 使用时:Javascript JS 3d图像旋转svg/canvas,javascript,image,svg,canvas,carousel,Javascript,Image,Svg,Canvas,Carousel,我想创建这样的图像旋转木马我尝试了许多解决方案,但看起来不太好…:(我试着用css制作3d变换、svg路径和画布上的绘图,但在每个解决方案中,我的结果都很平淡。 也许这里有人对此有什么想法?也许有人知道一些库/框架?我应该使用css、svg或画布 谢谢大家 例如: 使用时: CSS body { margin: 0; padding: 0; min-width: 900px; } .carousel { display: flex; justify-content:
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;
}
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, title, 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, title, 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, 14 0",
];
this.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, 14 0",
];
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',
easing: 'cubicBezier(.28,1.43,.52,.99)',
duration: 1500,
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();
JS
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;
}
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, title, 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, title, 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, 14 0",
];
this.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, 14 0",
];
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',
easing: 'cubicBezier(.28,1.43,.52,.99)',
duration: 1500,
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();
class AdvImagesCarousel{
建造师(id){
这是animationFrameTime;
this.id=id;
this.slides=[];
this.default\u slide\u width=649;
this.default\u slide\u height=900;
this.mouse\u start\u move=0;
this.mouse\u is\u down=false;
这是包装纸;
}
添加幻灯片(img_src、标题、url){
var key=this.slides.length;
this.slides[key]=新的AdvImagesCarouselImageSlide(img_src,title,url);
}
calcSizeByWindowWidth(尺寸){
返回$(window).width()*(size/19.20/100);
}
setLayout(){
for(本幻灯片中的变量k){
this.slides[k].setLayout(this.calcsizebyindowwidth(this.default\u slide\u width),this.calcsizebyindowwidth(this.default\u slide\u height));
}
}
init(){
var-k;
var=这个;
this.wrapper=$(“#”+this.id);
for(本幻灯片中的k){
this.wrapper.append(this.slides[k].getCode(this.id+“”+k));
this.slides[k].init(k);
}
这个.setLayout();
$(窗口)。调整大小(函数(){
setLayout();
});
$(“#”+this.id).mousedown(函数(ev){
that.mouse\u is\u down=true;
that.mouse\u start\u move=ev.clientX;
});
$(“#”+this.id).mouseup(函数(ev){
that.mouse\u is\u down=false;
鼠标开始移动=0;
});
$(“#”+this.id).mousemove(函数(ev){
如果(鼠标按下){
var move=ev.clientX-that.mouse\u start\u move;
如果(移动>50){
that.mouse\u is\u down=false;
鼠标开始移动=0;
那.移动幻灯片(1);
}否则,如果(移动<-50){
that.mouse\u is\u down=false;
鼠标开始移动=0;
即:移动幻灯片(-1);
}
}
});
}
移动幻灯片(移动){
var k,幻灯片;
for(本幻灯片中的k){
slide=this.slides[k];
slide.animeToShape((slide.current_pos+move));
}
}
}
类AdvImagesCarouselImageSlide{
构造函数(img\u src、标题、url、父id){
this.parent\u id=parent\u id;
this.img_src=img_src;
this.title=标题;
this.url=url;
这是当前位置=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];
这是默认的形状=[
“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、14 0”,
];
这是一个形状=[
“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、14 0”,
];
这把钥匙;
这个.slide_id;
这个.image\u id;
这是宽度;
这是身高;
}
getCode(键){
如果(!键){
key=this.key;
}
this.key=key;
此.slide\u id=“slide\u”+键;
返回“”+
'' +
'' +
'' +
'' +
' ' +
'' +
'';
}
calcSizeByWindowWidth(尺寸){
返回Math.round($(window.width()*(size/19.20/100));
}
重新计算值(字符串){
var k,val;
for(此.shapesValues中的k){
val=此。形状值[k];
string=string.replace(新的RegExp(“”+val,'g'),“”+this.calcsizebyindowwidth(val));
}
返回字符串;
}
重新计算图表(){
for(此.default_形状中的变量k){
this.shapes[k]=this.recreacteShapeValues(this.default_shapes[k]);
}
}
设置布局(宽度、高度){
这个。宽度=宽度;
高度=高度;
$(“#”+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);
这是。重新计算图像();
此.setShape(此.current_pos);
}
初始(位置){
此。设置形状(位置);
}
设置形状(位置){
if(this.shapes[位置]){
$(“#”+this.slide_id+”.shape').attr('d',this.shapes[position]);
this.current_pos=parseInt(位置);
}
}
动物形状(位置){
var=这个;
if(this.shapes[位置]){
动画({
目标:'#'+that.slide_id+'.shape',
d:[
{value:that.shapes[position]},
],
缓和:“cubicBezier(.28,1.43,52,99)”,
持续时间:1500,
循环:false
});
}
动画({
目标:“#”+t