Diagonal images on web page with text - css

Here is the effect i have tried to achieve:
When the user moves their mouse over the image, a line of text should overlay the image in a diagonal fashion.
The images could be the background to the <p>. Really just need help first with making the full thing diagonal. Do not want to use hard coded dimensions/positions that would not work on screens of different width/height.
<div class="testrows">
<div class="drow"><p>Hello World</p></div>
<div class="drow"><p>Hello World</p></div>
<div class="drowhalf">
<p>Hello World</p><p>Hello World</p>
</div>
<div class="drowhalf">
<p>Hello World</p><p>Hello World</p>
</div>
<div class="drow"><p>Hello World</p></div>
<div class="drow"><p>Hello World</p></div>
</div>
CSS
body {
background: #e5e5e5;
height:100%;
}
.testrows{
display:block;
height:100%;
}
.drow {
width: 100%;
height: 10%;
background: black;
position: absolute;
top: -50px;
left: 0;
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
text-align: center;
color: #fff;
vertical-align: middle;
}
.drow p {
ms-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
padding-right: 60px;
width: 100%;
padding-bottom: 55px;
}
.drowhalf {
width: 100%;
height: 10%;
background: black;
position: absolute;
top: -50px;
left: 0;
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
text-align: center;
color: #fff;
vertical-align: middle;
}
.drowhalf p {
ms-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
padding-right: 60px;
width: 50%;
padding-bottom: 55px;
}
https://jsfiddle.net/ufwmuuv4/

