簡體   English   中英

同時使用scaleX和translationX(VelocityJS)

[英]Using scaleX and translationX at the same time (VelocityJS)

我有一個酒吧,從某個百分比填充到另一個百分比(0%-50%)。 我想使動畫朝着新的范圍(25%-55%)移動。 這意味着條的寬度和位置都需要更改。 我在同時順利完成這兩項操作時遇到了一些麻煩。

經過一番研究,我發現我需要使用scaleX順利動畫的寬度和translateX順暢動畫的位置(其中translateX也受規模)。 現在出現的問題是,條形圖將超出其所需的百分比(55%),然后如下面的代碼片段所示向后移動。

 /* Button function to restart. */ const restart = () => { animate(); } const animate = () => { /* Reset the bar to its starting position. (from 0% - 50%) */ Velocity(document.getElementById('movingBar'), { scaleX: 0.5, translateX: 0 }, { duration: 0, easing: [0, 0, 1, 1] }); /* Move the bar to its final position. (from 25% - 55%). */ /* Split into two velocity calls so that they can have a seperate duration/easing if needed. */ Velocity(document.getElementById('movingBar'), { scaleX: 0.30 }, { duration: 1000, easing: [0, 0, 1, 1], queue: false }); Velocity(document.getElementById('movingBar'), { translateX: (25 / 0.30) + '%' }, { duration: 1000, easing: [0, 0, 1, 1], queue: false }); }; /* Start animation on run. */ animate(); 
 #root { width: 700px; height: 100%; } #container { width: 100%; height: 90px; background-color: #000000; } .bar { width: 100%; height: 30px; transform: scaleX(0.5); transform-origin: left; background-color: #FF0000; } #description { display: flex; } .percentage { display: flex; justify-content: flex-end; width: 10%; height: 20px; text-align: right; } .odd { background-color: #DDDDDD; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.2/velocity.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script> <div id='root' style='width: 100%; height: 100%'> <div id='container'> <div class="bar" style="background-color: #00FF00;"></div> <div id='movingBar' class="bar"></div> <div class="bar" style="background-color: #00FF00; transform: scaleX(0.30) translateX(calc(25 / 0.30 * 1%))"></div> </div> <div id='description'> <div class="percentage even">10%</div> <div class="percentage odd">20%</div> <div class="percentage even">30%</div> <div class="percentage odd">40%</div> <div class="percentage even">50%</div> <div class="percentage odd">60%</div> <div class="percentage even">70%</div> <div class="percentage odd">80%</div> <div class="percentage even">90%</div> <div class="percentage odd">100%</div> </div> <button onClick="restart()">restart</button> </div> 

該示例在頂部綠色欄中顯示了起始位置,並在底部綠色欄中顯示了應設置為動畫的所需位置。 中間的紅色條是應該從開始位置到所需位置進行動畫處理的條。 如您所見,紅色條最終達到了預期的結果,但在超過55%之前還沒有達到。 目前,我正在使用VelocityJS進行動畫處理。

知道我做錯了什么或如何制作動畫嗎? 我需要對持續時間/放松進行一些計算以糾正出現問題的地方嗎?

問題與值的插值方式有關。 確保使用scaleX和translateX進行全局線性變換將是一項艱巨的工作,因為您無法控制值的插值,並且瀏覽器將為您完成此操作。 因此,您可以對持續時間/緩和進行復雜的計算以找到理想的結果,或者考慮使用另一種動畫。

在這種情況下,即使支持不是最佳選擇,我也會考慮clip-path但是由於您只需要設置一個動畫屬性,並且不需要任何復雜的計算,因為您只需要使用百分比,就可以輕松處理clip-path 。圖。

