Skip to content

Commit

Permalink
release(shader-toy-player): v0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
surunzi committed Sep 15, 2024
1 parent fa9b434 commit 3e8a5c7
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 75 deletions.
2 changes: 1 addition & 1 deletion index.json
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@
"icon": true,
"vue": true,
"test": false,
"version": "0.1.0",
"version": "0.2.0",
"style": true,
"install": false,
"react": false,
Expand Down
7 changes: 6 additions & 1 deletion src/shader-toy-player/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import LunaShaderToyPlayer from 'luna-shader-toy-player'
const container = document.getElementById('container')
const shaderToyPlayer = new LunaShaderToyPlayer(container)

shaderToyPlayer.load([
shaderToyPlayer.setOption('renderPass', [
{
inputs: [],
outputs: [],
Expand All @@ -48,3 +48,8 @@ shaderToyPlayer.load([
},
])
```

## Configuration

* controls(boolean): Player controls.
* renderPass(any[]): Render pass.
59 changes: 43 additions & 16 deletions src/shader-toy-player/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Component from '../share/Component'
import Component, { IComponentOptions } from '../share/Component'
import stripIndent from 'licia/stripIndent'
import $ from 'licia/$'
import noop from 'licia/noop'
Expand All @@ -7,19 +7,28 @@ import fullscreen from 'licia/fullscreen'
import raf from 'licia/raf'
import { drag, eventPage, exportCjs } from '../share/util'
import { piCreateAudioContext, piCreateFPSCounter } from './piLibs'

// eslint-disable-next-line @typescript-eslint/no-var-requires
const Effect = require('./Effect').default

const $document = $(document as any)

/** IOptions */
export interface IOptions extends IComponentOptions {
/** Render pass. */
renderPass?: any[]
/** Player controls. */
controls?: boolean
}

/**
* Shader toy player.
*
* @example
* const container = document.getElementById('container')
* const shaderToyPlayer = new LunaShaderToyPlayer(container)
*
* shaderToyPlayer.load([
* shaderToyPlayer.setOption('renderPass', [
* {
* inputs: [],
* outputs: [],
Expand All @@ -35,7 +44,7 @@ const $document = $(document as any)
* },
* ])
*/
export default class ShaderToyPlayer extends Component {
export default class ShaderToyPlayer extends Component<IOptions> {
private $canvas: $.$
private canvas: HTMLCanvasElement = document.createElement('canvas')
private $controller: $.$
Expand All @@ -58,9 +67,13 @@ export default class ShaderToyPlayer extends Component {
private startY = 0
private x = 0
private y = 0
constructor(container: HTMLElement) {
constructor(container: HTMLElement, options: IOptions = {}) {
super(container, { compName: 'shader-toy-player' })

this.initOptions(options, {
controls: true,
})

this.fpsCounter.Reset(this.timeBase)

this.initTpl()
Expand All @@ -77,7 +90,7 @@ export default class ShaderToyPlayer extends Component {
null,
piCreateAudioContext(),
this.canvas,
noop,
null,
null,
false,
false,
Expand All @@ -86,20 +99,14 @@ export default class ShaderToyPlayer extends Component {
)

this.bindEvent()
}
load(pass: any[]) {
const { effect } = this
this.pause()

if (!effect.Load({ ver: '0.1', renderpass: pass })) {
return
if (this.options.renderPass) {
this.load(this.options.renderPass)
}

effect.Compile(true, () => {
this.isPaused = false
this.startRendering()
this.reset()
})
if (!this.options.controls) {
this.$controller.hide()
}
}
destroy() {
raf.cancel.call(window, this.animationId)
Expand Down Expand Up @@ -128,6 +135,20 @@ export default class ShaderToyPlayer extends Component {
this.isRestarted = true
this.effect.ResetTime()
}
private load(pass: any[]) {
const { effect } = this
this.pause()

if (!effect.Load({ ver: '0.1', renderpass: pass })) {
return
}

effect.Compile(true, () => {
this.isPaused = false
this.startRendering()
this.reset()
})
}
private get isPaused() {
return this._isPaused
}
Expand Down Expand Up @@ -165,6 +186,12 @@ export default class ShaderToyPlayer extends Component {
this.$container.on('mousemove', this.onMouseMove)

this.$canvas.on(drag('start'), this.onDragStart)

this.on('optionChange', (name, val) => {
if (name === 'renderPass') {
this.load(val)
}
})
}
private onDragStart = (e: any) => {
const { x, y } = this.getXY(e)
Expand Down
2 changes: 1 addition & 1 deletion src/shader-toy-player/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "shader-toy-player",
"version": "0.1.0",
"version": "0.2.0",
"description": "Shader toy player",
"luna": {
"icon": true,
Expand Down
129 changes: 78 additions & 51 deletions src/shader-toy-player/story.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import $ from 'licia/$'
import shaders, { cube } from './shaders'
import LunaShaderToyPlayer from './vue'
import { defineComponent, h } from 'vue'
import { text, optionsKnob, button } from '@storybook/addon-knobs'
import { text, optionsKnob, button, boolean } from '@storybook/addon-knobs'

const def = story(
'shader-toy-player',
Expand All @@ -19,84 +19,111 @@ const def = story(
aspectRatio: '1280/720',
})

const example = optionsKnob(
'Example',
{
'Star Nest': 'star',
Seascape: 'sea',
'Protean clouds': 'cloud',
},
'star',
{
display: 'select',
}
)

const userImage = text('Image', cube.image)
const userSound = text('Sound', cube.sound)
const { example, renderPass, controls } = createKnobs()

button('Compile', function () {
loadShader(userImage, userSound)
shaderToyPlayer.setOption('renderPass', renderPass)
return false
})

const shaderToyPlayer = new ShaderToyPlayer(container)

function loadShader(code, sound) {
const pass = [
{
inputs: [],
outputs: [],
code,
name: 'Image',
description: '',
type: 'image',
},
]

if (sound) {
pass.push({
inputs: [],
outputs: [],
code: sound,
name: 'Sound',
description: '',
type: 'sound',
})
}

shaderToyPlayer.load(pass)
}

loadShader(shaders[example])
const shaderToyPlayer = new ShaderToyPlayer(container, {
controls,
renderPass: example,
})

return shaderToyPlayer
},
{
readme,
source: __STORY__,
VueComponent({ theme }) {
VueComponent() {
const { example, renderPass, controls } = createKnobs()
let shaderToyPlayer

button('Compile', function () {
shaderToyPlayer.setOption('renderPass', renderPass)
return false
})

return defineComponent({
components: {
LunaShaderToyPlayer,
},
render() {
return h(LunaShaderToyPlayer, {
theme,
renderPass: example,
controls,
style: {
maxWidth: '640px',
width: '100%',
margin: '0 auto',
minHeight: '150px',
aspectRatio: '1280/720',
},
onCreate(instance) {
shaderToyPlayer = instance
},
})
},
})
},
}
)

function createKnobs() {
const controls = boolean('Controls', true)

const example = optionsKnob(
'Example',
{
'Star Nest': 'star',
Seascape: 'sea',
'Protean clouds': 'cloud',
},
'star',
{
display: 'select',
}
)

const userImage = text('Image', cube.image)
const userSound = text('Sound', cube.sound)

const renderPass = [
{
inputs: [],
outputs: [],
code: userImage,
name: 'Image',
description: '',
type: 'image',
},
]

if (userSound) {
renderPass.push({
inputs: [],
outputs: [],
code: userSound,
name: 'Sound',
description: '',
type: 'sound',
})
}

return {
controls,
example: [
{
inputs: [],
outputs: [],
code: shaders[example],
name: 'Image',
description: '',
type: 'image',
},
],
renderPass,
}
}

export default def

export const { shaderToyPlayer: html, vue } = def
7 changes: 5 additions & 2 deletions src/shader-toy-player/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ const code = `void mainImage( out vec4 fragColor, in vec2 fragCoord )
}`

test('shader-toy-player', (container) => {
const shaderToyPlayer = new ShaderToyPlayer(container)

it('basic', function () {
const shaderToyPlayer = new ShaderToyPlayer(container)
shaderToyPlayer.load([
shaderToyPlayer.setOption('renderPass', [
{
inputs: [],
outputs: [],
Expand All @@ -22,4 +23,6 @@ test('shader-toy-player', (container) => {
},
])
})

return shaderToyPlayer
})
23 changes: 20 additions & 3 deletions src/shader-toy-player/vue.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineComponent, h, onMounted, shallowRef } from 'vue'
import { defineComponent, h, onBeforeMount, onMounted, shallowRef } from 'vue'
import ShaderToyPlayer from './index'

const LunaShaderToyPlayer = defineComponent({
Expand All @@ -8,13 +8,30 @@ const LunaShaderToyPlayer = defineComponent({
type: Object,
default: () => ({}),
},
controls: {
type: Boolean,
default: true,
},
renderPass: {
type: Array,
},
},
setup(props) {
emits: ['create'],
setup(props, context) {
const container = shallowRef<HTMLDivElement>()
const shaderToyPlayer = shallowRef<ShaderToyPlayer>()

onMounted(() => {
shaderToyPlayer.value = new ShaderToyPlayer(container.value!)
shaderToyPlayer.value = new ShaderToyPlayer(container.value!, {
renderPass: props.renderPass,
controls: props.controls,
})

context.emit('create', shaderToyPlayer.value)
})

onBeforeMount(() => {
shaderToyPlayer.value?.destroy()
})

return () => {
Expand Down
Loading

0 comments on commit 3e8a5c7

Please sign in to comment.