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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;
} }

View File

@@ -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;
}
// } }
} }
} }

View File

@@ -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');
}

View File

@@ -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>