РЕДАКТИРОВАТЬ: Мне действительно удалось это решить! для которого я знаю разворот. Пост ниже и мое объяснение основаны на функции ослабления с использованием sin (), которую нелегко отменить. Не только это, но и встроенная функция ослабления для ease-out
не соответствует функции sin (), на которую я ссылался (я не совсем уверен, на чем основана эта сборка). Но я понял, что могу дать ему свою функцию, для которой я знал разворот, и бум работает как шарм!
Это был очень информативный опыт для меня, я рад, что у меня решение, которое работает. Я все еще думаю, что окунусь в другие идеи, которые мне нужно было посмотреть, какие из них будут лучше в долгосрочной перспективе.
Исторический пост:
Итак, после нескольких ночей, когда я ломал голову над этим, я пришел к выводу, что это либо невозможно, как я думал об этом, либо Если это возможно, то решение настолько надумано, что оно, вероятно, того не стоит, и мне лучше разработать новое решение (одно из которых я придумал, или несколько вещей, которые я хотел бы попробовать).
Пожалуйста, посмотрите этот jsfiddle для моего окончательного «решения» и вскрытия
https://jsfiddle.net/blitzmann/zc80p1n4/
let currentPercentageState = 0;
let easing = "linear";
let duration = 1000;
function animate(percentage) {
percentage = parseFloat(percentage);
// determine if we've crossed the 0 threshold, which would force us to do something else here
let threshold = currentPercentageState / percentage < 0;
console.log("Crosses 0: " + threshold);
if (!threshold && percentage != 0) {
// determine which blind we're animating
let blind = percentage < 0 ? "left" : "right";
$(`.blind.${blind}`)[0].animate(
[
{
transform: `translateX(${currentPercentageState}%)`,
easing: easing
},
{
transform: `translateX(${percentage}%)`
}
],
{
fill: "forwards",
duration: duration
}
);
} else {
// this happens when we cross the 0 boundry
// we'll have to create two animations - one for moving the currently offset blind back to 0, and then another to move the second blind
let firstBlind = percentage < 0 ? "right" : "left";
let secondBlind = percentage < 0 ? "left" : "right";
// get total travel distance
let delta = currentPercentageState - percentage;
// find the percentage of that travel that the first blind is responsible for
let firstTravel = currentPercentageState / delta;
let secondTravel = 1 - firstTravel;
console.log("delta; total values to travel: ", delta);
console.log(
"firstTravel; percentage of the total travel that should be done by the first blind: ",
firstTravel
);
console.log(
"secondTravel; percentage of the total travel that should be done by the second blind: ",
secondTravel
);
// animate the first blind.
$(`.blind.${firstBlind}`)[0].animate(
[
{
transform: `translateX(${currentPercentageState}%)`,
easing: easing
},
{
// we go towards the target value instead of 0 since we'll cut the animation short
transform: `translateX(${percentage}%)`
}
],
{
fill: "forwards",
duration: duration,
// cut the animation short, this should run the animation to this x value of the easing function
iterations: firstTravel
}
);
// animate the second blind
$(`.blind.${secondBlind}`)[0].animate(
[
{
transform: `translateX(${currentPercentageState}%)`,
easing: easing
},
{
transform: `translateX(${percentage}%)`
}
],
{
fill: "forwards",
duration: duration,
// start the iteration where the first should have left off. This should put up where the easing function left off
iterationStart: firstTravel,
// we only need to carry this aniamtion the rest of the way
iterations: 1-firstTravel,
// delay this animation until the first "meets" it
delay: duration * firstTravel
}
);
}
// save the new value so that the next iteration has a proper from keyframe
currentPercentageState = percentage;
}
// the following are just binding set ups for the buttons
$(document).ready(function () {
$(".apply").click(function () {
animate($("#amount").val());
});
$(".reset").click(function () {
animate(0);
});
$(".random").click(function () {
var val = (Math.random() * 2 - 1) * 100;
$("#amount").val(val);
animate(val);
});
$(".randomPos").click(function () {
var val = Math.random() * 100;
$("#amount").val(val);
animate(val);
});
$(".randomNeg").click(function () {
var val = Math.random() * -100;
$("#amount").val(val);
animate(val);
});
$(".flipSign").click(function () {
animate(currentPercentageState * -1);
});
$(".toggleBlinds").click(function () {
$(".blind").toggle();
});
$(".toggleLeft").click(function () {
$(".blind.left").toggle();
});
$(".toggleRight").click(function () {
$(".blind.right").toggle();
});
});
animate(50);
//setTimeout(()=>animate(-100), 1050)
$(function () {
// Build "dynamic" rulers by adding items
$(".ruler[data-items]").each(function () {
var ruler = $(this).empty(),
len = Number(ruler.attr("data-items")) || 0,
item = $(document.createElement("li")),
i;
for (i = -11; i < len - 11; i++) {
ruler.append(item.clone().text(i + 1));
}
});
// Change the spacing programatically
function changeRulerSpacing(spacing) {
$(".ruler")
.css("padding-right", spacing)
.find("li")
.css("padding-left", spacing);
}
changeRulerSpacing("30px");
});
.wrapper {
margin: 10px auto 2px;
height: 10px;
width: 600px;
background: linear-gradient(to right, red 50%, green 50%);
border: 1px solid black;
box-sizing: border-box;
position: relative;
overflow: hidden;
}
.blind {
height: 100%;
position: absolute;
top: 0;
background-color: rgb(51, 51, 51);
min-width: 50%;
}
.blind.right {
left: 50%;
border-left: 1px solid white;
transform-origin: left top;
}
.blind.left {
border-right: 1px solid white;
transform-origin: left top;
}
#buttons {
text-align: center;
}
/* Ruler crap */
.ruler-container {
text-align: center;
}
.ruler, .ruler li {
margin: 0;
padding: 0;
list-style: none;
display: inline-block;
}
/* IE6-7 Fix */
.ruler, .ruler li {
*display: inline;
}
.ruler {
display:inline-block;
margin: 0 auto;https://jsfiddle.net/user/login/
background: lightYellow;
box-shadow: 0 -1px 1em hsl(60, 60%, 84%) inset;
border-radius: 2px;
border: 1px solid #ccc;
color: #ccc;
height: 3em;
padding-right: 1cm;
white-space: nowrap;
margin-left: 1px;
}
.ruler li {
padding-left: 1cm;
width: 2em;
margin: .64em -1em -.64em;
text-align: center;
position: relative;
text-shadow: 1px 1px hsl(60, 60%, 84%);
}
.ruler li:before {
content: '';
position: absolute;
border-left: 1px solid #ccc;
height: .64em;
top: -.64em;
right: 1em;
}
Спасибо тем, кто пытался решить эту, по общему признанию, сложную задачу