如何根据设备尺寸调整画布滤镜模糊效果

huangapple go评论61阅读模式
英文:

how to adjust canvas filter blur depending on device size

问题

// this.#blur is usually 7
const ctx = this.#canvas.getContext("2d");
ctx.filter = "blur(" + this.#blur + "px)";
const draw_2DCanvas = () => {
    ctx.clearRect(0, 0, width, height);
    ctx.drawImage(this.#video, width_diff, height_diff, width, height);
    requestAnimationFrame(draw_2DCanvas);
};
draw_2DCanvas();
// this.#blur is usually 7
const ctx = this.#canvas.getContext("2d");
const draw_2DCanvas = () => {
    const blur = Math.ceil(this.#blur * this.#canvas.clientWidth / 360);
    ctx.filter = "blur(" + blur + "px)";
    ctx.clearRect(0, 0, width, height);
    ctx.drawImage(this.#video, width_diff, height_diff, width, height);
    requestAnimationFrame(draw_2DCanvas);
};
draw_2DCanvas();

The code you provided is already in Chinese, so I have retained the code parts in their original form without translation.

英文:

I am trying to apply a blur to a canvas and I am trying to apply it with the same strength on every device.

    // this.#blur is usually 7
    const ctx = this.#canvas.getContext("2d");
    ctx.filter = "blur(" + this.#blur + "px)";
    const draw_2DCanvas = () => {
        ctx.clearRect(0, 0, width, height);
        ctx.drawImage(this.#video, width_diff, height_diff, width, height);
        requestAnimationFrame(draw_2DCanvas);
    };
    draw_2DCanvas();

But with just this the blur strength changes depending on the device, possibly because the canvas size differs.
The blur applies as intended on pc devices, but is too strong on mobile devices.
So I tried to spice things a little and change the blur in accordance to the current canvas style width (the canvas and video size is 360x270 but the html style size is responsive).

    // this.#blur is usually 7
    const ctx = this.#canvas.getContext("2d");
    const draw_2DCanvas = () => {
        const blur =  Math.ceil(this.#blur * this.#canvas.clientWidth / 360);
        ctx.filter = "blur(" + blur + "px)";
        ctx.clearRect(0, 0, width, height);
        ctx.drawImage(this.#video, width_diff, height_diff, width, height);
        requestAnimationFrame(draw_2DCanvas);
    };
    draw_2DCanvas();

But this time the blur is too strong on pc devices and a little too weak on mobile devices.
What is the correct way to make the canvas blur consistent on every device?

答案1

得分: 1

以下是代码的翻译部分,不包括代码的注释:

import "context-filter-polyfill/dist/index.js";
const resize_dvr = this.#device.os == 'iOS' ? 1 : window.devicePixelRatio;
const width = calc_width / resize_dvr;
const height = calc_height / resize_dvr;
const width_diff = this.#ar ? calc_wdiff / resize_dvr / 2 : 0;
const height_diff = this.#ar ? calc_hdiff / resize_dvr / 2 : 0;
const ctx = this.#canvas.getContext("2d");
//不要在这里使用window.devicePixelRatio来计算宽度
this.#canvas.width = calc_width;
this.#canvas.height = calc_height;
ctx.scale(resize_dvr, resize_dvr);
ctx.filter = "blur(" + this.#blur + "px)";
const draw_2DCanvas = () => {
    ctx.clearRect(0, 0, width, height);
    ctx.drawImage(this.#video, width_diff, height_diff, width, height);
    requestAnimationFrame(draw_2DCanvas);
};
draw_2DCanvas();

如果你需要更多翻译或有其他问题,请随时提问。

英文:

Here is the final code to fix the blur before I explain the how or why:

    import "context-filter-polyfill/dist/index.js";
    const resize_dvr = this.#device.os == 'iOS' ? 1 : window.devicePixelRatio;
    const width = calc_width / resize_dvr;
    const height = calc_height / resize_dvr;
    const width_diff = this.#ar ? calc_wdiff / resize_dvr / 2 : 0;
    const height_diff = this.#ar ? calc_hdiff / resize_dvr / 2 : 0;
    const ctx = this.#canvas.getContext("2d");
    //do not use window.devicePixelRatio to calculate width here
    this.#canvas.width = calc_width;
    this.#canvas.height = calc_height;
    ctx.scale(resize_dvr, resize_dvr);
    ctx.filter = "blur(" + this.#blur + "px)";
    const draw_2DCanvas = () => {
        ctx.clearRect(0, 0, width, height);
        ctx.drawImage(this.#video, width_diff, height_diff, width, height);
        requestAnimationFrame(draw_2DCanvas);
    };
    draw_2DCanvas();

I'll start by saying that something like blur = blur * window.devicePixelRatio will not blur properly!
Also this is a simplified version of my code to make it more readable so is hasn't been tested as is.<br><br>
After testing directly changing the blur I tried changing the value of the scale like this:
(as shown in protob's link)

ctx.scale(window.devicePixelRatio, window.devicePixelRatio);

This managed to fix the blur for Android devices, but made the blur waaay too strong in iOS devices and also made Android devices zoom like crazy.
To fix the Android device version I simply divided all the canvas coordinates by window.devicePixelRatio like this:

    const resize_dvr = window.devicePixelRatio;
    const width = calc_width / resize_dvr;
    const height = calc_height / resize_dvr;
    const width_diff = this.#ar ? calc_wdiff / resize_dvr / 2 : 0;
    const height_diff = this.#ar ? calc_hdiff / resize_dvr / 2 : 0;

However iOS devices do not support ctx.filter at all! (more info on MDN)
So I was fully relying on the context-filter-polyfill for IOS devices, and this library seems to fully monkey patch the code with a window.devicePixelRatio = 1 setting.
So I had to change the devicePixelRatio i got to 1 for devices that had to rely on this library.

    const resize_dvr = this.#device.os == &#39;iOS&#39; ? 1 : window.devicePixelRatio;

Here is how you can catch an IOS device with your code:

const isIOS = /iP(hone|([oa])d)|Macintosh/.test(navigator.userAgent) &amp;&amp; &#39;ontouchend&#39; in document;

I do not recommend using libraries when catching IOS devices cuz they just read the userAgent as is, and iPads always fake being a Mac OS! (while having none of the web API you can use on a Mac available....)
And if you do use a library remember to double check that it catches all IOS devices!

huangapple
  • 本文由 发表于 2023年2月8日 14:17:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75381991.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定