html5 – 画布中的矩形尺寸错误

栏目: Html5 · 发布时间: 5年前

内容简介:首先要知道的是,canvas元素具有内部维度=内部坐标空间中的像素数(由width和height属性和属性设置).它还具有外在尺寸(style.width和style.height),即图像在网页中占据的像素数.缩放固有像素以适合外在空间.它令人困惑,因为img也有内在和外在的维度,但属性的名称与canvas完全不同.如果在图像上设置宽度和高度,它与设置style.width或style.height基本相同;他们都设置了外在尺寸来缩放页面内的图像.同时,您只能使用新的naturalWidth和natura

我正在实施一个颜色选择器.渲染有问题.当我调用c.fillRect(0,0,100,80)时;该矩形的大小为103×42像素而不是100×80.这有什么不对?

此外,矩形是抗锯齿的.我是否需要将位置偏移(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;
};

// https://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();
};

的index.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和height属性和属性设置).它还具有外在尺寸(style.width和style.height),即图像在网页中占据的像素数.缩放固有像素以适合外在空间.

它令人困惑,因为img也有内在和外在的维度,但属性的名称与canvas完全不同.如果在图像上设置宽度和高度,它与设置style.width或style.height基本相同;他们都设置了外在尺寸来缩放页面内的图像.同时,您只能使用新的naturalWidth和naturalHeight(仅限HTML5浏览器)属性获取img的内在维度.

如果未在img和canvas上设置外部尺寸,则图像将以与内在尺寸相同的尺寸布置(即,比例因子将为1).

现在,当你使用jQuery时,$(canvas).width(‘310px’)与$(canvas).css(‘310px’)相同,后者设置外部维度.你必须调用$(canvas).prop(‘width’,310)或者只需设置canvas.width = 310来设置内在宽度.

翻译自:https://stackoverflow.com/questions/9286483/wrong-rectangle-size-in-canvas


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

计算机程序的构造和解释

计算机程序的构造和解释

Harold Abelson、Gerald Jay Sussman、Julie Sussman / 裘宗燕 / 机械工业出版社 / 2004-2 / 45.00元

《计算机程序的构造和解释(原书第2版)》1984年出版,成型于美国麻省理工学院(MIT)多年使用的一本教材,1996年修订为第2版。在过去的二十多年里,《计算机程序的构造和解释(原书第2版)》对于计算机科学的教育计划产生了深刻的影响。第2版中大部分重要程序设计系统都重新修改并做过测试,包括各种解释器和编译器。作者根据其后十余年的教学实践,还对其他许多细节做了相应的修改。 海报:一起来看看 《计算机程序的构造和解释》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

URL 编码/解码
URL 编码/解码

URL 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具