From f40a5fbe97f3d9f9f51c1a8040104c6c65ab5009 Mon Sep 17 00:00:00 2001 From: rex Date: Tue, 2 Jun 2020 21:40:34 +0800 Subject: [PATCH] fix(circle): fix type not work (#3228) fix #3168 --- example/pages/circle/index.wxml | 2 +- package.json | 2 +- packages/circle/README.md | 2 +- packages/circle/canvas.ts | 47 +++++++++++++++++++ packages/circle/index.ts | 81 ++++++++++++++++++++++----------- packages/circle/index.wxml | 4 +- yarn.lock | 8 ++-- 7 files changed, 110 insertions(+), 36 deletions(-) create mode 100644 packages/circle/canvas.ts diff --git a/example/pages/circle/index.wxml b/example/pages/circle/index.wxml index a1175caf..02ca4048 100644 --- a/example/pages/circle/index.wxml +++ b/example/pages/circle/index.wxml @@ -1,5 +1,5 @@ - + diff --git a/package.json b/package.json index 1fb9283b..c10c9dec 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "less": "^3.9.0", "less-loader": "^5.0.0", "lint-staged": "^10.0.0", - "miniprogram-api-typings": "2.10.4", + "miniprogram-api-typings": "2.11.0", "miniprogram-ci": "^1.0.27", "postcss-loader": "^3.0.0", "prettier": "^2.0.5", diff --git a/packages/circle/README.md b/packages/circle/README.md index ff7cf0c9..df3d171d 100644 --- a/packages/circle/README.md +++ b/packages/circle/README.md @@ -89,7 +89,7 @@ Page({ | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | | value | 目标进度 | _number_ | `0` | - | -| type | 指定 canvas 类型,可选值为 `2d` `webgl` | _string_ | - | - | +| type | 指定 canvas 类型,可选值为 `2d` | _string_ | - | - | | size | 圆环直径,默认单位为 `px` | _number_ | `100` | - | | color | 进度条颜色,传入对象格式可以定义渐变色 | _string \| object_ | `#1989fa` | - | | layer-color | 轨道颜色 | _string_ | `#fff` | - | diff --git a/packages/circle/canvas.ts b/packages/circle/canvas.ts new file mode 100644 index 00000000..c82724a9 --- /dev/null +++ b/packages/circle/canvas.ts @@ -0,0 +1,47 @@ +type CanvasContext = WechatMiniprogram.CanvasContext; + +export function adaptor( + ctx: CanvasRenderingContext2D +): CanvasContext & CanvasRenderingContext2D { + // @ts-ignore + return Object.assign(ctx, { + setStrokeStyle(val) { + ctx.strokeStyle = val; + }, + setLineWidth(val) { + ctx.lineWidth = val; + }, + setLineCap(val) { + ctx.lineCap = val; + }, + setFillStyle(val) { + ctx.fillStyle = val; + }, + setFontSize(val) { + ctx.font = String(val); + }, + setGlobalAlpha(val) { + ctx.globalAlpha = val; + }, + setLineJoin(val) { + ctx.lineJoin = val; + }, + setTextAlign(val) { + ctx.textAlign = val; + }, + setMiterLimit(val) { + ctx.miterLimit = val; + }, + setShadow(offsetX, offsetY, blur, color) { + ctx.shadowOffsetX = offsetX; + ctx.shadowOffsetY = offsetY; + ctx.shadowBlur = blur; + ctx.shadowColor = color; + }, + setTextBaseline(val) { + ctx.textBaseline = val; + }, + createCircularGradient() {}, + draw() {}, + }); +} diff --git a/packages/circle/index.ts b/packages/circle/index.ts index 16718e2e..c8292308 100644 --- a/packages/circle/index.ts +++ b/packages/circle/index.ts @@ -1,6 +1,7 @@ import { VantComponent } from '../common/component'; import { isObj } from '../common/utils'; import { BLUE, WHITE } from '../common/color'; +import { adaptor } from './canvas'; function format(rate) { return Math.min(Math.max(rate, 0), 100); @@ -28,6 +29,9 @@ VantComponent({ size: { type: Number, value: 100, + observer() { + this.drawCircle(this.currentValue); + }, }, fill: String, layerColor: { @@ -59,38 +63,60 @@ VantComponent({ methods: { getContext() { - if (!this.ctx) { - this.ctx = wx.createCanvasContext('van-circle', this); + const { type } = this.data; + + if (type === '') { + const ctx = wx.createCanvasContext('van-circle', this); + return Promise.resolve(ctx); } - return this.ctx; + + const dpr = wx.getSystemInfoSync().pixelRatio; + + return new Promise((resolve) => { + wx.createSelectorQuery() + .in(this) + .select('#van-circle') + .fields({ node: true, size: true }) + .exec((res) => { + const canvas = res[0].node; + const ctx = canvas.getContext(type); + + canvas.width = res[0].width * dpr; + canvas.height = res[0].height * dpr; + ctx.scale(dpr, dpr); + + resolve(adaptor(ctx)); + }); + }); }, setHoverColor() { - const { color, size, type } = this.data; - const context = type ? this.getContext(type) : this.getContext(); - + const { color, size } = this.data; let hoverColor = color; - if (isObj(color)) { - const LinearColor = context.createLinearGradient(size, 0, 0, 0); - Object.keys(color) - .sort((a, b) => parseFloat(a) - parseFloat(b)) - .map((key) => - LinearColor.addColorStop(parseFloat(key) / 100, color[key]) - ); - hoverColor = LinearColor; - } + this.getContext().then((context) => { + if (isObj(color)) { + const LinearColor = context.createLinearGradient(size, 0, 0, 0); + Object.keys(color) + .sort((a, b) => parseFloat(a) - parseFloat(b)) + .map((key) => + LinearColor.addColorStop(parseFloat(key) / 100, color[key]) + ); + hoverColor = LinearColor; + } - this.setData({ hoverColor }); + this.setData({ hoverColor }); + }); }, presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) { - const { strokeWidth, lineCap, clockwise, size } = this.data; + const { strokeWidth, lineCap, clockwise, size, type } = this.data; const position = size / 2; const radius = position - strokeWidth / 2; context.setStrokeStyle(strokeStyle); context.setLineWidth(strokeWidth); context.setLineCap(lineCap); + context.beginPath(); context.arc(position, position, radius, beginAngle, endAngle, !clockwise); context.stroke(); @@ -118,17 +144,19 @@ VantComponent({ }, drawCircle(currentValue) { - const { size, type } = this.data; - const context = type ? this.getContext(type) : this.getContext(); - context.clearRect(0, 0, size, size); - this.renderLayerCircle(context); + const { size } = this.data; - const formatValue = format(currentValue); - if (formatValue !== 0) { - this.renderHoverCircle(context, formatValue); - } + this.getContext().then((context) => { + context.clearRect(0, 0, size, size); + this.renderLayerCircle(context); - context.draw(); + const formatValue = format(currentValue); + if (formatValue !== 0) { + this.renderHoverCircle(context, formatValue); + } + + context.draw(); + }); }, reRender() { @@ -171,7 +199,6 @@ VantComponent({ }, destroyed() { - this.ctx = null; this.clearInterval(); }, }); diff --git a/packages/circle/index.wxml b/packages/circle/index.wxml index 607fc9d5..52bc59fc 100644 --- a/packages/circle/index.wxml +++ b/packages/circle/index.wxml @@ -1,9 +1,9 @@ - + {{ text }} - \ No newline at end of file + diff --git a/yarn.lock b/yarn.lock index 9b06e3cc..5cb57cb5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7978,10 +7978,10 @@ minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -miniprogram-api-typings@2.10.4: - version "2.10.4" - resolved "https://registry.npmjs.org/miniprogram-api-typings/-/miniprogram-api-typings-2.10.4.tgz#13165d1e77084c3ec79ec93d8c74974f77425eb0" - integrity sha512-IXWi6sJFd/EH1wNR8rtOx2+hJOwZk7jKFVIshQ0aAlRaKk0P4Jack4SItzUwNURgRykvrleGgErI/jH5hsiniw== +miniprogram-api-typings@2.11.0: + version "2.11.0" + resolved "http://registry.npm.qima-inc.com/miniprogram-api-typings/download/miniprogram-api-typings-2.11.0.tgz#c0a91ca2fea80e344509399c580cbad504a8f905" + integrity sha1-wKkcov6oDjRFCTmcWAy61QSo+QU= miniprogram-ci@^1.0.27: version "1.0.29"