画布中的矩形尺寸错误

2023-11-23

我正在实现一个颜色选择器。渲染有问题。当我打电话时c.fillRect(0, 0, 100, 80);该矩形的大小是 103x42 像素,而不是 100x80。这里有什么问题吗?

此外,矩形是抗锯齿的。我是否需要将位置偏移 (0.5, 0.5) 以避免 AA?我没有使用任何类型的坐标系转换。

colorSlider = function($e, color) {
    this._$canvas = $('<canvas></canvas>');
    this._c = this._$canvas[0].getContext('2d');
    this._color = color || { r: 0, g: 0, b: 0 };
    this._$canvas.width('310px');
    this._$canvas.height('80px');
    $e.append(this._$canvas);
    this._render();
    var me = this;
    this._$canvas.mousedown(function(e) { me._mouseDown.call(me, e) });
    this._$canvas.mouseup(function(e) { me._mouseUp.call(me, e) });
    this._$canvas.mousemove(function(e) { me._mouseMove.call(me, e) });
    this._dragChannel = 0;
}

colorSlider.prototype._pointInRect = function(x, y, rect) {
    return x >= rect.x && x <= rect.x + rect.w && y >= rect.y && y <= rect.y + rect.h;
}

colorSlider.prototype._findTarget = function(event) {
    var x = event.offsetX;
    var y = event.offsetY;
    console.log(x, y, this._rectR);
    if (this._pointInRect(x, y, this._rectRThumb)) {
        return { target: 1, value: x - this._rectR.x };
    }
    if (this._pointInRect(x, y, this._rectGThumb)) {
        return { target: 2, value: x - this._rectG.x };
    }
    if (this._pointInRect(x, y, this._rectBThumb)) {
        return { target: 3, value: x - this._rectB.x };
    }
    if (this._pointInRect(x, y, this._rectR)) {
        return { target: 4, value: x - this._rectR.x };
    }
    if (this._pointInRect(x, y, this._rectG)) {
        return { target: 5, value: x - this._rectG.x };
    }
    if (this._pointInRect(x, y, this._rectB)) {
        return { target: 6, value: x - this._rectB.x };
    }
    return null;
}

colorSlider.prototype._mouseDown = function(event) {
    this._dragChannel = 0;
    var target = this._findTarget(event);
    if (target) {
        switch (target.target) {
            case 1:
                this._dragChannel = 1;
                break;
            case 2:
                this._dragChannel = 2;
                break;
            case 3:
                this._dragChannel = 3;
                break;
            case 4:
                this._color.r = target.value;
                break;
            case 5:
                this._color.g = target.value;
                break;
            case 6:
                this._color.b = target.value;
                break;
        }
        this._render();
    }
};

colorSlider.prototype._mouseUp = function(event) {
    //console.log('mouseUp');
};

colorSlider.prototype._mouseMove = function(event) {
    //console.log('mouseMove', event);
};

colorSlider.prototype.padding = 4;

colorSlider.prototype._render = function() {
    var padding = this.padding;
    var thickness = 16;
    var c = this._c;
    var w = 255;
    var h = this._$canvas.height();

    c.clearRect(0, 0, this._$canvas.width(), this._$canvas.height());

    var gradient = c.createLinearGradient(padding, 0, w, 0);
    c.fillStyle = gradient;

    gradient.addColorStop(0, this.colorToHex({ r: 0, g: this._color.g, b: this._color.b }));
    gradient.addColorStop(1, this.colorToHex({ r: 255, g: this._color.g, b: this._color.b }));
    c.fillRect(padding, padding, w, thickness);
    c.lineWidth = 0;
    c.fillRect(0, 0, 100, 80);
    this._rectR = { x: padding, y: padding, w: w, h: thickness };

    gradient = c.createLinearGradient(padding, 0, w, 0);
    c.fillStyle = gradient;
    gradient.addColorStop(0, this.colorToHex({ r: this._color.r, g: 0, b: this._color.b }));
    gradient.addColorStop(1, this.colorToHex({ r: this._color.r, g: 255, b: this._color.b }));
    c.fillRect(padding, padding + thickness + 2 * padding, w, thickness);
    this._rectG = { x: padding, y: padding + thickness + 2 * padding, w: w, h: thickness };

    gradient = c.createLinearGradient(padding, 0, w, 0);
    c.fillStyle = gradient;
    gradient.addColorStop(0, this.colorToHex({ r: this._color.r, g: this._color.g, b: 0 }));
    gradient.addColorStop(1, this.colorToHex({ r: this._color.r, g: this._color.g, b: 255 }));
    c.fillRect(padding, padding + 2 * (thickness + 2 * padding), w, thickness);
    this._rectB = { x: padding, y: padding + 2 * (thickness + 2 * padding), w: w, h: thickness };

    c.lineWidth = 2;
    c.fillStyle = "white";
    c.strokeStyle = "#888888";

    this._rectRThumb = { x: padding + this._color.r - 2, y: padding / 2, w: 8, h: 20, r: 2 };
    this.drawRoundedRectangle(c, this._rectRThumb);

    this._rectGThumb = { x: padding + this._color.g - 2, y: padding / 2 + 2 * padding + thickness, w: 8, h: 20, r: 2 };
    this.drawRoundedRectangle(c, this._rectGThumb);

    this._rectBThumb = { x: padding + this._color.b - 2, y: padding / 2 + 2 * (2 * padding + thickness), w: 8, h: 20, r: 2 };
    this.drawRoundedRectangle(c, this._rectBThumb);
};

