block by dribnet 5f4f801ee500384b15da15ec6971000f

MDDN 342 2021 Assignment 1: Random Faces

Full Screen

Assignment 1 Sample Code

In class demo for better drawing techniques.

index.html

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
    <script language="javascript" type="text/javascript" src="z_purview_helper.js"></script>
    <script language="javascript" type="text/javascript" src="face_code.js"></script>
    <script language="javascript" type="text/javascript" src="arrangement.js"></script>

    <style>
        body   { padding: 0; margin: 0; }
        .inner { position: absolute; }
        #controls {
            font: 300 12px "Helvetica Neue";
            padding: 5;
            margin: 5;
            background: #f0f0f0;
            opacity: 0.0;
            -webkit-transition: opacity 0.2s ease;
            -moz-transition: opacity 0.2s ease;
            -o-transition: opacity 0.2s ease;
            -ms-transition: opacity 0.2s ease;
        }
        #controls:hover { opacity: 0.9; }
    </style>

</head>
<body style="background-color:white">
    <div class="outer">
        <div class="inner">
            <div id="canvasContainer"></div>
<a href="index.html">arrangement</a>
(<a href="arrangement.js">arrangement code</a>, 
<a href="face_code.js">face code</a>)<br>
<a href="editor.html">editor</a>
(<a href="editor.js">editor code</a>, 
<a href="face_code.js">face code</a>)<br>
<a href="sketch.html">sketch</a>
        </div>
        <div class="inner" id="controls" height="500px">
            <table>
                <tr>
                    <td></td>
                    <td id="slider1Container"></td>
                </tr>
                <tr>
                    <td></td>
                    <td id="slider2Container"></td>
                </tr>
                <tr>
                    <td></td>
                    <td id="slider3Container"></td>
                </tr>
                <tr>
                    <td></td>
                    <td id="slider4Container"></td>
                </tr>
                <tr>
                    <td></td>
                    <td id="slider5Container"></td>
                </tr>
                <tr>
                    <td></td>
                    <td id="selector1Container"></td>
                </tr>
            </table>
        </div>
    </div>
</table>
</body>

arrangement.js

/*
 * This program draws your arrangement of faces on the canvas.
 */

const canvasWidth = 960;
const canvasHeight = 500;
let curRandomSeed = 0;

let lastSwapTime = 0;
const millisPerSwap = 3000;

function setup () {
  // create the drawing canvas, save the canvas element
  let main_canvas = createCanvas(canvasWidth, canvasHeight);
  main_canvas.parent('canvasContainer');

  curRandomSeed = int(random(0, 1000));

  // rotation in degrees
  angleMode(DEGREES);
}

function changeRandomSeed() {
  curRandomSeed = curRandomSeed + 1;
  lastSwapTime = millis();
}

// global variables for colors
const bg_color1 = [225, 206, 187];

function mouseClicked() {
  changeRandomSeed();
}

function draw () {
  if(millis() > lastSwapTime + millisPerSwap) {
    changeRandomSeed();
  }

  // reset the random number generator each time draw is called
  randomSeed(curRandomSeed);

  // clear screen
  background(bg_color1);

  const num_across=5;
  for (let i=1; i<=num_across; i++) {
    push();
      translate(width*i/(num_across+1), height/2);
      scale(10);
      let eyeColor = random(0, 100);
      drawFace(eyeColor);
    pop();    
  }
}

function keyTyped() {
  if (key == '!') {
    saveBlocksImages();
  }
  else if (key == '@') {
    saveBlocksImages(true);
  }
}

editor.html

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
    <script language="javascript" type="text/javascript" src="z_purview_helper.js"></script>
    <script language="javascript" type="text/javascript" src="face_code.js"></script>
    <script language="javascript" type="text/javascript" src="editor.js"></script>

    <style>
        body   { padding: 0; margin: 0; }
        .inner { position: absolute; }
        #controls {
            font: 300 12px "Helvetica Neue";
            padding: 5;
            margin: 5;
            background: #f0f0f0;
            opacity: 0.0;
            -webkit-transition: opacity 0.2s ease;
            -moz-transition: opacity 0.2s ease;
            -o-transition: opacity 0.2s ease;
            -ms-transition: opacity 0.2s ease;
        }
        #controls:hover { opacity: 0.9; }
    </style>

</head>
<body style="background-color:white">
    <div class="outer">
        <div class="inner">
            <div id="canvasContainer"></div>
