prev-next chapitre. read more arrow

This commit is contained in:
2026-02-19 16:41:43 +01:00
parent ca2a70f1b8
commit c821e49519
9 changed files with 308 additions and 157 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
<svg width="35" xmlns="http://www.w3.org/2000/svg" height="35" id="screenshot-52808c91-ee87-8059-8007-0f133be402ff" viewBox="0 0 35 35" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1"><g id="shape-52808c91-ee87-8059-8007-0f133be402ff" rx="0" ry="0"><g id="shape-52808c91-ee87-8059-8007-0f133be40302"><g class="fills" id="fills-52808c91-ee87-8059-8007-0f133be40302"><ellipse cx="17.5" cy="17.5" rx="17.5" ry="17.5" transform="matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)" style="fill: rgb(22, 66, 188); fill-opacity: 1;"/></g></g><g id="shape-52808c91-ee87-8059-8007-0f133be40303"><g class="fills" id="fills-52808c91-ee87-8059-8007-0f133be40303"><path d="M16.288759231567383,22.555646896362305L16.288759231567383,7.812972068786621L18.710634231567383,7.812972068786621L18.710634231567383,22.555646896362305L25.491884231567383,15.774886131286621L27.187196731567383,17.500471115112305L17.499696731567383,27.187971115112305L7.812196731567383,17.500471115112305L9.507509231567383,15.774886131286621L16.288759231567383,22.555646896362305Z" style="fill: rgb(255, 255, 255);"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1 @@
<svg width="35" xmlns="http://www.w3.org/2000/svg" height="35" id="screenshot-22989948-29ed-804e-8007-28b5a726c6cf" viewBox="0 0 35 35" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1"><g id="shape-22989948-29ed-804e-8007-28b5a726c6cf" rx="0" ry="0"><g id="shape-22989948-29ed-804e-8007-28b5a726c6d4"><g class="fills" id="fills-22989948-29ed-804e-8007-28b5a726c6d4"><ellipse cx="17.5" cy="17.5" rx="17.5" ry="17.5" transform="matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)" style="fill: rgb(255, 255, 255); fill-opacity: 1;"/></g></g><g id="shape-22989948-29ed-804e-8007-28b5a726c6d5"><g class="fills" id="fills-22989948-29ed-804e-8007-28b5a726c6d5"><path d="M22.5556640625,18.7113037109375L7.81298828125,18.7113037109375L7.81298828125,16.2896728515625L22.5556640625,16.2896728515625L15.77490234375,9.5079345703125L17.50048828125,7.8131103515625L27.18798828125,17.5006103515625L17.50048828125,27.1878662109375L15.77490234375,25.4920654296875L22.5556640625,18.7113037109375Z" style="fill: rgb(22, 66, 188);"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@@ -25,65 +25,38 @@
inkscape:pagecheckerboard="0" inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" inkscape:deskcolor="#d1d1d1"
inkscape:zoom="2.9820571" inkscape:zoom="2.9820571"
inkscape:cx="130.27919" inkscape:cx="130.2792"
inkscape:cy="168.67551" inkscape:cy="168.67551"
inkscape:window-width="1920" inkscape:window-width="1920"
inkscape:window-height="1149" inkscape:window-height="1029"
inkscape:window-x="0" inkscape:window-x="0"
inkscape:window-y="0" inkscape:window-y="0"
inkscape:window-maximized="1" inkscape:window-maximized="1"
inkscape:current-layer="screenshot-d8ccbdb6-0d67-80f5-8007-0f486309a42a" /> inkscape:current-layer="screenshot-d8ccbdb6-0d67-80f5-8007-0f486309a42a" />
<g
id="shape-d8ccbdb6-0d67-80f5-8007-0f486309a42a"
rx="0"
ry="0"
transform="translate(16.43161,-17.772966)">
<g
id="shape-d8ccbdb6-0d67-80f5-8007-0f486309a42b">
<g <g
class="fills" class="fills"
id="fills-d8ccbdb6-0d67-80f5-8007-0f486309a42b" id="fills-d8ccbdb6-0d67-80f5-8007-0f486309a42b"
style="fill:#ffffff;fill-opacity:1;stroke-opacity:1"> style="fill:#ffffff;fill-opacity:1;stroke-opacity:1"
transform="translate(16.43161,-17.772966)">
<path <path
d="M 194.34372,127.27941 63.900356,4.0450368 2.6562154,172.72058 133.09958,295.9552 194.34372,127.27941 v 0" d="M 194.34372,127.27941 63.900356,4.0450368 2.6562154,172.72058 133.09958,295.9552 194.34372,127.27941 v 0"
style="fill:#ffffff;fill-opacity:1;stroke-dasharray:6, 6;stroke-dashoffset:0;stroke-opacity:1" style="fill:#ffffff;fill-opacity:1;stroke-dasharray:6, 6;stroke-dashoffset:0;stroke-opacity:1"
id="path1" /> id="path1" />
</g> </g>
</g>
<g
id="shape-d8ccbdb6-0d67-80f5-8007-0f486309a42c">
<g <g
class="fills" class="fills"
id="fills-d8ccbdb6-0d67-80f5-8007-0f486309a42c"> id="fills-d8ccbdb6-0d67-80f5-8007-0f486309a42c"
transform="translate(16.43161,-17.772966)"
style="stroke-dasharray:6,6;stroke-dashoffset:0">
<path <path
d="m 64.296837,5.7176442 45.140133,123.5798458 24.4961,166.4602" d="m 64.296837,5.7176442 45.140133,123.5798458 24.4961,166.4602"
id="path2" /> id="path2"
</g> style="stroke-dasharray:6,6;stroke-dashoffset:0" />
<g
id="strokes-2cdddd35-cea9-805d-8007-9147f4aed317-d8ccbdb6-0d67-80f5-8007-0f486309a42c"
class="strokes">
<g
class="stroke-shape"
id="g3">
<path
d="m 64.296837,5.7176442 45.140133,123.5798458 24.4961,166.4602"
style="fill:none;stroke-width:1;stroke-dasharray:6, 6;stroke-dashoffset:0;stroke-opacity:1"
id="path3" />
</g>
</g>
</g>
<g
id="shape-d8ccbdb6-0d67-80f5-8007-0f486309a42d">
<g
class="fills"
id="fills-d8ccbdb6-0d67-80f5-8007-0f486309a42d">
<path
d="M 4.6205711,173.57971 110.0317,131.80676 l 83.57764,-3.91163"
id="path4" />
</g> </g>
<g <g
id="strokes-2cdddd35-cea9-805d-8007-9147f4af12eb-d8ccbdb6-0d67-80f5-8007-0f486309a42d" id="strokes-2cdddd35-cea9-805d-8007-9147f4af12eb-d8ccbdb6-0d67-80f5-8007-0f486309a42d"
class="strokes"> class="strokes"
transform="translate(16.43161,-17.772966)">
<g <g
class="stroke-shape" class="stroke-shape"
id="g5"> id="g5">
@@ -93,6 +66,4 @@
id="path5" /> id="path5" />
</g> </g>
</g> </g>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

