diff options
-rw-r--r-- | assets/canvas-runtime.js | 201 | ||||
-rwxr-xr-x | js/lib/geom/sub-path.js | 311 |
2 files changed, 357 insertions, 155 deletions
diff --git a/assets/canvas-runtime.js b/assets/canvas-runtime.js index eeafaab6..ec5097bc 100644 --- a/assets/canvas-runtime.js +++ b/assets/canvas-runtime.js | |||
@@ -350,6 +350,10 @@ NinjaCvsRt.GLRuntime = Object.create(Object.prototype, { | |||
350 | obj.importJSON( jObj ); | 350 | obj.importJSON( jObj ); |
351 | break; | 351 | break; |
352 | 352 | ||
353 | case 5: //subpath (created by pen tool) | ||
354 | obj = Object.create(NinjaCvsRt.RuntimeSubPath, {_materials: { value:[], writable:true}}); | ||
355 | obj.importJSON (jObj ); | ||
356 | break; | ||
353 | default: | 357 | default: |
354 | throw new Error( "Attempting to load unrecognized object type: " + type ); | 358 | throw new Error( "Attempting to load unrecognized object type: " + type ); |
355 | break; | 359 | break; |
@@ -1770,3 +1774,200 @@ NinjaCvsRt.RuntimePlasmaMaterial = Object.create(NinjaCvsRt.RuntimeMaterial, { | |||
1770 | }); | 1774 | }); |
1771 | 1775 | ||
1772 | 1776 | ||
1777 | |||
1778 | // ************************************************************************** | ||
1779 | // Runtime for the pen tool path | ||
1780 | // ************************************************************************** | ||
1781 | NinjaCvsRt.AnchorPoint = Object.create(Object.prototype, { | ||
1782 | ///////////////////////////////////////// | ||
1783 | // Instance variables | ||
1784 | ///////////////////////////////////////// | ||
1785 | _x: {value: 0.0, writable: true}, | ||
1786 | _y: {value: 0.0, writable: true}, | ||
1787 | _z: {value: 0.0, writable: true}, | ||
1788 | |||
1789 | _prevX: {value: 0.0, writable: true}, | ||
1790 | _prevY: {value: 0.0, writable: true}, | ||
1791 | _prevZ: {value: 0.0, writable: true}, | ||
1792 | |||
1793 | _nextX: {value: 0.0, writable: true}, | ||
1794 | _nextY: {value: 0.0, writable: true}, | ||
1795 | _nextZ: {value: 0.0, writable: true}, | ||
1796 | |||
1797 | // *********** setters ************ | ||
1798 | setPos: { | ||
1799 | value: function(x,y,z){ | ||
1800 | this._x = x; | ||
1801 | this._y = y; | ||
1802 | this._z = z; | ||
1803 | } | ||
1804 | }, | ||
1805 | |||
1806 | setPrevPos: { | ||
1807 | value: function (x, y, z) { | ||
1808 | this._prevX = x; | ||
1809 | this._prevY = y; | ||
1810 | this._prevZ = z; | ||
1811 | } | ||
1812 | }, | ||
1813 | |||
1814 | setNextPos: { | ||
1815 | value: function (x, y, z) { | ||
1816 | this._nextX = x; | ||
1817 | this._nextY = y; | ||
1818 | this._nextZ = z; | ||
1819 | } | ||
1820 | }, | ||
1821 | |||
1822 | // *************** getters ****************** | ||
1823 | // (add as needed) | ||
1824 | getPosX: { | ||
1825 | value: function () { | ||
1826 | return this._x; | ||
1827 | } | ||
1828 | }, | ||
1829 | |||
1830 | getPosY: { | ||
1831 | value: function () { | ||
1832 | return this._y; | ||
1833 | } | ||
1834 | }, | ||
1835 | |||
1836 | getPosZ: { | ||
1837 | value: function () { | ||
1838 | return this._z; | ||
1839 | } | ||
1840 | }, | ||
1841 | |||
1842 | getPrevX: { | ||
1843 | value: function () { | ||
1844 | return this._prevX; | ||
1845 | } | ||
1846 | }, | ||
1847 | |||
1848 | getPrevY: { | ||
1849 | value: function () { | ||
1850 | return this._prevY; | ||
1851 | } | ||
1852 | }, | ||
1853 | |||
1854 | getPrevZ: { | ||
1855 | value: function () { | ||
1856 | return this._prevZ; | ||
1857 | } | ||
1858 | }, | ||
1859 | |||
1860 | getNextX: { | ||
1861 | value: function () { | ||
1862 | return this._nextX; | ||
1863 | } | ||
1864 | }, | ||
1865 | |||
1866 | getNextY: { | ||
1867 | value: function () { | ||
1868 | return this._nextY; | ||
1869 | } | ||
1870 | }, | ||
1871 | |||
1872 | getNextZ: { | ||
1873 | value: function () { | ||
1874 | return this._nextZ; | ||
1875 | } | ||
1876 | } | ||
1877 | }); | ||
1878 | |||
1879 | NinjaCvsRt.RuntimeSubPath = Object.create(NinjaCvsRt.RuntimeGeomObj, { | ||
1880 | // array of anchor points | ||
1881 | _Anchors: { value: null, writable: true }, | ||
1882 | |||
1883 | //path properties | ||
1884 | _isClosed: {value: false, writable: true}, | ||
1885 | _strokeWidth: {value: 0, writable: true}, | ||
1886 | _strokeColor: {value: null, writable: true}, | ||
1887 | _fillColor: {value: null, writable: true}, | ||
1888 | |||
1889 | importJSON: { | ||
1890 | value: function(jo) { | ||
1891 | if (this.geomType()!== jo.geomType){ | ||
1892 | return; | ||
1893 | } | ||
1894 | //the geometry for this object | ||
1895 | this._Anchors = []; | ||
1896 | var i=0; | ||
1897 | for (i=0;i<jo.anchors.length;i++){ | ||
1898 | var newAnchor = new NinjaCvsRt.AnchorPoint(); | ||
1899 | var ipAnchor = jo.anchors[i]; | ||
1900 | newAnchor.setPos(ipAnchor._x, ipAnchor._y, ipAnchor._z); | ||
1901 | newAnchor.setPrevPos(ipAnchor._prevX, ipAnchor._prevY, ipAnchor._prevZ); | ||
1902 | newAnchor.setNextPos(ipAnchor._nextX, ipAnchor._nextY, ipAnchor._nextZ); | ||
1903 | this._Anchors.push(newAnchor); | ||
1904 | } | ||
1905 | this._isClosed = jo.isClosed; | ||
1906 | |||
1907 | //stroke appearance properties | ||
1908 | this._strokeWidth = jo.strokeWidth; | ||
1909 | this._strokeColor = jo.strokeColor; | ||
1910 | this._fillColor = jo.fillColor; | ||
1911 | } | ||
1912 | }, | ||
1913 | |||
1914 | render: { | ||
1915 | value: function() { | ||
1916 | // get the world | ||
1917 | var world = this.getWorld(); | ||
1918 | if (!world) { | ||
1919 | throw( "null world in subpath render" ); | ||
1920 | return; | ||
1921 | } | ||
1922 | |||
1923 | // get the context | ||
1924 | var ctx = world.get2DContext(); | ||
1925 | if (!ctx) { | ||
1926 | throw( "null world in subpath render" ); | ||
1927 | return; | ||
1928 | } | ||
1929 | |||
1930 | ctx.save(); | ||
1931 | ctx.lineWidth = this._strokeWidth; | ||
1932 | ctx.strokeStyle = "black"; | ||
1933 | if (this._strokeColor) { | ||
1934 | var strokeColorStr = "rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+","+this._strokeColor[3]+")"; | ||
1935 | ctx.strokeStyle = strokeColorStr; | ||
1936 | } | ||
1937 | |||
1938 | ctx.fillStyle = "white"; | ||
1939 | if (this._fillColor){ | ||
1940 | var fillColorStr = "rgba("+parseInt(255*this._fillColor[0])+","+parseInt(255*this._fillColor[1])+","+parseInt(255*this._fillColor[2])+","+this._fillColor[3]+")"; | ||
1941 | ctx.fillStyle = fillColorStr; | ||
1942 | } | ||
1943 | var lineCap = ['butt','round','square']; | ||
1944 | ctx.lineCap = lineCap[1]; | ||
1945 | var lineJoin = ['round','bevel','miter']; | ||
1946 | ctx.lineJoin = lineJoin[0]; | ||
1947 | |||
1948 | var numAnchors = this._Anchors.length; | ||
1949 | if (numAnchors>1) { | ||
1950 | ctx.beginPath(); | ||
1951 | var prevAnchor = this._Anchors[0]; | ||
1952 | ctx.moveTo(prevAnchor.getPosX(),prevAnchor.getPosY()); | ||
1953 | for (var i = 1; i < numAnchors; i++) { | ||
1954 | var currAnchor = this._Anchors[i]; | ||
1955 | ctx.bezierCurveTo(prevAnchor.getNextX(),prevAnchor.getNextY(), currAnchor.getPrevX(), currAnchor.getPrevY(), currAnchor.getPosX(), currAnchor.getPosY()); | ||
1956 | prevAnchor = currAnchor; | ||
1957 | } | ||
1958 | if (this._isClosed === true) { | ||
1959 | var currAnchor = this._Anchors[0]; | ||
1960 | ctx.bezierCurveTo(prevAnchor.getNextX(),prevAnchor.getNextY(), currAnchor.getPrevX(), currAnchor.getPrevY(), currAnchor.getPosX(), currAnchor.getPosY()); | ||
1961 | prevAnchor = currAnchor; | ||
1962 | ctx.fill(); | ||
1963 | } | ||
1964 | ctx.stroke(); | ||
1965 | } | ||
1966 | ctx.restore(); | ||
1967 | } | ||
1968 | } | ||
1969 | });// ************************************************************************** | ||
1970 | // END runtime for the pen tool path | ||
1971 | // ************************************************************************** | ||
1972 | |||
1973 | |||
diff --git a/js/lib/geom/sub-path.js b/js/lib/geom/sub-path.js index a9034def..db115655 100755 --- a/js/lib/geom/sub-path.js +++ b/js/lib/geom/sub-path.js | |||
@@ -68,178 +68,179 @@ var GLSubpath = function GLSubpath() { | |||
68 | this._selectedAnchorIndex = -1; | 68 | this._selectedAnchorIndex = -1; |
69 | 69 | ||
70 | this._SAMPLING_EPSILON = 0.5; //epsilon used for sampling the curve | 70 | this._SAMPLING_EPSILON = 0.5; //epsilon used for sampling the curve |
71 | }; //function GLSubpath ...class definition | ||
71 | 72 | ||
72 | // (current GeomObj complains if buildBuffers/render is added to GLSubpath prototype) | 73 | GLSubpath.prototype = Object.create(GeomObj, {}); |
73 | //buildBuffers | ||
74 | // Build the stroke vertices, normals, textures and colors | ||
75 | // Add that array data to the GPU using OpenGL data binding | ||
76 | this.buildBuffers = function () { | ||
77 | // return; //no need to do anything for now | ||
78 | }; | ||
79 | |||
80 | //render | ||
81 | // specify how to render the subpath in Canvas2D | ||
82 | this.render = function () { | ||
83 | // get the world | ||
84 | var world = this.getWorld(); | ||
85 | if (!world) throw( "null world in subpath render" ); | ||
86 | if (!this._canvas){ | ||
87 | //set the canvas by querying the world | ||
88 | this._canvas = this.getWorld().getCanvas(); | ||
89 | } | ||
90 | // get the context | ||
91 | var ctx = world.get2DContext(); | ||