<a href="index.html">arrangement</a>
(<a href="arrangement.js">arrangement code</a>, 
<a href="face_code.js">face code</a>)<br>
<a href="editor.html">editor</a>
(<a href="editor.js">editor code</a>, 
<a href="face_code.js">face code</a>)<br>
<a href="sketch.html">sketch</a>
        </div>
        <div class="inner" id="controls" height="500px">
            <table>
                <tr>
                    <td>Setting 1</td>
                    <td id="slider1Container"></td>
                </tr>
                <tr>
                    <td>Setting 2</td>
                    <td id="slider2Container"></td>
                </tr>
                <tr>
                    <td>Setting 3</td>
                    <td id="slider3Container"></td>
                </tr>
                <tr>
                    <td>Setting 4</td>
                    <td id="slider4Container"></td>
                </tr>
                <tr>
                    <td>Setting 5</td>
                    <td id="slider5Container"></td>
                </tr>
                <tr>
                    <td>Setting 6</td>
                    <td id="slider6Container"></td>
                </tr>
                <tr>
                    <td>Setting 7</td>
                    <td id="slider7Container"></td>
                </tr>
                <tr>
                    <td>Setting 8</td>
                    <td id="slider8Container"></td>
                </tr>
                <tr>
                    <td>Setting 9</td>
                    <td id="slider9Container"></td>
                </tr>
                <tr>
                    <td>Setting 10</td>
                    <td id="slider10Container"></td>
                </tr>
                <tr>
                    <td>Show Target</td>
                    <td id="checkbox1Container"></td>
                </tr>
                <tr>
                    <td>Face</td>
                    <td id="selector1Container"></td>
                </tr>
            </table>
        </div>
    </div>
</table>
</body>

editor.js

/*
 * This editor shows the possible faces that can be created
 */

const canvasWidth = 960;
const canvasHeight = 500;
let slider1, slider2, slider3, slider4, slider5;
let slider6, slider7, slider8, slider9, slider10;
let faceSelector;
let faceGuideCheckbox;

function setup () {
  // create the drawing canvas, save the canvas element
  let main_canvas = createCanvas(canvasWidth, canvasHeight);
  main_canvas.parent('canvasContainer');

  // create sliders
  slider1 = createSlider(0, 100, 50);
  slider2 = createSlider(0, 100, 50);
  slider3 = createSlider(0, 100, 50);
  slider4 = createSlider(0, 100, 50);
  slider5 = createSlider(0, 100, 50);
  slider6 = createSlider(0, 100, 50);
  slider7 = createSlider(0, 100, 50);
  slider8 = createSlider(0, 100, 50);
  slider9 = createSlider(0, 100, 50);
  slider10 = createSlider(0, 100, 50);

  slider1.parent('slider1Container');
  slider2.parent('slider2Container');
  slider3.parent('slider3Container');
  slider4.parent('slider4Container');
  slider5.parent('slider5Container');
  slider6.parent('slider6Container');
  slider7.parent('slider7Container');
  slider8.parent('slider8Container');
  slider9.parent('slider9Container');
  slider10.parent('slider10Container');

  faceGuideCheckbox = createCheckbox('', false);
  faceGuideCheckbox.parent('checkbox1Container');

  faceSelector = createSelect();
  faceSelector.option('1');
  faceSelector.option('2');
  faceSelector.option('3');
  faceSelector.value('1');
  faceSelector.parent('selector1Container');
}

const bg_color = [125, 125, 125];

function draw () {
  strokeWeight(0.2);

  let mode = faceSelector.value();

  background(bg_color);

  let s1 = slider1.value();
  let s2 = slider2.value();
  let s3 = slider3.value();
  let s4 = slider4.value();
  let s5 = slider5.value();
  let s6 = slider6.value();
  let s7 = slider7.value();
  let s8 = slider8.value();
  let s9 = slider9.value();
  let s10 = slider10.value();

  let show_face_guide = faceGuideCheckbox.checked();

  // use same size / y_pos for all faces
  let face_size = canvasWidth / 5;
  let face_scale = face_size / 10;
  let face_y = height / 2;
  let face_x = width / 2;

  push();
  translate(face_x, face_y);
  scale(face_scale);

  push();
  if (mode == '1') {
    // draw 1st face
    drawFace(s1);
  }

  if (mode == '2') {
    // draw 2nd face - let slider value 1 indicate thinness
    drawFace2(s1);
  }

  if (mode == '3') {
    // draw 3rd face using values mapped from 3 sliders
    let tilt_value = map(s1, 0, 100, -90, 90);
    let mouth_value = map(s2, 0, 100, 0.5, 10);
    let eye_value = int(map(s3, 0, 100, 1, 3));
    drawFace3(tilt_value, eye_value, mouth_value);
  }

  pop();

  if(show_face_guide) {
    strokeWeight(0.1);
    rectMode(CORNER); 
    noFill()
    stroke(0, 0, 255);
    // ellipse(0, 0, 20, 20);
    rect(-10, -10, 20, 20);
    line(  0, -11,  0, -10);
    line(  0,  10,  0, 11);
    line(-11,   0,-10,  0);
    line( 11,   0, 10,  0);
  }

  pop();
}

function keyTyped() {
  if (key == '!') {
    saveBlocksImages();
  }
  else if (key == '@') {
    saveBlocksImages(true);
  }
}

face_code.js

