簡體   English   中英

轉換 <canvas> linearGradient到CSS線性漸變

[英]Converting <canvas> linearGradient to CSS linear-gradient

我有一個使用HTML Canvas創建線性漸變的Web工具。 我想將這些漸變轉換為有效的CSS漸變。 我嘗試了我所知道的關於數學的一切(不是很多)……沒有真正的結果。

我現在知道的事情:-CSS線性gradeint可以從負值開始,而Canvas漸變則不能。

這是我目前的工作:

 var width = 50; var height = 50; var handlesPositions = [ { "x": 0.16, "y": -1.98 }, { "x": 0.84, "y": 2.98 }, ] var colorStops = [ { "color": "#FF0000", "position": 0.359 }, { "color": "#0094FF", "position": 0.495 }, { "color": "#FFFF00", "position": 0.652 } ]; // CANVAS var c = document.getElementById("source"); var ctx = c.getContext("2d"); var x0 = handlesPositions[0].x * width; var y0 = handlesPositions[0].y * height; var x1 = handlesPositions[1].x * width; var y1 = handlesPositions[1].y * height; var grd = ctx.createLinearGradient(x0, y0, x1, y1); grd.addColorStop(colorStops[0].position, colorStops[0].color); grd.addColorStop(colorStops[1].position, colorStops[1].color); grd.addColorStop(colorStops[2].position, colorStops[2].color); ctx.fillStyle = grd; ctx.fillRect(0, 0, 50, 50); // CANVAS TO CSS function canvasToLinearGradient(handles, stops) { const handle0 = handles[0]; const handle1 = handles[1]; const ydiff = handle1.y - handle0.y; const xdiff = handle0.x - handle1.x; const angle = Math.atan2(-xdiff, -ydiff); const cssStops = stops.map((stop) => { return `${stop.color} ${Math.round(stop.position * 100)}%`; }).join(', '); return `linear-gradient(${angle}rad, ${cssStops})`; } document.getElementById("current").style.backgroundImage = canvasToLinearGradient(handlesPositions, colorStops); 
 #goal { background: linear-gradient(172.19deg, #FF0000 -12.39%, #0094FF 48.06%, #FFFF00 117.89%); } .row { display: flex;flex-direction:row;justify-content:space-between;align-items:center;margin-bottom:10px } 
 <div style="width: 230px"> <div class="row">Goal <div id="goal" style="width:50px;height:50px;"></div></div> <div class="row">Source <canvas id="source" width="50" height="50"></canvas></div> <div class="row">Current result <div id="current" style="width:50px;height:50px;"></div> </div> 

正如我在上一個答案中所解釋的,您可以嘗試依靠background-size / background-position來創建漸變。

首先,這里是您如何轉換第一個漸變以使顏色介於0%100%並稍后使用Canvas輕松處理的方法

 #goal { background: linear-gradient(172.19deg, #FF0000 -12.39%, #0094FF 48.06%, #FFFF00 117.89%); } #goal-1 { /*we add 12.39% to all to make the first one 0%*/ background: linear-gradient(172.19deg, #FF0000 0%, #0094FF 60.45%, #FFFF00 130.29%); } #goal-2 { /*we divide by 1.3029 all to make the last one 100%*/ background: linear-gradient(172.19deg, #FF0000 0%, #0094FF 46.39%, #FFFF00 100%); } #goal-3 { /*we increase the size by 1.3029 to rectify the previous division*/ background: linear-gradient(172.19deg, #FF0000 0%, #0094FF 46.39%, #FFFF00 100%); background-size:130.29% 130.29%; } #goal-4 { /*we move the gradient to rectify the -12.39%*/ background: linear-gradient(172.19deg, #FF0000 0%, #0094FF 46.39%, #FFFF00 100%); background-size:130.29% 130.29%; background-position:calc((-0.1239 * 50px)/1.3029) calc((-0.1239 * 50px)/1.3029) } #goal-5 { /*we can also wrote*/ background: linear-gradient(172.19deg, #FF0000 0%, #0094FF 46.39%, #FFFF00 100%) calc((-0.1239 * 50px)/1.3029) calc((-0.1239 * 50px)/1.3029)/ 130.29% 130.29%;} .row { display: flex; flex-direction: row; justify-content: space-between; align-items: center; margin-bottom: 10px } 
 <div style="width: 230px"> <div class="row">Goal <div id="goal" style="width:50px;height:50px;"></div> </div> <div class="row">Transition 1 <div id="goal-1" style="width:50px;height:50px;"></div> </div> <div class="row">Transition 2 <div id="goal-2" style="width:50px;height:50px;"></div> </div> <div class="row">Transition 3 <div id="goal-3" style="width:50px;height:50px;"></div> </div> <div class="row">Transition final <div id="goal-4" style="width:50px;height:50px;"></div> </div> <div class="row">Transition final <div id="goal-5" style="width:50px;height:50px;"></div> </div> </div> 

現在,我們可以應用此邏輯來查找漸變。 我們已經有了色標。 現在我們需要正確找到漸變的大小,即兩點之間的距離。 然后找到背景位置。

這是我嘗試添加背景尺寸的第一次嘗試:

 var width = 50; var height = 50; var handlesPositions = [ { "x": 0.16, "y": -1.98 }, { "x": 0.84, "y": 2.98 }, ] var colorStops = [ { "color": "#FF0000", "position": 0.359 }, { "color": "#0094FF", "position": 0.495 }, { "color": "#FFFF00", "position": 0.652 } ]; // CANVAS var c = document.getElementById("source"); var ctx = c.getContext("2d"); var x0 = handlesPositions[0].x * width; var y0 = handlesPositions[0].y * height; var x1 = handlesPositions[1].x * width; var y1 = handlesPositions[1].y * height; var grd = ctx.createLinearGradient(x0, y0, x1, y1); grd.addColorStop(colorStops[0].position, colorStops[0].color); grd.addColorStop(colorStops[1].position, colorStops[1].color); grd.addColorStop(colorStops[2].position, colorStops[2].color); ctx.fillStyle = grd; ctx.fillRect(0, 0, 50, 50); // CANVAS TO CSS function canvasToLinearGradient(handles, stops) { const handle0 = handles[0]; const handle1 = handles[1]; const ydiff = handle1.y - handle0.y; const xdiff = handle0.x - handle1.x; const angle = Math.atan2(-xdiff, -ydiff); const dist= Math.sqrt((y1-y0)*(y1-y0) + (x1-x0)*(x1-x0)); console.log(dist); const cssStops = stops.map((stop) => { return `${stop.color} ${stop.position * 100}%`; }).join(', '); return `linear-gradient(${angle}rad, ${cssStops}) 50% 50%/${dist}px ${dist}px`; } document.getElementById("current").style.background = canvasToLinearGradient(handlesPositions, colorStops); 
 #goal { background: linear-gradient(172.19deg, #FF0000 -12.39%, #0094FF 48.06%, #FFFF00 117.89%); } .row { display: flex;flex-direction:row;justify-content:space-between;align-items:center;margin-bottom:10px } 
 <div style="width: 230px"> <div class="row">Goal <div id="goal" style="width:50px;height:50px;"></div></div> <div class="row">Source <canvas id="source" width="50" height="50"></canvas></div> <div class="row">Current result <div id="current" style="width:50px;height:50px;"></div> </div> 

如您所見,我們幾乎很好。 位置的計算有些棘手,將需要更多的深度說明。 稍后將嘗試對其進行編輯。

暫無
暫無

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

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