V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
lizheming
V2EX  ›  分享创造

[开源] SpriteJS -- 一款简单的跨终端 canvas 绘图框架

  •  1
     
  •   lizheming ·
    lizheming · 2018-06-20 09:20:08 +08:00 · 9740 次点击
    这是一个创建于 2359 天前的主题,其中的信息可能已经有所发展或是发生改变。

    SpriteJS 是一款由 360 奇舞团开源的跨终端 canvas 绘图框架,可以基于 canvas 快速绘制结构化 UI、动画和交互效果,并发布到任何拥有 canvas 环境的平台上(比如浏览器、小程序和 node )。

    为什么要开发 SpriteJS

    我们知道,canvas API 可以很灵活地绘制各种矢量图形到画布上,但是 canvas API 本身比较低级,比如我们要在画布中央绘制一个带有圆角的红色矩形,使用 canvas 原生的 API,需要这样:

    const canvas = document.getElementById('paper')
    const context = canvas.getContext('2d')
    
    const [x, y, w, h, r] = [200, 200, 200, 200, 50]
    
    context.fillStyle = 'red'
    context.beginPath()
    context.moveTo(x + r, y)
    context.arcTo(x + w, y, x + w, y + h, r)
    context.arcTo(x + w, y + h, x, y + h, r)
    context.arcTo(x, y + h, x, y, r)
    context.arcTo(x, y, x + w, y, r)
    context.closePath()
    context.fill()
    

    如果实现相同的效果,使用 SpriteJS 是这样写:

    const scene = new spritejs.Scene('#container')
    const layer = scene.layer()
    
    const s = new spritejs.Sprite({
      anchor: 0.5,
      bgcolor: 'red',
      pos: [300, 300],
      size: [200, 200],
      borderRadius: 50,
    })
    
    layer.append(s)
    

    Sprite 为图形创建类似于 DOM 的对象模型,因此我们可以像创建 DOM 元素一样,创建 Sprite 元素,并将它们 append 到 layer 上,从而将元素呈现到画布上。SpriteJS 有如下特点:

    • 基于 canvas 绘制的文档对象模型
    • 四种基本精灵类型:Sprite、Path、Label、Group
    • 支持基础和高级的精灵属性,精灵盒模型、属性与 CSS3 具有高度一致性。
    • 简便而强大的 Transition、Animation API
    • 支持雪碧图和资源预加载
    • 可扩展的事件机制
    • 高性能的缓存策略
    • D3Matter-jsProton和其他第三方库友好
    • 跨平台,支持服务端渲染微信小程序

    基本使用介绍

    通过 NPM 或者直接加载 CDN 版本即可使用 SpriteJS

    npm install spritejs — save
    
    <script src="//lib.baomitu.com/spritejs/2.0.0-alpha.28/spritejs.min.js"></script>
    

    注:在服务端使用需要安装 node-canvas

    下面是简单的用法示例,大家也可以直接访问 JSBin 查看效果。

    const {Scene, Sprite} = spritejs
    
    const scene = new Scene('#demo-quickStart', {viewport: [770, 200], resolution: [3080, 800]})
    
    const layer = scene.layer()
    
    const robot = new Sprite('https://p5.ssl.qhimg.com/t01c33383c0e168c3c4.png')
    
    robot.attr({
      anchor: [0, 0.5],
      pos: [0, 0],
    })
    
    robot.animate([
      {pos: [0, 0]},
      {pos: [0, 300]},
      {pos: [2700, 300]},
      {pos: [2700, 0]},
    ], {
      duration: 5000,
      iterations: Infinity,
      direction: 'alternate',
    })
    
    layer.append(robot)
    

    文档

    要深入了解 SpriteJS 或者希望给 SpriteJS 贡献代码,可以关注我们的 GitHub 仓库,大家的宝贵 star 是对我们最大的鼓励和支持。如果对 SpriteJS 有疑问,或者需要了解进一步细节,可以加入 SpriteJS 官方 QQ 群:801359678

    7 条回复    2019-09-04 11:12:43 +08:00
    AlphaTr
        1
    AlphaTr  
       2018-06-20 10:11:10 +08:00 via iPhone
    支持 +1
    marcong95
        2
    marcong95  
       2018-06-20 10:15:10 +08:00
    跟 DOM、CSS 保持一致感觉会不会导致 API 比较累赘,有空仔细看一下
    lizheming
        3
    lizheming  
    OP
       2018-06-20 10:41:22 +08:00
    @marcong95 我觉得还好,跟 DOM 和 CSS 保持一致可以无缝切换 Web Animation API,WAAPI 这个还是挺方便的。
    ajan
        4
    ajan  
       2018-06-20 10:46:27 +08:00
    厉害了
    oska117
        5
    oska117  
       2018-06-20 11:13:00 +08:00 via Android
    支持楼主,研究一下
    whxme
        6
    whxme  
       2018-06-27 11:06:28 +08:00
    label 能够自适应大小,但是对于指定大小的 Label,超出大小的部分文字将被遮挡,目前无法做到自动换行、撑开 box 等高级功能。这块内容后续可以通过为 spritejs 开发专门的文字类扩展库来实现。
    Alsmile
        7
    Alsmile  
       2019-09-04 11:12:43 +08:00
    另一个基于 typescript + canvas 的开源绘画微服务架构图、流程图等工具,可以了解下:
    https://juejin.im/post/5d6c88726fb9a06b0e54ab35
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3424 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 11:26 · PVG 19:26 · LAX 03:26 · JFK 06:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.