glide
glide copied to clipboard
3D Transform documentation
I am currently using version 3.x only vanilla js, could you indicate where you can configure the 3D transformation on the elements as you could do in previous versions
Hi, @andreslopezdreams!
I did some research on that and found quite small on that:
As you can see in the screenshot, there's a Translate function in glide.js
but I didn't figure out how it works =(
I also found that as for 3D @jedrzejchalubek uses classes like .frames, .frames__list, .frames__item and .frame
on the promo page glidejs.com that are linked to a specific app.css. There's nothing like that in 'glide.core.css' or 'glide.theme.css'.
Seems like it disappeared from there even it was there =(
I am also interested in 3D Transforms with Glide js. How is it possible to reproduce the promo page slider?
I was attracted by the promo page slider, but I found that I can not do the 3D slider according to the doc, pity
I found this digging through the code inside the demo,
Coverflow: function(e, t, n) {
var i = {
tilt: function(e) {
(e.querySelector(c).style.transform =
'perspective(1500px) rotateY(0deg)'),
this.tiltPrevElements(e),
this.tiltNextElements(e);
},
tiltPrevElements: function(e) {
for (
var t = (function(e) {
var t = [];
if (e)
for (; (e = e.previousElementSibling); )
t.push(e);
return t;
})(e),
n = 0;
n < t.length;
n++
) {
var i = t[n].querySelector(c);
(i.style.transformOrigin = '100% 50%'),
(i.style.transform =
'perspective(1500px) rotateY(' +
20 * Math.max(n, 2) +
'deg)');
}
},
tiltNextElements: function(e) {
for (
var t = (function(e) {
var t = [];
if (e)
for (; (e = e.nextElementSibling); ) t.push(e);
return t;
})(e),
n = 0;
n < t.length;
n++
) {
var i = t[n].querySelector(c);
(i.style.transformOrigin = '0% 50%'),
(i.style.transform =
'perspective(1500px) rotateY(' +
-20 * Math.max(n, 2) +
'deg)');
}
}
};
return (
n.on(['mount.after', 'run'], function() {
i.tilt(t.Html.slides[e.index]);
}),
i
);
}
It sounds like this is a custom plugin that was made, it's uglified, but I don't think its so bad that someone couldn't decipher it
Hello! I want made Coverflow effects but i didn't find any informations about this. Could you help me please?
I agree it's a bit odd to have something in the demo that isn't easily reproduced from the docs.
I was looking for a fix for this as well, couldn't find anything about it in the docs so I decided to recreate it from scratch (using the uglified code as an example).
This is my HTML structure, using .glide__container as my transformable container.
<div class="glide">
<div data-glide-el="track" class="glide__track">
<ul class="glide__slides">
<li class="glide__slide">
<div class="glide__container">
</div>
</li>
<li class="glide__slide">
<div class="glide__container">
</div>
</li>
<li class="glide__slide">
<div class="glide__container">
</div>
</li>
<li class="glide__slide">
<div class="glide__container">
</div>
</li>
<li class="glide__slide">
<div class="glide__container">
</div>
</li>
<li class="glide__slide">
<div class="glide__container">
</div>
</li>
</ul>
</div>
</div>
This is all the CSS i've used, using a black border around the container for testing purposes.
.glide__slides {
overflow: visible;
transform-style: preserve-3d;
}
.glide__slide {
transform: perspective(2000px);
}
.glide__container {
border: 2px solid #000;
border-radius: 4px;
width: 200px;
height: 200px;
transition: all 500ms ease;
will-change: transform;
transform-style: preserve-3d;
position: relative;
}
Now for the fun part, I've created a custom plugin that does the tilting based on the currently active slide. It's nowhere near perfect, but it should be a good starting point for anyone who's trying to achieve the same result. Keep in mind that this only works for the 'slider' type, as the clones that glide creates when using carousel mode interfere with the transforming.
const glider = new Glide('.glide', {
autoplay: 10000,
type: 'slider',
perView: 5,
focusAt: 'center'
});
// The classname for the element that gets transformed
const tiltableElement = '.glide__container';
glider.mount({
Coverflow: (Glide, Components, Events) => {
const Plugin = {
tilt (element) {
element.querySelector(tiltableElement).style.transform = "perspective(1500px) rotateY(0deg)";
this.tiltPrevElements();
this.tiltNextElements();
},
tiltPrevElements () {
const activeSlide = Components.Html.slides[Glide.index];
const previousElements = [];
const getPrevious = (element) => {
const e = element.previousElementSibling;
if (e) {
previousElements.push(e.querySelector(tiltableElement));
getPrevious(e);
}
};
getPrevious(activeSlide);
previousElements.forEach((item, index) => {
item.style.transformOrigin = "100% 50%";
item.style.transform = `perspective(1500px) rotateY(${20 * Math.max(index, 2)}deg)`
})
},
tiltNextElements () {
const activeSlide = Components.Html.slides[Glide.index];
const nextElements = [];
const getNext = (element) => {
const e = element.nextElementSibling;
if (e) {
nextElements.push(e.querySelector(tiltableElement));
getNext(e);
}
};
getNext(activeSlide);
nextElements.forEach((item, index) => {
item.style.transformOrigin = "0% 50%";
item.style.transform = `perspective(1500px) rotateY(${-20 * Math.max(index, 2)}deg)`
})
}
}
Events.on(['mount.after', 'run'], () => {
Plugin.tilt(Components.Html.slides[Glide.index]);
});
return Plugin;
}
});
I found the relative css in the download that makes the 3D transformation. It's far from ideal, but works. No Javascript required.
Find the file "docs/assets/css/main.css" Then just look for "glider-persp" classes and copy those.
Give your glider container that class, and you're good to go.
Hi @AvanOsch
Find the file "docs/assets/css/main.css" Then just look for "glider-persp" classes and copy those.
Looked everywhere on GitHub and Gliderjs.com and could not find "main.css". Any ideas or help would be greatly appreciated!
@Numinous It's been a while, so I don't remember exactly... Maybe you'll have to build it first?
You could also try and get the source code from glidejs.com (maybe glidejs.com/css/app.css) and use the homepage's example to work from...
Good luck!
@AvanOsch - ah yes it has been a while and thanks so much for circling back after so long! I haven't tried building it first - will do. I found the CodePen for the actual promo used on the GlideJS home page. In case you or anyone else is interested: https://codepen.io/smuglovsky/pen/RJBqpR
You can do it with just a little bit of CSS. No JS.
/* Rotate all */ .glide__slide { transform: perspective(600px) rotateY(20deg); transition: all ease-in-out 0.35s; }
/* Make the active one straight */ .glide__slide--active { transform: perspective(600px) rotateY(0deg); }
/* Give opposite rotation to slides after the active one */ .glide__slide--active ~ .glide__slide { transform: perspective(600px) rotateY(-20deg); }
Example: https://codepen.io/Jovan-Ralic/pen/ZEjbQKM
Agree that it is weird that the API docs for mount()
don't mention the Extensions object parameter.
...But that is the nice thing about open source...
Here is the mount()
function you call to initialize Glide. It defaults the Extensions parameter to an empty object ({}
) and ultimately calls another mount()
function in core/index.js
. So this "feature" is called "extensions" in the source.
That second mount()
function is where the behaviour of the Extensions is easily discernible.
- iterate the keys in the extensions object (doesn't care what the keys are)
- the value for each key MUST be type
function
- each extension function is called passing parameters:
glide
,components
,events
-
glide
is the Glide object -
components
is an object containing the RESULT (by name) of calling each extension function. This allows individual extensions/components to interact with others. -
events
is theGlide
event bus
-
- the value for each key MUST be type
finally, after all the extension functions have been called and resulting object/function stored into components object by name... the components are iterated and the ones that have a mount()
function are called. I guess this provides a signal to say: "all components have been initialized" in case one component wants to talk to another.
So in the simplest case if you you don't care about your components talking to each other you can just provide object of functions (keys arbitrary) that take Glide, components, eventbus and then listen for events and do certain things. They don't need to return any API in that case.
If you want components to talk to each other, they need to know each others' names/APIs and return an object with a mount function and wait for the mount function before calling other components APIs.
Example
So something like this would have 2 (useless) components that initialize and talk to each other after both are initialized.
const extensions = {
foo: function (glide, components, eventBus) {
console.log('foo initialized');
return {
mount: function () {
console.log('foo mount was called.');
components['bar'].myApi('hello from foo');
},
myApi: function () {
console.log('foo myApi was called');
console.log.apply(null, arguments);
},
};
},
bar: function (glide, components, eventBus) {
console.log('bar initialized');
return {
mount: function () {
console.log('bar mount was called.');
components['foo'].myApi('hello from bar');
},
myApi: function () {
console.log('bar myApi was called');
console.log.apply(null, arguments);
},
};
},
};
new Glide('#slider-container', {
type: 'slider',
focusAt: 'center',
perView: 3
}).mount(extensions);
...will result in the following console output:
foo initialized
bar initialized
foo mount was called.
bar myApi was called
hello from foo
bar mount was called.
foo myApi was called
hello from bar
by the way... it is in the docs
Not sure why the API Docs for mount()
don't mention/link to it...but extensions are documented here:
https://glidejs.com/docs/extending-components/
in addition to the extensions/components there is a very similar "transformer" extensions documented here...
https://glidejs.com/docs/extending-transformers/
It is odd that this issue sits open even though it is documented. The only "fix" would be to mention the extensions object on the API page and link to the extending-components page for details.