React Native(Expo)应用程序-使用drawImage()方法将本地图像绘制到画布中
我有一个透明的PNG精灵表,我将它加载到一个标记中,然后当“onload”触发时,我将元素保存到一个上下文对象(ImageLoader.js)中,这样我以后可以将它与画布上的drawImage(sprite.js)一起使用,以提取各种精灵并覆盖它们,为游戏生成一个复合瓷砖 Home.js只是选择显示一个虚拟的保留消息,但一旦触发“onload”就会重新绘制,然后呈现一个组件 我曾尝试使用react native canvas和各种其他方法,但我不确定我所尝试的是否可行 下面是各种代码片段,它们可能比试图描述更容易显示 该代码在浏览器中运行良好,但这是一个使用Expo框架的React本机应用程序,由于ImageLoader.js组件中的标记而失败。理想情况下,我会使用React原生图像,但这不是Canvas drawImage方法的选项,该方法需要DOM样式的图像对象 我对实现这一点的其他方法持开放态度,但实际上我需要能够创建一个自定义的React本机图像组件,其中基础图像在应用程序中生成,方法是使用本地透明PNG sprite表并将其各个部分覆盖到画布中,以便我创建一个合成图像 App.jsReact Native(Expo)应用程序-使用drawImage()方法将本地图像绘制到画布中,image,react-native,canvas,expo,drawimage,Image,React Native,Canvas,Expo,Drawimage,我有一个透明的PNG精灵表,我将它加载到一个标记中,然后当“onload”触发时,我将元素保存到一个上下文对象(ImageLoader.js)中,这样我以后可以将它与画布上的drawImage(sprite.js)一起使用,以提取各种精灵并覆盖它们,为游戏生成一个复合瓷砖 Home.js只是选择显示一个虚拟的保留消息,但一旦触发“onload”就会重新绘制,然后呈现一个组件 我曾尝试使用react native canvas和各种其他方法,但我不确定我所尝试的是否可行 下面是各种代码片段,它们可
import { Text, View } from 'react-native';
import Home from './components/Home';
import ConfigContextProvider from './contexts/ConfigContext';
export default class App extends Component {
render() {
return (
<ConfigContextProvider>
<Home />
</ConfigContextProvider>
);
}
}
import { Text, View, Button } from 'react-native';
import { ConfigContext } from '../contexts/ConfigContext';
import Sprite from './Sprite';
import ImageLoader from './ImageLoader';
class Home extends Component {
render() {
return (
<ConfigContext.Consumer>{(configContext) => {
if(configContext.spriteMapIsLoaded) {
return (
<View>
<Text>It's Alive!</Text>
<Text>Screen Width: {configContext.screenWidth}</Text>
<Text>Screen Height: {configContext.screenHeight}</Text>
<Sprite />
</View>
);
}
else {
return (
<View>
<Text>Image is not loaded!</Text>
<ImageLoader />
</View>
);
}
}}</ConfigContext.Consumer>
);
}
}
export default Home;
import { ConfigContext } from '../contexts/ConfigContext';
class ImageLoader extends Component {
static contextType = ConfigContext;
componentDidMount() {
const spriteMapImage = this.refs.spritemap;
spriteMapImage.onload = () => {
console.log("Image has loaded");
this.context.setSpriteMapImage(this.refs.spritemap);
}
}
render() {
return (
<img ref="spritemap" src={require('../assets/SpriteMap.png')} style={{width:0, height:0}} />
)
}
}
export default ImageLoader;
import { Dimensions } from 'react-native';
export const ConfigContext = createContext();
class ConfigContextProvider extends Component {
state = {
screenWidth: Dimensions.get('window').width,
screenHeight: Dimensions.get('window').height,
spriteSize: 50,
spriteMapIsLoaded: false,
spriteMapImage: null
}
setSpriteMapImage = (spriteMapImage) => {
this.setState({
spriteMapIsLoaded: true,
spriteMapImage: spriteMapImage});
}
render() {
return (
<ConfigContext.Provider value={{...this.state, setSpriteMapImage: this.setSpriteMapImage}}>
{this.props.children}
</ConfigContext.Provider>
);
}
}
export default ConfigContextProvider;
import { ConfigContext } from '../contexts/ConfigContext';
class Sprite extends Component {
static contextType = ConfigContext;
componentDidMount() {
console.log(this.context);
const canvas = this.refs.canvas;
const ctx = canvas.getContext('2d');
for(let x = 0; x <= 360; x += 120) {
let y = Math.floor(Math.random() * 8) * 120;
console.log(x, y);
ctx.drawImage(this.context.spriteMapImage, x, y, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
}
ctx.drawImage(this.context.spriteMapImage, 960, 120, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
const cardColour = Math.floor(Math.random() * 2);
const cardSuit = Math.floor(Math.random() * 2);
const cardSymbol = Math.floor(Math.random() * 4);
ctx.drawImage(this.context.spriteMapImage, 480 + cardSymbol * 120, cardColour * 120, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
ctx.drawImage(this.context.spriteMapImage, 480 + cardColour * 240 + cardSuit * 120, 240, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
}
render() {
return (
<div>
<canvas ref="canvas" width={this.context.spriteSize} height={this.context.spriteSize} />
</div>
);
}
}
export default Sprite;
从'react native'导入{Text,View};
从“./components/Home”导入Home;
从“./contexts/ConfigContext”导入ConfigContextProvider;
导出默认类应用程序扩展组件{
render(){
返回(
);
}
}
Home.js
import { Text, View } from 'react-native';
import Home from './components/Home';
import ConfigContextProvider from './contexts/ConfigContext';
export default class App extends Component {
render() {
return (
<ConfigContextProvider>
<Home />
</ConfigContextProvider>
);
}
}
import { Text, View, Button } from 'react-native';
import { ConfigContext } from '../contexts/ConfigContext';
import Sprite from './Sprite';
import ImageLoader from './ImageLoader';
class Home extends Component {
render() {
return (
<ConfigContext.Consumer>{(configContext) => {
if(configContext.spriteMapIsLoaded) {
return (
<View>
<Text>It's Alive!</Text>
<Text>Screen Width: {configContext.screenWidth}</Text>
<Text>Screen Height: {configContext.screenHeight}</Text>
<Sprite />
</View>
);
}
else {
return (
<View>
<Text>Image is not loaded!</Text>
<ImageLoader />
</View>
);
}
}}</ConfigContext.Consumer>
);
}
}
export default Home;
import { ConfigContext } from '../contexts/ConfigContext';
class ImageLoader extends Component {
static contextType = ConfigContext;
componentDidMount() {
const spriteMapImage = this.refs.spritemap;
spriteMapImage.onload = () => {
console.log("Image has loaded");
this.context.setSpriteMapImage(this.refs.spritemap);
}
}
render() {
return (
<img ref="spritemap" src={require('../assets/SpriteMap.png')} style={{width:0, height:0}} />
)
}
}
export default ImageLoader;
import { Dimensions } from 'react-native';
export const ConfigContext = createContext();
class ConfigContextProvider extends Component {
state = {
screenWidth: Dimensions.get('window').width,
screenHeight: Dimensions.get('window').height,
spriteSize: 50,
spriteMapIsLoaded: false,
spriteMapImage: null
}
setSpriteMapImage = (spriteMapImage) => {
this.setState({
spriteMapIsLoaded: true,
spriteMapImage: spriteMapImage});
}
render() {
return (
<ConfigContext.Provider value={{...this.state, setSpriteMapImage: this.setSpriteMapImage}}>
{this.props.children}
</ConfigContext.Provider>
);
}
}
export default ConfigContextProvider;
import { ConfigContext } from '../contexts/ConfigContext';
class Sprite extends Component {
static contextType = ConfigContext;
componentDidMount() {
console.log(this.context);
const canvas = this.refs.canvas;
const ctx = canvas.getContext('2d');
for(let x = 0; x <= 360; x += 120) {
let y = Math.floor(Math.random() * 8) * 120;
console.log(x, y);
ctx.drawImage(this.context.spriteMapImage, x, y, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
}
ctx.drawImage(this.context.spriteMapImage, 960, 120, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
const cardColour = Math.floor(Math.random() * 2);
const cardSuit = Math.floor(Math.random() * 2);
const cardSymbol = Math.floor(Math.random() * 4);
ctx.drawImage(this.context.spriteMapImage, 480 + cardSymbol * 120, cardColour * 120, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
ctx.drawImage(this.context.spriteMapImage, 480 + cardColour * 240 + cardSuit * 120, 240, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
}
render() {
return (
<div>
<canvas ref="canvas" width={this.context.spriteSize} height={this.context.spriteSize} />
</div>
);
}
}
export default Sprite;
从'react native'导入{文本、视图、按钮};
从“../Context/ConfigContext”导入{ConfigContext};
从“/Sprite”导入精灵;
从“/ImageLoader”导入ImageLoader;
类Home扩展组件{
render(){
报税表(
{(配置上下文)=>{
if(configContext.spriteMapIsLoaded){
返回(
它还活着!
屏幕宽度:{configContext.screenWidth}
屏幕高度:{configContext.screenHeight}
);
}
否则{
返回(
图像未加载!
);
}
}}
);
}
}
导出默认主页;
ImageLoader.js
import { Text, View } from 'react-native';
import Home from './components/Home';
import ConfigContextProvider from './contexts/ConfigContext';
export default class App extends Component {
render() {
return (
<ConfigContextProvider>
<Home />
</ConfigContextProvider>
);
}
}
import { Text, View, Button } from 'react-native';
import { ConfigContext } from '../contexts/ConfigContext';
import Sprite from './Sprite';
import ImageLoader from './ImageLoader';
class Home extends Component {
render() {
return (
<ConfigContext.Consumer>{(configContext) => {
if(configContext.spriteMapIsLoaded) {
return (
<View>
<Text>It's Alive!</Text>
<Text>Screen Width: {configContext.screenWidth}</Text>
<Text>Screen Height: {configContext.screenHeight}</Text>
<Sprite />
</View>
);
}
else {
return (
<View>
<Text>Image is not loaded!</Text>
<ImageLoader />
</View>
);
}
}}</ConfigContext.Consumer>
);
}
}
export default Home;
import { ConfigContext } from '../contexts/ConfigContext';
class ImageLoader extends Component {
static contextType = ConfigContext;
componentDidMount() {
const spriteMapImage = this.refs.spritemap;
spriteMapImage.onload = () => {
console.log("Image has loaded");
this.context.setSpriteMapImage(this.refs.spritemap);
}
}
render() {
return (
<img ref="spritemap" src={require('../assets/SpriteMap.png')} style={{width:0, height:0}} />
)
}
}
export default ImageLoader;
import { Dimensions } from 'react-native';
export const ConfigContext = createContext();
class ConfigContextProvider extends Component {
state = {
screenWidth: Dimensions.get('window').width,
screenHeight: Dimensions.get('window').height,
spriteSize: 50,
spriteMapIsLoaded: false,
spriteMapImage: null
}
setSpriteMapImage = (spriteMapImage) => {
this.setState({
spriteMapIsLoaded: true,
spriteMapImage: spriteMapImage});
}
render() {
return (
<ConfigContext.Provider value={{...this.state, setSpriteMapImage: this.setSpriteMapImage}}>
{this.props.children}
</ConfigContext.Provider>
);
}
}
export default ConfigContextProvider;
import { ConfigContext } from '../contexts/ConfigContext';
class Sprite extends Component {
static contextType = ConfigContext;
componentDidMount() {
console.log(this.context);
const canvas = this.refs.canvas;
const ctx = canvas.getContext('2d');
for(let x = 0; x <= 360; x += 120) {
let y = Math.floor(Math.random() * 8) * 120;
console.log(x, y);
ctx.drawImage(this.context.spriteMapImage, x, y, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
}
ctx.drawImage(this.context.spriteMapImage, 960, 120, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
const cardColour = Math.floor(Math.random() * 2);
const cardSuit = Math.floor(Math.random() * 2);
const cardSymbol = Math.floor(Math.random() * 4);
ctx.drawImage(this.context.spriteMapImage, 480 + cardSymbol * 120, cardColour * 120, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
ctx.drawImage(this.context.spriteMapImage, 480 + cardColour * 240 + cardSuit * 120, 240, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
}
render() {
return (
<div>
<canvas ref="canvas" width={this.context.spriteSize} height={this.context.spriteSize} />
</div>
);
}
}
export default Sprite;
从“../context/ConfigContext”导入{ConfigContext};
类ImageLoader扩展组件{
静态contextType=ConfigContext;
componentDidMount(){
const spriteMapImage=this.refs.spritemap;
spriteMapImage.onload=()=>{
log(“图像已加载”);
this.context.setPriteMapImage(this.refs.spritemap);
}
}
render(){
返回(
)
}
}
导出默认图像加载器;
ConfigContext.js
import { Text, View } from 'react-native';
import Home from './components/Home';
import ConfigContextProvider from './contexts/ConfigContext';
export default class App extends Component {
render() {
return (
<ConfigContextProvider>
<Home />
</ConfigContextProvider>
);
}
}
import { Text, View, Button } from 'react-native';
import { ConfigContext } from '../contexts/ConfigContext';
import Sprite from './Sprite';
import ImageLoader from './ImageLoader';
class Home extends Component {
render() {
return (
<ConfigContext.Consumer>{(configContext) => {
if(configContext.spriteMapIsLoaded) {
return (
<View>
<Text>It's Alive!</Text>
<Text>Screen Width: {configContext.screenWidth}</Text>
<Text>Screen Height: {configContext.screenHeight}</Text>
<Sprite />
</View>
);
}
else {
return (
<View>
<Text>Image is not loaded!</Text>
<ImageLoader />
</View>
);
}
}}</ConfigContext.Consumer>
);
}
}
export default Home;
import { ConfigContext } from '../contexts/ConfigContext';
class ImageLoader extends Component {
static contextType = ConfigContext;
componentDidMount() {
const spriteMapImage = this.refs.spritemap;
spriteMapImage.onload = () => {
console.log("Image has loaded");
this.context.setSpriteMapImage(this.refs.spritemap);
}
}
render() {
return (
<img ref="spritemap" src={require('../assets/SpriteMap.png')} style={{width:0, height:0}} />
)
}
}
export default ImageLoader;
import { Dimensions } from 'react-native';
export const ConfigContext = createContext();
class ConfigContextProvider extends Component {
state = {
screenWidth: Dimensions.get('window').width,
screenHeight: Dimensions.get('window').height,
spriteSize: 50,
spriteMapIsLoaded: false,
spriteMapImage: null
}
setSpriteMapImage = (spriteMapImage) => {
this.setState({
spriteMapIsLoaded: true,
spriteMapImage: spriteMapImage});
}
render() {
return (
<ConfigContext.Provider value={{...this.state, setSpriteMapImage: this.setSpriteMapImage}}>
{this.props.children}
</ConfigContext.Provider>
);
}
}
export default ConfigContextProvider;
import { ConfigContext } from '../contexts/ConfigContext';
class Sprite extends Component {
static contextType = ConfigContext;
componentDidMount() {
console.log(this.context);
const canvas = this.refs.canvas;
const ctx = canvas.getContext('2d');
for(let x = 0; x <= 360; x += 120) {
let y = Math.floor(Math.random() * 8) * 120;
console.log(x, y);
ctx.drawImage(this.context.spriteMapImage, x, y, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
}
ctx.drawImage(this.context.spriteMapImage, 960, 120, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
const cardColour = Math.floor(Math.random() * 2);
const cardSuit = Math.floor(Math.random() * 2);
const cardSymbol = Math.floor(Math.random() * 4);
ctx.drawImage(this.context.spriteMapImage, 480 + cardSymbol * 120, cardColour * 120, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
ctx.drawImage(this.context.spriteMapImage, 480 + cardColour * 240 + cardSuit * 120, 240, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
}
render() {
return (
<div>
<canvas ref="canvas" width={this.context.spriteSize} height={this.context.spriteSize} />
</div>
);
}
}
export default Sprite;
从'react native'导入{Dimensions};
export const ConfigContext=createContext();
类ConfigContextProvider扩展组件{
状态={
屏幕宽度:尺寸。获取('窗口')。宽度,
屏幕高度:尺寸。获取(“窗口”)。高度,
精灵化:50,
spriteMapIsLoaded:错误,
spriteMapImage:null
}
setSpriteMapImage=(spriteMapImage)=>{
这是我的国家({
spriteMapIsLoaded:没错,
spriteMapImage:spriteMapImage});
}
render(){
报税表(
{this.props.children}
);
}
}
导出默认ConfigContextProvider;
Sprite.js
import { Text, View } from 'react-native';
import Home from './components/Home';
import ConfigContextProvider from './contexts/ConfigContext';
export default class App extends Component {
render() {
return (
<ConfigContextProvider>
<Home />
</ConfigContextProvider>
);
}
}
import { Text, View, Button } from 'react-native';
import { ConfigContext } from '../contexts/ConfigContext';
import Sprite from './Sprite';
import ImageLoader from './ImageLoader';
class Home extends Component {
render() {
return (
<ConfigContext.Consumer>{(configContext) => {
if(configContext.spriteMapIsLoaded) {
return (
<View>
<Text>It's Alive!</Text>
<Text>Screen Width: {configContext.screenWidth}</Text>
<Text>Screen Height: {configContext.screenHeight}</Text>
<Sprite />
</View>
);
}
else {
return (
<View>
<Text>Image is not loaded!</Text>
<ImageLoader />
</View>
);
}
}}</ConfigContext.Consumer>
);
}
}
export default Home;
import { ConfigContext } from '../contexts/ConfigContext';
class ImageLoader extends Component {
static contextType = ConfigContext;
componentDidMount() {
const spriteMapImage = this.refs.spritemap;
spriteMapImage.onload = () => {
console.log("Image has loaded");
this.context.setSpriteMapImage(this.refs.spritemap);
}
}
render() {
return (
<img ref="spritemap" src={require('../assets/SpriteMap.png')} style={{width:0, height:0}} />
)
}
}
export default ImageLoader;
import { Dimensions } from 'react-native';
export const ConfigContext = createContext();
class ConfigContextProvider extends Component {
state = {
screenWidth: Dimensions.get('window').width,
screenHeight: Dimensions.get('window').height,
spriteSize: 50,
spriteMapIsLoaded: false,
spriteMapImage: null
}
setSpriteMapImage = (spriteMapImage) => {
this.setState({
spriteMapIsLoaded: true,
spriteMapImage: spriteMapImage});
}
render() {
return (
<ConfigContext.Provider value={{...this.state, setSpriteMapImage: this.setSpriteMapImage}}>
{this.props.children}
</ConfigContext.Provider>
);
}
}
export default ConfigContextProvider;
import { ConfigContext } from '../contexts/ConfigContext';
class Sprite extends Component {
static contextType = ConfigContext;
componentDidMount() {
console.log(this.context);
const canvas = this.refs.canvas;
const ctx = canvas.getContext('2d');
for(let x = 0; x <= 360; x += 120) {
let y = Math.floor(Math.random() * 8) * 120;
console.log(x, y);
ctx.drawImage(this.context.spriteMapImage, x, y, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
}
ctx.drawImage(this.context.spriteMapImage, 960, 120, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
const cardColour = Math.floor(Math.random() * 2);
const cardSuit = Math.floor(Math.random() * 2);
const cardSymbol = Math.floor(Math.random() * 4);
ctx.drawImage(this.context.spriteMapImage, 480 + cardSymbol * 120, cardColour * 120, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
ctx.drawImage(this.context.spriteMapImage, 480 + cardColour * 240 + cardSuit * 120, 240, 120, 120, 0, 0, this.context.spriteSize, this.context.spriteSize);
}
render() {
return (
<div>
<canvas ref="canvas" width={this.context.spriteSize} height={this.context.spriteSize} />
</div>
);
}
}
export default Sprite;
从“../context/ConfigContext”导入{ConfigContext};
类Sprite扩展组件{
静态contextType=ConfigContext;
componentDidMount(){
log(this.context);
const canvas=this.refs.canvas;
const ctx=canvas.getContext('2d');
对于(设x=0;x