/*
 * This file should contain code that draws your faces.
 *
 * Each function takes parameters and draws a face that is within
 * the bounding box (-10, -10) to (10, 10).
 *
 * These functions are used by your final arrangement of faces as well as the face editor.
 */

const background_color = [125, 125, 125];

const lightBrown = [234, 215, 194];
const darkBrown = [93, 84, 77];
const midBrown = [195, 166, 136];
const lightpink = [244, 209, 209];
const offWhite = [239, 235, 229];
const offWhiteAlpha = [239, 235, 229, 100];
const offBlack = [69, 62, 57];
const offBlackAlpha = [69, 62, 57, 50];


// eyeColor goes from 0 to 100 - 100 is bright
function drawFace(eyeColor) {

    angleMode(DEGREES);

  //strokeWeight(0.1);

  //overall shadow ADDED

  fill(offBlackAlpha);
  stroke(offBlackAlpha);
  strokeWeight(0.5);
  strokeJoin(ROUND);

  push();
  translate(0.5, 0.5);
  triangle(-8, -8, -7, -2, -2, -7); //left
  triangle(8, -8, 7, -2, 2, -7);//right
  noStroke();
  ellipse(0, 0, 15)

  fill(offBlackAlpha);
  stroke(offBlackAlpha);


  for(let i = 0; i < 4; i++){
    translate(0.11, 0.1);
    triangle(-8, -8, -7, -2, -2, -7); //left
    triangle(8, -8, 7, -2, 2, -7);//right
    noStroke();
    ellipse(0, 0, 15);//head
  }
  //head
  pop();

   

  noFill();
  strokeJoin(ROUND);
  strokeWeight(0.1);
  fill(lightBrown);
  stroke(lightBrown);
  strokeWeight(0.7);
  triangle(-8, -8, -7, -2, -2, -7);
  fill(lightpink);
  noStroke();
  triangle(-6.5, -6.5, -6, -4, -4, -6);
  fill(lightBrown);
  stroke(lightBrown);
  strokeWeight(0.7);
  triangle(8, -8, 7, -2, 2, -7);
  fill(lightpink);
  noStroke();
  triangle(6.5, -6.5, 6, -4, 4, -6);


  
  

  // head
  fill(lightBrown);
  ellipse(0, 0, 15);

  fill(offWhite);
  arc(0, 0, 15, 15, 30, 150);
  ellipse(0, 0, 2.5, 1.5);



  //nose ADDED
  fill(offBlack);
  ellipse(0, 0, 2, 1);
  //nose shine ADDED
  fill(offWhiteAlpha);
  push();
  translate(-0.3, -0.1);
  rotate(-7);
  ellipse(0, 0, 0.7, 0.3);
  ellipse(0, 0, 0.4, 0.1);
  pop();



  // eyes
  let brightness = map(eyeColor, 0, 100, 0, 200);
  fill(darkBrown);
  ellipse(-3, -3, 3);
  ellipse( 3, -3, 3);
  fill(offWhiteAlpha);
  ellipse(-3.5, -3.5, 0.8);
  ellipse( 2.5, -3.5, 0.8);
  ellipse(-3.5, -3.5, 0.6);//ADDED for eye shine depth
  ellipse( 2.5, -3.5, 0.6);//ADDED for eye shine depth




}

focused_random_demo.js

var canvasWidth = 960;
var canvasHeight = 500;
var sliders = [];
var faceSelector;
var curRandomSeed;

function setup () {
  // create the drawing canvas, save the canvas element
  var main_canvas = createCanvas(canvasWidth, canvasHeight);
  main_canvas.parent('canvasContainer');

  curRandomSeed = int(random(0, 1000));

  // create sliders
  for(i=1; i<=3; i++) {
    var slider = createSlider(0, 100, 50);
    var parentStr = 'slider' + i + 'Container';
    slider.parent(parentStr);
    sliders.push(slider);
  }
  sliders[0].value(0);
  sliders[1].value(100);
  sliders[2].value(0);

  randButton = createButton('randomize');
  randButton.mousePressed(changeRandomSeed);
  randButton.parent('selector1Container');

  // rotation in degrees
  angleMode(DEGREES);
}

function changeRandomSeed() {
  curRandomSeed = curRandomSeed + 1;
}

// global variables for colors
var bg_color = [200, 200, 200];
var fg_color = [255, 255, 255];
var stroke_color = [0, 0, 0];

var num_samples = 2000;
var num_bins = 20;

function getAveragedRandom(min, max, n) {
  let sum = 0;
  for(let i=0; i<n; i++) {
    sum = sum + random(min, max);
  }
  return sum / n;
}

