如题,需求如下图,实现这样一个图表,目前实现了环形图,但是渐变卡住了。
设计稿:
目前实现:
迫于不精通 Canvas ,想请教 v 友如何实现这样的环形渐变。
代码如下
async drawCanvas () {
await Taro._helper.waiting(200)
var exer_data = (this.archive.score_exercise - 60) * 12;
var skin_data = (this.archive.score_skin - 60) * 12;
var climate_data = (this.archive.score_climate - 60) * 12;
var AQI_data = (this.archive.score_air_quality - 60) * 12;
var uv_data = (this.archive.score_uv - 60) * 12;
var Mind_data = (this.archive.score_mind - 60) * 12;
var Nutrition_data = (this.archive.score_nutrition - 60) * 12;
wx.createSelectorQuery()
.select('#myCanvas') // 在 W
.fields({ node: true, size: true })// XML 中填入的 id
.exec((res) => {
const blob = (mask) => {
ctx.beginPath()
mask(data)
ctx.clip()
}
const drawBars = (opacity, thickness, radius, shadow = false) => {
ctx.rotate(3.1)
let colors = ["#F84F45", "#FE5C1E", "#FFE145", "#2EDC90", "#1CEEFC", "#3033FC", "#F117DB"];
let t = -1
// const gnt = ctx.createLinearGradient(0, 134, 20, 134)
// gnt.addColorStop(0/6, colors[0])
// gnt.addColorStop(1/6, colors[1])
// gnt.addColorStop(2/6, colors[2])
// gnt.addColorStop(3/6, colors[3])
// gnt.addColorStop(4/6, colors[4])
// gnt.addColorStop(5/6, colors[5])
// gnt.addColorStop(1, colors[6])
d3.range(totalBars).forEach(i => {
ctx.rotate(barThickness)
if (i % 2 === 0) {
// if (i % bars === 0) {
// ctx.fillStyle = 'rgba(255,255,255,0)'
// } else {
//
// }
if (parseInt(i % 20) == 0) {
t++
}
if (shadow) {
ctx.fillStyle = d3.rgb('#C2EFFF')
} else {
// ctx.fillStyle = gnt
ctx.fillStyle = d3.rgb(colors[t])
}
ctx.fillRect(0, 0, thickness, radius)
}
})
}
const drawCircle = (radius) => {
ctx.beginPath()
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 8;
ctx.shadowColor = '#DDF4FF';
ctx.fillStyle = 'white'
ctx.arc(0, 0, radius, 0, 2 * Math.PI)
ctx.fill()
}
var c = res[0].node
var ctx = c.getContext('2d')
const dpr = wx.getSystemInfoSync().pixelRatio
c.width = res[0].width * dpr
c.height = res[0].height * dpr
ctx.scale(dpr, dpr)
var data = [exer_data, skin_data, climate_data, AQI_data, uv_data, Mind_data, Nutrition_data];
var width = res[0].width
var category = 7
var bars = 20
var totalBars = category * bars
var innerCircleRadius = 20
var barHeight = (width - 60)/2
var shadowInnerCircle = innerCircleRadius - 20
var shadowBarHeight = barHeight + 10
var extent = d3.extent([0, 500])
var barThickness = 2 * Math.PI / totalBars
var barWidth = 40 * barThickness
var shadowExtent = d3.extent([0, 500 + 30])
var scales = {}
scales.bar = d3.scaleLinear().domain(extent).range([innerCircleRadius + 5, innerCircleRadius + barHeight - 15])
scales.shadow = d3.scaleLinear().domain(shadowExtent).range([shadowInnerCircle, shadowBarHeight])
scales.bar.range([0, innerCircleRadius + barHeight - 20])
var masks = {}
var categoryArcThickness = 2 * Math.PI / 7
var categoryMaxOffset = categoryArcThickness * 0.5
masks.bar = d3.radialLine()
.radius(d => {
return scales.bar(d)
})
.angle((d, i) => {
return (i * categoryArcThickness) - categoryMaxOffset
})
.curve(d3.curveCardinalClosed)
.context(ctx)
masks.shadow = d3.radialLine()
.radius(d => {
return scales.shadow(d) + 25
})
.angle((d, i) => {
return (i * categoryArcThickness) - categoryMaxOffset
})
.curve(d3.curveCardinalClosed)
.context(ctx)
ctx.translate(width / 2, width / 2)
ctx.save()
ctx.setTransform(1, 0, 0, 1, 0, 0)
ctx.clearRect(0, 0, 3 * width, 3 * width)
ctx.restore()
ctx.save()
ctx.beginPath()
ctx.rotate(3.1)
d3.range(totalBars).forEach(i => {
ctx.rotate(barThickness)
if (i % 2 === 0) {
if (i % bars === 0) {
const gnt = ctx.createLinearGradient(0, 0, 0, width/2)
gnt.addColorStop(0, '#C7C3D2')
gnt.addColorStop(1, '#FFFFFF')
ctx.fillStyle = gnt
// ctx.fillStyle = 'rgba(230,230,230, .5)'
ctx.fillRect(0, 0, 1.5, width/2)
} else {
}
}
})
ctx.restore()
ctx.save()
blob(masks.shadow)
drawBars(1, 1.5, 200, true)
ctx.restore()
ctx.save()
ctx.beginPath()
blob(masks.bar)
drawBars(1, 1.5, 200)
ctx.closePath()
drawCircle(innerCircleRadius - 5)
ctx.restore()
ctx.save()
})
}
如果可以直接有偿帮我完成这个需求就更好了 XD
详聊绿色:Y2FsaWJ1b3Jz
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.