Ionic on change event not working properly - javascript

I am building a mobile app with ionic, I have two range slides in my app, my problem is that the change event does not fires until i stop sliding, how can i add an event listener to the range slide so that as i am sliding it, it will automatically run the function, the reason i want this is that since they are two range slide, i want as any of the slides is moving, i have a function that will automatically change the value of the other slide, and i dont want the other slide to move only when i stop sliding, i want it to move as as i move any of the slides
here is my code
test.page.html
<div class="wrap" role="group" aria-labelledby="multi-lbl">
<label class="sr-only" for="a">Value A:</label>
<input (change)="onChangeVal(1)" name="min" id="a" type="range" min="0" [max]="VidDuration" [(ngModel)]="range.min"/>
<label class="sr-only" for="b">Value B:</label>
<input (change)="onChangeVal(2)" name="max" id="b" type="range" min="0" [max]="VidDuration" [(ngModel)]="range.max"/>
</div>
test.page.scss
*{
font: inherit;
}
.wrap {
--a: -30;
--b: 20;
--min: -50;
--max: 50;
--dif: calc(var(--max) - var(--min));
display: grid;
grid-template: repeat(2, -webkit-max-content) 4em/ 1fr 1fr;
grid-template: repeat(2, max-content) 4em/ 1fr 1fr;
overflow: hidden;
position: absolute;
bottom: 1% !important;
width: 100%;
height: 52px !important;
background: black;
}
.wrap::before, .wrap::after {
grid-column: 1/ span 2;
grid-row: 3;
background: transparent;
content: "";
}
.wrap::before {
margin-left: calc(1em + (var(--a) - var(--min))/var(--dif)*18em);
width: calc((var(--b) - var(--a))/var(--dif)*18em);
}
.wrap::after {
margin-left: calc(1em + (var(--b) - var(--min))/var(--dif)*18em);
width: calc((var(--a) - var(--b))/var(--dif)*18em);
}
[id='multi-lbl'] {
grid-column: 1/span 2;
}
.wrap, input[type='range']{
z-index:100000 !important;
}
.sr-only {
position: absolute;
-webkit-clip-path: inset(50%);
clip-path: inset(50%);
}
input[type='range'] {
grid-column: 1/ span 2;
grid-row: 3;
z-index: 1;
top: 0;
left: 0;
margin: 0;
background: none;
--col: transparent;
pointer-events: none;
border: 1px solid #f51646;
}
input[type='range']::-webkit-slider-runnable-track, input[type='range']::-webkit-slider-thumb, input[type='range'] {
-webkit-appearance: none;
}
input[type='range']::-webkit-slider-runnable-track {
width: 100%;
height: 105%;
background: none;
}
input[type='range']::-moz-range-track {
width: 100%;
height: 105%;
background: none;
}
input[type='range']::-webkit-slider-thumb {
border: none;
width: 2em;
height: 4em;
border-radius: 0;
background: linear-gradient(90deg, #fff 2px, transparent 0) calc(1em - 1px), radial-gradient(circle, var(--col) calc(1em - 1px), transparent 1em);
pointer-events: auto;
}
input[type='range']::-moz-range-thumb {
border: none;
width: 2em;
height: 4em;
border-radius: 0;
background: linear-gradient(90deg, #fff 2px, transparent 0) calc(1em - 1px), radial-gradient(circle, var(--col) calc(1em - 1px), transparent 1em);
pointer-events: auto;
}
input[type='range']:focus {
z-index: 2;
outline: dotted 1px currentcolor;
}
test.page.ts
onChangeVal(w) {
let vvid:any = document.getElementById("video");
vvid.pause()
clearTimeout(this.time_out)
if(w==1) this.range.max=(this.range.max <= this.VidDuration) ? this.range.min+this.max : this.VidDuration
else if((this.range.max-this.range.min)>this.max) this.range.min=this.range.max-this.max
else if(this.range.max <= this.range.min) this.range.max=this.range.min
console.log(this.range)
}
The mobile app is a video player the i want to trim so i want to be able to choose from with time to which time i want to trim the video

I would sugest to use the input or ionInput event:
<input (input)="onChangeVal(1)">
<input (ionInput)="onChangeVal(2)">
Because you use [(ngModel)] you could also use ngModelChange:
<input (ngModelChange)="onChangeVal(1)">

Related

Why is the div inside not load inside the a tag?

I am trying to make a slideshow inside of an accordion, however when I load the code into the browser, the content inside the <a> is beside it, not inside it. Is there any solution to it? The main problem is that when I load the code to debug the <div class="grid2 transition" id="grid4"> is supposed to be inside of <a onclick="openUp4()" class="pane1 button" id="pane4">, however it loads just side by side.
let slideIndex = [1, 1];
let slideId = ["mySlides1", "mySlides2"]
showSlides(1, 0);
showSlides(1, 1);
function plusSlides(n, no) {
showSlides(slideIndex[no] += n, no);
}
function showSlides(n, no) {
let i;
let x = document.getElementsByClassName(slideId[no]);
if (n > x.length) {
slideIndex[no] = 1
}
if (n < 1) {
slideIndex[no] = x.length
}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex[no] - 1].style.display = "block";
}
function openUp4() {
var element = document.getElementById("pane4");
element.classList.toggle("active2")
if (element.classList.contains("active2")) {
// document.getElementById("grid2").style.visibility = "visible";
document.getElementById("grid4").style.opacity = 1;
} else {
// document.getElementById("grid2").style.visibility = "hidden";
document.getElementById("grid4").style.opacity = 0;
}
}
.pane1 {
background-color: white;
height: 100px;
margin-top: 10px;
margin-bottom: 10px;
border-radius: 20px;
position: relative;
text-align: center;
font-size: 20px;
transition: 0.4s;
}
.active2 {
height: fit-content;
}
.grid2 {
display: grid;
gap: 0rem;
grid-template-rows: 1fr;
grid-auto-columns: 1fr;
height: inherit;
justify-content: center;
place-items: center;
overflow: hidden;
}
.blacktitle {
color: #ffffff;
position: absolute;
background-color: #191919;
height: 70px;
width: 50%;
left: -20px;
top: -45px;
border-radius: 10px;
padding: 21px;
letter-spacing: 6px;
}
.mySlides1 {
display: none
}
img {
vertical-align: middle;
max-width: 400px;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .2);
border-radius: 5px;
}
video {
max-width: 400px;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .2);
border-radius: 5px;
margin-top: 40%;
}
/* Slideshow container */
.slideshow-container {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
width: 400px;
max-width: 400px;
position: relative;
margin: 40px auto auto auto;
}
.videocontainer {
position: relative;
height: 533.333px;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a grey background color */
.prev:hover,
.next:hover {
background-color: #f1f1f1;
color: black;
}
<a onclick="openUp4()" class="pane1 button" id="pane4">
<div class="blacktitle">
Concerts
</div>
<div class="grid2 transition" id="grid4">
<div class="slideshow-container">
<div class="mySlides1">
<img src="Concerts/a03c3e49-cdff-4382-87c1-b473de9f6447.jpg" style="width:100%">
</div>
<div class="mySlides1">
<img src="Concerts/IMG_6847.png" style="width:100%">
</div>
<div class="mySlides1 videocontainer">
<video controls preload="metadata">
<source src="Concerts/IMG_5888.mov" type="video/mp4" style="width:100%">
</video>
</div>
<a class="prev" onclick="plusSlides(-1, 0)">❮</a>
<a class="next" onclick="plusSlides(1, 0)">❯</a>
</div>
</div>
</a>
I must admit I'm having a little trouble understanding the question, but from your code, 2 things pop up immediately:
The first is the usage of <div> inside <a>. You should never use a block element (like div, h1, p, etc) inside an inline element (like a,span,strong, etc). Some browsers might be able to parse it but this is definitely invalid HTML.
A solution to that would be to replace the <div> elements inside the anchor tag with <span> instead, and add a display:block CSS rule to the relevant <span> tags so they mimic how the <div> looks like.
The second issue is around this line:
x[slideIndex[no] - 1].style.display = "block";
x[slideIndex[no] - 1] does not always return an element, so you cannot assume you can access its style property. A safer way to do it would be this:
// Get the element first
const el = x[slideIndex[no] - 1];
// If it exists, *then* access and mutate its properties.
if(el) el.style.display = "block";
I fixed it this works:
<div class="pagebody">
<div class="container">
<div class="flex-container">
<div class="pane1 button" id="pane4">
<span onclick="openUp4()" class="blacktitle">
Concerts
</span>
<span class="grid2 transition" id="grid4">
<span class="slideshow-container">
<span class="mySlides1">
<div style="width: 400px; height: 533px; background-color:"></div>
</span>
<span class="mySlides1">
<div style="width: 400px; height: 533px; background-color: green"></div>
</span>
<span class="mySlides1">
<div style="width: 400px; height: 533px; background-color: blue"></div>
</span>
<button class="prev" onclick="plusSlides(-1, 0)">❮</button>
<button class="next" onclick="plusSlides(1, 0)">❯</button>
</span>
</span>
</div>
</div>
</div>
</div>
<style>
.blacktitle:hover {
background-color: #555555;
}
.blacktitle {
color: #ffffff;
position: absolute;
background-color: #191919;
height: 70px;
width: 50%;
left: -20px;
top: -45px;
border-radius: 10px;
padding: 21px;
letter-spacing: 6px;
z-index: 10;
}
.transition {
opacity: 0;
transition: opacity 0.5s linear;
}
.grid2 {
display: grid;
gap: 0rem;
grid-template-rows: 1fr;
grid-auto-columns: 1fr;
height: inherit;
justify-content: center;
place-items: center;
overflow: hidden;
}
.active2 {
height: 600px;
}
.pane1 {
background-color: white;
height: 100px;
margin-top: 10px;
margin-bottom: 10px;
border-radius: 20px;
position: relative;
text-align: center;
font-size: 20px;
transition: 0.4s;
}
.container {
padding: 0px 60px 60px 60px;
background-color: #191919;
max-width: 1000px;
min-width: 800px;
width: 100%; }
.flex-container {
display: flex;
justify-content: center;
align-items: top;
flex-direction: column;
margin-top: 60px;
}
.pagebody {
background-color: #191919;
margin: 0;
display: flex;
justify-content: center;
}
.mySlides1 {display: none; overflow: hidden;}
img {vertical-align: middle; max-width: 400px; box-shadow: 0 2px 4px 0 rgba(0,0,0,.2); border-radius: 5px;}
video {max-width: 400px; box-shadow: 0 2px 4px 0 rgba(0,0,0,.2); border-radius: 5px; margin-top: 40%;}
/* Slideshow container */
.slideshow-container {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
width: 400px;
max-width: 400px;
position: relative;
margin: 40px auto auto auto;
}
.videocontainer {
position: relative;
height: 533.333px;
}
/* Next & previous buttons */
.prev, .next {
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: white;
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
background:none;
border:none;
cursor: pointer;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a grey background color */
.prev:hover, .next:hover {
background-color: #f1f1f1;
color: black;
}
function openUp4(){
var element = document.getElementById("pane4");
element.classList.toggle("active2")
if (element.classList.contains("active2")) {
// document.getElementById("grid2").style.visibility = "visible";
document.getElementById("grid4").style.opacity = 1;
} else {
// document.getElementById("grid2").style.visibility = "hidden";
document.getElementById("grid4").style.opacity = 0;
}
}
let slideIndex = [1,1];
let slideId = ["mySlides1", "mySlides2"]
showSlides(1, 0);
showSlides(1, 1);
function plusSlides(n, no) {
showSlides(slideIndex[no] += n, no);
}
function showSlides(n, no) {
let i;
let x = document.getElementsByClassName(slideId[no]);
if (n > x.length) {slideIndex[no] = 1}
if (n < 1) {slideIndex[no] = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
const el = x[slideIndex[no] - 1];
if(el){el.style.display = "block";}
}
}

How to animate a pop up on show and close using css?

I have a layout as follows,
container - to hold all the cards.
card - div for containing information.
In the above Image, the left one shows the initial rendering of the screen,
When user clicks on any inner card, the corresponding card should popout/zoomout,
and when user click backs on pop up card, it should disappear and the first sceen should display.
The popup animation should be like that, it should start from the position of the card, we have clicked.
The popup close animation after second click(When popup is open), the animation should look like that, the popup should get minimized to the card clicked in the first step.
I have tried following code, but it is really animating..
let isOpen = false;
$(".child").on("click", function() {
if (!isOpen) {
$(".child").removeClass("active");
$(this).addClass("active");
isOpen = true;
} else {
$(this).removeClass("active");
isOpen = false;
}
})
* {
box-sizing: border-box;
}
.parent {
margin: 40px auto;
width: 400px;
height: 600px;
border: 1px solid #3b3b3b;
border-radius: 20px;
padding: 20px 40px;
position: relative;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
}
.child {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #000;
border-radius: 40px;
cursor: pointer;
transition: all 0.5s ease-in;
}
.child.active {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 10;
border: 1px solid red;
background: #000;
border-radius: 20px;
color: #fff;
}
#keyframes zoomIn {
0% {
transform: scale(1.1);
}
50% {
transform: scale(1.2);
}
100% {}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>
Please help me to simulate the same.
Your animation is pretty much complete. The problem as I see it is that when the .active class is added to a child, the other children fill up the void in the grid. This makes the active child not enlarge from its original position.
I made my own solution using CSS but without animations - and vanilla JavaScript. In my code (just as in yours) the child gets lose from the grid, gets an absolute position and then fills up the entire parent container with width: 100%; and height: 100%; I also added CSS specifications to the other children to stay put when this is happening (see below).
It's a rather snappy effect because transition is not applied to width and height unless the child is absolute positioned before the active class is added. To achieve a more "zoomy" effect is a bit more tricky:
You can observe for DOM attribute (class) mutations with JavaScript (in other words, add a class with absolute positioning, and when that operation is completed, add another class with width: 100%; and height: 100%;).
Or you could use position: absolute on all the child elements from the start, but then you also need to specify width, height, top, left etc.
Some other solution I'm too tired or not skilled enough to think of.
Current Solution
// Turn all 4 .child selectors into an integer array ranging from 0-3
let cardArray = Array.from(document.querySelectorAll(".child"));
// Loop over each integer [0-3] and give them an index number
// Listen for clicks, and then toggle the "larger" class onto the item with the corresponding index number [0-3]
cardArray.forEach(function(everyItem, index) {
everyItem.addEventListener("click", function() {
cardArray[index].classList.toggle("larger");
});
});
* {
box-sizing: border-box;
}
.parent {
margin: 40px auto;
width: 400px;
height: 600px;
border: 1px solid #3b3b3b;
border-radius: 20px;
padding: 20px 40px;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 20px;
transition: all 0.5s;
/* relative position required for enlarged items to stay within parent container */
position: relative;
}
.child {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #000;
border-radius: 40px;
cursor: pointer;
transition: all 0.2s;
/* z-index not neccessary, just a precaution */
z-index: 1;
}
/* top/bottom/left/right required for the CURRENTLY ACTIVE child to resize from the correct corner.
:nth-child() with grid-area specified required for NOT CURRENTLY active children to stay put in grid. */
.child:nth-child(1) {
grid-area: 1 / 1;
top: 0;
left: 0;
}
.child:nth-child(2) {
grid-area: 1 / 2;
top: 0;
right: 0;
}
.child:nth-child(3) {
grid-area: 2 / 1;
bottom: 0;
left: 0;
}
.child:nth-child(4) {
grid-area: 2 / 2;
bottom: 0;
right: 0;
}
/* .larger class added with the help
of JavaScript on click */
.child.larger {
/* Unhinge from the grid */
grid-area: unset;
/* Position absolute in order to resize it */
position: absolute;
/* Fill the WIDTH of the parent container */
width: 100%;
/* Fill the HEIGHT of the parent container */
height: 100%;
/* z-index not neccessary, just a precaution */
z-index: 2;
background: #000;
opacity: 0.5;
color: #fff;
}
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>
You can try achieve this with by css variables calculation, position: absolute and a separate .active class for each element.
let isOpen = false;
$('.child').on('click', function() {
if (!isOpen) {
$('.child').removeClass('active');
$(this).addClass('active');
isOpen = true;
} else {
$(this).removeClass('active');
isOpen = false;
}
});
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--parent-width: 400px;
--parent-height: 600px;
--gap: 20px;
}
.parent {
margin: 40px auto;
width: var(--parent-width);
height: var(--parent-height);
border: 1px solid #3b3b3b;
border-radius: 20px;
position: relative;
}
.child {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #000;
border-radius: 40px;
cursor: pointer;
transition: all 0.5s ease-in;
position: absolute;
height: calc((var(--parent-height) / 2) - (var(--gap) * 2));
width: calc((var(--parent-width) / 2) - (var(--gap) * 3));
}
/* Init size */
.child:nth-child(1) {
top: var(--gap); /* padding top 20px */
left: calc(var(--gap) * 2); /* padding left 40px */
}
.child:nth-child(2) {
top: var(--gap);
right: calc(var(--gap) * 2); /* padding right 40px */
}
.child:nth-child(3) {
bottom: var(--gap); /* padding bottom 20px */
left: calc(var(--gap) * 2); /* padding left 40px */
}
.child:nth-child(4) {
bottom: var(--gap);
right: calc(var(--gap) * 2);
}
/* Full size */
.child:nth-child(1).active {
top: 0;
left: 0;
}
.child:nth-child(2).active {
top: 0;
right: 0;
}
.child:nth-child(3).active {
bottom: 0;
left: 0;
}
.child:nth-child(4).active {
bottom: 0;
right: 0;
}
.child.active {
width: 100%;
height: 100%;
z-index: 10;
border: 1px solid red;
background: #000;
border-radius: 20px;
color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
</div>

Increasing CSS value instead of decreasing with jquery

I have a page that I need to convert to rtl.
The active tab & tab arrow position doesn't match.
I need to change the tab arrow position from TAB 1 to TAB 2 and vice versa.
I already changed some js value but in vain
HTML :
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="main-search-container">
<form class="main-search-form">
<div class="search-type">
<label class="active"><input class="first-tab" name="tab" checked="checked" type="radio">TEXT</label>
<label><input name="tab" type="radio">TEXT</label>
<label><input name="tab" type="radio">TEXT</label>
<div class="search-type-arrow"></div>
</div>
<div class="main-search-box">
<div class="main-search-input larger-input">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
CSS :
body {
direction:rtl;
color: #707070;
background-color: #cccccc;
}
.parallax {
background-repeat: no-repeat;
background-position: 50% 50%;
position: relative;
z-index: 99;
}
.parallax-overlay {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
z-index: 101;
background-color: #333;
opacity: 0.4;
}
.parallax-content {
position: relative;
z-index: 999;
padding: 105px 0;
}
.main-search-container {
transform: translate3d(0,-12px,0);
}
.main-search-form {
width: 660px;
display: block;
margin: 0 auto;
position: relative;
margin-top: 35px;
}
.search-type {
display: inline-block;
padding-bottom: 35px;
position: relative;
}
.search-type input[type="radio"] { display: none; }
.search-type label {
background-color: #fff;
color: #333;
cursor: pointer;
display:inline-block;
text-align: center;
padding: 9px 18px;
margin: 0 0 0 15px;
float: right;
transition: all 0.2s;
border-radius: 3px;
}
.search-type label:hover,
.search-type label.active {
background-color: #66676b;
color: #fff;
}
.search-type-arrow {
width: 0;
height: 0;
border-right: 15px solid transparent;
border-left: 15px solid transparent;
border-bottom: 15px solid #fff;
position: absolute;
bottom: 0;
right: 0;
transform: translate3d(-3px,0,0);
}
.main-search-box {
background-color: #fff;
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.12);
padding: 30px;
padding-bottom: 20px;
margin-top: -9px;
border-radius: 3px;
}
.main-search-box.no-shadow {
box-shadow: none;
padding: 0;
margin: 0;
}
.search-container .main-search-input input {
font-weight: 500;
font-size: 17px;
height: 57px !important;
float: right;
box-sizing: border-box;
border: none;
float: right;
height: auto;
}
.search-container .main-search-input button.button {
width: initial;
min-width: 100px;
max-width: 100px;
margin: 0;
font-size: 18px;
position: relative;
margin-right: 20px;
flex: 0 auto;
height: 57px;
}
.search-container .main-search-input button.button i {
position: relative;
right: 2px;
}
JS :
(function($){
"use strict";
$(document).ready(function(){
function searchTypeButtons() {
// Radio attr reset
$('.search-type label.active input[type="radio"]').prop('checked',true);
// Positioning indicator arrow
var buttonWidth = $('.search-type label.active').width();
var arrowDist = $('.search-type label.active').position().left;
$('.search-type-arrow').css('right', arrowDist + (buttonWidth/2) );
$('.search-type label').on('change', function() {
$('.search-type input[type="radio"]').parent('label').removeClass('active');
$('.search-type input[type="radio"]:checked').parent('label').addClass('active');
// Positioning indicator arrow
var buttonWidth = $('.search-type label.active').width();
var arrowDist = $('.search-type label.active').position().left;
$('.search-type-arrow').css({
'right': arrowDist + (buttonWidth/2),
'transition':'right 0.4s cubic-bezier(.87,-.41,.19,1.44)'
});
});
}
// Init
if ($(".main-search-form").length){
searchTypeButtons();
$(window).on('load resize', function() { searchTypeButtons(); });
}
// ------------------ End Document ------------------ //
});
})(this.jQuery);
I'm using bootstrap, bootstrap rtl flipped & jquery 2.2.0 as external ressources.
Here's the snippet:
https://jsfiddle.net/s3hy37nd/5/
Can someone help with that?
So many errors... I can only say I tried to comment them all inside the code so... yeah it's all there:
"use strict";
jQuery(function($) { // DOM ready and $ alias secured
// Radio attr reset (on DOM ready... makes sense?)
$('.search-type label.active input[type="radio"]').prop('checked', true);
function repositionArrow() { // Use a meaningful fn name
// Positioning indicator arrow
// Width? No. You need .outerWidth! you have paddings!!
var buttonWidth = $('.search-type label.active').outerWidth();
// Again use meaningful names
// If you do console.log( $('.search-type label.active').position() );
// you'll see no `.right` property. So yeah, use .left
var posLeft = $('.search-type label.active').position().left;
$('.search-type-arrow').css({
left: posLeft + (buttonWidth / 2)
// No need for transition here - move it to Stylesheet instead
});
}
// Init
if ($(".main-search-form").length) {
// You might want this too inside the "if"
$('.search-type label').on('change', function() {
$('.search-type input[type="radio"]').parent('label').removeClass('active');
$('.search-type input[type="radio"]:checked').parent('label').addClass('active');
repositionArrow(); // Now you have such function
});
repositionArrow();
$(window).on('load resize', repositionArrow);
}
});
body {
direction: rtl;
color: #707070;
background-color: #cccccc;
}
.parallax {
background-repeat: no-repeat;
background-position: 50% 50%;
position: relative;
z-index: 99;
}
.parallax-overlay {
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
z-index: 101;
background-color: #333;
opacity: 0.4;
}
.parallax-content {
position: relative;
z-index: 999;
padding: 105px 0;
}
.main-search-container {
transform: translate3d(0, -12px, 0);
}
.main-search-form {
width: 660px;
display: block;
margin: 0 auto;
position: relative;
margin-top: 35px;
}
.search-type {
display: inline-block;
padding-bottom: 35px;
position: relative;
}
.search-type input[type="radio"] {
display: none;
}
.search-type label {
position: relative;
/* YOU NEED SOME POSITION! */
background-color: #fff;
color: #333;
cursor: pointer;
display: inline-block;
text-align: center;
padding: 9px 18px;
margin: 0 0 0 15px;
/*float: right; WHY? you use rtl already */
transition: all 0.2s;
border-radius: 3px;
}
.search-type label:hover,
.search-type label.active {
background-color: #66676b;
color: #fff;
}
.search-type-arrow {
width: 0;
height: 0;
border-right: 15px solid transparent;
border-left: 15px solid transparent;
border-bottom: 15px solid #fff;
position: absolute;
bottom: 0;
/*right: 0; ...Nope. See JS, we need left */
left: calc(100% - 30px);
/* calc to the rescue */
/*transform: translate3d(-3px,0,0); but why */
transition: left 0.4s cubic-bezier(.87, -.41, .19, 1.44);
/* Moved from JS */
}
.main-search-box {
background-color: #fff;
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.12);
padding: 30px;
padding-bottom: 20px;
margin-top: -9px;
border-radius: 3px;
}
<div class="parallax-content">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="main-search-container">
<form class="main-search-form">
<div class="search-type">
<label class="active"><input class="first-tab" name="tab" checked="checked" type="radio">TAB 1</label>
<label><input name="tab" type="radio">TAB 2</label>
<label><input name="tab" type="radio">TAB 3</label>
<div class="search-type-arrow"></div>
</div>
<div class="main-search-box">
<div class="main-search-input larger-input">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
Updated jsFiddle

