123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- <template>
- <view class="l-f2" :style="customStyle" v-if="canvasId">
- <!-- #ifndef APP-NVUE -->
- <cover-view class="l-f2__mask" v-if="isMask"></cover-view>
- <canvas
- class="l-f2__canvas"
- v-if="use2dCanvas"
- type="2d"
- :id="canvasId"
- :style="'width:' + width + 'px;height:' + height + 'px'"
- :disable-scroll="isDisableScroll"
- @touchstart="touchStart"
- @touchmove="touchMove"
- @touchend="touchEnd"
- />
- <canvas
- class="l-f2__canvas"
- v-else
- :width="nodeWidth"
- :height="nodeHeight"
- :style="'width:' + width + 'px;height:' + height + 'px'"
- :canvas-id="canvasId"
- :id="canvasId"
- :disable-scroll="isDisableScroll"
- @touchstart="touchStart"
- @touchmove="touchMove"
- @touchend="touchEnd"
- />
- <view v-if="isCloud" style="width:2048px; height:2048px; position: fixed; left: 9999px;">
- <canvas v-if="use2dCanvas" type="2d" :canvas-id="canvasId + '_cloud'" :id="canvasId + '_cloud'" class="l-f2__canvas"></canvas>
- <canvas v-else :canvas-id="canvasId + '_cloud'" :id="canvasId + '_cloud'" class="l-f2__canvas"></canvas>
- </view>
- <!-- #endif -->
- <!-- #ifdef APP-NVUE -->
- <web-view
- class="l-f2__canvas"
- :id="canvasId"
- ref="webview"
- :webviewStyles="webviewStyles"
- src="http://liangei.gitee.io/limeui/hybrid/html/lime-ui/lime-f2/index.html?v=0.4.8"
- @pagefinish="isFinish = true"
- @onPostMessage="onMessage"
- ></web-view>
- <!-- #endif -->
- </view>
- </template>
- <script>
- // #ifndef APP-NVUE
- import extendContext from './canvas';
- import { compareVersion, wrapEvent, pixelRatio } from './utils';
- // #endif
- // #ifdef APP-NVUE
- import { base64ToPath } from './utils';
- // #endif
- export default {
- // version: '0.5.1'
- name: 'lime-f2',
- props: {
- // #ifdef MP-WEIXIN || MP-TOUTIAO
- type: {
- type: String,
- default: '2d'
- },
- // #endif
- // #ifdef APP-NVUE
- webviewStyles: Object,
- params: {
- type: Object,
- default: () => {}
- },
- // #endif
- customStyle: String,
- imageMask: String,
- source: {
- type: Array,
- default: () => []
- },
- isAutoPlay: Boolean,
- isDisableScroll: Boolean,
- isCloud: Boolean,
- onInit: {
- type: [Function, Object],
- default: () => {}
- }
- },
- data() {
- return {
- // #ifdef MP-WEIXIN || MP-TOUTIAO
- use2dCanvas: true,
- // #endif
- // #ifndef MP-WEIXIN || MP-TOUTIAO
- use2dCanvas: false,
- // #endif
- // #ifndef APP-NVUE
- width: null,
- height: null,
- nodeWidth: null,
- nodeHeight: null,
- isMask: false,
- isInited: false,
- imageData: null,
- // config: {},
- // #endif
- // #ifdef APP-NVUE
- isFinish: false,
- file: ''
- // #endif
- };
- },
- computed: {
- canvasId() {
- return `l-f2${this._uid}`;
- }
- },
- watch: {
- isAutoPlay(val) {
- if (val) {
- this.changeData(this.source);
- }
- },
- source: {
- handler: function(data) {
- if (this.isAutoPlay) {
- this.changeData(data);
- }
- },
- deep: true
- }
- },
- beforeDestroy() {
- this.clear();
- this.destroy();
- },
- created() {
- this.config = {}
- this.isMask = this.isCloud && this.imageMask;
- // #ifdef MP-WEIXIN || MP-TOUTIAO
- const { SDKVersion, version, platform, environment } = uni.getSystemInfoSync();
- // #endif
- // #ifdef MP-WEIXIN
- this.use2dCanvas = this.type === '2d' && compareVersion(SDKVersion, '2.9.2') >= 0 && !((/ios/i.test(platform) && /7.0.20/.test(version)) || /wxwork/i.test(environment)) && !/windows/i.test(platform);;
- // #endif
- // #ifdef MP-TOUTIAO
- this.use2dCanvas = this.type === '2d' && compareVersion(SDKVersion, '1.78.0') >= 0;
- // #endif
- },
- async mounted() {
- if (this.onInit) {
- this.init(this.onInit);
- }
- },
- methods: {
- // #ifdef APP-NVUE
- onMessage(e) {
- const res = e?.detail?.data[0] || null;
- if (res?.event) {
- this.$emit(res.event, JSON.parse(res.data));
- } else if (res?.file) {
- this.file = res.data;
- } else {
- console.error(res);
- }
- },
- // #endif
- async init(func, params = null) {
- // #ifdef APP-NVUE
- this.$watch(
- 'isFinish',
- (n, o) => {
- (n || o) && (params || this.params) && this.$refs.webview.evalJs(`init(${JSON.stringify(func.toString())}, ${JSON.stringify(params || this.params)})`);
- this.isInited = true;
- },
- {
- immediate: true
- }
- );
- // #endif
- // #ifndef APP-NVUE
- let config = await this.getContext(this.canvasId);
- if (this.isCloud) {
- let imageMask = null;
- if (this.imageMask) {
- this.isMask = true;
- imageMask = await this.getImageMask(config);
- this.imageData = imageMask;
- this.isMask = false;
- }
- let cloud = await this.getContext(this.canvasId + '_cloud');
- config = Object.assign({}, config, { cloud, imageMask });
- }
- const chart = await func(config);
- if (chart) {
- this.chart = chart;
- this.canvasEl = chart.get('el');
- this.isInited = true;
- }
- // #endif
- },
- changeData(data) {
- // #ifndef APP-NVUE
- if (this.chart) {
- this.chart.changeData(data || this.source);
- }
- // #endif
- // #ifdef APP-NVUE
- this.$refs.webview.evalJs(`changeData(${JSON.stringify(data || this.source)})`);
- // #endif
- },
- clear() {
- // #ifndef APP-NVUE
- if (this.chart) {
- this.chart.clear();
- }
- // #endif
- // #ifdef APP-NVUE
- this.$refs.webview.evalJs(`clear()`);
- // #endif
- },
- destroy() {
- // #ifndef APP-NVUE
- if (this.chart) {
- this.chart.destroy();
- }
- // #endif
- // #ifdef APP-NVUE
- this.$refs.webview.evalJs(`destroy()`);
- // #endif
- },
- repaint() {
- this.changeData(this.source);
- },
- reset(func, params = null) {
- // #ifndef APP-NVUE
- this.$watch(
- 'isInited',
- v => v && func(this.chart),
- {
- immediate: true
- }
- );
- // #endif
- // #ifdef APP-NVUE
- this.$refs.webview.evalJs(`reset(${JSON.stringify(func.toString())}, ${JSON.stringify(params || this.params)})`);
- // #endif
- },
- canvasToTempFilePath(args = {}) {
- // #ifndef APP-NVUE
- const { use2dCanvas, canvasId, config } = this;
- return new Promise((resolve, reject) => {
- const copyArgs = Object.assign(
- {
- canvasId,
- success: resolve,
- fail: reject
- },
- args
- );
- if (use2dCanvas) {
- let { canvas } = config[canvasId];
- delete copyArgs.canvasId;
- copyArgs.canvas = canvas;
- }
- uni.canvasToTempFilePath(copyArgs, this);
- });
- // #endif
- // #ifdef APP-NVUE
- this.file = '';
- this.$refs.webview.evalJs(`canvasToTempFilePath()`);
- return new Promise((resolve, reject) => {
- this.$watch('file', async file => {
- if (file) {
- const tempFilePath = await base64ToPath(file);
- resolve(args.success({ tempFilePath }));
- } else {
- reject(args.fail({ error: `` }));
- }
- });
- });
- // #endif
- },
- // #ifndef APP-NVUE
- getImageMask(config) {
- return new Promise(resolve => {
- uni.getImageInfo({
- src: this.imageMask,
- success: async res => {
- if (res.path) {
- // #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO
- const localReg = /^\.|^\/(?=[^\/])/;
- res.path = localReg.test(this.imageMask) ? `/${res.path}` : res.path;
- // #endif
- const { context, width, height, canvas } = config;
- if (this.use2dCanvas) {
- const imageMask = () => {
- const imageMask = canvas.createImage();
- imageMask.crossOrigin = '';
- imageMask.src = res.path;
- imageMask.onload = async () => {
- context.drawImage(imageMask, 0, 0, res.width, res.height, 0, 0, width, height);
- const imageData = context.getImageData(0, 0, width, height).data;
- context.clearRect(0, 0, width, height);
- resolve(imageData);
- };
- };
- imageMask();
- } else {
- // #ifndef MP-BAIDU
- context.drawImage(res.path, 0, 0, res.width, res.height, 0, 0, width, height);
- // #endif
- // #ifdef MP-BAIDU
- context.drawImage(res.path, 0, 0, width, height, 0, 0, res.width, res.height);
- // #endif
- await this.canvasDraw(context);
- const imageData = await context.getImageData(0, 0, width, height);
- context.clearRect(0, 0, width, height);
- await this.canvasDraw(context);
- resolve(imageData);
- }
- }
- },
- fail(err) {
- console.error(JSON.stringify(err));
- resolve(null);
- }
- });
- });
- },
- canvasDraw(ctx) {
- return new Promise(resolve => {
- ctx.draw(false, () => {
- setTimeout(() => {
- resolve(true);
- }, 100);
- });
- });
- },
- getContext(canvasId) {
- const { use2dCanvas, type = '2d', config } = this;
- if (config[canvasId]?.context) {
- return Promise.resolve(config[canvasId]);
- }
- if (use2dCanvas) {
- return new Promise(resolve => {
- uni.createSelectorQuery()
- .in(this)
- .select(`#${canvasId}`)
- .fields({
- node: true,
- size: true
- })
- .exec(res => {
- let { node, width, height } = res[0];
- width = width || 300;
- height = height || 300;
- const context = node.getContext(type);
- if (!canvasId.includes('_cloud')) {
- this.width = width;
- this.height = height;
- }
- node.width = width * pixelRatio;
- node.height = height * pixelRatio;
- this.config[canvasId] = { context, width, height, pixelRatio, canvas: node };
- resolve(this.config[canvasId]);
- });
- });
- }
- return new Promise(resolve => {
- uni.createSelectorQuery()
- .in(this)
- .select(`#${canvasId}`)
- .boundingClientRect()
- .exec(res => {
- if (res) {
- let { width, height } = res[0];
- width = width || 300;
- height = height || 300;
- const context = uni.createCanvasContext(canvasId, this);
- if (!canvasId.includes('_cloud')) {
- this.width = width;
- this.height = height;
- // #ifdef MP-ALIPAY
- this.nodeWidth = width * pixelRatio;
- this.nodeHeight = height * pixelRatio;
- // #endif
- }
- this.config[canvasId] = {
- context: extendContext(context),
- width,
- height,
- // #ifdef H5 || APP-PLUS
- pixelRatio: 1,
- oPixelRatio: pixelRatio,
- // #endif
- // #ifndef H5
- pixelRatio
- // #endif
- };
- resolve(this.config[canvasId]);
- }
- });
- });
- },
- touchStart(e) {
- if (this.canvasEl) {
- this.canvasEl.dispatchEvent('touchstart', wrapEvent(e));
- }
- },
- touchMove(e) {
- if (this.canvasEl) {
- this.canvasEl.dispatchEvent('touchmove', wrapEvent(e));
- }
- },
- touchEnd(e) {
- if (this.canvasEl) {
- this.canvasEl.dispatchEvent('touchend', wrapEvent(e));
- }
- }
- // #endif
- }
- };
- </script>
- <style scoped lang="stylus">
- full()
- // #ifndef APP-NVUE
- width 100%
- height 100%
- // #endif
- // #ifdef APP-NVUE
- flex 1
- // #endif
- .l-f2
- full()
- position relative
- &__mask
- position absolute
- left 0
- right 0
- bottom 0
- top 0
- background-color #fff
- z-index 1
- &__canvas
- full()
- </style>
|