colorSlider.prototype.colorToHex = function(color) {
    var c = '#'
    + (color.r + 256).toString(16).substr(1, 2)
    + (color.g + 256).toString(16).substr(1, 2)
    + (color.b + 256).toString(16).substr(1, 2);
    console.log(c);
    return c;
};

// http://stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-on-html-canvas
colorSlider.prototype.drawRoundedRectangle = function(c, rect) {
    var x = rect.x;
    var y = rect.y;
    var width = rect.w;
    var height = rect.h;
    var radius = rect.r;
    c.beginPath();
    c.moveTo(x + radius, y);
    c.lineTo(x + width - radius, y);
    c.quadraticCurveTo(x + width, y, x + width, y + radius);
    c.lineTo(x + width, y + height - radius);
    c.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    c.lineTo(x + radius, y + height);
    c.quadraticCurveTo(x, y + height, x, y + height - radius);
    c.lineTo(x, y + radius);
    c.quadraticCurveTo(x, y, x + radius, y);
    c.closePath();
    c.stroke();
    c.fill();
};

索引.html

<script>
$(function() {
    $("#directionalLight,#ambientLight").each(function() {
        new colorSlider($(this));
    });

});
</script>

<body>
<div>Directional light</div>
<div id="directionalLight"></div>
<div>Ambient light</div>
<div id="ambientLight"></div>
</body>

首先要知道的是canvas元素有内在维度= 中的像素数内部坐标空间(由width and height属性和性质)。它也有外在维度 (style.width and style.height)是图像在网页中所占的像素数。内部像素被缩放以适应外部空间。

这很令人困惑,因为img也有内在维度和外在维度,但属性的名称与canvas。如果你设置width and height在图像上,它与设置基本相同style.width or style.height;他们都设置了外在维度缩放页面内的图像。同时,你只能得到内在维度 of an img使用新的naturalWidth and naturalHeight(仅限 HTML5 浏览器)属性。

如果两者均未设置外部尺寸img and canvas,图像将以与固有尺寸相同的尺寸布局(即比例因子为 1)。

现在,当你使用 jQuery 时,$(canvas).width('310px')是相同的$(canvas).css('310px'),它设置外部尺寸。你必须打电话$(canvas).prop('width', 310)或者简单地设置canvas.width = 310设置固有宽度。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

画布中的矩形尺寸错误 的相关文章