You can wrap all .drow elements by a wrapper (.inner-wrapper) and then rotate it (DRY), set transform-origin to top left to rotate from top left of element and finally give translateX(-50%) to .inner-wrapper to center it in its parent.
For stretching .drow, you can give width:200% to .inner-wrapper.
To calculate .drow's height, you have to use js.
Jsfiddle
function stretch(){
var $wrapper = $('.wrapper'),
diagonal = Math.ceil(Math.sqrt(Math.pow($wrapper.width(),2) + Math.pow($wrapper.height(),2))),
height = diagonal / $wrapper.find('.inner-wrapper .drow').length;
$wrapper.find('.inner-wrapper .drow').height(height).css('line-height', height + 'px');
}
$(document).ready(function(){
stretch();
});
$( window ).resize(function(){
stretch();
});
html,
body {
margin: 0;
padding: 0;
}
html,
body,
.wrapper,
.inner-wrapper {
height: 100%;
}
body {
background: #e5e5e5;
}
p {
margin: 0;
}
.wrapper {
overflow: hidden;
}
.inner-wrapper {
transform: rotate(-45deg) translateX(-50%);
transform-origin: top left;
text-align: center;
width: 200%;
}
.drow {
height: 100px;
line-height: 100px;
color: #fff;
background: rgba(0, 0, 0, 1);
}
.drowhalf p {
display: inline-block;
width: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="inner-wrapper">
<div class="drow">
<p>Hello World</p>
</div>
<div class="drow">
<p>Hello World</p>
</div>
<div class="drow drowhalf">
<p>Hello World</p><p>Hello World</p>
</div>
<div class="drow drowhalf">
<p>Hello World</p><p>Hello World</p>
</div>
<div class="drow">
<p>Hello World</p>
</div>
<div class="drow">
<p>Hello World</p>
</div>
</div>
</div>

$("div").hover(function () {
$('p').css('display', 'block');
}, function () {
$('p').css('display', 'none');
});
div {
-webkit-transform: rotate(-30deg);
-moz-transform: rotate(-30deg);
-ms-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
transform: rotate(-30deg);
margin: 100px;
height: 150px;
width: 350px;
background-image: url('http://placehold.it/350x150');
}
p {display:none}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div>
<p>Hello World</p>
</div>
You can do a rotation with transform:rotate
-webkit-transform: rotate(-30deg);
-moz-transform: rotate(-30deg);
-ms-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
transform: rotate(-30deg);
W3C as reference https://www.w3schools.com/cssref/playit.asp?filename=playcss_transform_rotate
Try to create a div and set your image as a background-img, then rotate this div.
Inside this div, put your text in a p and use jQuery to displayed it on hover.
See this on Codepen http://codepen.io/Qasph/pen/PmoNVz

Wouldn't it be better to use rotate?
I think this may be your answer:
CSS:
body {
background: #e5e5e5;
}
.aviso {
width: 50px;
height: 200px;
background: black;
position: absolute;
top: -50px;
left: 0;
-ms-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
text-align: center;
color: #fff;
vertical-align: middle;
}
.aviso p {
ms-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
padding-right: 60px;
width: 100%;
padding-bottom: 55px;
}
HTML:
<div class="aviso">
<p>WIP</p>
</div>
http://codepen.io/AyrtonAlves/pen/NxMBxO

Use rotate instead of skew.
.div {
width: 200px;
height: 200px;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}

You can achieve this effect with pure css..
div {
margin: 100px;
height: 150px;
width: 350px;
background-image: url('http://placehold.it/350x150');
}
div:hover p{
display:block;
}
p {
display:none;
-webkit-transform: rotate(-30deg);
-moz-transform: rotate(-30deg);
-ms-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
transform: rotate(-30deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div>
<p>Hello World</p>
</div>

Ok so it was only possible to do with Javascript and jquery. There was no CSS way to do it.
js
<script type="text/javascript">
$(window).on('resize', function (){
updateWidth();
});
function toRadians (angle) {
return angle * (Math.PI / 180);
}
function updateWidth(){
//add this to the width to make sure it fits
var idealRatio = 45.0/114;
idealHeight = 134.0;
var safetyAdd = 10;
//var topMargin = .;
var divHeightPercent = 1/6.4;
//first get the new content container height and width
var contentHeight = $('#content').height();
console.log('height:' + contentHeight);
var contentWidth = $('#content').width();
console.log('width:' + contentWidth);
//scale the hieght in proportion to the diagonal
/*
var proportion = Math.sqrt(contentHeight*contentHeight+ contentWidth*contentWidth)/(contentHeight/Math.cos(toRadians(20)));
console.log('proportion:' + proportion);
var theta = Math.atan(contentWidth/contentHeight);
var degree = 180*theta/Math.PI;
console.log('degree:' + degree);*/
//calculate the correction factor for height
var correctionFactor= (contentHeight*1.0/Math.cos(toRadians(20)))/contentHeight;
correctionFactor= (idealRatio/(contentHeight/contentWidth));
correctionFactor= 1+correctionFactor;
console.log('correctionFactor:' + correctionFactor);
divHeightPercent = divHeightPercent*correctionFactor;
console.log('divHeightPercent:' + divHeightPercent);
//topMargin=topMargin*correctionFactor;
//console.log('topMargin:' + topMargin);
//calculate the height of each section
var commonDivHeight = contentHeight*divHeightPercent;
console.log('divHeight:' + commonDivHeight);
$("#drow0").height(commonDivHeight);
$("#drow1").height(commonDivHeight);
$("#drow2").height(commonDivHeight);
$("#drow3").height(commonDivHeight);
$("#drow4").height(commonDivHeight);
$("#drow5").height(commonDivHeight);
//correctio for common div height
var cdhCorr = Math.tan(toRadians(20))*commonDivHeight;
cdhCorr = Math.sin(toRadians(20))*cdhCorr;
console.log('cdhCorr:' + cdhCorr);
var diagonalHeight = commonDivHeight/Math.cos(toRadians(20));
console.log('diagonalHeight:' + diagonalHeight);
//calculate the bottom for the first div and proper width
var zeroRowBotPoint = diagonalHeight;
console.log('zeroRowBotPoint:' + zeroRowBotPoint);
//var zeroRowWidth = zeroRowBotPoint/Math.sin(toRadians(20));//apply some correction faction here
//console.log('zeroRowWidth:' + firstRowWidth);
var zeroRowWidth = calcMaxWidthNeeded(zeroRowBotPoint, contentWidth, commonDivHeight);
$("#drow0").width(zeroRowWidth);
$("#drow0").css({top: 0});
//calculate the bottom for the first div and proper width
var firstRowBotPoint = diagonalHeight+zeroRowBotPoint;
console.log('firstRowBotPoint:' + firstRowBotPoint);
//var firstRowWidth = firstRowBotPoint/Math.sin(toRadians(20));//apply some correction faction here
//console.log('firstRowWidth:' + firstRowWidth);
var firstRowWidth = calcMaxWidthNeeded(firstRowBotPoint, contentWidth, commonDivHeight);
$("#drow1").width(firstRowWidth);
var row1padding = getLeftPadding(contentHeight, firstRowBotPoint, diagonalHeight, commonDivHeight);
$("#drow1").css({top: zeroRowBotPoint, paddingLeft: row1padding, marginRight:700});
//calculate the bottom for the second div and proper width
var secondRowBotPoint = diagonalHeight+firstRowBotPoint;
console.log('secondRowBotPoint:' + secondRowBotPoint);
//var secondRowWidth = secondRowBotPoint/Math.sin(toRadians(20));//apply some correction faction here
//console.log('secondRowWidth:' + secondRowWidth);
var secondRowWidth = calcMaxWidthNeeded(secondRowBotPoint, contentWidth, commonDivHeight);
$("#drow2").width(secondRowWidth);
var row2padding = getLeftPadding(contentHeight, secondRowBotPoint, diagonalHeight, commonDivHeight);
$("#drow2").css({top: firstRowBotPoint, paddingLeft: row2padding});
//calculate the bottom for the third div and proper width
var thirdRowBotPoint = diagonalHeight+secondRowBotPoint;
console.log('thirdRowBotPoint:' + thirdRowBotPoint);
//var thirdRowWidth = thirdRowBotPoint/Math.sin(toRadians(20));//apply some correction faction here
//console.log('thirdRowWidth:' + thirdRowWidth);
var thirdRowWidth = calcMaxWidthNeeded(thirdRowBotPoint, contentWidth, commonDivHeight);
$("#drow3").width(thirdRowWidth);
var row3padding = getLeftPadding(contentHeight, thirdRowBotPoint, diagonalHeight, commonDivHeight);
$("#drow3").css({top: secondRowBotPoint, paddingLeft: row3padding});
//calculate the bottom for the forth div and proper width
var forthRowBotPoint = diagonalHeight+thirdRowBotPoint;
console.log('forthRowBotPoint:' + forthRowBotPoint);
//var forthRowWidth = forthRowBotPoint/Math.sin(toRadians(20));//apply some correction faction here
//console.log('forthRowWidth:' + forthRowWidth);
var row4padding = getLeftPadding(contentHeight, forthRowBotPoint, diagonalHeight, commonDivHeight);
var forthRowWidth = calcMaxWidthNeeded(forthRowBotPoint, contentWidth, commonDivHeight)- row4padding;
$("#drow4").width(forthRowWidth);
var topCorrection4 = row4padding*Math.tan(toRadians(20));
console.log('topCorrection4:' + topCorrection4);
$("#drow4").css({top: thirdRowBotPoint-topCorrection4, left: row4padding});
//calculate the bottom for the fith div and proper width
var fifthRowBotPoint = diagonalHeight+forthRowBotPoint;
console.log('fifthRowBotPoint:' + fifthRowBotPoint);
//var fifthRowWidth = fifthRowBotPoint/Math.sin(toRadians(20)) - row5padding;//apply some correction faction here
//console.log('fifthRowWidth:' + fifthRowWidth);
var row5padding = getLeftPadding(contentHeight, fifthRowBotPoint, diagonalHeight, commonDivHeight);
var fifthRowWidth = calcMaxWidthNeeded(fifthRowBotPoint, contentWidth, commonDivHeight)- row5padding;
var topCorrection5 = row5padding*Math.tan(toRadians(20));
$("#drow5").width(fifthRowWidth);
$("#drow5").css({top: forthRowBotPoint-topCorrection5, left: row5padding});
/*correct the padding
//var y = contentHeight;
var row0padding = 0; //its not possible
var row1padding = getLeftPadding(contentHeight, firstRowBotPoint, diagonalHeight, commonDivHeight);
var row2padding = getLeftPadding(contentHeight, secondRowBotPoint, diagonalHeight, commonDivHeight);
var row3padding = getLeftPadding(contentHeight, thirdRowBotPoint, diagonalHeight, commonDivHeight);
var row4padding = getLeftPadding(contentHeight, forthRowBotPoint, diagonalHeight, commonDivHeight);
var row5padding = getLeftPadding(contentHeight, fifthRowBotPoint, diagonalHeight, commonDivHeight);
//*/
//get font height
var topPadding = (commonDivHeight-32)/2;
$("#rowp1").css({marginTop: topPadding, marginLeft:-250});
$("#rowp2").css({marginTop: topPadding});
$("#rowp3").css({marginTop: topPadding});
$("#rowp4").css({marginTop: topPadding});
$("#rowp5").css({marginTop: topPadding});
$("#rowp6").css({marginTop: topPadding, marginLeft:250});
//finall unhide the contents
$("#content").css({opacity:1});
}
function calcMaxWidthNeeded (bottomLoc, contentWidth, height){
//first find the width of the triangle formed by the section
var xDistance = bottomLoc/Math.tan(toRadians(20));
if(xDistance <= contentWidth){
//the width calculated by the simple function will be most efficient
console.log('Using simple Width Calculation');
return bottomLoc/Math.sin(toRadians(20));
}
var x = xDistance - contentWidth;
var bigHyp = xDistance/Math.cos(toRadians(20));
var ratio = x/xDistance;
var smallHyp = bigHyp*ratio;
//get the extra width due to the 20 degree rotaion
var extraWidth = height*Math.tan(toRadians(20));
var efficientWidth = bigHyp-smallHyp+extraWidth;
console.log('efficientWidth:' + efficientWidth);
return efficientWidth;
}
function getLeftPadding(contentHeight, bottomLoc, diagonalHeight, height){
var y = bottomLoc - contentHeight;
var x = y-diagonalHeight;
//return if there is no need to change the padding
if(x<=0){
console.log('Left padding change not required');
return 0;
}
var bottHyp = y/Math.sin(toRadians(20));
var xtoyRatio = x/y;
var topHyp = bottHyp*xtoyRatio;
//get the extra width due to the 20 degree rotaion
var extraWidth = height*Math.tan(toRadians(20));
console.log('extraWidth:' + extraWidth);
//finally calculate the padding
var paddingVal = topHyp ;
console.log('paddingVal:' + paddingVal);
return paddingVal;
}
function myFunction() {
document.querySelector('#selected').style.color='#008ed2';
updateWidth();
}
</script>
HTML
<div class="content" id="content">
<!--div class="inner-wrapper"-->
<div class="drow0" id="drow0"></div>
<div class="drow1" id="drow1"><p id="rowp1">DEVICES, IN A REALLY HUMAN WAY.</p></div>
<div class="drow2" id="drow2">
<div class="drow2-1" id="drow2-1"><p id="rowp2">EAT, DRINK AND BE MARY.</p></div>
<div class="drow2-2"><p id="rowp3">BE CAUSE.</p></div>
</div>
<div class="drow3" id="drow3">
<div class="drow3-1"><p id="rowp4">HEY, NICE PACKAGE.</p></div>
<div class="drow3-2"><p id="rowp5">WAIT FOR APPLAUSE.</p></div>
</div>
<div class="drow4" id="drow4"><p id="rowp6">WE FEEL BETTER ALREADY.</p></div>
<div class="drow5" id="drow5"></div>
<!--/div-->
</div>
CSS
.p, .drow1, .drow2, .drow3,.drow4{
margin: 0;
}
.content {
overflow: show;
position:relative;
text-align: center;
background-color: black;
color: white;
font-family: 'futura-pt-bold', sans-serif;
font-style: normal;
font-weight: 700;
font-size: 2em;
text-shadow:0px 0px 16px black;
opacity: 0;
}
.drow0, .drow1, .drow2, .drow3, .drow4, .drow5{
position:absolute;
transform: rotate(-20deg);
transform-origin: bottom left;
height:16.66%;
left:0%;
width: 100%;
background-repeat:no-repeat;
background-size:cover;
}
.drow0{
top:0%;
background-image: url("../desktop_images/1.jpg");
}
.drow1{
top:16.66%;
background-image: url("../desktop_images/2.jpg");
}
.drow2{
display: inline-flex;
top:33.33%;
}
.drow2-1{
width: 60%;
background-image: url("../desktop_images/3.jpg");
background-repeat:no-repeat;
background-size:cover;
}
.drow2-2{
width: 40%;
background-image: url("../desktop_images/4.jpg");
background-repeat:no-repeat;
background-size:cover;
}
.drow3{
display: inline-flex;
top:50%;
}
.drow3-1{
width: 45%;
background-image: url("../desktop_images/5.jpg");
background-repeat:no-repeat;
background-size:cover;
}
.drow3-2{
width: 55%;
background-image: url("../desktop_images/6.jpg");
background-repeat:no-repeat;
background-size:cover;
}
.drow4{
background-image: url("../desktop_images/7.jpg");
top:66.66%;
}
.drow5{
background-image: url("../desktop_images/8.jpg");
top:83.33%;
}
.drow1:hover {
background-repeat: no-repeat;
background-position: center;
color: transparent;
text-shadow:0px 0px 0px transparent;
background-image: url("../desktop_images/bg-2.png");
background-size: auto 65%;
}
.drow2-1:hover {
background-repeat: no-repeat;
background-position: center;
color: transparent;
text-shadow:0px 0px 0px transparent;
background-image: url("../desktop_images/bg-3.png");
background-size: 52% auto;
}
.drow2-2:hover {
background-repeat: no-repeat;
background-position: center;
color: transparent;
text-shadow:0px 0px 0px transparent;
background-image: url("../desktop_images/bg-4.png");
background-size: 75% auto;
}
.drow3-1:hover {
background-repeat: no-repeat;
background-position: center;
color: transparent;
text-shadow:0px 0px 0px transparent;
background-image: url("../desktop_images/bg-5.png");
background-size: auto 65%;
}
.drow3-2:hover {
background-repeat: no-repeat;
background-position: center;
color: transparent;
text-shadow:0px 0px 0px transparent;
background-image: url("../desktop_images/bg-6.png");
background-size: auto 65%;
}
.drow4:hover {
background-repeat: no-repeat;
background-position: center;
color: transparent;
text-shadow:0px 0px 0px transparent;
background-image: url("../desktop_images/bg-7.png");
background-size: auto 65%;
}

Related

Parts of the background are forming a border around the red border

How come there are thin lines going around the whole border, and can they be removed?
It looks like parts of the background are forming a border around the red border.
Can that be fixed?
That is the whole issue
https://jsfiddle.net/59t3k1gn/
One is an image of it zoomed in on the border, and the other is not zoomed in.
How come the background is forming a border around the red border, and how is that fixed?
(function manageCurtain() {
"use strict";
function hide(el) {
el.classList.add("hide");
}
function coverClickHandler(evt) {
const cover = evt.currentTarget;
hide(cover);
const curtain = document.querySelector(".outer");
curtain.classList.add("slide");
//curtain.classList.add("fadeout");
const wrap = document.querySelector(".wrap");
wrap.classList.remove("hide");
}
const cover = document.querySelector(".play");
cover.addEventListener("click", coverClickHandler);
}());
const videoPlayer = (function makeVideoPlayer() {
"use strict";
let player = null;
const tag = document.createElement("script");
tag.src = "https://www.youtube.com/iframe_api";
const firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function onPlayerReady(event) {
player = event.target;
player.setVolume(100); // percent
}
let hasShuffled = false;
function onPlayerStateChange(event) {
player = event.target;
const shufflePlaylist = true;
if (!hasShuffled) {
player.setShuffle(shufflePlaylist);
player.playVideoAt(0);
hasShuffled = true;
}
}
function addPlayer(video) {
const playlist = "M7lc1UVf-VE";
const config = {
height: 360,
host: "https://www.youtube-nocookie.com",
width: 640
};
config.playerVars = {
autoplay: 0,
cc_load_policy: 0,
controls: 1,
disablekb: 1,
fs: 0,
iv_load_policy: 3,
loop: 1,
playlist,
rel: 0
};
config.events = {
"onReady": onPlayerReady,
"onStateChange": onPlayerStateChange
};
player = new YT.Player(video, config);
}
return {
addPlayer
};
}());
function onYouTubeIframeAPIReady() {
const cover = document.querySelector(".play");
const wrapper = cover.parentElement;
const frameContainer = wrapper.querySelector(".video");
videoPlayer.addPlayer(frameContainer);
}
(function iife() {
"use strict";
function show(el) {
el.classList.remove("hide");
}
function coverClickHandler(evt) {
const wrapper = evt.currentTarget.parentElement;
show(wrapper);
}
const cover = document.querySelector(".play");
cover.addEventListener("click", coverClickHandler);
}());
html,
body {
height: 100%;
padding: 0;
margin: 0;
}
body {
background: url(https://picsum.photos/id/1015/1500/1500) no-repeat;
background-attachment: fixed;
background-size: cover;
}
.fadeout .split-wrap {
opacity: 0;
transition: opacity 1s ease 3s, width 0s 10s, height 0s 10s;
}
.outer {
position: relative;
display: table;
height: 100%;
margin: 0 auto;
width: 100%;
overflow: hidden;
}
.tcell {
display: table-cell;
vertical-align: middle;
padding: 8px 8px;
}
.curtain {
max-width: 640px;
margin: auto;
border: 3px solid red;
box-sizing: border-box;
border-radius: 25px;
overflow: hidden;
background: transparent;
}
.curtain-ratio-keeper {
position: relative;
width: 100%;
height: 0;
padding-top: 56.25%;
overflow: hidden;
background: transparent;
}
.slide-wrap:before,
.slide-wrap:after {
content: "";
position: absolute;
top: 0;
width: 50%;
height: 100%;
transition: transform 5s linear;
background: url(https://picsum.photos/id/1015/1500/1500) no-repeat;
background-attachment: fixed;
background-size: cover;
}
.slide-wrap:before {
left: 0;
}
.slide-wrap:after {
right: 0;
}
.slide .slide-wrap::before {
transform: translateX(-100%);
}
.slide .slide-wrap::after {
transform: translateX(100%);
}
.video-frame {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: transparent;
}
.play {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
width: 98px;
height: 98px;
border-radius: 50%;
fill: red;
filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.7));
cursor: pointer;
}
.hide {
display: none;
}
<div class="outer">
<div class="tcell">
<div class="curtain">
<div class="curtain-ratio-keeper">
<div class="wrap hide">
<div class="video video-frame"></div>
</div>
<div class="slide-wrap"></div>
</div>
<svg class="play " width="100%" height="100%" viewBox="0 0 64 64">
<path d="M25.6,46.4L44.8,32L25.6,17.6V46.4z M32,0C14.3,0,0,14.3,0,32s14.3,32,32,32s32-14.3,32-32S49.7,0,32,0z
M32,57.6C17.9,57.6,6.4,46.1,6.4,32S17.9,6.4,32,6.4S57.6,17.9,57.6,32S46.1,57.6,32,57.6z" />
</svg>
</div>
</div>
</div>
Seems fine to me, what exactly is the issue? This effect you described might be either yous screen blurring pixels in certain zoom levels, or a visual illusion called Mach bands

increasing/lowering image opacity as a transition between lists of images

What my code does:
creates a background
changes background image with the next one in the list every 3 seconds
loops back to the first image in the list at index 0 and repeats.
What I want to happen:
each time we switch from one image to the next there is a transition
every 3 seconds a new image opacity gradually increases from 0 to 100%
then gradually decrease its opacity to 0 before switching to the next image
<div id="background" class="text-center background">
<script type = "text/javascript">
var background = document.getElementById("background");
var currentPos = 0;
var images = ["/images/backgroundimg1.jpg", "/images/backgroundimg2.jpg", "/images/backgroundimg3.jpg", "/images/backgroundimg4"], i = 0;
function changeimage()
{
if (++currentPos >= images.length)
currentPos = 0;
background.style.backgroundImage = "url(" + images[currentPos] + ")";
}
setInterval(changeimage, 3000);
</script>
</div>
<style>
.background{
background-repeat: no-repeat;
background-size: cover;
height: 1000px;
}
</style>
For myself, I would do it like this:
var background = document.getElementById("background");
var currentPos = 0;
var images = ["https://i.stack.imgur.com/MraLT.jpg", "https://i.stack.imgur.com/VxVNC.jpg", "https://i.stack.imgur.com/A9VLC.jpg", "https://i.stack.imgur.com/oYG0R.jpg"],
i = 0;
function changeimage() {
if (++currentPos >= images.length) currentPos = 0;
background.style.backgroundImage = "url(" + images[currentPos] + ")";
}
setInterval(changeimage, 3000);
.background { display: grid; place-items: center; font: bold 48px sans-serif; text-shadow: 0 0 4px #fff, 0 0 2px #fff;
height: 1000px;
background-repeat: no-repeat;
background-size: cover;
transition: 2s linear;
}
<div id="background" class="text-center background">Only transition</div>
But, if a transparency phase is needed, then:
you can use a 1×1px transparent PNG image in Base64:
var background = document.getElementById("background");
var currentPos = 0;
var images = ["https://i.stack.imgur.com/MraLT.jpg", "https://i.stack.imgur.com/VxVNC.jpg", "https://i.stack.imgur.com/A9VLC.jpg", "https://i.stack.imgur.com/oYG0R.jpg"],
i = 0;
function changeimage() {
if (++currentPos >= images.length) currentPos = 0;
background.style.backgroundImage = `url('${images[currentPos]}')`;
setTimeout(function() {
background.style.backgroundImage = `url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=)`;
}, 2500);
}
setInterval(changeimage, 4000);
.background { display: grid; place-items: center; font: bold 48px sans-serif; text-shadow: 0 0 4px #fff, 0 0 2px #fff;
height: 1000px;
background-image: linear-gradient(to left, #0000, #0000);
background-repeat: no-repeat;
background-size: cover;
transition: 1.4s linear;
}
<div id="background" class="text-center background">With transparent image</div>
you can insert a pseudo-element as an underlay and use CSS variables:
var background = document.getElementById("background");
var currentPos = 0;
var images = ["https://i.stack.imgur.com/MraLT.jpg", "https://i.stack.imgur.com/VxVNC.jpg", "https://i.stack.imgur.com/A9VLC.jpg", "https://i.stack.imgur.com/oYG0R.jpg"],
i = 0;
function changeimage() {
if (++currentPos >= images.length) currentPos = 0;
background.style.setProperty('--bg', `url('${images[currentPos]}')`);
background.style.setProperty('--op', 1);
setTimeout(function() {
background.style.setProperty('--op', 0);
}, 2500);
}
setInterval(changeimage, 4000);
.background { display: grid; place-items: center; font: bold 48px sans-serif; text-shadow: 0 0 4px #fff, 0 0 2px #fff;
--bg: linear-gradient(to left, #0000, #0000);
--op: 0;
position: relative;
height: 1000px;
}
.background::before {
content: '';
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
z-index: -1;
background-image: var(--bg);
background-repeat: no-repeat;
background-size: cover;
opacity: var(--op);
transition: opacity 1.4s linear;
}
<div id="background" class="text-center background">Using pseudo element and CSS variables</div>

UI Alignment Issue

Hope after so many tries I will get some pointers over here for issue i am facing.
As per above image, I need to have an POI in center of page(round circle in the image) and when I click on POI; I would like to open a pop up window in four position at shown in the image above with different css classes. Problem is that popup height can not be fixed and should be auto and that is where its tricky to handle the margin if I would like to achieve above UI.
Issues:
any pointers on positioning the popup with css classes as per images shown.
I have setup a fiddle here including popup and POI.
HTML:
<div id="follow-hotspot" class="hotspot-wrapper">
<img width="20px" heigh="20px" class="hotspot" src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-ios7-contact-512.png"/>
<div id="follow-textbox" class="textbox_hotspot hide" data-video="true">
<h1>Header</h1>
<p>
<b>Follow me</b> to see the css video
</p>
<iframe id="follow_video" width="230" height="150" src="https://www.youtube.com/embed/9YffrCViTVk" frameborder="0" id = "Overlayvideo" allow="accelerometer; autoplay *; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
JavaScript:
Let me know if any details are required. Any pointer how to achieve is ample enough; I am not expecting you to write code for me. How would I go about the implementation is all I am expecting.
//annonymous function
var poi = document.getElementById("follow-hotspot");
var popup = document.getElementById("follow-textbox");
poi.onclick = function() {
//alert("clicked");
if (popup.classList.contains('hide')) {
popup.classList.remove('hide');
popup.classList.add('show');
}
else if (popup.classList.contains('show')) {
popup.classList.remove('show');
popup.classList.add('hide');
videoEle = document.getElementById('follow_video');
videoEle.src = videoEle.src;
}
};
CSS:
Please refer to the fiddle for css.
I used translate property to give position to these content blocks and used percentage as units.I checked the output on changing the height and width of the content and still the position remained intact.
Glimpse of the output(->its The output)
var point_er = document.getElementsByClassName('pointer')[0];
var win_dow = document.getElementsByClassName('window');
var count = 0;
point_er.onclick = function() {
if (count % 2 == 0) {
for (var i = 0; i < win_dow.length; i++) {
win_dow[i].style.height = "250px";
win_dow[i].style.width = "300px";
}
win_dow[2].style.height = "300px";
win_dow[3].style.width = "400px";
} else {
for (var i = 0; i < win_dow.length; i++) {
win_dow[i].style.height = "0px";
win_dow[i].style.width = "0px";
}
}
count++;
}
* {
margin: 0px;
padding: 0px;
}
body {
height: 2400px;
}
.main {
width: 100%;
height: 100vh;
}
.window_main {}
.window {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 0px;
height: 0px;
border: 2px solid black;
}
.window:nth-child(1) {
transform-origin: 100% 100%;
transform: translate(-105%, -105%);
transition: 0.4s;
}
.window:nth-child(2) {
transform-origin: 0 100%;
transform: translate(5%, -105%);
transition: 0.5s;
}
.window:nth-child(3) {
transform-origin: 100% 0;
transform: translate(-105%, 5%);
transition: 0.6s;
}
.window:nth-child(4) {
transform-origin: 0% 0%;
transform: translate(5%, 5%);
transition: 0.7s;
}
.pointer {
text-decoration: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
height: 50px;
width: 50px;
background-color: #8B8AFF;
cursor: pointer;
transition: 0.4s;
}
.pointer:hover {
background-color: #6D6DE8
}
<div class="main">
<div class="window">1</div>
<div class="window">2</div>
<div class="window">3</div>
<div class="window">4</div>
</div>

Change text color to white on any non-white background

Changing the text color to white when the background color is black works great using mix-blend-mode: difference. Move the mouse to the text to see the effect:
const blackBox = document.querySelector(".black-box");
window.addEventListener('mousemove', function(event) {
blackBox.style.left = `${event.pageX - 50}px`;
blackBox.style.top = `${event.pageY - 50}px`;
});
.wrapper {
background-color: white;
}
h1 {
position: relative;
z-index: 2;
color: white;
mix-blend-mode: difference;
}
.black-box {
width: 100px;
height: 100px;
position: absolute;
z-index: 1;
background-color: black;
}
<div class="wrapper">
<h1>Lorem Ipsum</h1>
</div>
<div class="black-box"></div>
This understandably doesn't result in white text if the background is anything other than black:
const box = document.querySelector(".box");
window.addEventListener('mousemove', function(event) {
box.style.left = `${event.pageX - 50}px`;
box.style.top = `${event.pageY - 50}px`;
});
.wrapper {
background-color: white;
}
h1 {
position: relative;
z-index: 2;
color: white;
mix-blend-mode: difference;
}
.box {
width: 100px;
height: 100px;
position: absolute;
z-index: 1;
background-image: url("https://placekitten.com/100/100")
}
<div class="wrapper">
<h1>Lorem Ipsum</h1>
</div>
<div class="box"></div>
Is there any way to make it so the text changes color from black to white as soon as the background differs from white?
Here is an idea that rely on background coloration and not mix-blend-mode. The trick is to have a gradient with the same dimension as the image that you move the same way to simulate the blend mode:
const box = document.querySelector(".box");
const h1 = document.querySelector("h1");
window.addEventListener('mousemove', function(event) {
box.style.left = `${event.pageX - 50}px`;
box.style.top = `${event.pageY - 50}px`;
h1.style.backgroundPosition = `${event.pageX - 50}px ${event.pageY - 50}px`;
});
.wrapper {
background-color: white;
}
h1 {
position: relative;
z-index: 2;
color: white;
background:
/*gradient position / size */
linear-gradient(#fff,#fff) -100px -100px/100px 100px fixed no-repeat,
#000;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
.box {
width: 100px;
height: 100px;
position: absolute;
z-index: 1;
background-image: url("https://placekitten.com/100/100")
}
<div class="wrapper">
<h1>Lorem Ipsum</h1>
</div>
<div class="box"></div>
I have considered background-attachment:fixed to place the gradient relatively to the viewport since your element is position:absolute with no ancestor positioned so it's also positioned relatively to the viewport.

CSS: Position loading indicator in the center of the screen

How can I position my loading indicator in the center of the screen. Currently I'm using a little placeholder and it seems to work fine. However, when I scroll down, the loading indicator stays right in that predefined position. How can I make it follow the scrolling so that it always sits on top??
#busy
{
position: absolute;
left: 50%;
top: 35%;
display: none;
background: transparent url("../images/loading-big.gif");
z-index: 1000;
height: 31px;
width: 31px;
}
#busy-holder
{
background: transparent;
width: 100%;
height: 100%;
}
use position:fixed instead of position:absolute
The first one is relative to your screen window. (not affected by scrolling)
The second one is relative to the page. (affected by scrolling)
Note : IE6 doesn't support position:fixed.
.loader{
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 9999;
background: url('//upload.wikimedia.org/wikipedia/commons/thumb/e/e5/Phi_fenomeni.gif/50px-Phi_fenomeni.gif')
50% 50% no-repeat rgb(249,249,249);
}
<div class="loader"></div>
This is what I've done for Angular 4:
<style type="text/css">
.centered {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transform: -webkit-translate(-50%, -50%);
transform: -moz-translate(-50%, -50%);
transform: -ms-translate(-50%, -50%);
color:darkred;
}
</style>
</head>
<body>
<app-root>
<div class="centered">
<h1>Loading...</h1>
</div>
</app-root>
</body>
Here is a solution using an overlay that inhibits along with material design spinner that you configure one time in your app and you can call it from anywhere.
app.component.html
(put this somewhere at the root level of your html)
<div class="overlay" [style.height.px]="height" [style.width.px]="width" *ngIf="message.plzWait$ | async">
<mat-spinner class="plzWait" mode="indeterminate"></mat-spinner>
</div>
app.component.css
.plzWait{
position: relative;
left: calc(50% - 50px);
top:50%;
}
.overlay{
position: absolute;
top:0px;
left:0px;
width: 100%;
height: 100%;
background: black;
opacity: .5;
z-index: 999999;
}
app.component.ts
height = 0;
width = 0;
constructor(
private message: MessagingService
}
ngOnInit() {
this.height = document.body.clientHeight;
this.width = document.body.clientWidth;
}
messaging.service.ts
import { Injectable } from '#angular/core';
import { Subject } from 'rxjs';
#Injectable({
providedIn: 'root',
})
export class MessagingService {
// Observable string sources
private plzWaitObservable = new Subject<boolean>();
// Public Observables you subscribe to
public plzWait$ = this.plzWaitObservable.asObservable();
public plzWait = (wait: boolean) => this.plzWaitObservable.next(wait);
}
Some other component
constructor(private message: MessagingService) { }
somefunction() {
this.message.plzWait(true);
setTimeout(() => {
this.message.plzWait(false);
}, 5000);
}
change the position absolute of div busy to fixed
You can use this OnLoad or during fetch infos from DB
In HTML Add following code:
<div id="divLoading">
<p id="loading">
<img src="~/images/spinner.gif">
</p>
In CSS add following Code:
#divLoading {
margin: 0px;
display: none;
padding: 0px;
position: absolute;
right: 0px;
top: 0px;
width: 100%;
height: 100%;
background-color: rgb(255, 255, 255);
z-index: 30001;
opacity: 0.8;}
#loading {
position: absolute;
color: White;
top: 50%;
left: 45%;}
if you want to show and hide from JS:
document.getElementById('divLoading').style.display = 'none'; //Not Visible
document.getElementById('divLoading').style.display = 'block';//Visible
Worked for me in angular 4
by adding style="margin:0 auto;"
<mat-progress-spinner
style="margin:0 auto;"
*ngIf="isLoading"
mode="indeterminate">
</mat-progress-spinner>
transform: translate(50%, 50%);
You may try this is in my case it will work
<div class="position-relative">
<div class="position-absolute" style="transform: translate(50%, 50%)"> loader or anything Else</div>
</div>
.loader{
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 9999;
background: url('//upload.wikimedia.org/wikipedia/commons/thumb/e/e5/Phi_fenomeni.gif/50px-Phi_fenomeni.gif')
50% 50% no-repeat rgb(249,249,249);
}
<div class="loader"></div>

Resources