chxj1992 / kline

一个 javascript K线插件. A K line library written in javascript.
Do What The F*ck You Want To Public License
790 stars 338 forks source link

移动端模糊的问题 #80

Open jsoncode opened 6 years ago

jsoncode commented 6 years ago

移动端显示时,非常模糊,对比了tradingview,好像缺少了backingStorePixelRatio的判断。

还有一个bug,如果把默认显示的ma先选择为none,则有时候k线会消失,如果整屏都是一个价格的话

jsoncode commented 6 years ago

哥们,我看了tradingview的源码,解决这个问题,是需要引入一个hidpi-canvas.js的类库,但是我试了多遍,还是没解决移动端模糊的问题,

这是我从tradingview中摘出来的一段hidpi的代码。希望对你有用

(function(prototype) {
    var pixelRatio = (function() {
        var canvas = document.createElement('canvas'),
            context = canvas.getContext('2d'),
            backingStore = context.backingStorePixelRatio ||
            context.webkitBackingStorePixelRatio ||
            context.mozBackingStorePixelRatio ||
            context.msBackingStorePixelRatio ||
            context.oBackingStorePixelRatio ||
            context.backingStorePixelRatio || 1;

        return (window.devicePixelRatio || 1) / backingStore;
    })();
    var forEach = function(obj, func) {
        for (var p in obj) {
            if (obj.hasOwnProperty(p)) {
                func(obj[p], p);
            }
        }
    };

    var ratioArgs = {
        fillRect: "all",
        clearRect: "all",
        strokeRect: "all",
        moveTo: "all",
        lineTo: "all",
        arc: [0, 1, 2],
        arcTo: "all",
        bezierCurveTo: "all",
        isPointinPath: "all",
        isPointinStroke: "all",
        quadraticCurveTo: "all",
        rect: "all",
        translate: "all",
        createRadialGradient: "all",
        createLinearGradient: "all",
        drawImagePatchedSource: [1, 2, 3, 4]
    };

    if (pixelRatio === 1) return;

    forEach(ratioArgs, function(value, key) {
        prototype[key] = (function(_super) {
            return function() {
                var i, len,
                    args = Array.prototype.slice.call(arguments);

                if (value === 'all') {
                    args = args.map(function(a) {
                        return a * pixelRatio;
                    });
                } else if (Array.isArray(value)) {
                    for (i = 0, len = value.length; i < len; i++) {
                        args[value[i]] *= pixelRatio;
                    }
                }

                return _super.apply(this, args);
            };
        })(prototype[key]);
    });

    prototype.drawImagePatchedSource = prototype.drawImage;
    var drawImage = prototype.drawImage;
    prototype.drawImagePatchedSourceAndDest = function(t) {
        var o, n = Array.prototype.slice.call(arguments);
        for (o = 1; o < n.length; ++o)
            n[o] && (n[o] *= pixelRatio);
        return n.length > 5 && ("width" in t && (n[3] = Math.min(t.width, Math.max(1, n[3]))),
                "height" in t && (n[4] = Math.min(t.height, Math.max(1, n[4])))),
            drawImage.apply(this, n);
    };
    prototype.drawImage = function(t) {
        return function() {
            return arguments[0] instanceof HTMLCanvasElement ? t.drawImagePatchedSourceAndDest.apply(this, arguments) : t.drawImagePatchedSource.apply(this, arguments)
        }
    }(prototype);
    // Stroke lineWidth adjustment
    prototype.stroke = (function(_super) {
        return function() {
            this.lineWidth *= pixelRatio;
            _super.apply(this, arguments);
            this.lineWidth /= pixelRatio;
        };
    })(prototype.stroke);

    // Text
    //
    prototype.fillText = (function(_super) {
        return function() {
            var args = Array.prototype.slice.call(arguments);

            args[1] *= pixelRatio; // x
            args[2] *= pixelRatio; // y

            this.font = this.font.replace(
                /(\d+)(px|em|rem|pt)/g,
                function(w, m, u) {
                    return (m * pixelRatio) + u;
                }
            );

            _super.apply(this, args);

            this.font = this.font.replace(
                /(\d+)(px|em|rem|pt)/g,
                function(w, m, u) {
                    return (m / pixelRatio) + u;
                }
            );
        };
    })(prototype.fillText);

    prototype.strokeText = (function(_super) {
        return function() {
            var args = Array.prototype.slice.call(arguments);

            args[1] *= pixelRatio; // x
            args[2] *= pixelRatio; // y

            this.font = this.font.replace(
                /(\d+)(px|em|rem|pt)/g,
                function(w, m, u) {
                    return (m * pixelRatio) + u;
                }
            );

            _super.apply(this, args);

            this.font = this.font.replace(
                /(\d+)(px|em|rem|pt)/g,
                function(w, m, u) {
                    return (m / pixelRatio) + u;
                }
            );
        };
    })(prototype.strokeText);
})(CanvasRenderingContext2D.prototype);;
(function(prototype) {
    prototype.getContext = (function(_super) {
        return function(type) {
            var backingStore, ratio,
                context = _super.call(this, type);

            if (type === '2d') {

                backingStore = context.backingStorePixelRatio ||
                    context.webkitBackingStorePixelRatio ||
                    context.mozBackingStorePixelRatio ||
                    context.msBackingStorePixelRatio ||
                    context.oBackingStorePixelRatio ||
                    context.backingStorePixelRatio || 1;

                ratio = (window.devicePixelRatio || 1) / backingStore;

                if (ratio > 1) {
                    this.style.height = this.height + 'px';
                    this.style.width = this.width + 'px';
                    this.width *= ratio;
                    this.height *= ratio;
                }
            }

            return context;
        };
    })(prototype.getContext);
})(HTMLCanvasElement.prototype);
chxj1992 commented 6 years ago