随机推荐

  • 获取添加的 DOM 节点的 className (mutationObserver)

    我正在编写一个简单的用户脚本 如果 Facebook 帖子包含特定的单词列表 它将自动隐藏该帖子 核心功能有效 但我的MutationObserver似乎没有读过className of mutation addedNodes适当地 我循环
  • char 与 wchar_t

    我正在尝试打印出 wchar t 字符串 代码如下 include
  • 如何验证 ASP.Net MVC 2 中的复选框?

    使用 MVC2 我有一个简单的 ViewModel 其中包含一个布尔字段 该字段在视图上呈现为复选框 我想验证用户是否选中了该框 我的 ViewModel 上的 Required 属性似乎不起作用 我相信这是因为未选中的复选框表单字段实际上
  • 重写虚函数仅因调用约定不同是什么意思?

    我正在尝试实施IUnknown 我按照发球台的说明进行操作 但不起作用 当我尝试编译时 我得到 Error 2 error C2695 testInterfaceImplementation AddRef overriding virtua
  • 是否可以检测 Android 强制门户浏览器?

    我有一个强制门户 从 Android 5 0 Lollipop 开始 它在 Android 的强制门户浏览器而不是设备的默认浏览器中启动 我需要以某种方式检测它们是否在强制门户浏览器中 而不是常规网络浏览器 如果是 则显示不同的内容 是否可
  • 服务器端 Blazor 不提供 HttpClient 进行注入

    当我尝试注入 HttpClient 时 我在 razor 页面中收到错误 未处理的承诺拒绝 错误 System InvalidOperationException 无法为类型上的属性 Http 提供值 没有 类型为 System Net H
  • 使用 Visual Studio 开发服务器时如何让 Web 服务使用固定端口号?

    我有一个 ASP NET 网站和一个 Windows 窗体应用程序 我的网络服务的位置是 http localhost 12312 MyWebSiteFolder WSFile asmx 问题是 端口号不断变化 如果我重新打开解决方案 它会
  • 在获取聊天历史记录时,我没有从 Openfire 获取用户历史记录

    我通过在 open fire 中安装 open fire 插件来从 openfire 获取历史记录并尝试了这段代码 let iq1 DDXMLElement name iq iq1 addAttribute withName type st
  • Kotlin中如何在延迟后调用函数?

    如标题 有没有办法在延迟 例如1秒 后调用函数Kotlin 还有一个选项可以使用Handler gt postDelayed Handler postDelayed doSomethingHere 1000
  • 处理可选的 python 字典字段

    我正在处理加载到 Python 字典中的 JSON 数据 其中很多都有可选字段 其中可能包含字典之类的东西 dictionary1 required value1 one value2 two optional value1 one dic
  • 使 Java 类通用,但仅适用于两种或三种类型

    我很惊讶在 stackoverflow 上找不到这个问题 我只能将其归咎于我的谷歌搜索不佳 无论如何都要指出重复的问题 这是一个玩具类 它返回与您放入其中的内容相反的内容 目前它适用于整数 但只需要非常小的更改即可适用于字符串 public
  • 如何在SceneKit中从Collada文件中分离出多个动画

    我正在将第三方 dae Collada 文件作为场景加载到 SceneKit 项目中 dae 文件中有许多不同的动画 设置在不同的时间 帧 我试图弄清楚如何将它们分开并通过引用名称引用每个单独的动画 dae 文件中没有易于理解的参考名称 动
  • 如何从 Jupyter 4.x 获取 IPython 配置文件行为?

    官方 建议运行 IPython Notebook 服务器 并通过以下方式创建配置文件 ipython profile create nbserver 正如推荐的http ipython org ipython doc 1 interacti
  • DropCreateDatabaseAlways 未调用种子

    我在自定义数据库初始值设定项上调用 Seed 方法时遇到问题 我正在使用 EF 5 0 并具有以下代码 public static class MyDatabase public static void Initialize Databas
  • 是否可以使用gdb和qemu同时调试linux用户空间程序和内核空间?

    到目前为止 使用 gdb qemu 我可以单步执行 Linux 内核源代码 是否可以同时调试用户空间程序 例如 将程序从用户空间单步执行到内核空间 这样我就可以通过发出以下命令来观察 qemu 监视器上寄存器的变化info register
  • 在 foreach 循环内手动增加枚举器

    我在 foreach 循环内有一个嵌套的 while 循环 我想在满足特定条件时无限期地推进枚举器 为此 我尝试将枚举器转换为 IEnumerator 如果它位于 foreach 循环中 则必须如此 然后在转换的对象上调用 MoveNext
  • 网络编程:是否维护套接字?

    我目前正在将 API 从 C 转换为具有网络组件的 Java C 版本似乎在使用其类期间保持输入和输出流以及套接字打开 它是否正确 记住应用程序根据用户输入发送命令和接收事件 为每个 消息 打开一个新的套接字流是否更明智 我正在维护一个 S
  • 如何在 JavaScript 中取消移动或添加到参数对象的开头

    我刚刚学会了弹出第一个元素的约定arguments array 我还了解到这实际上是一个Object 现在我需要做相反的事情 我需要使用一个unshift将值添加到开头的操作arguments数组 或Object就像一个数组 这可能吗 我试
  • R 中 stri_detect_regex 错误

    我收到此错误 stri detect regex string pattern opts regex opts pattern 中的错误 正则表达式模式中的括号嵌套不正确 U REGEX MISMATCHED PAREN 当我运行代码时 f
  • 画布中的矩形尺寸错误

    我正在实现一个颜色选择器 渲染有问题 当我打电话时c fillRect 0 0 100 80 该矩形的大小是 103x42 像素 而不是 100x80 这里有什么问题吗 此外 矩形是抗锯齿的 我是否需要将位置偏移 0 5 0 5 以避免 A