diff options
Diffstat (limited to 'assets/canvas-runtime.js')
-rw-r--r-- | assets/canvas-runtime.js | 493 |
1 files changed, 493 insertions, 0 deletions
diff --git a/assets/canvas-runtime.js b/assets/canvas-runtime.js index af860b95..fe5f839c 100644 --- a/assets/canvas-runtime.js +++ b/assets/canvas-runtime.js | |||
@@ -378,6 +378,16 @@ NinjaCvsRt.GLRuntime = Object.create(Object.prototype, { | |||
378 | obj.importJSON( jObj ); | 378 | obj.importJSON( jObj ); |
379 | break; | 379 | break; |
380 | 380 | ||
381 | case 5: //subpath (created by pen tool) | ||
382 | obj = Object.create(NinjaCvsRt.RuntimeSubPath, {_materials: { value:[], writable:true}}); | ||
383 | obj.importJSON (jObj ); | ||
384 | break; | ||
385 | |||
386 | case 6: //brushstroke (created by brush tool) | ||
387 | obj = Object.create(NinjaCvsRt.RuntimeBrushStroke, {_materials: { value:[], writable:true}}); | ||
388 | obj.importJSON (jObj ); | ||
389 | break; | ||
390 | |||
381 | default: | 391 | default: |
382 | throw new Error( "Attempting to load unrecognized object type: " + type ); | 392 | throw new Error( "Attempting to load unrecognized object type: " + type ); |
383 | break; | 393 | break; |
@@ -520,6 +530,7 @@ NinjaCvsRt.RuntimeGeomObj = Object.create(Object.prototype, { | |||
520 | GEOM_TYPE_LINE: { value: 3, writable: false }, | 530 | GEOM_TYPE_LINE: { value: 3, writable: false }, |
521 | GEOM_TYPE_PATH: { value: 4, writable: false }, | 531 | GEOM_TYPE_PATH: { value: 4, writable: false }, |
522 | GEOM_TYPE_CUBIC_BEZIER: { value: 5, writable: false }, | 532 | GEOM_TYPE_CUBIC_BEZIER: { value: 5, writable: false }, |
533 | GEOM_TYPE_BRUSH_STROKE: { value: 6, writable: false }, | ||
523 | GEOM_TYPE_UNDEFINED: { value: -1, writable: false }, | 534 | GEOM_TYPE_UNDEFINED: { value: -1, writable: false }, |
524 | 535 | ||
525 | /////////////////////////////////////////////////////////////////////// | 536 | /////////////////////////////////////////////////////////////////////// |
@@ -1804,3 +1815,485 @@ NinjaCvsRt.RuntimePlasmaMaterial = Object.create(NinjaCvsRt.RuntimeMaterial, { | |||
1804 | }); | 1815 | }); |
1805 | 1816 | ||
1806 | 1817 | ||
1818 | |||
1819 | // ************************************************************************** | ||
1820 | // Runtime for the pen tool path | ||
1821 | // ************************************************************************** | ||
1822 | NinjaCvsRt.AnchorPoint = Object.create(Object.prototype, { | ||
1823 | ///////////////////////////////////////// | ||
1824 | // Instance variables | ||
1825 | ///////////////////////////////////////// | ||
1826 | _x: {value: 0.0, writable: true}, | ||
1827 | _y: {value: 0.0, writable: true}, | ||
1828 | _z: {value: 0.0, writable: true}, | ||
1829 | |||
1830 | _prevX: {value: 0.0, writable: true}, | ||
1831 | _prevY: {value: 0.0, writable: true}, | ||
1832 | _prevZ: {value: 0.0, writable: true}, | ||
1833 | |||
1834 | _nextX: {value: 0.0, writable: true}, | ||
1835 | _nextY: {value: 0.0, writable: true}, | ||
1836 | _nextZ: {value: 0.0, writable: true}, | ||
1837 | |||
1838 | // *********** setters ************ | ||
1839 | setPos: { | ||
1840 | value: function(x,y,z){ | ||
1841 | this._x = x; | ||
1842 | this._y = y; | ||
1843 | this._z = z; | ||
1844 | } | ||
1845 | }, | ||
1846 | |||
1847 | setPrevPos: { | ||
1848 | value: function (x, y, z) { | ||
1849 | this._prevX = x; | ||
1850 | this._prevY = y; | ||
1851 | this._prevZ = z; | ||
1852 | } | ||
1853 | }, | ||
1854 | |||
1855 | setNextPos: { | ||
1856 | value: function (x, y, z) { | ||
1857 | this._nextX = x; | ||
1858 | this._nextY = y; | ||
1859 | this._nextZ = z; | ||
1860 | } | ||
1861 | }, | ||
1862 | |||
1863 | // *************** getters ****************** | ||
1864 | // (add as needed) | ||
1865 | getPosX: { | ||
1866 | value: function () { | ||
1867 | return this._x; | ||
1868 | } | ||
1869 | }, | ||
1870 | |||
1871 | getPosY: { | ||
1872 | value: function () { | ||
1873 | return this._y; | ||
1874 | } | ||
1875 | }, | ||
1876 | |||
1877 | getPosZ: { | ||
1878 | value: function () { | ||
1879 | return this._z; | ||
1880 | } | ||
1881 | }, | ||
1882 | |||
1883 | getPrevX: { | ||
1884 | value: function () { | ||
1885 | return this._prevX; | ||
1886 | } | ||
1887 | }, | ||
1888 | |||
1889 | getPrevY: { | ||
1890 | value: function () { | ||
1891 | return this._prevY; | ||
1892 | } | ||
1893 | }, | ||
1894 | |||
1895 | getPrevZ: { | ||
1896 | value: function () { | ||
1897 | return this._prevZ; | ||
1898 | } | ||
1899 | }, | ||
1900 | |||
1901 | getNextX: { | ||
1902 | value: function () { | ||
1903 | return this._nextX; | ||
1904 | } | ||
1905 | }, | ||
1906 | |||
1907 | getNextY: { | ||
1908 | value: function () { | ||
1909 | return this._nextY; | ||
1910 | } | ||
1911 | }, | ||
1912 | |||
1913 | getNextZ: { | ||
1914 | value: function () { | ||
1915 | return this._nextZ; | ||
1916 | } | ||
1917 | } | ||
1918 | }); | ||
1919 | |||
1920 | NinjaCvsRt.RuntimeSubPath = Object.create(NinjaCvsRt.RuntimeGeomObj, { | ||
1921 | // array of anchor points | ||
1922 | _Anchors: { value: null, writable: true }, | ||
1923 | |||
1924 | //path properties | ||
1925 | _isClosed: {value: false, writable: true}, | ||
1926 | _strokeWidth: {value: 0, writable: true}, | ||
1927 | _strokeColor: {value: null, writable: true}, | ||
1928 | _fillColor: {value: null, writable: true}, | ||
1929 | |||
1930 | geomType: { | ||
1931 | value: function () { | ||
1932 | return this.GEOM_TYPE_CUBIC_BEZIER; | ||
1933 | } | ||
1934 | }, | ||
1935 | |||
1936 | importJSON: { | ||
1937 | value: function(jo) { | ||
1938 | if (this.geomType()!== jo.geomType){ | ||
1939 | return; | ||
1940 | } | ||
1941 | //the geometry for this object | ||
1942 | this._Anchors = []; | ||
1943 | var i=0; | ||
1944 | for (i=0;i<jo.anchors.length;i++){ | ||
1945 | var newAnchor = Object.create(NinjaCvsRt.AnchorPoint); | ||
1946 | var ipAnchor = jo.anchors[i]; | ||
1947 | newAnchor.setPos(ipAnchor._x, ipAnchor._y, ipAnchor._z); | ||
1948 | newAnchor.setPrevPos(ipAnchor._prevX, ipAnchor._prevY, ipAnchor._prevZ); | ||
1949 | newAnchor.setNextPos(ipAnchor._nextX, ipAnchor._nextY, ipAnchor._nextZ); | ||
1950 | this._Anchors.push(newAnchor); | ||
1951 | } | ||
1952 | this._isClosed = jo.isClosed; | ||
1953 | |||
1954 | //stroke appearance properties | ||
1955 | this._strokeWidth = jo.strokeWidth; | ||
1956 | this._strokeColor = jo.strokeColor; | ||
1957 | this._fillColor = jo.fillColor; | ||
1958 | } | ||
1959 | }, | ||
1960 | |||
1961 | //buildColor returns the fillStyle or strokeStyle for the Canvas 2D context | ||
1962 | buildColor: { | ||
1963 | value: function(ctx, //the 2D rendering context (for creating gradients if necessary) | ||
1964 | ipColor, //color string, also encodes whether there's a gradient and of what type | ||
1965 | w, //width of the region of color | ||
1966 | h, //height of the region of color | ||
1967 | lw) //linewidth (i.e. stroke width/size) | ||
1968 | { | ||
1969 | if (ipColor.gradientMode){ | ||
1970 | var position, gradient, cs, inset; //vars used in gradient calculations | ||
1971 | inset = Math.ceil( lw ) - 0.5; | ||
1972 | |||
1973 | if(ipColor.gradientMode === "radial") { | ||
1974 | var ww = w - 2*lw, hh = h - 2*lw; | ||
1975 | gradient = ctx.createRadialGradient(w/2, h/2, 0, w/2, h/2, Math.max(ww, hh)/2); | ||
1976 | } else { | ||
1977 | gradient = ctx.createLinearGradient(inset, h/2, w-inset, h/2); | ||
1978 | } | ||
1979 | var colors = ipColor.color; | ||
1980 | |||
1981 | var len = colors.length; | ||
1982 | for(n=0; n<len; n++) { | ||
1983 | position = colors[n].position/100; | ||
1984 | cs = colors[n].value; | ||
1985 | gradient.addColorStop(position, "rgba(" + cs.r + "," + cs.g + "," + cs.b + "," + cs.a + ")"); | ||
1986 | } | ||
1987 | return gradient; | ||
1988 | } else { | ||
1989 | var c = "rgba(" + 255*ipColor[0] + "," + 255*ipColor[1] + "," + 255*ipColor[2] + "," + ipColor[3] + ")"; | ||
1990 | return c; | ||
1991 | } | ||
1992 | } | ||
1993 | }, | ||
1994 | |||
1995 | render: { | ||
1996 | value: function() { | ||
1997 | // get the world | ||
1998 | var world = this.getWorld(); | ||
1999 | if (!world) { | ||
2000 | throw( "null world in subpath render" ); | ||
2001 | return; | ||
2002 | } | ||
2003 | |||
2004 | // get the context | ||
2005 | var ctx = world.get2DContext(); | ||
2006 | if (!ctx) { | ||
2007 | throw( "null world in subpath render" ); | ||
2008 | return; | ||
2009 | } | ||
2010 | |||
2011 | //vars used for the gradient computation in buildColor | ||
2012 | var w = world.getViewportWidth(), h = world.getViewportHeight(); | ||
2013 | |||
2014 | ctx.save(); | ||
2015 | ctx.lineWidth = this._strokeWidth; | ||
2016 | ctx.strokeStyle = "black"; | ||
2017 | if (this._strokeColor) { | ||
2018 | ctx.strokeStyle = this.buildColor(ctx, this._strokeColor, w,h, this._strokeWidth); | ||
2019 | } | ||
2020 | |||
2021 | ctx.fillStyle = "white"; | ||
2022 | if (this._fillColor){ | ||
2023 | ctx.fillStyle = this.buildColor(ctx, this._fillColor, w,h, this._strokeWidth); | ||
2024 | } | ||
2025 | var lineCap = ['butt','round','square']; | ||
2026 | ctx.lineCap = lineCap[1]; | ||
2027 | var lineJoin = ['round','bevel','miter']; | ||