function draw () {
  // reset the random number generator each time draw is called
  randomSeed(curRandomSeed);

  var min = sliders[0].value();
  var max = sliders[1].value();
  var focus = int(map(sliders[2].value(), 0, 100, 1, 8));

  var samples = []
  var bins = Array(num_bins)
  for(var i=0; i<num_bins; i++) {
    bins[i] = 0;
  }
  var s, b;
  for(var i=0; i<num_samples; i++) {
    s = getAveragedRandom(min, max, focus);
    b = Math.floor(s*4 / num_bins);
    bins[b] = bins[b] + 1;
  }

  background(bg_color);
  fill(fg_color);
  for(var i=0; i<num_bins; i++) {
    x = i * width / num_bins;
    y = bins[i];
    rect(x, height-y, width/num_bins, y);
  }

  fill(0);
  var info = "min " + min + "  max " + max + "  n " + focus;
  textSize(36);
  text(info, 300, 100);


}

function keyTyped() {
  if (key == '!') {
    saveBlocksImages();
  }
  else if (key == '@') {
    saveBlocksImages(true);
  }
}

preview.jpg

����JFIF��C	

			

		


��C	����"��	��N

!1AQa"q��BR����2�����#3brs�����	$%5STc�4C������'1!A"Q2Baq���?�sZ���R�kZx���fA��]����ͣ�>�w=�-"٦�oZb��V�����y����ܻ�vo��t�m~�3���M���,�<�Q:���L��*��w[�ۛm]��
jt�~Z���ŷ.�}���N׮��)�Դ�׬G�[^V���另�v��'iW?J�
}�=�z�x�g6c:Ϳ_�d�[��Q�����jO�0�����v�kj�
p9Th��~��m�F�����?�C&�{$�#u��!��O�QX��&�mz���N���P�F��{�u���k�;^���ɞ״}Ԭ��e;ou�-x����o�K���i��m��_�Y|��G�*���ݛ�x�N�_�L�5S^����ϻ�Gn�N[tƆv��&�f�olymq[Ŧ}}9�8���9ئu�g�2kh�9�mKM/Y��<LLq1.Y@lY-�%2�x�-��@O
�Y�q����/�j��5~�V&?z��vG�~U��`����i#O?�S8��e|m5�=�ϕb@�t͇���b�Z[ַ�Z'�p��ٯ@��η�v�Z޷ǧ�;O�S���[r��پ������|ϧ��Sh��"͜,�l����qR��C�]�����GW�š�,[�֭��1m˻g_�9��Q���y�KO�z�~ԡW���{U<\S􆻗d��m\�+�5���Ξ��?�͘Ƴo���=��E��_�sc�'�OL�0jq�Fe��kzŢ~�]_�-��U<(��
Or�Ӡ7ng[�\�޶ǧ�V�֧�w.빝.
�o���>�m�$Y}y�縘U<;�R��@n]���Ͷ���O�5:X��մ~�#��r�o�~�]�K���
G�kFH�~+���n���|��jѸ���}[��o��{n�'ָ�y�_�ʱ�K&�w\ٱ��G�5��>�ML_�l�r���1��?H�%��og�"=�m�Q>�i��V��a���q���~w���hW<�Q�w<��D�-sv�nH�\_:ksOﴭ�����g��9�}<������jI�S�'��?H�$N���͓���Y�����je��V3�wc��5m}�{�u�����y�#�G�++��o���M86���˴-���}teio�}G�m�8�q��2���ޞ8����/�K�Z֟ܛr�׻"�|��G�*v��x�V
�p���F�k�U�m��t���Ck�W��4�����T۟�:���ü�(g��k���A�ϩ��8q���D2}��^�7^>���"}'QH��&���
68ç�LT��iX�G��m���֫c�r��ovο��mn�k���3���������m����%�4�ib�~��?����ޖ�}5���׳}����	�_�j��?��YN�ٯ@�<N��v�ھ�ɧ�KG�_����Sl�-ݥlb�z�L8p���->*b�}+J�b>�wn�SnZ�[fݪܳO��/���ֳ3��,���:{����f���t�?<֌_�H�B-:��=����-7�|����(��T5΋_]M��o9�.��ֶ��y�'���'ocO�����/��}
���:����Rխ��͛a{��^^��Z��1���>�m�j�����5��|�@:�s�ˎ'����������9�a>6����u�!ȏ��w��}�i��[�S^}iJ_$��O� P��������N���굹+��ڔ����w7��RQ�j͖s��}'���;,�
=����V<�MY�����S��|�6ւ�->|�����*X��{��_A�'�m�k����o?�Zvq�~I�݃]6�֚�4��){xm�-)��?���D�ǥÝ�`���]�c�ٻ�;�����8��f��p�k�8��p�g��,�z�2���
�˷���O�n)��x[�k�Y�������+��vu�U\��4�4�ad�n��W�����6��G�>�5����O瘝��_������"�:[u�b�?c���6��Í�eG"-�'�Ǫ���<�3�����t���!��/O��ǔ����o^�<����������[�|v��~�'fۭ��iw��`�j���L~�L�ȷ/ʽ�l���i��<��L��u�!_ƶm�O�0��yo@wtv��4��h�>��̓>�p�ٷ�פeɿ����gG1>�iÛ_���ɯ�]����<����� ��G��X�m�]�g���t�u7��iY���yA�>]n�6�=�Ysd�����3������F���N����3�o��'�>s�0��y����$|f^�
=L��g�CbtN��Jߏ�?ts�Y���xb�_�?��zu��[�N@��׹F����-o����G–�m�l�
��or��7����3M#��V�֯��ͯ���Y�XH #���Á1i�I�����kt�n�>�jq���\v͛.Kq\t�skL��"&A�ɓ,v˖��)kZ��V#�f}���w�ӲΏϓo�5���㙭��Egm��i���O:v��7z�7_�`�N}Kb�Ҹ�3L��'�y}��=#�y�M9�n�3ණ�Q�
����5��b8l������7�R{W߯s�Y�g\x��ە�i��p��=��|�k���W���ˢ�W<��֟�D!w��������0�ֺ�������=+�ˤ��Q�>x����9��0yS�n��˸`�v�v}�Kxɇ>�/��8M������7��V_.��c��-b+M~(��G�d�άyL}h��#.^<�<���e��-�:�_v���`��[�t��_-&8������_>>s�|�߼�x�2�'�wŗ�ux��2�"��b�KLzNI��ϔG֟."a.�W��.�_�ϫܷ
]�&\��e˒��3>s-��x�J�e��	_�w����>��^�<W.�Y\��)[�Yj�w���,~R��O|S>~�r�m��b-���4�'�L9#֙+5����j��?ҏ�����^����|z
n�Q��ܓ�7*ָ�o�e��c��-�K�-+��z^"յg���I�yBݝ�w���3�����g�:[-���i����?����Ǿ����}i����,�o�'��赺M�G�q�jq�4ڬu͇.;s\��s[D��bb_f6�sϗ3i�i���G���������]/��]�)��)K��ui����O|qǿ�┝�������v��ŇS��_��ԥ'�K�(Ͱ����S��~3�x��8a�O�-����Z�|D~�)���i��U
�� 	@ٝ��/����M7�5�\�_^#�G�ͬ�g;�m=y���<V��5��+kEm�-*�W���;�>7�MP<��c��N}�h��6���.�_��3Y�~�[q��e�[L�������~���]׶����g���LQ�5�L������������U��mӸ:��t{n����iz���LDD��S��K�/J�:]%tt۱M+X�3~_	�}�!Lo��k{�o"m8m��NJ��o�����#�l�F�$�QZ�jZ����"'�L���C
�Z�����t�Pa�����&/Z�G�DLO9��"}�Z��L�̝y�}:��4ع�U������(���1K���������mM��ݿ=52V}-Y�9���L{�f����I�}�uv��\{�����<�<�����-_�~hN�۶]d��[L�ۻ���>�1�����o+%|m0�Y�b@���z�IН��v��l{f����<{L����^k_�hN�;�]d�}+LF����>4�2d��(��B->12�;����.����M���=��Z}mi�x�DzD{�"�����v���j��1f�g�[%�9�[�g����G>�Po>�;r۶-���1j���,��f"8��"|����>oZ=<�nY�l�n�/����bè�Y�;Dq��8�x�L��y��ۖݾ��.��[�D��b'�1��3���y{��h��]�����{IϺ��fۦ�reګ�ݺm<���n2S���'�	8�ߺ��j���▘ǭ�F�,~�m������Bw"�7��نwP�f��W��F�/�Ӡ�����&k9�?�5�I���n='��&�p��z��]��f�[x�}�Q��i����÷E��Ybx��1��஫�3N�e�1W�����;S(�r�Zg�o
��/Y�LO0�w���n[v�q�ǃU�����Չ�ީa��n_�;6�5>?��ƞ|���q���9z��k�{��*Ā9H<����v��:��+1]FL�s�U�s�����j)w���>Z�]�m�&��H�w�&�)���k�g�H_Ʒ������&�YF߷�wm~�k�t��j�yi�G6ɒ�Z��fb6;���t��뵹k1��6L:W*s����H/هFb���v^��5���4W=��|���[G�okq��<����}cU�p����ۗW�N�[��1��p���e�?ε�b���f.кz��Z�p�Mp^ޔ�Y������?.]㷍�\�<�0�Tn
nկ�훎��}^�-�g�x���Vf-Y���가6�v
�.�ۇMWfk��}NI��I��G��5��vy�
w^�5�&��I�v�*�(�k�˚ұ?+�V��M����^�@-E�nx�M�p�s���\�����&����i�O}����u��2x-�o�g�&g=�����SX�B&uy�}F]n�.�5�y3^r^�L�3��D��4���s�G����om�}���I��i||{����=�<����$�v����5[,�����i��H������9ݓh����-���&�[�~4�X��kݸ�+_5��0o㍀(Z�{�v΢�5{��Ǫ���|7�+R��������aZ���{�.����=�]oOj2Oз
ט��Lyx�NH�-���`�_r�6��A�kݴ85�=M'l������Y�G���W���|���5[���i�??
�1zG�o�6��Ƶv{�ꅢA���v��,�I��֣>V�NjO8�^_���q��ϖ���k���sͣC�&����'���������v�#F,Ys�8�&KEiJ�6���""=e3;��t�t}����z��z������1����1<D~lL��?Wcvg�볎��S_�m��7Z��a��ɖ���Eq���.<�e�r�<�ƫ���� ˀ{�wt�u��v�К��J�q��+咑���1��ǜ}hg�\o�6;cɎ�[��ūh򘘟Iz��}�wz�����m�������&1���G\��;G��(�i���)ɋ��<�g}�7ո2�zg�v�f.y�k�d�Z#��#$L����Iܛ�L�b��領����s^x�Db��a����S��􏍟ؗa}E���'�ˢ��>H�n�j��?��?�y�}�2�{��v˟����F����.*}O���L�����	��v͠���:=������=լyD)�ɍj�)�{��l�gN�M�e����t8k�GJV8��~3�3�ʴ�h���z]��ݻ��7��r��>�0Vm{}׶(��];�t�=۳���+^s����q��Y�ϋ�lX����q��%��u8���[�a���"?h���Ŭ�-�<�zlY#.ن��<��7��^�	؎�4�l���l��g��|ymh��c�g+BicC�;��'٦�������}|�Y���{x�T�p�"&g��f@�6mfh�Z��'��]z~8�����O�[\-�!]�R��Vay�O�SU<����L�6�M�X��>��l+�͎�J�&&'��&K��A�Sx�3��M"�����ﯳώ�1��h��Q�v���ϳ��xy��&���;����xu�uh�Z7Y��Xt�떶�X�&��-O�I&y���֑<LO���i��3�>_���u/+$n��'~ۃ��v�M�����+�t�xɇJ�ū�>p���{�������o_u��ش�J�եb�r䷕1c��s{O���T5w}������)�������]~-޺|��T�<��JW�x��h�Y��G31
\J��f~��6���E����k;�}��,鍶&|4��/��s�9u#����_N<������L�w޴�u�>s���Ui��w7����zW����u��%Z0��eŚ�[ט�LZ��yL|׽��w��>�L�qE�~齭��=]k��E�Gi�5��v��]�S���уuώkh�&'�o�wv[�׶.����u��Xmh���ָ�t��i����H�?F�Z״���Z����32�\�i�+�ɒ�JR����3�DDz̆��D��I���:.���L����?V���Œ���d�L�z�𘙉�T5wr��:��N�-��p��k��~]�������<x�K��y�Qi�X�DO
���u��L5q�3@� (��,k�m~�c�Q�ˋ�Ԙ�*��S��t�s_�
)kO>�D<�d�5�kz�O��̱���o�J����v���e��1��r���Ń����^���5��gNmZ��c>�N~�q?�rb���#_��Og��àLJ�8��ʟ9x��ۤ� ]��h5��N+��D&+6�B&b��S�[6-v8����o>-��*t{V�K��=�OҴz}��n�ǚO���7"-5���7�Gc�f���z7O�J����Ӧ���mjq'���H��lvg�-��u�R��3�SQL��s�_
l��D������e�����]e"y�i�?.f�n�̻�v1�.jk�K�t�����m:�LOƶ�1�̊����yŮ��<X+��}~�YY��Y�i�\ޱ��~�G���ɛ�7�*�V�X�1�Q���4v�->�����a��Υ�&-�$Yz�YwF�ۄ���5Y��xqZ����xܣj�o�5So�jͧ��,{?��Hݢi�m����L�HYW���Z?���!�[���O:\s�����}������h�iJ���k�5�i�Q3��g��˛{O�����׷Ȧ�z鼗�Lz�1Ͼ�����$��W�-���X�B�ֶ��k3>���Ã6���9��K��dɓ����_яY���ZzF<4��>
8�ַ�z�|����}��=�>/����F=#�W8�V"����H�#u1�j��{��;p-Z�&����X��Y�R��I>~��O��]G�\��C�^ԝՉf���ls[G�іf��QOg�Z>~�Y�d����9+�3�����kS�}�n>Em�ޥk�Mfkh����p��I���ck�W[��DN������<_�Oзb"���ɸt�Fa��#]�Q^}f���~��]ǯ�Hq�uIEfA�S��>ذV9����}�֤���^�v�l�tQƗ|�}�0WÇ~����K�1�]������˛����e�3򉘷�J��LLO����u$uoFm[��-�6�?�u>��։��a�!N������#�>�m�Wn0Ә��|��ѧ�q|��r|f<�셸��']*ɚ���k��Z�W�{<�1��B�����q�
���i��@ߏq��L�������W���#�%8����k6�F��D{L����#��\���c�l���C��4��o��I�Ǥ��.�G��[���#�h���m�����N�|T���z�:׵ޢݰ���pj~������dz�>V��߬�ݰu�{?��~���i��Ǥ��FO�����L��^gLͦmi���fg��§wf�[��a��$3
�ͫ�G�b�~,�?6wӺo�I������Ƕ+�&��8�(ۻ7WW�_�z��F��舌���"���h��`���9�h�ݾ�F�5r��<z�~S���Vl-&�1_�Y:����Sl�-�m���r��>���O1?8dZ=�6^/��>�?��֟��l��neA�L׊b����]�{k��s�Љ���q������8�{�2����־��X�rfޫ��)Lu�R�ZǤD9�p8�)��K�-Y��� ��Y����G<O�L�}Ҵeœ
�i5�{���Y��54�f��t��'��_Rя�5�olP\��.l<�O>ҟΏ�b�]��gEt���;�Og��4�ϓ�n=)�Z�V>sV�jO��mo[��Qo��hUϫ�{4�f�4�n[�V>�5�I�+7���UEe߫��r�>�ܺ�w��W��/����^gʱ�qX�D-x��G���b��H�KyZet�psh�?��[c�����<�����b[.�α1���gzL^�OJLy�����Hf���,V	�W�=6�s�����Zs��-��x����E�<Q����BR���j�:Vv�5��4�+�JO��<��?��Nn��N�v�Ҙ�׾:n�8��|�98�G�߉����)��,���Y�
�w��{K�n�~ɶ��=���oi�����}&+[x������5�H��ݳ�;�,��2����i��-���n<�Z��JDŭ^bm0���f��n[��&�U��|��d���2ZfmkO�fffe:�k+������{�����)1Roh�<�ӣ��|�������/���W��_�=k&Q�h���q�����+�j�w 	@��~�w�ͺ�Pms�1�c��x���֬�'�X�'	��=鞤�:�c�uŪ��=e<t�z�}��{��L|atA��{`ܻ.�f����b��>����k>��>Qx�X��G�Y�������6�6�kq��Z�q�ls�m_�1<��������5��+"v��@X�׬�����wS�cM�����Kz���ZR?:֞"#�*Π�
��v]gQu�A��1NmF�4�ZV?l�����DL�C����7�ۺ��4��C��fK~M�Zx�KzN�7S�c�#�)Y��9��=���탵��틬�=W���b�š�����i�gÎ>3ﵽ���(�#	���!«I�����!Ӿ�;v�oh�=��,�c����V#��?�k�v���x>��fZM<i�E?:|�?5��6����,Vdv;�>��~�:l�ɭ�uW��h�~�'�����/ǬyE�8�<�5����R��=����z�i��?�b��5�cˎ��:�=&����J�]���՝�n��zwS\�|����3�}����з��8�ţ����Ƕ��WA�7O�-�_���nۨ⚝4Ͼk�ԟu��g��LE��dNٸ��꾞荇W��U��۶�
<y��(�V"<�i�(�D���DL����i�N�v��=[���sVӤ��q}N�c�k������b'��ٻt�^ڷ����4�f���ׂ��4՟(��<�z�}|���Չ��Dm~��7~��x����ޕ��hv����h�����'$�<V9�D�����c���<��N�4�-���ȶ���5�>~���v��������i�+J�\���o�uXڻY����㌖��W�޸��ۖ�p�o�?��6��Co�[�����џҬ�Mg�bf=����LN��n��Kj0��m�\{N��q��pR~���x��X�>��9���R!(t:��øm���.���|"��V}-[G���a���m4鵘����~ug����ѻW�/[����k��Y4Y�r�2��g���U�����:Yzx#oe��;:��bۺ��Ws����ˢ�o�d�����D~��>ջ�[��nz]�E��,Z�.j��x��ՙ�V���X����lzۦ��it-=f�u��ŋ~6��"#�G~�{�vsұ�o�m.^��i3_kI�:*Z'�<�+�~�f��P&"e"�
�A���[���I���ͨϒ1��H���n"">2�}����v�j:{��t�u�[������g�9�I��>�Zx���^%{O�ô��5~׫���G[x���h�ZL3������M������q].=A�;�Un�����]N�j��ͨ�d�������(�(���ڴ����]�ט���ˤ�����m��q���ߵͦ>������v��g���?w�YNߵSb�+��k��U���{UiXɒ>����x��� Di\�����L��d�Z��&&9�r�:�Ũ�8�y�~����ꮿ��r�oKu�g�D�t٭Zd��/O��>V���S�4Mu'�
m��É�K��c�}�}�;C����u�M�C��9��tz�|f�X�9�"�o>��ؗQxqo�ϧ3��x��&����D|�BMӡ�394S���XƯa�im1ls��W4�Ț��O���=Y��=k����I�Ŗ��ֶ������ˎx�&>��d���kt�;��׊�Q�G�f�H�Z�!Ɠ���ys�w���k�WM�v�x��ũ���%l�S��x�W��ۏ�ա���M/L���}�*�S�-���E�
ջw���z�8������>�$�K?��M/QX�Q����HsQ��&�x��g��c�I�)3⟺Wo}�]C�p��k�nx��Mf�4O�{J�h�z#�}�;�+jl��^��5��i'8���7���X�Eu�Nҷ���tnŶt�׈��榳�^#�8���m>�2�'Q�W����}��wYuF����59���ϯ��ɤ|���ji��x�U`�/y�jS��kkzG*�+䘙�/ؼ�vkZc�s��{��V���9����+2�n�h��L�՞~�?��m�$ۏ����}��^t�F8���zz�"+V""=в*�m��M�Ŧ���6����������ثx���ϫ����x&V=gE^9�U�}��D�%�Za�3t�|s18�ʒ�zO����[G�L|��K\���>�Ij�l�����%g�X�����hm�)�43����#�?#ZWh�?�?��>�ٲϭg�lx��Q��?�޻F�����x#^c��?��ð�ߎ~���w]�����f_J��O��}��s7bz^�����}��r����#�xc���=�1X�yJ�ݦ��<\|}?LDDq�� ��

purview.json

{
  "commits": [
    {
      "sha": "4d409e6b1216cb9e86087a31cf93f4f809abe996",
      "name": "drawing tips"
    },
    {
      "sha": "8085c457780ce116a282fe8d502e5b0646911269",
      "name": "getAveragedRandom() histogram"
    },
    {
      "sha": "4e72c9b327f050f40eb45cb59a305cbe17919e98",
      "name": "gaussian distribution"
    },
    {
      "sha": "5acd3634c58d1cb046b824018766ec4854d57975",
      "name": "weighted distribution"
    },
    {
      "sha": "ea91c483f8c3c75765ca5a93052f4caad5971792",
      "name": "cat in arrangement"
    },
    {
      "sha": "3009699893cad9fc31d4f52a5c413f0b3099e5e6",
      "name": "cat in editor"
    },
    {
      "sha": "83f4e2b64085b3ea695e0250791fe7d8098e1dc9",
      "name": "sketch"
    }
  ]
}

sketch.html

<head>
    <style> body {padding: 0; margin: 0;} </style>
</head>
<body style="background-color:white">
<img src="sketch.jpg" width="960" height="480"/>
<p>
<a href="index.html">arrangement</a>
(<a href="arrangement.js">arrangement code</a>, 
<a href="face_code.js">face code</a>)<br>
<a href="editor.html">editor</a>
(<a href="editor.js">editor code</a>, 
<a href="face_code.js">face code</a>)<br>
<a href="sketch.html">sketch</a>
</body>

z_purview_helper.js

// note: this file is poorly named - it can generally be ignored.

// helper functions below for supporting blocks/purview

function saveBlocksImages(doZoom) {
  if(doZoom == null) {
    doZoom = false;
  }

  // generate 960x500 preview.jpg of entire canvas
  // TODO: should this be recycled?
  var offscreenCanvas = document.createElement('canvas');
  offscreenCanvas.width = 960;
  offscreenCanvas.height = 500;
  var context = offscreenCanvas.getContext('2d');
  // background is flat white
  context.fillStyle="#FFFFFF";
  context.fillRect(0, 0, 960, 500);
  context.drawImage(this.canvas, 0, 0, 960, 500);
  // save to browser
  var downloadMime = 'image/octet-stream';
  var imageData = offscreenCanvas.toDataURL('image/jpeg');
  imageData = imageData.replace('image/jpeg', downloadMime);
  p5.prototype.downloadFile(imageData, 'preview.jpg', 'jpg');

  // generate 230x120 thumbnail.png centered on mouse
  offscreenCanvas.width = 230;
  offscreenCanvas.height = 120;

  // background is flat white  
  context = offscreenCanvas.getContext('2d');
  context.fillStyle="#FFFFFF";
  context.fillRect(0, 0, 230, 120);

  if(doZoom) {
    // pixelDensity does the right thing on retina displays
    var pd = this._pixelDensity;
    var sx = pd * mouseX - pd * 230/2;
    var sy = pd * mouseY - pd * 120/2;
    var sw = pd * 230;
    var sh = pd * 120;
    // bounds checking - just displace if necessary
    if (sx < 0) {
      sx = 0;
    }
    if (sx > this.canvas.width - sw) {
      sx = this.canvas.width - sw;
    }
    if (sy < 0) {
      sy = 0;
    }
    if (sy > this.canvas.height - sh) {
      sy = this.canvas.height - sh;
    }
    // save to browser
    context.drawImage(this.canvas, sx, sy, sw, sh, 0, 0, 230, 120);
  }
  else {
    // now scaledown
    var full_width = this.canvas.width;
    var full_height = this.canvas.height;
    context.drawImage(this.canvas, 0, 0, full_width, full_height, 0, 0, 230, 120);
  }
  imageData = offscreenCanvas.toDataURL('image/png');
  imageData = imageData.replace('image/png', downloadMime);
  // call this function after 1 second
  setTimeout(function(){
    p5.prototype.downloadFile(imageData, 'thumbnail.png', 'png');
  }, 1000);
}