41. Play
var store = sessionStorage,
user = { screen_name : ‘rem’,
rating : 11 };
store.user = JSON.stringify(user));
var gotUser = JSON.parse(store.user);
alert(gotUser.screen_name);
47. sessionStorage = (function () {
var data = window.name ? JSON.parse(window.name) : {};
return {
clear: function () {
data = {};
window.top.name = '';
},
getItem: function (key) {
return data[key] || null;
},
removeItem: function (key) {
delete data[key];
window.top.name = JSON.stringify(data);
},
setItem: function (key, value) {
data[key] = value;
window.top.name = JSON.stringify(data);
}
};
})();
http://gist.github.com/350433
48. t ip
Firefox cookie security
applies to Storage too :(
49. t ip
var cookiesEnabled = (function () {
// the id is our test value
var id = +new Date();
// generate a cookie to probe cookie access
document.cookie = '__cookieprobe=' + id + ';path=/';
// if the cookie has been set, then we're good
return (document.cookie.indexOf(id) !== -1);
})();
56. • It's not one is better than the other,
they do different things
• Select canvas when it makes sense
• Don't assume interactive means
canvas
• Check out raphaeljs.com
95. pixels.data[i * 4 + 0];
0 1 2 3
i = 0 r g b a
i = 1 r g b a
i... r g b a
96. pixels.data[i * 4 + 1];
0 1 2 3
i = 0 r g b a
i = 1 r g b a
i... r g b a
97. pixels.data[i * 4 + 2];
0 1 2 3
i = 0 r g b a
i = 1 r g b a
i... r g b a
98. pixels.data[i * 4 + 3];
0 1 2 3
i = 0 r g b a
i = 1 r g b a
i... r g b a
99. var pixels = ctx.getImageData(0, 0, w, h),
l = pixels.data.length,
i;
for (i = 0; i < l; i += 4) {
}
100. var pixels = ctx.getImageData(0, 0, w, h),
l = pixels.data.length,
i;
for (i = 0; i < l; i += 4) {
This says loop
over each pixel
}
101. var pixels = ctx.getImageData(0, 0, w, h),
l = pixels.data.length,
i;
for (i = 0; i < l; i += 4) {
// red: pixels.data[i+0]
}
102. var pixels = ctx.getImageData(0, 0, w, h),
l = pixels.data.length,
i;
for (i = 0; i < l; i += 4) {
// red: pixels.data[i+0]
// green: pixels.data[i+1]
}
103. var pixels = ctx.getImageData(0, 0, w, h),
l = pixels.data.length,
i;
for (i = 0; i < l; i += 4) {
// red: pixels.data[i+0]
// green: pixels.data[i+1]
// blue: pixels.data[i+2]
}
104. var pixels = ctx.getImageData(0, 0, w, h),
l = pixels.data.length,
i;
for (i = 0; i < l; i += 4) {
// red: pixels.data[i+0]
// green: pixels.data[i+1]
// blue: pixels.data[i+2]
// alpha: pixels.data[i+3]
}
107. t ip security_err
To use getImageData, your document
must be served over http (or https) -
i.e. it doesn't work offline.
108. /workshop/authors-large.jpg
Play
greyscale = r*.3 + g*.59 + b*.11;
r = g = b = greyscale;
saturation = (Math.max(r,g,b) +
Math.min(r,g,b))/2;
r = g = b = saturation;
http://jsbin.com/aguho3/2/edit
123. CACHE MANIFEST
/
index.html
Served from cache range.js
datastore.js
FALLBACK:
# force everything through
# the index url
/ /
# this won't match
# anything unless it's on
# another domain
NETWORK:
*
# v4
124. CACHE MANIFEST
/
index.html
range.js
Requests for files not datastore.js
found in the cache, are FALLBACK:
# force everything through
directed to / # the index url
/ /
i.e. index.html
# this won't match
(when offline). # anything unless it's on
# another domain
NETWORK:
*
# v4
125. CACHE MANIFEST
/
index.html
range.js
datastore.js
Any requests to urls
FALLBACK:
that don't match / - # force everything through
# the index url
i.e. on another / /
domain, will be # this won't match
# anything unless it's on
served through the # another domain
NETWORK:
web. *
# v4
126. CACHE MANIFEST
/
index.html
range.js
datastore.js
FALLBACK:
# force everything through
# the index url
/ /
Also ensures
# this won't match
browser even # anything unless it's on
# another domain
attempts to load the NETWORK:
*
asset
# v4
127. CACHE MANIFEST
/
index.html
range.js
datastore.js
FALLBACK:
# force everything through
# the index url
/ /
The contents of the
# this won't match
manifest must # anything unless it's on
# another domain
change to trigger an NETWORK:
*
update
# v4
144. var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
145. var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
146. var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
147. var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
148. var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
149. var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
150. var url = 'ws://node.remysharp.com:8000',
conn = new WebSocket(url);
conn.onopen = function () {
conn.send('hello world');
};
conn.onmessage = function (event) {
console.log(event.data);
};
Play
151. Questions?
To contact me after my presentation
– text NHT to INTRO (46876)
Or --
remy@leftlogic.com
@rem