@jsoncode 多谢 !

WaiSiuKei commented 6 years ago

跪求tradingview源码~~

jsoncode commented 6 years ago

tradingview源码给你也用不了,要向官方申请授权,可以免费使用。api都是官方授权后才能打开的

WaiSiuKei commented 6 years ago

我不是要用它。。。。

alibbbian commented 6 years ago

有没有大神给解决下

alibbbian commented 5 years ago

解决了,也添加其他一些方法,修改了一些默认配置,见 https://github.com/alibbbian/kline

liaoqifeng commented 5 years ago

解决了,也添加其他一些方法,修改了一些默认配置,见 https://github.com/alibbbian/kline

兄弟, K线图右边的刻度的宽度是改哪个地方, 在移动端的时候太窄了

liaoqifeng commented 5 years ago

哥们,我看了tradingview的源码,解决这个问题,是需要引入一个hidpi-canvas.js的类库,但是我试了多遍,还是没解决移动端模糊的问题,

这是我从tradingview中摘出来的一段hidpi的代码。希望对你有用

(function(prototype) {
    var pixelRatio = (function() {
        var canvas = document.createElement('canvas'),
            context = canvas.getContext('2d'),
            backingStore = context.backingStorePixelRatio ||
            context.webkitBackingStorePixelRatio ||
            context.mozBackingStorePixelRatio ||
            context.msBackingStorePixelRatio ||
            context.oBackingStorePixelRatio ||
            context.backingStorePixelRatio || 1;

        return (window.devicePixelRatio || 1) / backingStore;
    })();
    var forEach = function(obj, func) {
        for (var p in obj) {
            if (obj.hasOwnProperty(p)) {
                func(obj[p], p);
            }
        }
    };

    var ratioArgs = {
        fillRect: "all",
        clearRect: "all",
        strokeRect: "all",
        moveTo: "all",
        lineTo: "all",
        arc: [0, 1, 2],
        arcTo: "all",
        bezierCurveTo: "all",
        isPointinPath: "all",
        isPointinStroke: "all",
        quadraticCurveTo: "all",
        rect: "all",
        translate: "all",
        createRadialGradient: "all",
        createLinearGradient: "all",
        drawImagePatchedSource: [1, 2, 3, 4]
    };

    if (pixelRatio === 1) return;

    forEach(ratioArgs, function(value, key) {
        prototype[key] = (function(_super) {
            return function() {
                var i, len,
                    args = Array.prototype.slice.call(arguments);

                if (value === 'all') {
                    args = args.map(function(a) {
                        return a * pixelRatio;
                    });
                } else if (Array.isArray(value)) {
                    for (i = 0, len = value.length; i < len; i++) {
                        args[value[i]] *= pixelRatio;
                    }
                }

                return _super.apply(this, args);
            };
        })(prototype[key]);
    });

    prototype.drawImagePatchedSource = prototype.drawImage;
    var drawImage = prototype.drawImage;
    prototype.drawImagePatchedSourceAndDest = function(t) {
        var o, n = Array.prototype.slice.call(arguments);
        for (o = 1; o < n.length; ++o)
            n[o] && (n[o] *= pixelRatio);
        return n.length > 5 && ("width" in t && (n[3] = Math.min(t.width, Math.max(1, n[3]))),
                "height" in t && (n[4] = Math.min(t.height, Math.max(1, n[4])))),
            drawImage.apply(this, n);
    };
    prototype.drawImage = function(t) {
        return function() {
            return arguments[0] instanceof HTMLCanvasElement ? t.drawImagePatchedSourceAndDest.apply(this, arguments) : t.drawImagePatchedSource.apply(this, arguments)
        }
    }(prototype);
    // Stroke lineWidth adjustment
    prototype.stroke = (function(_super) {
        return function() {
            this.lineWidth *= pixelRatio;
            _super.apply(this, arguments);
            this.lineWidth /= pixelRatio;
        };
    })(prototype.stroke);

    // Text
    //
    prototype.fillText = (function(_super) {
        return function() {
            var args = Array.prototype.slice.call(arguments);

            args[1] *= pixelRatio; // x
            args[2] *= pixelRatio; // y

            this.font = this.font.replace(
                /(\d+)(px|em|rem|pt)/g,
                function(w, m, u) {
                    return (m * pixelRatio) + u;
                }
            );

            _super.apply(this, args);

            this.font = this.font.replace(
                /(\d+)(px|em|rem|pt)/g,
                function(w, m, u) {
                    return (m / pixelRatio) + u;
                }
            );
        };
    })(prototype.fillText);

    prototype.strokeText = (function(_super) {
        return function() {
            var args = Array.prototype.slice.call(arguments);

            args[1] *= pixelRatio; // x
            args[2] *= pixelRatio; // y

            this.font = this.font.replace(
                /(\d+)(px|em|rem|pt)/g,
                function(w, m, u) {
                    return (m * pixelRatio) + u;
                }
            );

            _super.apply(this, args);

            this.font = this.font.replace(
                /(\d+)(px|em|rem|pt)/g,
                function(w, m, u) {
                    return (m / pixelRatio) + u;
                }
            );
        };
    })(prototype.strokeText);
})(CanvasRenderingContext2D.prototype);;
(function(prototype) {
    prototype.getContext = (function(_super) {
        return function(type) {
            var backingStore, ratio,
                context = _super.call(this, type);

            if (type === '2d') {

                backingStore = context.backingStorePixelRatio ||
                    context.webkitBackingStorePixelRatio ||
                    context.mozBackingStorePixelRatio ||
                    context.msBackingStorePixelRatio ||
                    context.oBackingStorePixelRatio ||
                    context.backingStorePixelRatio || 1;

                ratio = (window.devicePixelRatio || 1) / backingStore;

                if (ratio > 1) {
                    this.style.height = this.height + 'px';
                    this.style.width = this.width + 'px';
                    this.width *= ratio;
                    this.height *= ratio;
                }
            }

            return context;
        };
    })(prototype.getContext);
})(HTMLCanvasElement.prototype);

兄弟, K线图右边的刻度的宽度是改哪个地方, 在移动端的时候太窄了