高清canvas,柯里化实际运用

我在做canvas时遇到了这个问题,画完了看起来好好的,一放大,就糊的不能看,甚至有时候不放大也显得有些糊。解决的方法是放大绘制,缩小观看。就像这样:

// html
<canvas width="200" height="200"></canvas>
// css
canvas {
    width: 100px;
    height: 100px;
}
  • 在设定style时,如果大小和绘制大小不一致,会对canvas进行缩放,而不是裁剪。
  • 可以采用固定放大比例,或者固定绘制大小(4k分辨率)两种方式,我这里用的是固定放大比例

在demo最开始只有html和css时是这样的:

// html
<body>
    <div class="box">
        <canvas></canvas>
    </div>
    <script src="a.js"></script>
</body>
// css
body {
    margin: 0;
    font-size: 0;
}
.box {
    display: flex;
    width: 100vw;
    height: 100vh;
}
canvas {
    margin: auto auto;
    width: 80%;
    height: 80%;
    border: 2px solid red;
}

刷新页面会得到一个居中的大红框
添加js:

class Demo {
    constructor() {
        this.cns = null // canvas对象
        this.W = 0 // 宽高
        this.H = 0
        this.k = 2 // 缩放比例
        this.initDom()
    }
    initDom() {
        let dom = document.querySelector('canvas')
        this.cns = dom.getContext('2d')
        this.W = dom.offsetWidth
        this.H = dom.offsetHeight
        let k = this.k
        dom.width = this.W * k
        dom.height = this.H * k
    }
}
let demo = new Demo();

这样就得到了2倍绘制区域的canvas。
如果想要在左上角绘制一个100 * 100的正方形

draw() {
    let cns = this.cns
    let k = this.k
    cns.fillRect(0, 0, 100 * k, 100 * k)
}

每个不是0的数都要乘一下这个k,写起来真的好麻烦,写个函数就好啦。这个函数肯定要写在class内部,因为是绘制专用的。

a(flt) {
    return flt * this.k | 0
}

但是每次都敲this.a(100)看起来太蠢了,即使这个函数名只有一个字母。如果我们拷贝这个函数 let a = this.a,很遗憾,这会无法找到k,拷贝的时候this变化了。我对call的使用并不熟悉,这里用call我只能写成

cns.fillRect(0, 0, f.call(this, 100), f.call(this, 100))

不知道有没有可以简单的写法?在这里做一个柯里化我觉着还是比较好的。
首先需要一个转化柯里化的函数:

function curry(def, ...first) {
    return function (...other) {
        let all = [...first, ...other]
        return def.apply(null, all)
    }
}
// 高程604页,这里我只是用了新语法,书中原函数:
function curry(fn) {
    var args = Array.prototype.slice.call(arguments, 1)
    return function () {
        var innerArgs = Array.prototype.slice.call(arguments)
        var finalArgs = args.concat(innerArgs)
        return fn.apply(null, finalArgs)
    }
}

在class内这样写:

draw() {
    let cns = this.cns
    let f = curry(this.floot2int, this.k)
    cns.fillRect(0, 0, f(100), f(100))
}
floot2int(k, flt) {
    return k * flt | 0
}

f(100)这个写法实在是不能再简单了。

完整的js:

class Demo {
    constructor() {
        this.cns = null // canvas对象
        this.W = 0 // 宽高
        this.H = 0
        this.k = 2 // 缩放比例
        this.initDom()
        this.draw()
    }
    initDom() {
        let dom = document.querySelector('canvas')
        this.cns = dom.getContext('2d')
        this.W = dom.offsetWidth
        this.H = dom.offsetHeight
        let k = this.k
        dom.width = this.W * k
        dom.height = this.H * k
    }
    draw() {
        let cns = this.cns
        let f = curry(this.floot2int, this.k)
        cns.fillRect(0, 0, f(100), f(100))
    }
    floot2int(k, flt) {
        return k * flt | 0
    }
}
let demo = new Demo();
function curry(fn, ...first) {
    return function (...other) {
        let all = [...first, ...other]
        return fn.apply(null, all)
    }
}
    原文作者:秋无衣
    原文地址: https://www.jianshu.com/p/a7a43b8bf089
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