gpt4 book ai didi

fabricjs - 如何让 Fabric.js 和 Redux 成为 friend ?

转载 作者:行者123 更新时间:2023-12-04 16:38:54 28 4
gpt4 key购买 nike

有没有什么方法可以同时使用 Fabric.js 和 Redux? Fabric.js 状态应该用作 store 的一部分,但它不是一成不变的,并且可以通过用户 Canvas 交互来改变自己。任何的想法?谢谢。

最佳答案

我从 React-Redux 和 Fabric.js 的实现中提取了一个小例子。

它的工作原理是通过fabric.toObject() 获取整个fabric 对象,将其保存到状态并通过fabric.loadFromJSON() 撤销。您可以使用 Redux DevTools 来玩玩。并穿越该州。

enter image description here

在任何情况下,还有 jsfiddle 可用:https://jsfiddle.net/radomeer/74t5y1r0/

// don't be scared, just some initial objects to play with (fabric's serialized JSON)
const initialState = {
canvasObject: {
"objects": [{
"type": "circle",
"originX": "center",
"originY": "center",
"left": 50,
"top": 50,
"width": 100,
"height": 100,
"fill": "#FF00FF",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"radius": 50,
"startAngle": 0,
"endAngle": 6.283185307179586
}, {
"type": "rect",
"originX": "center",
"originY": "center",
"left": 126,
"top": 210,
"width": 100,
"height": 100,
"fill": "#FF0000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"radius": 50,
"startAngle": 0,
"endAngle": 6.283185307179586
}, {
"type": "triangle",
"originX": "center",
"originY": "center",
"left": 250,
"top": 100,
"width": 100,
"height": 100,
"fill": "#00F00F",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"transformMatrix": null,
"radius": 50,
"startAngle": 0,
"endAngle": 6.283185307179586
}],
"background": ""
}
};
// Redux part
const canvasObjectReducer = function(state = initialState, action) {
switch (action.type) {
case "OBJECTS_CANVAS_CHANGE":
return Object.assign({}, state, {
canvasObject: action.payload.canvasObject,
selectedObject: action.payload.selectedObject
});
default:
return state
}
return state;
}
// standard react-redux boilerplate
const reducers = Redux.combineReducers({
canvasObjectState: canvasObjectReducer
});
const { createStore } = Redux;
const store = createStore(reducers, window.devToolsExtension && window.devToolsExtension());

const { Provider } = ReactRedux;
const { Component } = React;
const MyProvider = React.createClass({
render: function() {
return (
<div>
<Provider store={store}>
<FabricCanvasReduxed/>
</Provider>
</div>
);
}
});

// Fabric part
var fabricCanvas = new fabric.Canvas();

// class which takes care about instantiating fabric and passing state to component with actual canvas
const FabricCanvas = React.createClass({
componentDidMount() {
// we need to get canvas element by ref to initialize fabric
var el = this.refs.canvasContainer.refs.objectsCanvas;
fabricCanvas.initialize(el, {
height: 400,
width: 400,
});
// initial call to load objects in store and render canvas
this.refs.canvasContainer.loadAndRender();

fabricCanvas.on('mouse:up', () => {
store.dispatch({
type: 'OBJECTS_CANVAS_CHANGE',
payload: {
// send complete fabric canvas object to store
canvasObject: fabricCanvas.toObject(),
// also keep lastly active (selected) object
selectedObject: fabricCanvas.getObjects().indexOf(fabricCanvas.getActiveObject())
}
});
this.refs.canvasContainer.loadAndRender();
});
},
render: function() {
return (
<div>
{/* send store and fabricInstance viac refs (maybe not the cleanest way, but I was not able to create global instance of fabric due to use of ES6 modules) */}
<CanvasContainer ref="canvasContainer" canvasObjectState={this.props.objects} fabricInstance={fabricCanvas}/>
</div>
)
}
});
const mapStateToProps = function(store) {
return {
objects: store.canvasObjectState
};
};

// we can not use export default on jsfiddle so we need react class with mapped state in separate constant
const FabricCanvasReduxed = ReactRedux.connect(mapStateToProps)(FabricCanvas);

const CanvasContainer = React.createClass({
loadAndRender: function() {
var fabricCanvas = this.props.fabricInstance;
fabricCanvas.loadFromJSON(this.props.canvasObjectState.canvasObject);
fabricCanvas.renderAll();
// if there is any previously active object, we need to re-set it after rendering canvas
var selectedObject = this.props.canvasObjectState.selectedObject;
if (selectedObject > -1) {
fabricCanvas.setActiveObject(fabricCanvas.getObjects()[this.props.canvasObjectState.selectedObject]);
}

},
render: function() {
this.loadAndRender();
return (
<canvas ref="objectsCanvas">
</canvas>
);
}
});

var App = React.createClass({
render: function() {
return (
<div>
<MyProvider/>
</div>
);
}
});

ReactDOM.render( <App/>, document.getElementById('container'));
<!-- 
Please use Redux DevTools for Chrome or Firefox to see the store changes and time traveling
https://github.com/zalmoxisus/redux-devtools-extension
Inspired by https://jsfiddle.net/STHayden/2pncoLb5/
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.4/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.5/react-redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.js"></script>
<div id="container">
</div>

关于fabricjs - 如何让 Fabric.js 和 Redux 成为 friend ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37742465/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com