Last active
November 26, 2023 23:51
-
-
Save BretHudson/edceeaea0cd7511ade4b0592d59a2811 to your computer and use it in GitHub Desktop.
Creating a "scoped" render that then undoes all the operations so you don't have to store temporary variables for an eventual reset
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // whatever your canvas initialization code is | |
| // just creating a canvas in JS and not putting in the DOM since this is just an example | |
| const canvas = document.createElement('canvas'); | |
| const ctx = canvas.getContext("2d"); | |
| // get previous values | |
| const prevFillStyle = ctx.fillStyle; | |
| const prevFillStyle = ctx.strokeStyle; | |
| // update the values | |
| ctx.fillStyle = '#FFFFFF'; | |
| ctx.strokeStyle = '#FFFFFF'; | |
| // reset the values | |
| ctx.fillStyle = prevFillStyle; | |
| ctx.strokeStyle = prevStrokeStyle; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // whatever your canvas initialization code is | |
| // just creating a canvas in JS and not putting in the DOM since this is just an example | |
| const canvas = document.createElement('canvas'); | |
| const ctx = canvas.getContext("2d"); | |
| function scopedRender(ctx, func) { | |
| const updates = {}; | |
| func(new Proxy(ctx, { | |
| get: function (target, key) { | |
| return target[key]; | |
| }, | |
| set: function (target, key, value) { | |
| updates[key] ??= target[key]; | |
| target[key] = value; | |
| return true; | |
| } | |
| })); | |
| Object.entries(updates).forEach(([k, v]) => { | |
| ctx[k] = v; | |
| }); | |
| } | |
| console.log('before scopedRender: ', ctx.fillStyle); // #000000 | |
| scopedRender(ctx, (ctx) => { | |
| console.log('before set: ', ctx.fillStyle); // #000000 | |
| ctx.fillStyle = "#FFFFFF"; | |
| console.log('after set: ', ctx.fillStyle); // #FFFFFF | |
| }) | |
| console.log('after scopedRender: ', ctx.fillStyle); // #000000 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // whatever your canvas initialization code is | |
| // just creating a canvas in JS and not putting in the DOM since this is just an example | |
| const canvas = document.createElement('canvas'); | |
| const ctx = canvas.getContext("2d"); | |
| // First approach, allows for more flexibility but the setup would be messier | |
| // I might come back and make this have access to all props without having to one-by-one define them | |
| class Draw { | |
| static stateStack = []; | |
| static save() { | |
| Draw.stateStack.push({}); | |
| } | |
| static pop() { | |
| const obj = Draw.stateStack.pop(); | |
| if (!obj) { | |
| console.error('cannot pop an empty stack'); | |
| return; | |
| } | |
| Object.entries(obj).forEach(([k, v]) => { | |
| ctx[k] = v; | |
| }); | |
| } | |
| static _storeProperty(k, v) { | |
| const curState = Draw.stateStack.at(-1); | |
| if (!curState) return; | |
| curState[k] ??= ctx[k]; | |
| ctx[k] = v; | |
| } | |
| static setFill(color) { | |
| Draw._storeProperty('fillStyle', color); | |
| } | |
| } | |
| console.log('before save: ', ctx.fillStyle); // #000000 | |
| Draw.save(); | |
| console.log('before set: ', ctx.fillStyle); // #000000 | |
| Draw.setFill('#FFFFFF'); | |
| console.log('after set: ', ctx.fillStyle); // #FFFFFF | |
| Draw.pop(); | |
| console.log('after pop: ', ctx.fillStyle); // #000000 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment