0

Is there a way to control the level of implementation of a class change in JS / jQuery.

Imagine the following:

.box {
background: green;
width: 500px;
height: 100px;
transition:all 1s;
}
.box.active {
tranform: translateX(200px);
width:250px;
background:blue;
}

Conventionally using jQuery for example we would add and remove the new class experiencing an animation as it changes to the "active" state.

$("box").addClass("active");

BUT.. What is we want to implement 50% or even 28% of the active state. Imagine a scrolling gallery where we have multiple elements experiencing multiple transitions and we are matching the extent of those transitions to the level the user has scrolled or dragged on the gallery. Hope that makes sense.

eg. $("box").partialAddClass("active", 20% );

Is such a thing possible. Are there alternative ways of achieving this. We can obviously do this to some extent by creating the css properties of the normal and active state in JS and applying them but this works for numeric qualities like opacity and width. It is hardly the most efficient method for the programmer though. Is there an easy option.

Walrus
  • 19,801
  • 35
  • 121
  • 199
  • So in other words, you want to control the class numeric values by an overal percentage? E.G 50% partial = width:125px & translateX(100px) ? – ProEvilz Oct 05 '17 at 12:42
  • @ProEvilz partly yes. It would be nice to also control no numeric qualities but not essential. – Walrus Oct 05 '17 at 12:43
  • Well sure you can do it, you just need to create a JS function to output the CSS – ProEvilz Oct 05 '17 at 12:44
  • @ProEvilz Thought that might be the only way. – Walrus Oct 05 '17 at 12:45
  • 3
    No, of course that is not possible, because it does not even make _sense_. You can not “partially apply a class” - the class only _selects the element_ here, and the idea of doing _that_ “only a bit” ... makes no sense whatsoever. – CBroe Oct 05 '17 at 12:45
  • @CBroe Thank you for your input. Sorry to hear it isn't possible. Its hardly nonsensical though. I gave you an example usage where it would be very handy. – Walrus Oct 05 '17 at 12:47
  • But it *is* possible to achieve this via a simple JS function – ProEvilz Oct 05 '17 at 12:48
  • 2
    I did not say what you _want_ is nonsense, but the idea that it could be achieved this way. With CSS _animations_ you can do some stuff that might go vaguely into the direction, but I am not sure if that would be applicable for your situation. https://stackoverflow.com/q/29513628/1427878, https://stackoverflow.com/q/18006099/1427878 – CBroe Oct 05 '17 at 12:50
  • @CBroe OP's example is an example **function** and as such, functions can do what ever you want provided you can code it. Therefor, I disagree. I'm going to add an example – ProEvilz Oct 05 '17 at 12:52
  • 1
    @ProEvilz I am not saying you can’t manipulate the CSS values directly ... but you can not do this by some “magic” that calculates “20% of a class” or sth. like that; that logic will have to be explicitly written. (This may be more about the actual phrasing, granted - but understanding what the desired effect entails and what needs to happen to achieve it, is part of solving a problem.) – CBroe Oct 05 '17 at 12:56

3 Answers3

0

You can't do what you want with just plain CSS. You can however do it with Javascript. I'm going to show you how to do it with LESS, which is a super-set of CSS.

Take this for example. Taken directly from their docs.

.average(@x, @y) {
    @average: ((@x + @y) / 2);
}

div {
  .average(16px, 50px); // "call" the mixin
  padding: @average;    // use its "return" value
}

You essentially define a function and pass in arguments to it. In your case, you can do this,

.cutDownByPercent(@percent, @width, @height){
    @cutDownWidth: @percent * @width;
    @cutDownHeight: @percent * @height;
}  
.box {
    background: green;
    .cutDownByPercent(0.2, 500, 100);
    width: @cutDownWidth;
    height: @cutDownHeight;
    transition:all 1s;
}

This can be done with Javascript, but I just want to show you and others that it can be done in CSS. You just have to create multiple classes within the LESS file.

Jimenemex
  • 3,104
  • 3
  • 24
  • 56
0

So this is the basic idea I have using jQuery. This function assumes that you would set this up specifically for a certain class. You could expand it to accept CSS as a parameter or to even use .CSS() to detect the styles (to make it a global function) and manipulate it from there. But this should be a starting point...

It works by passing the percentage you want and then the class name of the element you wish to affect. For colors, you can use a hex color code to rgba converted. Then, you can control the alpha channel of the rgba to control the opacity.

function addPartialClass(percentage, el){
  var w = 250;
  var tr = 200;
 w = w/100*percentage;
 tr = tr/100*percentage;
 $(el).css({
  'transform': 'translateX('+tr+'px)',
  'width': w
 });
}

$('button').on('click', function(){
  addPartialClass(50, ".box"); 
});
.box {
background: green;
width: 500px;
height: 100px;
transition:all 1s;
}
.box.active {
transform: translateX(200px);
width:250px;
background:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box"></div>

<button>Click me</button>
ProEvilz
  • 5,310
  • 9
  • 44
  • 74
0

As suggested by @CBroe in comment, you can get "partial" style application with animation:

@keyframes x {
  from { /* State "A". Could as well be the initial style. */
    background: green;
    color: gold;
    width: 250px;
  }
  to { /* State "B". */
    background: blue;
    color: white;
    width: 500px;
  }
  50% { /* … just to show off */
    font-weight: bold;
    font-style: italic;
  }
}
.box {
  animation-name: x;
  animation-duration: 1s; /* "100%" */
  animation-play-state: paused; /* don't move */
  animation-timing-function: linear; /* predictable */
  animation-iteration-count: 1; /* no need for more */
  animation-fill-mode: both; /* just to show the initial and final states */
}
.box.halfway {
  animation-delay: -0.5s; /* = start in the middle, 50% of the duration */
}
.box.twenty {
  animation-delay: -0.2s; /* = 20% */
}
.box.finish {
  animation-delay: -1s; /* = 100% */
}
<p class="box">State "A"</p>
<p class="box twenty">20% applied State "B"</p>
<p class="box halfway">Half applied State "B"</p>
<p class="box finish">State "B"</p>

(Update 2018-01-23: realized you can exploit negative delay and paused state from the start, so no need for JS and calculations. Wohoo!)

myf
  • 9,874
  • 2
  • 37
  • 49