• Spring
    2020-06-24
    老师,有点不太理解translate的平移操作,平移后画布的坐标系是怎么发生变化的呢? 平移的是画布还是坐标系。

    作者回复: 平移的是坐标系,你可以理解为将坐标原点移动了,例如本来画布左上角坐标是0,0,现在translate(100,100),那么也就是距离画布左上角(100,100)处的坐标是0,0,相应左上角坐标就是-100,-100了。相当于此时开始再绘制任何图形,每个顶点的坐标和原来相比都偏移了100,100

    
    33
  • 特异型大光头
    2020-06-25
    原理大致听懂了,学着做个打砖块练习 https://codepen.io/ysosu/pen/MWKorYj 问题: function draw(ctx, node, {fillStyle = 'rgba(0, 0, 0, 0.2)', textColor = 'white'} = {}) {}; 里面这个{fillStyle = 'rgba(0, 0, 0, 0.2)', textColor = 'white'} = {}没看懂 跟这样写的差别是啥function draw(ctx, node, fillStyle = 'rgba(0, 0, 0, 0.2)', textColor = 'white' ) {};

    作者回复: 这两种写法是参数签名不同,我上面这种写法调用起来虽然麻烦一点,但是能让代码可读性更好。 因为同样调用: draw(context, el, {fillStyle: 'red', textColor: 'black'}) 比 draw(context, el, 'red', 'black') 可读性要好 假设你是代码维护者,前者你一看就知道后面两个颜色参数哪个是fillStyle,哪个是textColor;后者你不看函数定义,不知道red和black分别哪个是fillStyle,哪个是textColor。 代码是给人阅读的,所以设计API的时候需要考虑这样的细节。 打砖块很赞~~

    共 2 条评论
    24
  • 宁康
    2020-06-26
    借鉴了之前留言的朋友的部分逻辑重新开发了一个五子棋程序,主要修改了几个地方: - 使用二维数组记录落子情况,方便后续判断胜负 - 重新获取光标后不进行整个棋盘的渲染,而是将上一个光标处局部修复 - 根据当前落子周围八个方向4个单位距离的棋盘中是否赢了 遇到的问题: - 光标是用1个单位线宽绘制出来的,我用同样一个单位线宽去覆盖,发现覆盖不全,还会残留线段,最后只能加大线宽去覆盖,请问老师这个是什么问题? 五子棋在线预览:https://codesandbox.io/s/chess-demo-d2qgt

    作者回复: 赞~这个五子棋不错。同样宽度覆盖,因为Canvas有反锯齿等处理,另外还有光栅化的精度问题,所以边缘的像素会覆盖不了的,一般来说是需要增加线宽,这个是正常的。

    共 2 条评论
    18
  • Geek_3469f6
    2020-06-25
    老师现在讲的还可以完全听懂,学习了之后立刻实践了以下。并且,学练结合,把以前的想法实现了下。这次没有偷懒。画了个五子棋盘+棋子,输赢判定逻辑还没写。 https://codepen.io/maslke/pen/MWKoKKp

    作者回复: 赞👍

    共 2 条评论
    10
  • 随遇而安
    2020-06-24
    我尝试了用canvas绘制不规则多边形,如果想要添加鼠标交互事件,获取到鼠标的坐标之后,可以利用凸包算法判断点是否在不规则多边形内。

    作者回复: 棒~

    共 4 条评论
    9
  • 筑梦师刘渊
    2020-06-26
    作业2: 1. 先封装一个清除圆形方法: CanvasRenderingContext2D.prototype.clearCircle = function (x, y,r) { context.save(); context.fillStyle = "rgba(255,255,255,255)"; context.beginPath(); context.arc(x, y, r, 0, TAU); context.fill(); context.restore(); }; 2. 检测鼠标是否在圆内(在圆内就先清除圆再绘制名称和新颜色): // 鼠标检测移动到小圆就变色 function isInCircle(ctx, mx, my, node) { const children = node.children; if (children) { for (let i = 0; i < children.length; i++) { isInCircle(ctx, mx, my, children[i]); } } else { const { x, y, r } = node; if ((my - y) * (my - y) + (mx - x) * (mx - x) < r * r) { console.log(x, y); ctx.clearCircle(x, y, r); ctx.fillStyle = "rgba(255,0,0,0.2)"; ctx.beginPath(); ctx.arc(x, y, r, 0, TAU); ctx.fill(); const name = node.data.name; ctx.fillStyle = "white"; ctx.font = "1.5rem Arial"; ctx.textAlign = "center"; ctx.fillText(name, x, y); } } } 3. 监听鼠标mousemove事件(变换页面鼠标位置与canvas内坐标的关系): canvas.addEventListener("mousemove", (e) => { const x = e.clientX * 2; const y = e.clientY * 2; isInCircle(context, x, y, root); });
    展开

    作者回复: 很棒~

    共 6 条评论
    3
  • gltjk
    2020-06-24
    提交一下第二个作业。之前纠结了一下怎么在鼠标移出城市时恢复小圆的颜色,最后决定专门做一个新的 canvas 叠在上面。另外鼠标移动的事件是不是要做个节流比较好?我试了一下感觉又不够流畅,就去掉了…… https://codepen.io/gltjk/pen/GRomzQE

    作者回复: 可以,这个思路挺好的,当然这个问题也可以只用一个canvas,不过用两个的好处也是有的,这样只需要更新局部的图形了。

    共 2 条评论
    3
  • 1830
    2021-07-07
    老师,JSON数据不能用了可以解决一下不,或者把数据结构要求贴一下我们模拟一下

    作者回复: 因为之前用了360的CDN服务,那个域名过期了,把代码里面的qhres全都换成qhres2就可以了

    
    2
  • 春饼sama
    2021-07-05
    老师,获取json的都挂了

    作者回复: 把代码里的qhres全都替换成qhres2就可以了

    
    2
  • sheeeeep
    2020-07-08
    交作业:https://output.jsbin.com/rirahom,思路基本和大家一致。 看完评论有两个主要的优化方法: 1. 减少重绘次数:判断是否在「圆」内 或 判断结果和上次不同,才进行重绘 2. 缩小重绘区域:进行局部清除和局部重绘

    作者回复: 棒~

    共 2 条评论
    2