Give your hero section a dynamic and fresh look with this section tutorial. Select up to 5 images, alter the text size, and add a punchy background colour to craft a unique experience. Crafted with responsiveness in mind, the design looks impeccable across desktop and mobile platforms.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Block quote
Ordered list
Unordered list
Bold text
Emphasis
Superscript
Subscript
<div id="canvas-parent">
<div class="hover-text page-width">
<h1 class="image-hover-h1"> {{section.settings.heading-text}} </h1>
<a href="{{section.settings.button-link}}" class="button button-custom"> {{section.settings.button-text}} </a>
</div>
</div>
{% schema %}
{
"name": "Image Cursor Hero",
"tag": "section",
"settings": [
{
"type": "image_picker",
"id": "image1",
"label": "Image 1"
},
{
"type": "image_picker",
"id": "image2",
"label": "Image 2"
},
{
"type": "image_picker",
"id": "image3",
"label": "Image 3"
},
{
"type": "image_picker",
"id": "image4",
"label": "Image 4"
},
{
"type": "image_picker",
"id": "image5",
"label": "Image 5"
},
{
"type": "range",
"id": "image-size",
"min": 1,
"max": 8,
"step": 1,
"label": "Image Size",
"default": 5
},
{
"type": "text",
"id": "heading-text",
"label": "Heading Text"
},
{
"type": "range",
"id": "heading-size",
"min": 6,
"max": 12,
"step": 2,
"unit": "rem",
"label": "Heading size",
"default": 8
},
{
"type": "text",
"id": "button-text",
"label": "Button Text"
},
{
"type": "url",
"id": "button-link",
"label": "Button Link"
},
{
"type": "color",
"id": "text-color",
"label": "Text Color",
"default": "#121212"
},
{
"type": "color",
"id": "background-color",
"label": "Background Color",
"default": "#FFFFFF"
},
{
"type": "color",
"id": "button-text-color",
"label": "Button Text Color",
"default": "#121212"
}
],
"presets": [
{"name": "Image Cursor Hero" }
],
"limit": 1
}
{% endschema %}
<style>
#canvas-parent {
height: 80vh;
overflow: hidden;
background-color: {{section.settings.background-color}};
}
.p5Canvas {
position: relative!important;
}
.hover-text {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 80vh;
z-index: 2;
position: absolute;
flex-direction: column;
text-align: center;
max-width: none!important;
}
.image-hover-h1 {
font-size: {{ section.settings.heading-size}}rem;
color: {{ section.settings.text-color}};
line-height: 100%;
margin: 4rem;
max-width: 850px;
}
.button-custom {
color: {{section.settings.button-text-color}};
}
@media screen and (max-width:500px) {
.image-hover-h1 {
font-size:{{ section.settings.heading-size | divided_by: 1.5}}rem!important;
margin: 2.5rem;
}
.hover-text {
height: 50vh;
}
#canvas-parent {
height: 50vh
}
}
</style>
<script src="https://cdn.jsdelivr.net/npm/p5@1.6.0/lib/p5.js"></script>
<script>
let imageUrls = [
"{{ section.settings.image1 | image_url }}",
"{{ section.settings.image2 | image_url }}",
"{{ section.settings.image3 | image_url }}",
"{{ section.settings.image4 | image_url }}",
"{{ section.settings.image5 | image_url }}",
];
// distance mouse needs to move before next image is shown
let distThreshold = 45;
// scale factor to size images
let scaleFactor = {{section.settings.image-size}};
// VARIABLES
// array to hold all of our images
let images = [];
// array to hold history of mouse positions and image index for that position
let queue = [];
// object containing our last (stored) mouse position
let lastMousePos = { x: 0, y: 0 };
// current image to show
let imgIndex = 0;
// load all of the images from their urls into the images array
function preload() {
for (let i = 0; i < imageUrls.length; i++) {
images[i] = loadImage(imageUrls[i]);
}
}
// setup canvas and store initial mouse position
function setup() {
let cnv = createCanvas(windowWidth, windowHeight);
cnv.parent("canvas-parent");
cnv.style("display", "block");
cnv.style("position", "absolute");
cnv.style("inset", "0");
cnv.style("z-index", "1");
lastMousePos = { x: mouseX, y: mouseY };
}
function draw() {
// clear the canvas
clear();
// calculate distance between current mouse position and last stored mouse position.
let d = dist(mouseX, mouseY, lastMousePos.x, lastMousePos.y);
// If distance is greater than threshold:
// 1. Add current mouse position and current image index to the front of the queue
// 2. Update lastMousePos to current mouse position
// 3. Update imgIndex to next image index
if (d > distThreshold) {
queue.unshift({ x: mouseX, y: mouseY, index: imgIndex });
lastMousePos = { x: mouseX, y: mouseY };
imgIndex = (imgIndex + 1) % images.length;
}
// maintain queue length equal to number of images by removing the last item
if (queue.length > images.length) {
queue.pop();
}
// define scale of images based on width of canvas
let scale = width / scaleFactor;
// draw images in queue
// draw order is reversed so that the first image in the queue is drawn on top
for (let i = queue.length - 1; i >= 0; i--) {
let img = images[queue[i].index];
if (img) {
// scale image based on scale factor
let imgWidth = (img.width * scale) / img.width;
let imgHeight = (img.height * scale) / img.width;
// draw image at mouse position offset by half of image width and height
image(
img,
queue[i].x - imgWidth / 2,
queue[i].y - imgHeight / 2,
imgWidth,
imgHeight
);
}
}
}
// resize canvas when window is resized
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
</script>