Is there a way to blur the all the background elements except the clicked box. Reason why the background element needed to be blurred is that I want the clicked box to be the focal point.
I tried some Javascript like
if (div.firstChild && div.firstChild.classList.contains('container')) {
renderBoxes(div.firstChild);
}
And so on. but it doesn't work properly as I intended.
My expected is to blur the blue, pink backgrounds and the other boxes that are not clicked.
function applyStyles(element, styles) {
for (const [key, value] of Object.entries(styles)) {
element.style[key] = value;
}
}
let currentlyClickedBox = null;
function renderBoxes(container) {
let numberOfBoxes = boxes.length;
let additionalXValue = 500 - (9 - numberOfBoxes) * 10;
let offsetValue = 40;
let offsetAdditional = 0;
// Loop through tokens array
boxes.forEach(token => {
// Create a new div for each token
const div = document.createElement('div');
div.className = token.class;
applyStyles(div, token.style);
// Add additional offset to each token
div.setAttribute('data-offset-additional', offsetAdditional);
// Add click event listener to each token
div.addEventListener('click', () => {
// Check if another token was previously clicked
if (currentlyClickedBox && currentlyClickedBox !== div) {
// Reset previously clicked token
currentlyClickedBox.style.transform = 'none';
currentlyClickedBox.style.position = "relative";
}
// Check if this token is currently clicked
if (currentlyClickedBox === div) {
// Reset clicked token
currentlyClickedBox.style.transform = 'none';
currentlyClickedBox.style.position = "relative";
currentlyClickedBox = null;
} else {
const translateXValue = -div.getBoundingClientRect().x; // Get the px distance of right corner to token;
// (Adjust token to center) - (Offset of each token)
const translateXOffset = (translateXValue + additionalXValue) - (offsetValue + parseInt(div.getAttribute('data-offset-additional')));
// Transform clicked token
currentlyClickedBox = div;
div.style.transform = `translate(${translateXOffset}px, -350px) rotateY(180deg) scale(3)`;
}
});
// Append token div to container
container.appendChild(div);
offsetAdditional = offsetAdditional + 20; // Increment additional offset each token
});
}
function renderForeignObjects() {
const svg = document.getElementById('mySvg');
foreignObjects.forEach(obj => {
const foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
foreignObject.setAttribute('x', obj.x);
foreignObject.setAttribute('y', obj.y);
foreignObject.setAttribute('width', obj.width);
foreignObject.setAttribute('height', obj.height);
const div = document.createElement('div');
div.innerHTML = obj.content;
applyStyles(div.firstChild, obj.style);
if (div.firstChild && div.firstChild.classList.contains('container')) {
renderBoxes(div.firstChild);
}
foreignObject.appendChild(div);
svg.appendChild(foreignObject);
});
}
const foreignObjects = [{
x: 0,
y: 0,
width: "100%",
height: "100%",
content: '<div xmlns="http://www.w3.org/1999/xhtml"></div>',
style: {
backgroundColor: "blue"
}
},
{
x: 0,
y: 0,
width: 1200,
height: 200,
content: '<div></div>',
style: {
backgroundColor: "pink"
}
},
{
x: 0,
y: 300,
width: 1200,
height: 200,
content: '<div></div>',
style: {
backgroundColor: "pink"
}
},
{
// Whole page
x: 100,
y: 0,
width: 1000,
height: 750,
content: '<div class="container"></div>',
style: {}
}
];
const boxes = [{
y: -50,
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ccc"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ddd"
}
},
{
class: "box",
style: {
width: "110px",
height: "110px",
margin: "0 5px",
backgroundColor: "#ccc"
}
}
];
// Call the function to render foreign objects
renderForeignObjects();
.a {
height: 100vh;
width: 100%;
}
div {
width: 100%;
height: 100%;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.container {
display: flex;
align-items: flex-end;
justify-content: center;
position: relative;
}
.box {
transition: transform 0.5s ease;
}
<svg id="mySvg" xmlns="http://www.w3.org/2000/svg" class="a p" viewBox="0 0 1200 800"></svg>
you can do it with this algorithm:
Assign a class to box's container showing that one box is active e.g. active
Assign another class to the currently active box e.g. focused
now use this additional css to your code:
.container.active box:not(.focused) {
filter: blur(5px);
}
css above means :"when container is active
, blur every box that is not the focused
one"
Hope it helped. ^_^