這是一個簡化的示例:

 body { background:#000; } .box { height:50px; background:red; clip-path:polygon(10% 100%,10% 0, 40% 0,40% 100%); /*from [10% 40%]*/ transition:1s all; } body:hover .box { clip-path:polygon(50% 100%,50% 0, 60% 0,60% 100%); /*to [50% 60%]*/ } 
 <div class="box"> </div> 

我從數學開始,試圖尋找答案,並且得到了幾乎完美的翻譯緩和: [1/3, 0.2, 2/3, 1 - (8/15)];

我通過為轉換路徑看起來像25x / (-0.2x + 0.5)的公式創建了一個公式。 然后,將其除以83.333333以在[0,1]窗口中獲得所需的轉換公式。 然后,我使用(25x / (-0.2x + 0.5)) / 83.333333來計算上面使用的三次(25x / (-0.2x + 0.5)) / 83.333333點。 請注意,我對第4點做1-C2y,不知道為什么,否則不起作用。

注意:這適用於上面的原始問題,但是當比例從0.5-0.3以外的任何其他值更改時,此方法將無法工作。 我還在弄清楚為什么。

 /* Button function to restart. */ const restart = () => { animate(); } const desiredX = 0.5; let desiredYScale = 0; let desiredYTranslation = 0; const animate = () => { const barMax = 100; const scaleStart = 0.5; const scaleEnd = 0.4; const offsetStart = 0; const offsetEnd = 10; const translationStart = 100 / barMax * offsetStart / scaleStart; const translationEnd = 100 / barMax * offsetEnd / scaleEnd; const dataS = {}; const dataT = {}; const F = 0.5; const scaleFormula = ((-scaleStart + scaleEnd) * F + scaleStart); //console.log("scale formula: ", scaleFormula); const translationPath = (offsetEnd * F) / scaleFormula; const diffPath = translationPath - (offsetEnd / scaleEnd * F); const diffFormulaA = - (diffPath / (F * F)); const diffFormula = (diffFormulaA/diffPath) * (F - 0.5) * (F - 0.5) + 1 const diffA = diffFormulaA / diffPath; const cX = 0.5; const cY = 0.5 * Math.abs(diffA); const cAx = 2/3 * cX; const cAy = 2/3 * cY; const cBx = 2/3 * cX + 1/3 * 1; const cBy = 2/3 * cY + 1/3 * 1; const multiplicant = 0.5; const realCAX = cAx / cBy * multiplicant; const realCAY = cAy / cBy * multiplicant; const realCBX = 1 - (cBx / cBy * multiplicant); const realCBY = cBy / cBy * multiplicant; console.log("realCAX: ", realCAX); console.log("realCAY: ", realCAY); console.log("realCBX: ", realCBX); console.log("realCBY: ", realCBY); const linearEasing = [0, 0, 1, 1]; //const one = 0.5 + (scaleEnd / 4); //const two = 0.525 - (scaleStart - scaleEnd); //const one = 0.40 + 0.025 / (0.5 - (scaleStart - scaleEnd)); //console.log("One: ", one, (scaleStart - scaleEnd)); //const one = 0.5; //const one = 0.535; //const one = 0.5; const one = 0.5; const two = 0.1; //const two = 0.125; //const translationEasing = [0.33, 10, 0.66, 16]; //const translationEasing = [1/3, 0.2, 2/3, 1-(8/15)]; //const translationEasing = [1/3, 1/15, 2/3, 1-0.4]; //const translationEasing = [0.24, 0.06666, 0.85, 0.1]; //const translationEasing = [0.33, 1.33, 0.66, 1.66]; //const translationEasing = [0.2, 0.8, 0.4, 1]; //const translationEasing = [0.1, 0.4, 1-0.2, 0.5]; //const translationEasing = [realCAX, realCAY, realCBX, realCBY]; //const translationEasing = [1/3, 0.0833333, 2/3, 0.42]; const translationEasing = [one, two, 1-two, 1-one]; //const translationEasing = [0, 0, 1, 1];5 /* Reset the bar to its starting position. (from 0% - 50%) */ Velocity(document.getElementById('movingBar'), { scaleX: scaleStart, translateX: translationStart + '%' }, { duration: 0, easing: linearEasing }); /* Move the bar to its final position. (from 25% - 55%). */ /* Split into two velocity calls so that they can have a seperate duration/easing if needed. */ Velocity(document.getElementById('movingBar'), { scaleX: scaleEnd }, { duration: 1000, easing: linearEasing, queue: false, progress: function(elements, complete, remaining, start, tweenValue) { dataS[complete] = scaleStart + ((scaleEnd - scaleStart) * complete); } }); Velocity(document.getElementById('movingBar'), { translateX: translationEnd + '%', tween: translationEnd }, { duration: 1000, easing: translationEasing, queue: false, progress: function(elements, complete, remaining, start, tweenValue) { dataT[complete] = translationStart + ((translationEnd - translationStart) * complete); console.log("TWEEN", complete, tweenValue); }, complete: function() { //console.log("DONE!"); //console.log("SCALE:"); //if (desiredX in dataS) { //console.log('Scale[0.5]: ', dataS[desiredX], ', Translation[0.5]: ', dataT[desiredX]); //desiredYScale = dataS[desiredX]; //desiredYTranslation = dataT[desiredX]; //} else { //animate(); //} for (const key in dataS) { if (dataS.hasOwnProperty(key)) { //console.log('', key, ': ', dataS[key]); } } //console.log("TRANSLATION:"); for (const key in dataT) { if (dataT.hasOwnProperty(key)) { //console.log('', key, ': ', dataT[key]); } } } }); }; /* Start animation on run. */ animate(); 
 #root { width: 700px; height: 100%; } #container { width: 100%; height: 90px; background-color: #000000; } .bar { width: 100%; height: 30px; transform: scaleX(0.5) transform (calc(20 / 0.5 * 1%)); transform-origin: left; background-color: #FF0000; } #description { display: flex; } .percentage { display: flex; justify-content: flex-end; width: 10%; height: 20px; text-align: right; } .odd { background-color: #DDDDDD; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.2/velocity.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script> <div id='root' style='width: 100%; height: 100%'> <div id='container'> <div class="bar" style="background-color: #00FF00; transform: scaleX(0.5) translateX(calc(0 / 0.5 * 1%))"></div> <div id='movingBar' class="bar"></div> <div class="bar" style="background-color: #00FF00; transform: scaleX(0.4) translateX(calc(10 / 0.4 * 1%))"></div> </div> <div id='description'> <div class="percentage even">10%</div> <div class="percentage odd">20%</div> <div class="percentage even">30%</div> <div class="percentage odd">40%</div> <div class="percentage even">50%</div> <div class="percentage odd">60%</div> <div class="percentage even">70%</div> <div class="percentage odd">80%</div> <div class="percentage even">90%</div> <div class="percentage odd">100%</div> </div> <button onClick="restart()">restart</button> </div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM