From fb1f8057c3b435418894fe528fed1812921d45dd Mon Sep 17 00:00:00 2001 From: Erick Dransch Date: Sat, 16 Nov 2013 20:15:56 -0500 Subject: [PATCH 001/646] add simple opengl program --- modeller/test.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 modeller/test.py diff --git a/modeller/test.py b/modeller/test.py new file mode 100644 index 000000000..a33acda1f --- /dev/null +++ b/modeller/test.py @@ -0,0 +1,68 @@ +#! /usr/bin/env python + +from OpenGLContext import testingcontext +BaseContext = testingcontext.getInteractive() + + +from OpenGL.GL import * +from OpenGL.arrays import vbo +from OpenGLContext.arrays import * + +from OpenGL.GL import shaders + +class TestContext(BaseContext): + """ creates a simple vertex shader """ + + def OnInit(self): + VERTEX_SHADER = shaders.compileShader(""" + varying vec4 vertex_color; + void main(){ + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + vertex_color = gl_Color; + }""", GL_VERTEX_SHADER) + + FRAGMENT_SHADER = shaders.compileShader(""" + varying vec4 vertex_color; + void main(){ + gl_FragColor = vertex_color; + }""", GL_FRAGMENT_SHADER) + + self.shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER) + + + self.vbo = vbo.VBO(array([ + [ 0, 1, 0, 0,1,0], + [-1, -1, 0, 1,1,0], + [ 1, -1, 0, 0,1,1], + [ 2, -1, 0, 1,0,0], + [ 4, -1, 0, 0,1,0], + [ 4, 1, 0, 0,0,1], + [ 2, -1, 0, 1,0,0], + [ 4, 1, 0, 0,0,1], + [ 2, 1, 0, 0,1,1], + ], 'f')) + + + def Render(self, mode): + """ Render geometry """ + shaders.glUseProgram(self.shader) + try: + self.vbo.bind() + try: + glEnableClientState(GL_VERTEX_ARRAY) + glEnableClientState(GL_COLOR_ARRAY) + + glVertexPointer(3, GL_FLOAT, 24, self.vbo) + glColorPointer(3, GL_FLOAT, 24, self.vbo+12) + + + glDrawArrays(GL_TRIANGLES, 0, 9) + + finally: + self.vbo.unbind() + glDisableClientState(GL_VERTEX_ARRAY) + finally: + shaders.glUseProgram(0) + +if __name__=="__main__": + TestContext.ContextMainLoop() From c0f9f6ac276280fb62c70d452e017e4f9269ecc6 Mon Sep 17 00:00:00 2001 From: Erick Dransch Date: Sun, 17 Nov 2013 15:13:33 -0500 Subject: [PATCH 002/646] more legacy code removal --- modeller/test.py | 78 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/modeller/test.py b/modeller/test.py index a33acda1f..4f28507b7 100644 --- a/modeller/test.py +++ b/modeller/test.py @@ -1,68 +1,100 @@ #! /usr/bin/env python from OpenGLContext import testingcontext +from OpenGLContext.arrays import * +from OpenGLContext.events.timer import Timer BaseContext = testingcontext.getInteractive() from OpenGL.GL import * -from OpenGL.arrays import vbo -from OpenGLContext.arrays import * - from OpenGL.GL import shaders +from OpenGL.arrays import vbo class TestContext(BaseContext): """ creates a simple vertex shader """ def OnInit(self): VERTEX_SHADER = shaders.compileShader(""" - varying vec4 vertex_color; + uniform float tween; + attribute vec3 position; + attribute vec3 tweened; + attribute vec3 color; + varying vec4 baseColor; void main(){ - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - vertex_color = gl_Color; + gl_Position = gl_ModelViewProjectionMatrix * mix( + vec4(position, 1.0), + vec4(tweened, 1.0), + tween); + baseColor = vec4(color, 1.0); }""", GL_VERTEX_SHADER) FRAGMENT_SHADER = shaders.compileShader(""" - varying vec4 vertex_color; + varying vec4 baseColor; void main(){ - gl_FragColor = vertex_color; + gl_FragColor = baseColor; }""", GL_FRAGMENT_SHADER) self.shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER) self.vbo = vbo.VBO(array([ - [ 0, 1, 0, 0,1,0], - [-1, -1, 0, 1,1,0], - [ 1, -1, 0, 0,1,1], - [ 2, -1, 0, 1,0,0], - [ 4, -1, 0, 0,1,0], - [ 4, 1, 0, 0,0,1], - [ 2, -1, 0, 1,0,0], - [ 4, 1, 0, 0,0,1], - [ 2, 1, 0, 0,1,1], + [ 0, 1, 0, 1, 3, 0, 0,1,0], + [-1, -1, 0, -1,-1, 0, 1, 1,0], + [ 1, -1, 0, 1,-1, 0, 0,1,1], + [ 2, -1, 0, 2,-1, 0, 1,0,0], + [ 4, -1, 0, 4,-1, 0, 0,1,0], + [ 4, 1, 0, 4, 9, 0, 0,0,1], + [ 2, -1, 0, 2,-1, 0, 1,0,0], + [ 4, 1, 0, 1, 3, 0, 0,0,1], + [ 2, 1, 0, 1,-1, 0, 0,1,1], ], 'f')) + self.position_location = glGetAttribLocation(self.shader, 'position') + self.tweened_location = glGetAttribLocation(self.shader, 'tweened') + self.color_location = glGetAttribLocation(self.shader, 'color') + self.tween_location = glGetUniformLocation(self.shader, 'tween') + + self.time = Timer(duration=2.0, repeating=1) + self.time.addEventHandler("fraction", self.OnTimerFraction) + self.time.register(self) + self.time.start() + self.tween_fraction = 0.0 def Render(self, mode): """ Render geometry """ - shaders.glUseProgram(self.shader) + BaseContext.Render(self, mode) + glUseProgram(self.shader) + glUniform1f(self.tween_location, self.tween_fraction) try: self.vbo.bind() try: - glEnableClientState(GL_VERTEX_ARRAY) - glEnableClientState(GL_COLOR_ARRAY) - - glVertexPointer(3, GL_FLOAT, 24, self.vbo) - glColorPointer(3, GL_FLOAT, 24, self.vbo+12) + glEnableVertexAttribArray(self.position_location) + glEnableVertexAttribArray(self.tweened_location) + glEnableVertexAttribArray(self.color_location) + stride = 9*4 + glVertexAttribPointer( self.position_location, 3, GL_FLOAT, False, stride, self.vbo) + glVertexAttribPointer( self.tweened_location, 3, GL_FLOAT, False, stride, self.vbo+12) + glVertexAttribPointer( self.color_location, 3, GL_FLOAT, False, stride, self.vbo+24) glDrawArrays(GL_TRIANGLES, 0, 9) finally: self.vbo.unbind() glDisableClientState(GL_VERTEX_ARRAY) + glDisableVertexAttribArray(self.position_location) + glDisableVertexAttribArray(self.tweened_location) + glDisableVertexAttribArray(self.color_location) finally: shaders.glUseProgram(0) + def OnTimerFraction(self, event): + frac = event.fraction() + if frac > 0.5: + frac = 1.0 - frac + frac *= 2 + self.tween_fraction = frac + self.triggerRedraw() + if __name__=="__main__": TestContext.ContextMainLoop() From 22ec0552c54f20cfa676b3db01da801112cd9a96 Mon Sep 17 00:00:00 2001 From: Erick Dransch Date: Sun, 17 Nov 2013 20:03:28 -0500 Subject: [PATCH 003/646] add diffuse lighting --- modeller/test.py | 144 +++++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 56 deletions(-) diff --git a/modeller/test.py b/modeller/test.py index 4f28507b7..a7a63331e 100644 --- a/modeller/test.py +++ b/modeller/test.py @@ -2,7 +2,6 @@ from OpenGLContext import testingcontext from OpenGLContext.arrays import * -from OpenGLContext.events.timer import Timer BaseContext = testingcontext.getInteractive() @@ -11,21 +10,49 @@ from OpenGL.arrays import vbo class TestContext(BaseContext): - """ creates a simple vertex shader """ + """ Attribute types """ def OnInit(self): - VERTEX_SHADER = shaders.compileShader(""" - uniform float tween; - attribute vec3 position; - attribute vec3 tweened; - attribute vec3 color; + + phong_calc = """ + float phong_weightCalc( + in vec3 light_pos, // light position + in vec3 frag_normal // geometre normal + ){ + // returns vec2( ambientMult, diffuseMult) + float n_dot_pos = max(0.0, dot( + frag_normal, light_pos + )); + return n_dot_pos; + }""" + + + VERTEX_SHADER = shaders.compileShader(phong_calc + """ + uniform vec4 Global_ambient; + uniform vec4 Light_ambient; + uniform vec4 Light_diffuse; + uniform vec3 Light_location; + uniform vec4 Material_ambient; + uniform vec4 Material_diffuse; + attribute vec3 Vertex_position; + attribute vec3 Vertex_normal; varying vec4 baseColor; void main(){ - gl_Position = gl_ModelViewProjectionMatrix * mix( - vec4(position, 1.0), - vec4(tweened, 1.0), - tween); - baseColor = vec4(color, 1.0); + gl_Position = gl_ModelViewProjectionMatrix * vec4( Vertex_position, 1.0); + vec3 EC_Light_location = gl_NormalMatrix * Light_location; + float diffuse_weight = phong_weightCalc( + normalize(EC_Light_location), + normalize(gl_NormalMatrix * Vertex_normal)); + baseColor = clamp( + ( + // global component + (Global_ambient * Material_ambient) + // material's interaction with light's contribution + // to the ambient lighting + + (Light_ambient * Material_ambient) + // material's interaction with direct light + + (Light_diffuse * Material_diffuse * diffuse_weight) + ), 0.0, 1.0); }""", GL_VERTEX_SHADER) FRAGMENT_SHADER = shaders.compileShader(""" @@ -38,63 +65,68 @@ def OnInit(self): self.vbo = vbo.VBO(array([ - [ 0, 1, 0, 1, 3, 0, 0,1,0], - [-1, -1, 0, -1,-1, 0, 1, 1,0], - [ 1, -1, 0, 1,-1, 0, 0,1,1], - [ 2, -1, 0, 2,-1, 0, 1,0,0], - [ 4, -1, 0, 4,-1, 0, 0,1,0], - [ 4, 1, 0, 4, 9, 0, 0,0,1], - [ 2, -1, 0, 2,-1, 0, 1,0,0], - [ 4, 1, 0, 1, 3, 0, 0,0,1], - [ 2, 1, 0, 1,-1, 0, 0,1,1], + [-1, 0, 0, -1, 0, 1], + [ 0, 0, 1, -1, 0, 2], + [ 0, 1, 1, -1, 0, 2], + [-1, 0, 0, -1, 0, 1], + [ 0, 1, 1, -1, 0, 2], + [-1, 1, 0, -1, 0, 1], + [ 0, 0, 1, -1, 0, 2], + [ 1, 0, 1, 1, 0, 2], + [ 1, 1, 1, 1, 0, 2], + [ 0, 0, 1, -1, 0, 2], + [ 1, 1, 1, 1, 0, 2], + [ 0, 1, 1, -1, 0, 2], + [ 1, 0, 1, 1, 0, 2], + [ 2, 0, 0, 1, 0, 1], + [ 2, 1, 0, 1, 0, 1], + [ 1, 0, 1, 1, 0, 2], + [ 2, 1, 0, 1, 0, 1], + [ 1, 1, 1, 1, 0, 2], ], 'f')) - - self.position_location = glGetAttribLocation(self.shader, 'position') - self.tweened_location = glGetAttribLocation(self.shader, 'tweened') - self.color_location = glGetAttribLocation(self.shader, 'color') - self.tween_location = glGetUniformLocation(self.shader, 'tween') - - self.time = Timer(duration=2.0, repeating=1) - self.time.addEventHandler("fraction", self.OnTimerFraction) - self.time.register(self) - self.time.start() - self.tween_fraction = 0.0 - - def Render(self, mode): + + for uniform in ( 'Global_ambient', 'Light_ambient', 'Light_diffuse', + 'Light_location', 'Material_ambient', 'Material_diffuse',): + location = glGetUniformLocation( self.shader, uniform) + if location in (None, -1): + print 'Warning, no uniform: %s' % (uniform) + setattr(self, uniform+'_loc', location) + + for attribute in ( 'Vertex_position', 'Vertex_normal',): + location = glGetAttribLocation(self.shader, attribute) + if location in (None, -1): + print 'Warning, no attr: %s' % (uniform) + setattr(self, attribute+'_loc', location) + + def Render(self, mode=None): """ Render geometry """ BaseContext.Render(self, mode) glUseProgram(self.shader) - glUniform1f(self.tween_location, self.tween_fraction) try: self.vbo.bind() try: - glEnableVertexAttribArray(self.position_location) - glEnableVertexAttribArray(self.tweened_location) - glEnableVertexAttribArray(self.color_location) + glUniform4f(self.Global_ambient_loc, .3, .05, .05, .1) + glUniform4f(self.Light_ambient_loc, .2, .2, .2, 1.0) + glUniform4f(self.Light_diffuse_loc, 1, 1, 1, 1) + glUniform3f(self.Light_location_loc, 2, 2, 10) + glUniform4f(self.Material_ambient_loc, 0.2, 0.2, 0.2, 1.0) + glUniform4f(self.Material_diffuse_loc, 1, 1, 1, 1.0) + + glEnableVertexAttribArray(self.Vertex_position_loc) + glEnableVertexAttribArray(self.Vertex_normal_loc) - stride = 9*4 - glVertexAttribPointer( self.position_location, 3, GL_FLOAT, False, stride, self.vbo) - glVertexAttribPointer( self.tweened_location, 3, GL_FLOAT, False, stride, self.vbo+12) - glVertexAttribPointer( self.color_location, 3, GL_FLOAT, False, stride, self.vbo+24) + stride = 6*4 + glVertexAttribPointer( self.Vertex_position_loc, 3, GL_FLOAT, False, stride, self.vbo) + glVertexAttribPointer( self.Vertex_normal_loc, 3, GL_FLOAT, False, stride, self.vbo+12) - glDrawArrays(GL_TRIANGLES, 0, 9) + glDrawArrays(GL_TRIANGLES, 0, 18) finally: self.vbo.unbind() - glDisableClientState(GL_VERTEX_ARRAY) - glDisableVertexAttribArray(self.position_location) - glDisableVertexAttribArray(self.tweened_location) - glDisableVertexAttribArray(self.color_location) + glDisableVertexAttribArray(self.Vertex_position_loc) + glDisableVertexAttribArray(self.Vertex_normal_loc) finally: - shaders.glUseProgram(0) - - def OnTimerFraction(self, event): - frac = event.fraction() - if frac > 0.5: - frac = 1.0 - frac - frac *= 2 - self.tween_fraction = frac - self.triggerRedraw() + glUseProgram(0) if __name__=="__main__": TestContext.ContextMainLoop() From e72aec303ab49100fb5b239fc9cdd24b3ba45418 Mon Sep 17 00:00:00 2001 From: Erick Dransch Date: Sun, 8 Dec 2013 19:53:51 -0500 Subject: [PATCH 004/646] finish lighting tutorials --- modeller/test.py | 118 ++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 64 deletions(-) diff --git a/modeller/test.py b/modeller/test.py index a7a63331e..c6703d31c 100644 --- a/modeller/test.py +++ b/modeller/test.py @@ -2,6 +2,7 @@ from OpenGLContext import testingcontext from OpenGLContext.arrays import * +from OpenGLContext.scenegraph.basenodes import Sphere BaseContext = testingcontext.getInteractive() @@ -15,78 +16,62 @@ class TestContext(BaseContext): def OnInit(self): phong_calc = """ - float phong_weightCalc( + vec2 phong_weightCalc( in vec3 light_pos, // light position - in vec3 frag_normal // geometre normal + in vec3 half_light, // half-way vector between light and view + in vec3 frag_normal, // geometre normal + in float shininess ){ // returns vec2( ambientMult, diffuseMult) - float n_dot_pos = max(0.0, dot( - frag_normal, light_pos - )); - return n_dot_pos; + float n_dot_pos = max(0.0, dot(frag_normal, light_pos)); + float n_dot_half = 0.0; + if (n_dot_pos > -0.05){ + n_dot_half = pow(max(0.0, dot(half_light, frag_normal)), shininess); + } + return vec2(n_dot_pos, n_dot_half); }""" - VERTEX_SHADER = shaders.compileShader(phong_calc + """ + VERTEX_SHADER = shaders.compileShader(""" + attribute vec3 Vertex_position; + attribute vec3 Vertex_normal; + varying vec3 baseNormal; + void main(){ + gl_Position = gl_ModelViewProjectionMatrix * vec4( Vertex_position, 1.0); + baseNormal = gl_NormalMatrix * normalize(Vertex_normal); + }""", GL_VERTEX_SHADER) + + FRAGMENT_SHADER = shaders.compileShader(phong_calc + """ uniform vec4 Global_ambient; uniform vec4 Light_ambient; uniform vec4 Light_diffuse; + uniform vec4 Light_specular; uniform vec3 Light_location; + uniform float Material_shininess; + uniform vec4 Material_specular; uniform vec4 Material_ambient; uniform vec4 Material_diffuse; - attribute vec3 Vertex_position; - attribute vec3 Vertex_normal; - varying vec4 baseColor; - void main(){ - gl_Position = gl_ModelViewProjectionMatrix * vec4( Vertex_position, 1.0); - vec3 EC_Light_location = gl_NormalMatrix * Light_location; - float diffuse_weight = phong_weightCalc( - normalize(EC_Light_location), - normalize(gl_NormalMatrix * Vertex_normal)); - baseColor = clamp( - ( - // global component - (Global_ambient * Material_ambient) - // material's interaction with light's contribution - // to the ambient lighting - + (Light_ambient * Material_ambient) - // material's interaction with direct light - + (Light_diffuse * Material_diffuse * diffuse_weight) - ), 0.0, 1.0); - }""", GL_VERTEX_SHADER) + varying vec3 baseNormal; - FRAGMENT_SHADER = shaders.compileShader(""" - varying vec4 baseColor; void main(){ - gl_FragColor = baseColor; + // normalized eye-coord Light location + vec3 EC_Light_location = normalize(gl_NormalMatrix * Light_location); + // half vector + vec3 Light_half = normalize(EC_Light_location - vec3(0,0,-1)); + vec2 weights = phong_weightCalc( EC_Light_location, Light_half, baseNormal, Material_shininess); + gl_FragColor = clamp(((Global_ambient * Material_ambient) + + (Light_ambient * Material_ambient) + + (Light_diffuse * Material_diffuse * weights.x) + + (Light_specular * Material_specular * weights.y)), 0.0, 1.0); }""", GL_FRAGMENT_SHADER) self.shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER) - self.vbo = vbo.VBO(array([ - [-1, 0, 0, -1, 0, 1], - [ 0, 0, 1, -1, 0, 2], - [ 0, 1, 1, -1, 0, 2], - [-1, 0, 0, -1, 0, 1], - [ 0, 1, 1, -1, 0, 2], - [-1, 1, 0, -1, 0, 1], - [ 0, 0, 1, -1, 0, 2], - [ 1, 0, 1, 1, 0, 2], - [ 1, 1, 1, 1, 0, 2], - [ 0, 0, 1, -1, 0, 2], - [ 1, 1, 1, 1, 0, 2], - [ 0, 1, 1, -1, 0, 2], - [ 1, 0, 1, 1, 0, 2], - [ 2, 0, 0, 1, 0, 1], - [ 2, 1, 0, 1, 0, 1], - [ 1, 0, 1, 1, 0, 2], - [ 2, 1, 0, 1, 0, 1], - [ 1, 1, 1, 1, 0, 2], - ], 'f')) + self.coords, self.indices, self.count = Sphere(radius = 1).compile() - for uniform in ( 'Global_ambient', 'Light_ambient', 'Light_diffuse', - 'Light_location', 'Material_ambient', 'Material_diffuse',): + for uniform in ( 'Global_ambient', 'Light_ambient', 'Light_diffuse', 'Light_specular', 'Light_location', \ + 'Material_ambient', 'Material_diffuse', 'Material_shininess', 'Material_specular',): location = glGetUniformLocation( self.shader, uniform) if location in (None, -1): print 'Warning, no uniform: %s' % (uniform) @@ -103,26 +88,31 @@ def Render(self, mode=None): BaseContext.Render(self, mode) glUseProgram(self.shader) try: - self.vbo.bind() + self.coords.bind() + self.indices.bind() + stride = self.coords.data[0].nbytes try: - glUniform4f(self.Global_ambient_loc, .3, .05, .05, .1) - glUniform4f(self.Light_ambient_loc, .2, .2, .2, 1.0) - glUniform4f(self.Light_diffuse_loc, 1, 1, 1, 1) - glUniform3f(self.Light_location_loc, 2, 2, 10) - glUniform4f(self.Material_ambient_loc, 0.2, 0.2, 0.2, 1.0) - glUniform4f(self.Material_diffuse_loc, 1, 1, 1, 1.0) + glUniform4f(self.Global_ambient_loc, .05, .05, .05, .1) + glUniform4f(self.Light_ambient_loc, .1, .1, .1, 1.0) + glUniform4f(self.Light_diffuse_loc, 0.25, 0.25, 0.25, 1) + glUniform4f(self.Light_specular_loc, 0.0, 1.0, 0.0, 1) + glUniform3f(self.Light_location_loc, 6, 2, 4) + glUniform4f(self.Material_ambient_loc, 0.1, 0.1, 0.1, 1.0) + glUniform4f(self.Material_diffuse_loc, 0.15, 0.15, 0.15, 1.0) + glUniform4f(self.Material_specular_loc, 1.0, 1.0, 1.0, 1.0) + glUniform1f(self.Material_shininess_loc, 0.95) glEnableVertexAttribArray(self.Vertex_position_loc) glEnableVertexAttribArray(self.Vertex_normal_loc) - stride = 6*4 - glVertexAttribPointer( self.Vertex_position_loc, 3, GL_FLOAT, False, stride, self.vbo) - glVertexAttribPointer( self.Vertex_normal_loc, 3, GL_FLOAT, False, stride, self.vbo+12) + glVertexAttribPointer( self.Vertex_position_loc, 3, GL_FLOAT, False, stride, self.coords) + glVertexAttribPointer( self.Vertex_normal_loc, 3, GL_FLOAT, False, stride, self.coords+(5*4)) - glDrawArrays(GL_TRIANGLES, 0, 18) + glDrawElements(GL_TRIANGLES, self.count, GL_UNSIGNED_SHORT, self.indices) finally: - self.vbo.unbind() + self.coords.unbind() + self.indices.unbind() glDisableVertexAttribArray(self.Vertex_position_loc) glDisableVertexAttribArray(self.Vertex_normal_loc) finally: From 6971d65e239e24586874863a50c054f3c0fda9fa Mon Sep 17 00:00:00 2001 From: dethe Date: Thu, 12 Dec 2013 18:36:13 -0800 Subject: [PATCH 005/646] refactoring into separate files --- blockcode/blocks.css | 44 ++++++++ blockcode/blocks.js | 135 +++++++++++++++++++++++++ blockcode/native_dragging.html | 179 +-------------------------------- 3 files changed, 183 insertions(+), 175 deletions(-) create mode 100644 blockcode/blocks.css create mode 100644 blockcode/blocks.js diff --git a/blockcode/blocks.css b/blockcode/blocks.css new file mode 100644 index 000000000..02df4ce42 --- /dev/null +++ b/blockcode/blocks.css @@ -0,0 +1,44 @@ +html, body{ + height: 100%; + padding: 0; + border: 0; + margin: 0; +} +div{ + border: 1px inset #021429; + border-radius: 7px; +} +h1, h2, h3, h4, h5, h6{ + text-align: center; +} +.menu{ + background-color: PeachPuff; + width: 24%; + height: 85%; + float: left; + margin-left: 10px; +} +.menu.over{ + background-color: BurlyWood; +} +.script{ + background-color: LightSteelBlue; + width: 73%; + height: 85%; + float: right; + margin-right: 10px; +} +.script.over{ + background-color: CadetBlue; +} +.block{ + padding: 20px; + margin: 10px; + cursor: move; +} +.menu .block{ + background-color: Coral; +} +.script .block{ + background-color: DodgerBlue; +} diff --git a/blockcode/blocks.js b/blockcode/blocks.js new file mode 100644 index 000000000..4e20ad9a3 --- /dev/null +++ b/blockcode/blocks.js @@ -0,0 +1,135 @@ +(function(global){ + 'use strict'; + // Remove namespace for matches + if (document.body.matches){ + global.matches = function matches(elem, selector){ return elem.matches(selector); }; + }else if(document.body.mozMatchesSelector){ + global.matches = function matches(elem, selector){ return elem.mozMatchesSelector(selector); }; + }else if (document.body.webkitMatchesSelector){ + global.matches = function matches(elem, selector){ return elem.webkitMatchesSelector(selector); }; + }else if (document.body.msMatchesSelector){ + global.matches = function matches(elem, selector){ return elem.msMatchesSelector(selector); }; + }else if(document.body.oMatchesSelector){ + global.matches = function matches(elem, selector){ return elem.oMatchesSelector(selector); }; + } + + global.closest = function closest(elem, selector){ + while(elem){ + if (matches(elem, selector)) return elem; + elem = elem.parentElement; + } + return null; + }; + + /* Debugging only, remove soon */ + function elname(el){ + return el.localName + '.' + el.className; + } + + /* Debugging only, remove soon */ + function evlog(ev){ + console.log(ev.type + ': ' + elname(ev.target)); + } + + var dragTarget = null; + var dragType = null; + + function dragStart(evt){ + if (!matches(evt.target, '.block')) return; + if (matches(evt.target, '.menu .block')){ + dragType = 'menu'; + }else{ + dragType = 'script'; + } + evt.target.style.opacity = '0.4'; + dragTarget = evt.target; + // For dragging to take place in Firefox, we have to set this, even if we don't use it + evt.dataTransfer.setData('text/html', evt.target.outerHTML); + if (matches(evt.target, '.menu .block')){ + evt.dataTransfer.effectAllowed = 'copy'; + }else{ + evt.dataTransfer.effectAllowed = 'move'; + } + evlog(evt); + } + document.addEventListener('dragstart', dragStart, false); + + function drag(evt){ + // this is where we can set the cursor to show where the element will end up + // evlog(evt); + } + document.addEventListener('drag', drag, false); + + function dragEnter(evt){ + // evlog(evt); + if (matches(evt.target, '.menu, .script')){ + evt.target.classList.add('over'); + }else{ + if (!matches(evt.target, '.menu *, .script *')){ + var over = document.querySelector('.over'); + if (over){ + over.classList.remove('over'); + } + evt.target.classList.remove('over'); + console.log('left all drag targets'); + }else{ + console.log('mysterious'); + } + } + if (evt.preventDefault) { + evt.preventDefault(); // Necessary. Allows us to drop. + } + return false; + } + document.addEventListener('dragenter', dragEnter, false); + + function dragOver(evt){ + evlog(evt); + if (!matches(evt.target, '.menu, .menu *, .script, .script *')) return; + if (evt.preventDefault) { + evt.preventDefault(); // Necessary. Allows us to drop. + } + if (dragType === 'menu'){ + evt.dataTransfer.dropEffect = 'copy'; // See the section on the DataTransfer object. + }else{ + evt.dataTransfer.dropEffect = 'move'; + } + return false; + } + document.addEventListener('dragover', dragOver, false); + + function drop(evt){ + if (!matches(evt.target, '.menu, .menu *, .script, .script *')) return; + var dropTarget = closest(evt.target, '.menu, .script'); + var dropType = 'script'; + if (matches(dropTarget, '.menu')){ + dropType = 'menu'; + } + if (evt.stopPropagation) { + evt.stopPropagation(); // stops the browser from redirecting. + } + if (dragType === 'script' && dropType === 'menu'){ + // If dragging from script to menu, delete dragTarget + dragTarget.parentElement.removeChild(dragTarget); + }else if (dragType ==='script' && dropType === 'script'){ + // If dragging from script to script, move dragTarget + // simulate proper moving with appendChild for now + dropTarget.appendChild(dragTarget); + }else if (dragType === 'menu' && dropType === 'script'){ + // If dragging from menu to script, copy dragTarget + var newNode = dragTarget.cloneNode(true); + newNode.removeAttribute('style'); + dropTarget.appendChild(newNode); + }else{ + // If dragging from menu to menu, do nothing + } + evlog(evt); + }; + document.addEventListener('drop', drop, false); + + function dragEnd(evt){ + evt.target.style.opacity = '1.0'; + evlog(evt); + } + document.addEventListener('dragend', dragEnd, false); +})(window); \ No newline at end of file diff --git a/blockcode/native_dragging.html b/blockcode/native_dragging.html index e21e1590c..21a0ad8ad 100644 --- a/blockcode/native_dragging.html +++ b/blockcode/native_dragging.html @@ -2,56 +2,11 @@ - Native Dragging Test - + Block Code + -

Native Dragging Test

+

Block Code