@@ -98,14 +98,14 @@ gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
// console.log('container', container); // console.log('container', container);
// listes all available sizes // listes all available sizes
let min = 150; // let min = 150;
let increment = Math.round((350 / (formesclasses.length -1))); // let increment = Math.round((350 / (formesclasses.length -1)));
for (let i = 0; i < formesclasses.length; i++) { // for (let i = 0; i < formesclasses.length; i++) {
sizes.push( min + increment * i) // sizes.push( min + increment * i)
} // }
// console.log('sizes', sizes); // console.log('sizes', sizes);
let cards = document.querySelectorAll('.field-card, .node-type-chapitre, .node-type-partie'); let cards = document.querySelectorAll('article[role="home-presentation"], .field-card, .node-type-chapitre, .node-type-partie');
// console.log('cards', cards); // console.log('cards', cards);
let used_n = []; let used_n = [];
let oddeven=1; let oddeven=1;
@@ -152,6 +152,7 @@ gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
// }, // },
} }
}) })
// cards opacity
.from(card.children, { .from(card.children, {
opacity: 0.4, opacity: 0.4,
}, 0) }, 0)
@@ -161,6 +162,7 @@ gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
.to(card.children, { .to(card.children, {
opacity: 0.4, opacity: 0.4,
}, 0.7) }, 0.7)
// cards mvmt
.from(card, { .from(card, {
translateX: `${200 * oddeven}px`, translateX: `${200 * oddeven}px`,
translateY: `${100 * oddeven}px` translateY: `${100 * oddeven}px`
@@ -173,8 +175,6 @@ gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
// translateX: `${200 * oddeven}px`, // translateX: `${200 * oddeven}px`,
// }, 0.9); // }, 0.9);
// inverse oddeven
oddeven*=-1;
// Animation des formes continue de rotation + skew pendant tout le scroll // Animation des formes continue de rotation + skew pendant tout le scroll
gsap.to(forme.querySelector('svg'), { gsap.to(forme.querySelector('svg'), {
@@ -185,14 +185,14 @@ gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
scrub: true, scrub: true,
ease: "power4.out" ease: "power4.out"
}, },
rotation: 45, rotation: Math.random() > 0.5 ? 45 : -45,
skewX: 10 skewX: Math.random() > 0.5 ? 10 : -10
}); });
// Animation de couleur des formes uniquement au centre de l'écran // Animation de couleur des formes uniquement au centre de l'écran
gsap.timeline({ gsap.timeline({
scrollTrigger: { scrollTrigger: {
trigger: forme, trigger: card,
start: "top center", // Commence quand le haut de l'élément atteint le centre start: "top center", // Commence quand le haut de l'élément atteint le centre
end: "bottom center", // Termine quand le bas de l'élément passe le centre end: "bottom center", // Termine quand le bas de l'élément passe le centre
scrub: true, scrub: true,
@@ -202,13 +202,14 @@ gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
.to(forme.querySelector('svg'), { .to(forme.querySelector('svg'), {
stroke: "#f661e2", // Passage au rose stroke: "#f661e2", // Passage au rose
duration: 0.1 duration: 0.1
}, 0.4) // Au milieu de la timeline (centre de l'écran) }, 0.3) // Au milieu de la timeline (centre de l'écran)
.to(forme.querySelector('svg'), { .to(forme.querySelector('svg'), {
stroke: "#1642bc", // Retour au bleu stroke: "#1642bc", // Retour au bleu
duration: 0.1 duration: 0.1
}, 0.6); // Juste après le centre }, 0.7); // Juste après le centre
// inverse oddeven
oddeven*=-1;
} }
} }
@@ -228,9 +229,10 @@ gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
const svgNode = forme.querySelector('svg'); const svgNode = forme.querySelector('svg');
// random size // random size
// let wh = 150 + Math.random()*350; let wh = 200 + Math.random()*300;
// OR
// pic a size // pic a size
let wh = sizes.splice(Math.floor(Math.random() * sizes.length), 1)[0]; // let wh = sizes.splice(Math.floor(Math.random() * sizes.length), 1)[0];
// record the original scale for stroke width rescalling // record the original scale for stroke width rescalling
const init_wh = svgNode.getAttribute('width'); const init_wh = svgNode.getAttribute('width');
// set the new size // set the new size
@@ -238,35 +240,42 @@ gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
svgNode.setAttribute('width', wh); svgNode.setAttribute('width', wh);
svgNode.setAttribute('height', wh); svgNode.setAttribute('height', wh);
// keep stroke width to visualy 1px // // keep stroke width to visualy 1px
let scale = wh / init_wh; // let scale = wh / init_wh;
const paths = svgNode.querySelectorAll('path, line, rect, circle, ellipse, polygon, polyline'); // const paths = svgNode.querySelectorAll('path, line, rect, circle, ellipse, polygon, polyline');
// console.log('paths', paths); // // console.log('paths', paths);
paths.forEach(path => { // paths.forEach(path => {
const init_SW = parseFloat(path.getAttribute('stroke-width')) || 1; // const init_SW = parseFloat(path.getAttribute('stroke-width')) || 1;
let new_SW = init_SW / scale; // let new_SW = init_SW / scale;
path.setAttribute('stroke-width', `${new_SW}px`); // path.setAttribute('stroke-width', `${new_SW}px`);
path.style.strokeWidth = `${new_SW}px`; // path.style.strokeWidth = `${new_SW}px`;
}); // });
// random position // random position
// top // top
let top = card.offsetTop + card.clientHeight/2 - wh/2; let top = card.offsetTop + card.clientHeight/2 - wh/2;
if (card.clientHeight < 300) {
top = Math.random() > 0.5
? card.offsetTop - wh/2 // on top
: card.offsetTop + card.clientHeight - wh/2; // on bottom
}
forme.style.top = `${top}px`; forme.style.top = `${top}px`;
let randoffset = 20 + Math.random() * 20;
// left right // left right
if (card.classList.contains('field-principes-reflexion')) { if (card.classList.contains('field-principes-reflexion')) {
// left // left
forme.style.left = `${card.offsetLeft - wh}px`; forme.style.left = `${card.offsetLeft - wh + randoffset}px`;
} else if(card.classList.contains('field-en-pratique')) { } else if(card.classList.contains('field-en-pratique')) {
// right // right
forme.style.left = `${card.offsetLeft + card.clientWidth}px`; forme.style.left = `${card.offsetLeft + card.clientWidth - randoffset}px`;
} else { } else {
// random // random
forme.style.left = Math.random() > 0.5 ? `${card.offsetLeft - wh}px` : `${card.offsetLeft + card.clientWidth}px`; forme.style.left = Math.random() > 0.5
? `${card.offsetLeft - wh + randoffset}px`
: `${card.offsetLeft + card.clientWidth - randoffset}px`;
} }
return forme; return forme;
} }
@@ -267,52 +267,101 @@ main[role="main"]{
position:relative; position:relative;
padding-bottom: 100vh; padding-bottom: 100vh;
} }
nav.arrow-more{ // next chapitre
text-align: center; nav.prev-chapitre,
a.arrow{ nav.next-chapitre{
position:absolute;
top:-10em;
padding: 0.5em 1em;
@include menu-contenus;
.wrapper{
position: relative; position: relative;
display: inline-block; }
$wh:30px; ul{
width: $wh; height: $wh; margin:0;
padding-left: 0.5em;
li{
list-style: none;
display: none;
}
}
// prev
&.prev-chapitre{
left:0;
a:after{
transform: rotate(180deg);
}
li:has(+ li.in-active-trail){
display: block;
}
}
// next
&.next-chapitre{
right:0;
li.in-active-trail + li{
display: block;
}
}
// common
label{
background-color: $bleu_site; background-color: $bleu_site;
border-radius: $wh / 2; color: #fff;
text-indent: $wh * 3; padding: 0.5em 1em;
overflow: hidden; z-index: 2;
top:-3em;
$bw:3px;
// triangle
&::before {
content: '';
display: block;
width: $wh / 3;
height: $wh / 3;
top: 50%;
left: 50%;
border-style: solid;
border-color: #fff;
border-width: $bw $bw 0 0;
position: absolute;
transform-origin: 50% 50%;
// downward
transform: rotate(135deg) translateY($wh / 3);
} }
// bare a{
&::after {
content: '';
display: block; display: block;
top: 50%; padding:0.5em 1em;
left: 50%;
border-style: solid; background-color: #fff;
border-color: #fff; box-shadow: 0 0 10px rgba(0,0,0,0.25);
border: white 1px solid;
transition: border-color 0.5s;
&:hover{
border-color: $rose;
}
&:after{
content:"";
@include arrow-white();
position:absolute; position:absolute;
transform-origin: 50% 50%;
// downward box-shadow: 0 0 10px rgba(0,0,0,0.25);
width: 0; top:calc(100% + 0.5em);
height: $wh / 3; left: calc(50% - 15px);
border-width: 0 $bw 0 0; }
transform: translateX(-2px) translateY(-$wh / 5); }
} }
// more
ul.links{
margin:0;
padding:0;
position: absolute;
top:calc(100% - 15px);
left: calc(50% - 15px);
li{
list-style: none;
a{
@include arrow-blue;
}
}
}
// arrox
nav.arrow-more{
position: absolute;
top:calc(100% - 15px);
left: calc(50% - 15px);
a.arrow{
@include arrow-blue;
} }
} }
@@ -351,8 +400,8 @@ main[role="main"]{
// Page Chapitres // Page Chapitres
section.parties{ section.parties{
display: flex; // display: flex;
gap: 2em; // gap: 2em;
padding:1em; padding:1em;
} }
@@ -420,10 +469,16 @@ main[role="main"]{
@mixin front-card{ @mixin front-card{
z-index: 2; z-index: 2;
background-color: #fff; background-color: #fff;
&>*>*{
opacity: 1;
}
} }
@mixin back-card{ @mixin back-card{
z-index: 1; z-index: 1;
background-color: #eee; background-color: rgba(247,247,247,1);
&>*>*{
opacity: 0.6;
}
} }
&.field-principes-reflexion{ &.field-principes-reflexion{
@@ -450,11 +505,11 @@ main[role="main"]{
// HOME // HOME
div.views-home-chapitres{ div.views-home-chapitres{
display: flex; // display: flex;
gap: 2em; // gap: 2em;
padding:1em; padding:1em;
>.views-row{ >.views-row{
max-width: 700px; // max-width: 700px;
article.node-type-chapitre{ article.node-type-chapitre{
h2{ h2{
@@ -479,6 +534,7 @@ main[role="main"]{
background-size: contain; background-size: contain;
background-repeat: no-repeat; background-repeat: no-repeat;
// &.pyramide{ background-image: url('/themes/custom/mathallo/assets/img/formes/pyramide.svg'); } // &.pyramide{ background-image: url('/themes/custom/mathallo/assets/img/formes/pyramide.svg'); }
// &.infinite{ background-image: url('/themes/custom/mathallo/assets/img/formes/infinite.svg'); } // &.infinite{ background-image: url('/themes/custom/mathallo/assets/img/formes/infinite.svg'); }
// &.prct{ background-image: url('/themes/custom/mathallo/assets/img/formes/prct.svg'); } // &.prct{ background-image: url('/themes/custom/mathallo/assets/img/formes/prct.svg'); }
@@ -490,14 +546,15 @@ main[role="main"]{
// &.croissant{ background-image: url('/themes/custom/mathallo/assets/img/formes/croissant.svg'); } // &.croissant{ background-image: url('/themes/custom/mathallo/assets/img/formes/croissant.svg'); }
// &.cylindre{ background-image: url('/themes/custom/mathallo/assets/img/formes/cylindre.svg'); } // &.cylindre{ background-image: url('/themes/custom/mathallo/assets/img/formes/cylindre.svg'); }
// svg{ svg{
// width: 100%; // width: 100%;
// height: 100%; // height: 100%;
// path,line,rect,circle,ellipse,polygon,polyline{ path,line,rect,circle,ellipse,polygon,polyline{
// stroke-width: 1px!important; vector-effect: non-scaling-stroke;
// } stroke-width: 1px!important;
}
// } }
} }
} }
@@ -40,7 +40,30 @@
padding:2em; padding:2em;
box-shadow: 0 0 10px rgba(0,0,0,0.25); box-shadow: 0 0 10px rgba(0,0,0,0.25);
max-width: 50em; max-width: 50em;
margin: 40vh auto 0;
box-sizing: content-box; box-sizing: content-box;
margin: 30vh auto 0;
&[role="home-presentation"]{
margin-top: 10vh;
}
} }
@mixin arrow{
display: block;
width:30px; height:30px;
border-radius: 15px;
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
text-indent: 100px;
overflow: hidden;
}
@mixin arrow-white{
@include arrow();
background-image: url('/themes/custom/mathallo/assets/img/arrow-white.svg');
}
@mixin arrow-blue{
@include arrow();
background-image: url('/themes/custom/mathallo/assets/img/arrow-blue.svg');
}
@@ -0,0 +1,89 @@
{#
/**
* @file
* Default theme implementation to display a node.
*
* Available variables:
* - node: The node entity with limited access to object properties and methods.
* Only method names starting with "get", "has", or "is" and a few common
* methods such as "id", "label", and "bundle" are available. For example:
* - node.getCreatedTime() will return the node creation timestamp.
* - node.hasField('field_example') returns TRUE if the node bundle includes
* field_example. (This does not indicate the presence of a value in this
* field.)
* - node.isPublished() will return whether the node is published or not.
* Calling other methods, such as node.delete(), will result in an exception.
* See \Drupal\node\Entity\Node for a full list of public properties and
* methods for the node object.
* - label: (optional) The title of the node.
* - content: All node items. Use {{ content }} to print them all,
* or print a subset such as {{ content.field_example }}. Use
* {{ content|without('field_example') }} to temporarily suppress the printing
* of a given child element.
* - author_picture: The node author user entity, rendered using the "compact"
* view mode.
* - metadata: Metadata for this node.
* - date: (optional) Themed creation date field.
* - author_name: (optional) Themed author name field.
* - url: Direct URL of the current node.
* - display_submitted: Whether submission information should be displayed.
* - attributes: HTML attributes for the containing element.
* The attributes.class element may contain one or more of the following
* classes:
* - node: The current template type (also known as a "theming hook").
* - node--type-[type]: The current node type. For example, if the node is an
* "Article" it would result in "node--type-article". Note that the machine
* name will often be in a short form of the human readable label.
* - node--view-mode-[view_mode]: The View Mode of the node; for example, a
* teaser would result in: "node--view-mode-teaser", and
* full: "node--view-mode-full".
* The following are controlled through the node publishing options.
* - node--promoted: Appears on nodes promoted to the front page.
* - node--sticky: Appears on nodes ordered above other non-sticky nodes in
* teaser listings.
* - node--unpublished: Appears on unpublished nodes visible only to site
* admins.
* - title_attributes: Same as attributes, except applied to the main title
* tag that appears in the template.
* - content_attributes: Same as attributes, except applied to the main
* content tag that appears in the template.
* - author_attributes: Same as attributes, except applied to the author of
* the node tag that appears in the template.
* - title_prefix: Additional output populated by modules, intended to be
* displayed in front of the main title tag that appears in the template.
* - title_suffix: Additional output populated by modules, intended to be
* displayed after the main title tag that appears in the template.
* - view_mode: View mode; for example, "teaser" or "full".
* - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'.
* - page: Flag for the full page state. Will be true if view_mode is 'full'.
*
* @see template_preprocess_node()
*
* @ingroup themeable
*/
#}
<article{{ attributes }} role="home-presentation">
{{ title_prefix }}
{% if label and not page %}
<h2{{ title_attributes }}>
<a href="{{ url }}" rel="bookmark">{{ label }}</a>
</h2>
{% endif %}
{{ title_suffix }}
{% if display_submitted %}
<footer>
{{ author_picture }}
<div{{ author_attributes }}>
{% trans %}Submitted by {{ author_name }} on {{ date }}{% endtrans %}
{{ metadata }}
</div>
</footer>
{% endif %}
<div{{ content_attributes }}>
{{ content }}
</div>
</article>