{"id":19014218,"url":"https://github.com/spritejs/sprite-wxapp","last_synced_at":"2025-05-06T23:45:46.367Z","repository":{"id":57162096,"uuid":"125800027","full_name":"spritejs/sprite-wxapp","owner":"spritejs","description":"spritejs 小程序版","archived":false,"fork":false,"pushed_at":"2019-07-16T08:21:28.000Z","size":4058,"stargazers_count":159,"open_issues_count":14,"forks_count":24,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-18T15:18:04.661Z","etag":null,"topics":["animation","canvas","dom","graphics","oop","sprites","wechat"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spritejs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-19T04:08:46.000Z","updated_at":"2025-02-04T09:46:54.000Z","dependencies_parsed_at":"2022-09-06T16:30:30.084Z","dependency_job_id":null,"html_url":"https://github.com/spritejs/sprite-wxapp","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spritejs%2Fsprite-wxapp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spritejs%2Fsprite-wxapp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spritejs%2Fsprite-wxapp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spritejs%2Fsprite-wxapp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spritejs","download_url":"https://codeload.github.com/spritejs/sprite-wxapp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252788404,"owners_count":21804280,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","canvas","dom","graphics","oop","sprites","wechat"],"created_at":"2024-11-08T19:28:24.823Z","updated_at":"2025-05-06T23:45:46.341Z","avatar_url":"https://github.com/spritejs.png","language":"JavaScript","readme":"# spritejs 微信小程序版\n\n这是 [spritejs](https://github.com/spritejs/spritejs) 的微信小程序版，目前支持 spritejs v 2.0 的大部分功能，具体可以参考[帮助文档](https://github.com/spritejs/spritejs/tree/master/docs#%E6%95%B4%E4%BD%93%E7%BB%93%E6%9E%84)\n\n## 特性\n\n- Sprite属性更新自动（分批）重绘\n- 以rpx为默认单位\n- 动画支持Web Animations API\n- 支持事件机制\n\n## 快速使用\n\n### 安装\n\nv1.10.0 版本之后，小程序版支持使用 NPM 安装。\n\n```bash\nnpm install @spritejs/wxapp --save\n```\n\n然后在微信小程序中[构建 NPM 包](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html)。\n\n### 通过组件使用\n\n安装并构建之后，要使用 SpriteJS，最简单的方式是通过内置的 scene 组件使用。\n\n在小程序配置 app.json 中注册组件：\n\n```json\n  \"usingComponents\": {\n    \"s-scene\": \"@spritejs/wxapp/scene\"\n  }\n```\n\n然后在要使用的页面引入组件：\n\n```xml\n\u003cview\u003e\n  \u003cs-scene id=\"container\"\n    layers=\"bglayer,fglayer\"\n    bindSceneCreated=\"onSceneCreated\"\n  \u003e\u003c/s-scene\u003e\n\u003c/view\u003e\n```\n\n参数layers表示创建几个layer以及它们的ID，缺省为default。\n\nbindSceneCreated为创建Scene后的回调事件，事件方法中传回所创建的layers：\n\n```js\nconst { Sprite } = require('@spritejs/wxapp');\n\nPage({\n  onSceneCreated({ detail: layers }) {\n    const { bglayer, fglayer } = layers;\n    const s = new Sprite({\n      size: [100, 100],\n      pos: [300, 300],\n      bgcolor: 'red',\n    });\n    fglayer.append(s);\n\n    const s2 = new Sprite({\n      size: [300, 300],\n      pos: [200, 200],\n      bgcolor: 'blue',\n    });\n    bglayer.append(s2);\n\n    s.on('touchstart', () =\u003e {\n      s.attr('bgcolor', 'green');\n    });\n    s.on('touchmove', () =\u003e {\n      s.attr('bgcolor', 'yellow');\n    });\n    s.on('touchend', () =\u003e {\n      s.attr('bgcolor', 'red');\n    });\n  },\n});\n```\n\n### 自定义使用\n\n如果不想使用组件，你也可以自己创建canvas，然后构造scene\n\n```xml\n\u003cview class=\"scene-layout\" id=\"container\" catchtouchmove=\"noop\"\u003e\n  \u003cblock wx:for=\"{{layers}}\" wx:key=\"{{item}}\"\u003e\n    \u003ccanvas canvas-id=\"{{item}}\" disable-scroll=\"true\"\u003e\u003c/canvas\u003e\n  \u003c/block\u003e\n\u003c/view\u003e\n```\n\n```js\nconst spritejs = require('@spritejs/wxapp');\n\nPage({\n  data: {\n    layers: ['fglayer'],\n    eventOffset: [0, 0],\n  },\n  onTouchStart(event) {\n    // 派发 touchstart 事件\n    this.scene.layer('fglayer').dispatchEvent(event, this.data.eventOffset);\n  },\n  onReady: function() {\n    // 由于代理事件的 scene-layout 相对窗口可能有偏移，所以需要传入这个偏移量\n    // 以正确定位事件坐标\n    const query = wx.createSelectorQuery();\n    query.select('.scene-layout').boundingClientRect().exec(([rect]) =\u003e {\n      if(rect) {\n        this.setData({\n          eventOffset: [rect.left, rect.top],\n        });\n      }\n    });\n\n    const scene = new spritejs.Scene();\n    this.scene = scene;\n    const layer = scene.layer('fglayer');\n    \n    // 预加载资源\n    scene.preload(['../../assets/img/birds.png', require('../../assets/img/birds.json.js')]);\n    \n    const bird = new spritejs.Sprite('bird1.png');\n    bird.attr({\n      anchor: [0.5, 0.5],\n      pos: [100, 200],\n    });\n\n    // 添加 ontouch 事件\n    bird.on('touchstart', evt =\u003e {\n      console.log(evt)\n    });\n\n    // 纹理动画\n    let i = 0;\n    setInterval(() =\u003e {\n      bird.textures = [`bird${i++%3+1}.png`];\n    }, 100);\n\n    // 添加文字\n    const text = new spritejs.Label('Hello\\n World!');\n    text.attr({\n      //anchor: [0.5, 0.5],\n      font: '44px Arial',\n      border: [2, 'red'],\n    });\n\n    const posFrom = [0, 0];\n    const posTo = [100, 0];\n\n    // 播放一个移位动画\n    text.animate([\n      {pos: posFrom},\n      {pos: posTo},\n    ], {\n      duration: 2000\n    });\n\n    // 将两个精灵添加到 layer\n    layer.append(bird, text);\n  },\n})\n```\n\n**注意**，自己调用的时候，创建canvas需要设置canvas-id属性与创建的layer的ID一致。\n\n## 小程序版与原版限制/差异\n\n### Scene 的参数差异\n\n不同于web/node版，小程序版的Scene构造函数只能传width和height，单位是rpx。rpx是微信小程序特有的单位，具体描述参考[文档](https://mp.weixin.qq.com/debug/wxadoc/dev/framework/view/wxss.html)。\n\n```js\nconst info = wx.getSystemInfoSync();\nconst scene = new Scene(750, 1433); // 单位是rpx\n```\n\n### 事件处理的差异\n\n如果通过组件加载方式使用，`touchstart, touchend, touchmove, tap, longpress` 等事件被scene自动代理，所以你可以在sprite元素中添加对应的事件处理函数，能够正常触发事件。\n\n如果是自己创建scene，那么需要自己手动代理事件：\n\n```xml\n\u003c!--index.wxml--\u003e\n\u003cview class=\"scene-layout\" id=\"container\"\u003e\n  \u003cblock wx:for=\"{{layers}}\" wx:key=\"{{item}}\"\u003e\n    \u003ccanvas canvas-id=\"{{item}}\" bindtouchstart=\"touched\"\u003e\u003c/canvas\u003e\n  \u003c/block\u003e\n\u003c/view\u003e\n```\n\n```js\nconst spritejs = require('@spritejs/wxapp')\n\nPage({\n  data: {\n    layers: ['fglayer'],\n    eventOffset: [0, 0],\n  },\n  touched: function(event) {\n    this.scene.layer('fglayer').delegateEvent(event, this.data.eventOffset);\n  },\n  onReady: function() {\n    // 由于代理事件的 scene-layout 相对窗口可能有偏移，所以需要传入这个偏移量\n    // 以正确定位事件坐标\n    const query = wx.createSelectorQuery();\n    query.select('.scene-layout').boundingClientRect().exec(([rect]) =\u003e {\n      if(rect) {\n        this.setData({\n          eventOffset: [rect.left, rect.top],\n        });\n      }\n    });\n\n    const scene = new spritejs.Scene();\n    this.scene = scene;\n\n    const layer = scene.layer('fglayer');\n    \n    // 如果在自定义组件中使用，传递第二个参数为组件实例的引用。\n    // const layer = scene.layer('fglayer', this)\n    \n    ...\n  },\n})\n```\n\n### layer的canvas元素需要预先创建\n\n微信不支持动态创建元素，因此canvas要先在模板里创建好，并赋给对应的canvas-id。\n\n### 资源预加载和Sprite图片支持的限制\n\n目前不支持远程url的加载，只支持本地图片素材，另外web/node版的Sprite可以预加载图片并获得图片宽高，所以sprite可以默认自适应宽高，而微信小程序版除非使用texturepacker打包图片，否则不能获得默认的宽高，必须指定宽高才可以将sprite对象显示出来。\n\n另外**注意**scene.preload预加frames资源载时，不支持从json文件加载frameData，必须是js对象，可以将frameData存成js，然后在app中require进来。\n\n另外目前不支持 texture packer 的 rotated 和 trimmed 功能。\n\n```js\n// 微信小程序版的 scene.preload 是同步的\nscene.preload(['../../assets/img/birds.png', require('../../assets/img/birds.json.js')])\n\nconst sprite1 = new Sprite('bird1.png') \nsprite1.attr({\n  pos: [0, 0],\n})\n// 从frames中加载的图片有默认大小，可以正常显示\nscene.layer().append(sprite1)\n\nconst sprite2 = new Sprite('../../assets/img/rambda.png')\nsprite2.attr({\n  pos: [50, 50],\n  size: [100, 100], // 非frames的图片必须指定宽高\n})\n\nscene.layer().append(sprite2)\n```\n\n### 调试示例代码\n\n我们放了一个“十滴水”小游戏的例子在 `app` 文件夹下。\n\n要调试示例代码，可以启动webpack编译\n\n```bash\nnpm start\n```\n\n然后用微信开发者工具调试代码\n\n![示例小程序](https://p1.ssl.qhimg.com/t01c8802b28edfcb127.gif)\n\n### 目前不支持的特性\n\n* 微信不支持动态创建Dom元素，不兼容d3，目前d3的功能暂时不支持（未来打算通过shim适配）。\n* 微信context不支持滤镜，所以滤镜filter无效果。\n* 微信canvas不支持渐变（linearGradients 和 createRadialGradient)，如果在 attr 中使用渐变属性会出错。\n* 微信的canvas不支持动态创建context，因此无法使用缓存优化。\n\n### 目前暂时无法解决的Bug\n\n* 由于微信的模拟器的clip有问题，所以在模拟器下sprite元素的clip区域可能不正确\n* 微信的canvas的globalAlpha只有setter没有getter，因此小程序设置opacity属性的时候没法层叠，子元素的opacity会覆盖父容器的opacity值\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspritejs%2Fsprite-wxapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspritejs%2Fsprite-wxapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspritejs%2Fsprite-wxapp/lists"}