Skip to content

Commit

Permalink
feat: download gif
Browse files Browse the repository at this point in the history
  • Loading branch information
kmkzt committed Jun 10, 2019
1 parent c06c661 commit 06ad3bc
Show file tree
Hide file tree
Showing 8 changed files with 2,812 additions and 23 deletions.
43 changes: 27 additions & 16 deletions src/SvgAnimation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class SvgAnimation extends Two {
this.strokeAnimation = this.strokeAnimation.bind(this)
this.loadScene = this.loadScene.bind(this)
this.loadSvgXml = this.loadSvgXml.bind(this)
this.splitEnd = this.splitEnd.bind(this)
/**
* Setup parameter
*/
Expand Down Expand Up @@ -119,35 +120,45 @@ export class SvgAnimation extends Two {
;(fresh as any).subdivide()
this.scene.add(fresh)
}

/**
* strokeAnimationGif
*/
public strokeAnimation() {
const distances = calculateDistances(this.scene)
const total = distances.reduce((to: number, d: number) => to + d, 0)
const setEnding = (group: Two.Group, ti: number) => {
const traversed: number = ti * total
let current = 0
group.children.map((child: Two.Object, i: number) => {
const distance = distances[i]
const min = current
const max = current + distance
;(child as Two.Path).ending = cmap(traversed, min, max, 0, 1)
current = max
})
}
let t = 0
const update = (...arg: any[]) => {
const update = () => {
if (t < 0.9999) {
t += 0.00625
} else {
t = 0
}
setEnding(this.scene, t)
setEndScene(this.scene, t)
}
this.bind('update', update).play()
return () => this.unbind('update', update)
}
/**
* SplitEnd
* @param {number} p
*/
public splitEnd(p: number) {
setEndScene(this.scene, p)
this.update()
}
}

const setEndScene = (group: Two.Group, ti: number) => {
const distances = calculateDistances(group)
const total = distances.reduce((to: number, d: number) => to + d, 0)
const traversed: number = ti * total
let current = 0
for (let i = 0; i < group.children.length; i++) {
const distance = distances[i]
const min = current
const max = current + distance
;(group.children[i] as Two.Path).ending = cmap(traversed, min, max, 0, 1)
current = max
}
}
function calculateDistances(group: Two.Group): number[] {
return group.children.reduce((distances: number[], child: Two.Object) => {
let d: number = 0
Expand Down
6 changes: 1 addition & 5 deletions src/SvgDrawing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,7 @@ export class SvgDrawing extends Two {
const domElement: HTMLElement = (this.renderer as any).domElement
const svgElement: SVGSVGElement = svgFormatting(domElement.outerHTML)
if (!domElement) return null
return `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${
this.width
}" height="${this.height}" viewBox="0 0 ${this.width} ${this.height}">${
svgElement.innerHTML
}</svg>`
return `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${this.width}" height="${this.height}" viewBox="0 0 ${this.width} ${this.height}">${svgElement.innerHTML}</svg>`
}
/**
* toSvgXML
Expand Down
20 changes: 20 additions & 0 deletions src/example/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import React, {
} from 'react'
import Two from 'two.js'
import { render } from 'react-dom'
import GIFEncoder from './jsgif'
import { createGrid } from './createGrid'
import { SvgDrawing, SvgAnimation } from '../'
import Pressure from 'pressure'
Expand Down Expand Up @@ -120,6 +121,24 @@ const Example = () => {
},
[]
)
/**
* TODO: Download action
*/
const clickDownloadGIF = useCallback(() => {
if (!svgAnimationRef.current) return
const frame: number = 50
const encoder = new (GIFEncoder as any)()
encoder.setRepeat(0)
encoder.setDelay(500 / frame)
encoder.setQuality(5)
encoder.start()
for (let i = 0; i <= frame; i++) {
svgAnimationRef.current.splitEnd(i / frame)
encoder.addFrame((svgAnimationRef.current.renderer as any).ctx)
}
encoder.finish()
encoder.download(`${new Date().toISOString()}.gif`)
}, [])
const clickDownloadSVG = useCallback(() => {
if (!svgDrawingRef.current) return
const data = svgDrawingRef.current.toSvgBase64()
Expand Down Expand Up @@ -342,6 +361,7 @@ const Example = () => {
<button onClick={clickUndo}>Undo</button>
<button onClick={clickDownload('png')}>Download PNG</button>
<button onClick={clickDownload('jpg')}>Download JPG</button>
<button onClick={clickDownloadGIF}>Download GIF</button>
<button onClick={clickDownloadSVG}>Download SVG</button>
</div>
</Fragment>
Expand Down
Loading

0 comments on commit 06ad3bc

Please sign in to comment.