How to draw line on a webpage using html, css and javascript

I am currently working on a "tic tac toe like" game.
This is the link. I started upgrading some of its functionalities and I have a problem.
I used the image included below as the background image of the game and I positioned nine input fields, one on each edge/side of the image with css.
I no longer want to use a background image. Is there any way I can draw those lines with css, javascript and/or html?
Please I will be very happy if it can be done with pure html, css and javascript or with jquery
You can use 2 elements and their pseudo elements to draw the lines with absolute positioning in and transform: rotate()
div {
width: 25%;
border: 1px solid black;
margin: auto;
overflow: hidden;
}
span {
display: block;
padding-bottom: 100%;
}
div,span {
position: relative;
}
div::after,div::before,span::after,span::before {
content: '';
position: absolute;
background: black;
}
div::after {
top: 50%;
left: 0; right: 0;
height: 1px;
}
div::before {
width: 1px;
left: 50%;
top: 0; bottom: 0;
}
span::before,span::after {
height: 1px;
top: 50%;
left: -25%;
right: -25%;
background: red;
}
span::before {
transform: rotate(45deg);
}
span::after {
transform: rotate(-45deg);
}
<div><span></span></div>
you can also use gradients :
the idea
background:
linear-gradient(0deg,black,black) repeat-y center,
linear-gradient(0deg,black,black) repeat-x center,
linear-gradient(26deg, transparent calc(50% - 2px), black calc(50% - 1px) , black calc(50% + 2px), transparent calc(50% + 2px)),
linear-gradient(-26deg, transparent calc(50% - 2px), black calc(50% - 1px) , black calc(50% + 2px), transparent calc(50% + 2px)) yellow;
background-size: 3px 100%, 100% 3px, auto,auto;
here is a snippet with margin and size of inputs updated too, the snippet uses also a background-color and a shadow.
body {
color: black;
width: 26.8cm;
overflow: scroll;
background-color: white;
}
.welcome{
padding:20px;
text-align: center;
background: #ccc;
}
.transit{
transition: 5s;
}
#player{
color: green;
}
.gamelet { /*This style is for the boxes containing the hexadecimal color codes*/
width: 5.6cm;
display: inline-block;
vertical-align: top;
}
.gamelet2 {
margin-top: 4.3cm;
}
.fr { /*This style is for the red box only*/
margin-left: -0.3cm;
width:0.6cm;
}
.sr { /*This style is for the green box only*/
margin:0 9.6cm;
width:0.6cm;
}
.tr { /*This style is for the blue box only*/
margin-right:-0.3cm;
width:0.6cm;
}
div:nth-child(1),
div:nth-child(2),
div:nth-child(3){margin-top:-0.3cm;}
div:nth-child(7),
div:nth-child(8),
div:nth-child(9){margin-bottom:-0.3cm;}
.gamelet1 {
border-radius: 90px;
width: 0.6cm;
cursor: pointer;
}
.board {
background:
linear-gradient(0deg,black,black) repeat-y center,
linear-gradient(0deg,black,black) repeat-x center,
linear-gradient(26deg, transparent calc(50% - 2px), black calc(50% - 1px) , black calc(50% + 2px), transparent calc(50% + 2px)),
linear-gradient(-26deg, transparent calc(50% - 2px), black calc(50% - 1px) , black calc(50% + 2px), transparent calc(50% + 2px)) yellow;
background-size: 3px 100%, 100% 3px, auto,auto;
box-shadow: 0 0 0 0.6cm yellow;
border:solid;
margin: 2cm 3cm;
}
/*//styles from bootstrap*/
.alert-danger {
color: #a94442;
background-color: #f2dede;
border-color: #ebccd1;
text-align: center;
padding:20px;
display: none;
}
.alert-success {
color: #3c763d;
background-color: #dff0d8;
border-color: #d6e9c6;
text-align: center;
padding:20px;
display: none;
}
.alert-info {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
text-align: center;
padding:20px;
}
<script src="https://kofimokome.github.io/tic-tac-toe/TTT_files/TTTscript.js"></script>
<form name="game" class="board">
<div class="gamelet fr"><input onclick="C_11(cplayer); autoname(0);" name="C11" type="text" class="gamelet1" /></div>
<div class="gamelet sr"><input onclick="C_12(cplayer); autoname(1);" name="C12" type="text" class="gamelet1" /></div>
<div class="gamelet tr"><input onclick="C_13(cplayer); autoname(2);" name="C13" type="text" class="gamelet1" /></div>
<div class="gamelet fr"><input onclick="C_21(cplayer); autoname(3);" name="C21" type="text" class="gamelet1 gamelet2" /></div>
<div class="gamelet sr"><input onclick="C_22(cplayer); autoname(4);" name="C22" type="text" class="gamelet1 gamelet2" /></div>
<div class="gamelet tr"><input onclick="C_23(cplayer); autoname(5);" name="C23" type="text" class="gamelet1 gamelet2" /></div>
<div class="gamelet fr"><input onclick="C_31(cplayer); autoname(6);" name="C31" type="text" class="gamelet1 gamelet2" /></div>
<div class="gamelet sr"><input onclick="C_32(cplayer); autoname(7);" name="C32" type="text" class="gamelet1 gamelet2" /></div>
<div class="gamelet tr"><input onclick="C_33(cplayer); autoname(8);" name="C33" type="text" class="gamelet1 gamelet2" /></div>
</form>
a codepen to fork & play with
NOTE:
IDs can only be used once per document, use class instead if multiple use (code snippet for #gamelet turned into .gamelet )

Achieve animated seesaw -ish effect with linear-gradient (pure CSS)

I have an element with one diagonal side achieved by adjusting linear-gradient and height - in two different states. Now I try to toggle between these states and have a smooth transition of the red triangle, so that it would look like a seesaw :-) The problem is, that from one state to another it changes the direction and is jumpy, I did not find a way to animate it fluently .. Is there a way to to what I want using pure CSS e.g. using transitions?
let btn = document.getElementsByTagName('button')[0];
let stage = document.getElementById('stage');
btn.addEventListener('click', function() {
stage.classList.toggle('fixie');
});
body,
ul {
padding: 0;
margin: 0;
}
#stage {
width: 100%;
height: 14em;
background: pink;
padding: 0;
border: 1px solid blue;
}
#stage::before {
display: block;
position: relative;
width: 100%;
height: 100%;
/*as high as #stage*/
opacity: 0.4;
content: '';
z-index: 1;
background: linear-gradient(to left bottom, red 50%, pink 50%);
/*transition: height 4s;*/
/*transition: linear-gradient 4s 8s;*/
}
#stage.fixie::before {
height: 30%;
background: linear-gradient(to right bottom, red 50%, pink 50%);
}
<div id="stage"></div>
<button>animate gradient</button>
Here is my FIDDLE
As you can't animate linear-gradient, here is a workaround using transform
In this sample I used skew. As the degree of skew will differ based on the width/height, and as long as its ratio is kept, this will be fully responsive, else you'll need a small script.
(function(){
let btn = document.getElementsByTagName('button')[0];
let stage = document.getElementById('stage');
btn.addEventListener('click', function() {
stage.classList.toggle('fixie');
});
})();
body, ul {
padding: 0;
margin: 0;
}
#stage {
position: relative;
overflow: hidden;
width: 90vw;
height: calc(90vw * 0.2677); /* 0.2677, aspect ratio that match skew degree */
background: pink;
padding: 0;
border: 1px solid blue;
}
.navi {
width: 100%;
min-height: 4em;
height: auto;
background: green;
z-index: 2;
position: relative;
}
#stage::before {
content: '';
position: absolute;
width: 100%;
height: 100%; /*as high as #stage*/
bottom: 100%;
opacity: 0.4;
z-index: 1;
background: red;
transform: skewY(15deg);
transform-origin: left bottom;
transition: transform 2s;
}
#stage.fixie::before {
transform: skewY(-15deg) translateY(100%);
}
.navi ul {
list-style: none;
display: flex;
background: lightblue;
justify-content: flex-end;
}
.navi ul li {
display: flex;
align-items: center;
justify-content: center;
min-width: 4em;
width: auto;
height: 2em;
margin: 1px;
background: yellow;
}
<div id="stage"></div>
<button>
animate
</button>
Side note:
One can use any fixed value instead of vw, as long as the #stage's ratio is kept. If to change ratio, you'll either need a script, since CSS calc can't do math with sqrt and sin/cos etc. to get the angle, or using media query's, and have angle's and ratio's manually set for different screens.

Categories