var riserMaterial = {mdf:{cost:0.75,thickness:9}, ply:{cost:0.75,thickness:9}, pine:{cost:2.20,thickness:9.5}, oak:{cost:3.2,thickness:9.5}, sapele:{cost:2.9,thickness:9.5}} var delivery = {collected:0, mainland:65, highland:130} var stringMaterial = {pine32:{cost:3.6,thickness:32,width:270}, pine:{cost:1.8,thickness:28,width:220}, redwood:{cost:3.5,thickness:32,width:220}, oak:{cost:33,thickness:32,width:220}, sapele:{cost:15,thickness:32,width:220}} var newelStyle = {pine:{square:{cost:3.8,thickness:91},turned:{cost:6.00,thickness:91},turning:{cost:9,cap:1.4}}, oak:{square:{cost:35,thickness:90},turned:{cost:38,thickness:91},turning:{cost:28.8,cap:7.16}}, sapele:{square:{cost:22,thickness:90},turned:{cost:25,thickness:91},turning:{cost:16,cap:5.15}}, pinestdcomb:10.30, fitting:15} var balustrade = {square:{pine:{cost: 0.73},oak:{cost: 1.50},thickness:41,spaceing: 140}, stopchamfered:{pine:{cost: 0.73},oak:{cost: 1.50},thickness:41,spaceing: 140}, turned:{pine:{cost: 0.85},oak:{cost: 2.10},thickness:41,spaceing: 120}} var handrail = {pine:{cost:5.33,thickness:68}, oak:{cost:27,thickness:68}, sapele:{cost:22,thickness:68}} var paddleStandards = {baseCost: 170, assembley: 25, profit:38, bubblewrap:12.76} var commonStandards = {vatRate: 17.5, wasteRate: 10, profit: 81, labor: 18} var treadMaterial = {mdf30:{cost:2.65,thickness:30}, pine32:{cost:4.5,thickness:32}, pine:{cost:4,thickness:22}, mdf:{cost:2,thickness:22}, oak:{cost:15,thickness:22}, sapele:{cost:8,thickness:22}} var decorativeTreads = {bullnose:{mdf:25,pine:40,pine32:50,oak:60,sapele:55}, curtail:{mdf:50,pine:80,pine32:95,oak:110,sapele:100}, dstep:{mdf:35,pine:52,pine32:62,oak:80,sapele:72}, doublemultiplier:1.5 } var wallRail = {single:17.02, double:25.53 } var tradstairStandards = {quaterSpace:{mdf:10,pine:35,pine32:45,oak:70,sapele:60}, prefabQuaterSpace:{mdf:15,pine:50,pine32:70,oak:100,sapele:78}, winder:{mdf:23,pine:70,pine32:90,oak:125,sapele:110}, bubblewrap:17.02} var part_41BLK895M = 4.03; var part_41BLK895O = 5.90; var part_41BLK895P = 1.26; var part_41ST90M = 4.68; var part_41ST90O = 7.79; var part_41ST90P = 1.49; var part_ED90M = 4.87; var part_ED90O = 7.83; var part_ED90P = 1.38; var floorHeight; var numberOfRisers; var overAll; var rise; var going; var scale = 1; var riserThickness = riserMaterial['mdf']['thickness'];//thickness of the riser (so that we can work out sizes) var stringThickness = stringMaterial['pine32']['thickness']; var newelSize = newelStyle['pine']['square']['thickness']; var nosing = 16; var spindleSpaceingSquare = balustrade['square']['spaceing']; var spindleSize = balustrade['square']['thickness']; var handrailSize = handrail['pine']['thickness']; var spindleStyle = 'square'; var treadAngle = 30; //angle that the tread goes across (you know what i mean, used to be 120 on qcad) var tanTreadAngle = Math.tan(treadAngle / (180 / Math.PI)); var treadRadius = 80; //radius on the treads (you know what i mean, on the acrosss the tread bits!) var ctx; var ctxEmbedded; var ctxPopOut; var cadBorder = 10; var maxWidth = 1; var maxHeight = 1; var ctxWidth; var ctxHeight; var windowWidth; var windowHeight; var handrailComboValue; var footCombo; var wallrailCombo; var bubbleWrap; var treadMat; var riserMat; var assembledCombo; var deliveryCombo; var treadNumberOpp; var newelFill = 'rgb(255,200,100)'; function pricing () { totalTravis = numberOfRisers * Math.sqrt(halfGo * halfGo + rise * rise) / 1000;//total travis (in meters) price = 0; price = numberOfRisers * treadMaterial[treadMat]['cost']; price = price + numberOfRisers * riserMaterial[riserMat]['cost']; price = price + (totalTravis * stringMaterial['pine32']['cost'] * 2); if(handrailComboValue != 'none'){ price = price + ((newelStyle['pine']['square']['cost'] * 1.5) + newelStyle['fitting']) * 2;//the 1.5 is cause all paddle flight newels come from 1.5s price = price + ((((numberOfRisers - 1) * halfGo - newelSize) / spindleSpaceingSquare + 0.5).toFixed(0)) * part_41BLK895P; price = price + totalTravis * handrail['pine']['cost']; } price = price * (1 + commonStandards['wasteRate'] / 100); price = price + (commonStandards['labor'] * 1);//labor per hour (1hrs to make a padd flight) price = price * (1 + commonStandards['profit'] / 100); if(price <= paddleStandards['baseCost']){ price = paddleStandards['baseCost']; } if(assembledCombo == 'assembled') { price = price + paddleStandards['assembley']; } if(wallrailCombo != 'none'){ if(wallrailCombo == '1sidemop'){ price = price + wallRail['single']; } else{ price = price + wallRail['double']; } } if($('#bubble').attr('checked')){ price = price + paddleStandards['bubblewrap']; } price = price + delivery[deliveryCombo]; $('.collected, .mainland, .highland').hide();//Hiding the delivery things $('.' + deliveryCombo).show();//showing relevant delivery thing $('#netprice').html(price.toFixed(2)); $('#foxyprice').val(price.toFixed(2)); $('#grossprice').html((price * (1 + commonStandards['vatRate'] / 100)).toFixed(2)); } function treadMaterialCombo () { treadMaterialHtml = ''; treadMaterialHtml += ''; treadMaterialHtml += ''; $('#treadMaterial').html(treadMaterialHtml); treadMat = 'mdf30'; $('#treadMaterial').val(treadMat); riserMaterialCombo (); } function riserMaterialCombo () { setRiserMaterial = $('#riserMaterial').val(); riserMaterialHtml = ''; riserMaterialHtml += ''; riserMaterialHtml += ''; if (treadMat == 'pine32'){ riserMaterialHtml += ''; } $('#riserMaterial').html(riserMaterialHtml); if(setRiserMaterial != 'pine' && setRiserMaterial != null) { $('#riserMaterial').val(setRiserMaterial); } if(treadMat == 'pine32'){ $('#riserMaterial').val('pine'); } } function stairVariables () { overAll = $('#widthCombo').val(); floorHeight = $('#floorHeight').val(); numberOfRisers = $('#riseCombo').val(); handrailComboValue = $('#handrailCombo').val(); footCombo = $('#footCombo').val(); treadMat = $('#treadMaterial').val(); riserMat = $('#riserMaterial').val(); wallrailCombo = $('#wallrailCombo').val(); assembledCombo = $('#assembledCombo').val(); deliveryCombo = $('#deliveryCombo').val(); rise = floorHeight / numberOfRisers; going = rise / (Math.tan(42 * (Math.PI / 180))); if (going < 220) { going = 220; } halfGo = going / 2; } function drawStairRun (numberOfTreads, firstTreadNumber, handrailHanding) { var not = parseInt(numberOfTreads, 10); function drawTread () { ctx.save(); ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo((parseInt(overAll, 10) - stringThickness * 2 - tanTreadAngle * halfGo) / 2 - ((treadRadius / 2) / Math.cos(treadAngle / (180 / Math.PI))),0); if($.browser.msie && treadNumberOpp == 1){ ctx.arc((parseInt(overAll, 10) - stringThickness * 2 - tanTreadAngle * halfGo) / 2 - ((treadRadius / 2) / Math.cos(treadAngle / (180 / Math.PI))), - treadRadius, treadRadius, (90 / (180 / Math.PI)), (30 / (180 / Math.PI)), false); } else{ ctx.arc((parseInt(overAll, 10) - stringThickness * 2 - tanTreadAngle * halfGo) / 2 - ((treadRadius / 2) / Math.cos(treadAngle / (180 / Math.PI))), - treadRadius, treadRadius, (90 / (180 / Math.PI)), (30 / (180 / Math.PI)), true); } ctx.lineTo((parseInt(overAll, 10) - stringThickness * 2) / 2,-halfGo / 2); ctx.lineTo((parseInt(overAll, 10) - stringThickness * 2) / 2 + (tanTreadAngle * ((halfGo - treadRadius)/2)),-(halfGo - treadRadius/2)); if($.browser.msie && treadNumberOpp == 1){ ctx.arc((parseInt(overAll, 10) - stringThickness * 2) / 2 + (tanTreadAngle * ((halfGo - treadRadius)/2)) + (treadRadius * Math.cos(treadAngle / (180 / Math.PI))), -(halfGo - treadRadius), treadRadius, (210 / (180 / Math.PI)), (270 / (180 / Math.PI)), true); } else{ ctx.arc((parseInt(overAll, 10) - stringThickness * 2) / 2 + (tanTreadAngle * ((halfGo - treadRadius)/2)) + (treadRadius * Math.cos(treadAngle / (180 / Math.PI))), -(halfGo - treadRadius), treadRadius, (210 / (180 / Math.PI)), (270 / (180 / Math.PI)), false); } ctx.lineTo((parseInt(overAll, 10) - stringThickness * 2),-halfGo); ctx.stroke(); ctx.save(); ctx.translate(parseInt(overAll, 10) / 5, -going / 2); if(treadNumberOpp == 1) { ctx.scale(-1,1); } ctx.fillText('#' + treadNumber, 0, 0); ctx.restore(); ctx.restore(); } ctx.save(); ctx.translate(stringThickness, halfGo * not + nosing); ctx.save(); treadNumberOpp = 0; //do we need to flip the tread number? treadNumber = firstTreadNumber; if(footCombo == 'right'){ ctx.translate(parseInt(overAll, 10) - 2 * stringThickness, 0); ctx.scale(-1,1); treadNumberOpp = 1; } for(i=0; i<=not; 0) { ctx.translate(0, 0); i++; drawTread(); treadNumber++; if(treadNumberOpp == 1) {treadNumberOpp = 0;} else {treadNumberOpp = 1;} ctx.translate(0, -going); if(i <= not){ ctx.save(); ctx.translate(parseInt(overAll, 10) - 2 * stringThickness, 0); ctx.scale(-1,1); i++; ctx.translate(0, halfGo); drawTread(); treadNumber++; if(treadNumberOpp === 0) {treadNumberOpp = 1;} else {treadNumberOpp = 0;} ctx.restore(); } } ctx.restore(); ctx.restore(); if(handrailHanding == 'left') { lhHandrailCompensation = 0; rhHandrailCompensation = halfGo + newelSize / 2; } if(handrailHanding == 'right') { lhHandrailCompensation = halfGo + newelSize / 2; rhHandrailCompensation = 0; } if(handrailHanding == 'none') { lhHandrailCompensation = 0; rhHandrailCompensation = 0; } ctx.strokeRect (0, - halfGo, stringThickness, (numberOfTreads + 1) * halfGo + 50 - rhHandrailCompensation); ctx.strokeRect (parseInt(overAll, 10) - stringThickness, - halfGo, stringThickness, (numberOfTreads + 1) * halfGo + 50 - lhHandrailCompensation); } function runSizes () { //dimentioning variables endLines = 100; // the size of the lines (where you would draw arrows) sizeOfFont = 50;//so we can move the other stuff around fontVar = sizeOfFont + "pt Verdana"; sizeOffset = 150;//the distance the size is away from the edge size = 0; rot = 0; ctx.save(); ctx.font = fontVar; //end of dimentioning variables //doing Overall Dimension ctx.save(); size = parseInt(overAll, 10) ctx.translate(size/2, (numberOfRisers - 1) * halfGo + sizeOffset); drawSize(size, rot); ctx.restore(); //doing length of flight measurement ctx.save(); size = numberOfRisers * halfGo + nosing + riserThickness; rot = 90; ctx.translate(- sizeOffset, size/2 - halfGo - riserThickness); drawSize(size, rot); ctx.restore(); //end of function ctx.restore(); } function drawStairs() { ctx.save();//saves current canvas state ctx.translate(ctxWidth / 2, ctxHeight / 2); ctx.scale(scale,scale);//rescale canvas to suit ctx.translate(1.5 * going - maxHeight / 2, parseInt(overAll, 10)/2); ctx.rotate(270 * (Math.PI / 180)); handrailHanding = handrailComboValue; drawStairRun(numberOfRisers - 1, 1, handrailHanding); runSizes(); if(handrailComboValue != 'none' && handrailComboValue != null) { ctx.save(); handrailLength = (numberOfRisers - 1) * halfGo - newelSize; spindlesReq = 1; ctx.translate(0, -halfGo + newelSize / 2); //if(handrailComboValue != 1 && handrailComboValue != 2) {spindlesReq = 0;} if(handrailComboValue == 'left') { ctx.translate(stringThickness / 2,0); } else { ctx.translate(parseInt(overAll, 10) - stringThickness / 2,0); } drawHandrail(handrailLength, spindlesReq, 1, 1); ctx.restore(); } //done inserting hr/newels ctx.restore();//restore canvas state } function stairTriggers (skip) { function stairTriggers1(skip){ stairVariables(); if(skip == 1) { if(handrailComboValue != 'none') { if(handrailComboValue == 'left'){ $('#footCombo').val('right'); } else{ $('#footCombo').val('left'); } } } if(skip == 4) { if(handrailComboValue == footCombo){ if(handrailComboValue == 'right'){ $('#handrailCombo').val('left'); } else{ $('#handrailCombo').val('right'); } } } stairVariables(); reScale(); drawStairs(); } if(skip != 2) { //drawing embedded canvas ctxWidth = $('#embeddedCanvas').width(); ctxHeight = $('#embeddedCanvas').height(); ctx = ctxEmbedded; ctx.save(); ctx.clearRect(0,0,ctxWidth,ctxHeight); ctx.lineWidth = 5; ctx.font = "60pt Verdana"; ctx.textAlign = 'center'; stairTriggers1(skip); ctx.restore(); annotateEmbedded(); stairBoxLogo(); //doing popOut canvas: ctx = ctxPopOut; ctxWidth = $('#popOutCanvas').width(); ctxHeight = $('#popOutCanvas').height(); ctx.clearRect(0,0,ctxWidth,ctxHeight); drawPopOutBorder(); ctx.save(); ctx.translate(cadBorder * 1.5, cadBorder * 1.5); ctxWidth = ctxWidth - cadBorder * 8; ctxHeight = ctxHeight - cadBorder * 4; ctx.lineWidth = 5; ctx.font = "60pt Verdana"; ctx.textAlign = 'center'; stairTriggers1(skip); ctx.restore(); stairBoxLogo(); } if(skip == 3){ stairVariables(); riserMaterialCombo(); } //call pricing function here stairVariables(); pricing(); } function reScale() { maxHeight = (numberOfRisers) * halfGo; maxHeight = maxHeight + going * 3; maxWidth = parseInt(overAll, 10); maxWidth = maxWidth + going; if((maxHeight - ctxHeight) >= (maxWidth - ctxWidth)){ scale = ctxWidth / maxHeight; } else { scale = ctxHeight / maxWidth; } } function init() { //variables for canvas ctxEmbedded = $("#embeddedCanvas")[0].getContext("2d"); ctxPopOut = $('#popOutCanvas')[0].getContext("2d"); //triggering functions floorHeightCombo(); widthCombo(580,750,650); riseCombo(); treadMaterialCombo(); stairTriggers(); createStairCode('loftStair'); } function drawStairsFromCode () { var stairCode = document.location.search; stairCode = stairCode.replace(/^\?/, "") stairCode = decode64(stairCode); var stairCodeArray = new Array(); stairCodeArray = stairCode.split('D'); $('#floorHeight').val(stairCodeArray[0]); riseCombo(); $('#riseCombo').val(stairCodeArray[1]); stairTriggers(); $('#widthCombo').val(stairCodeArray[2]); stairTriggers(); $('#footCombo').val(stairCodeArray[3]); stairTriggers(4); $('#handrailCombo').val(stairCodeArray[4]); stairTriggers(1); $('#treadMaterial').val(stairCodeArray[5]); stairTriggers(3); $('#riserMaterial').val(stairCodeArray[6]); $('#wallrailCombo').val(stairCodeArray[7]); $('#assembledCombo').val(stairCodeArray[8]); $('#deliveryCombo').val(stairCodeArray[9]); if(stairCodeArray[10] == "false"){$('input[id=bubble]').attr('checked', false).trigger('change');} if(stairCodeArray[10] == "true"){$('input[id=bubble]').attr('checked', true).trigger('change');} stairTriggers(2); pricing(); } function stepButtonClick (direction) { if($('#stairBuilderStep1').is(":visible")) { currentStep = 1; } if($('#stairBuilderStep2').is(":visible")) { currentStep = 2; } if(direction == 'back'){ backStep(); } if(direction == 'forward'){ nextStep(); } function backStep () { $('#stairBuilderStep' + currentStep).hide(); $('#stairBuilderStep' + (currentStep - 1)).show(); if((currentStep - 1) == 1){ $('#backStep').hide(); } $('#nextStep').show(); $('#submit').hide(); } function nextStep () { $('#stairBuilderStep' + currentStep).hide(); $('#stairBuilderStep' + (currentStep + 1)).show(); if((currentStep + 1) == 2){ $('#nextStep').hide(); $('#submit').show(); } $('#backStep').show(); } } $(document).ready(function () { $('#footCombo').val('left'); $('#treadMaterial').val('mdf'); $('#riserMaterial').val('mdf'); $('#handrailCombo').val('none'); setTimeout("init()",250); $('#floorHeight').change( function () {riseCombo(); stairTriggers();} ); $('#riseCombo').change( function () {stairTriggers();} ); $('#widthCombo').change( function () {stairTriggers();} ); $('#footCombo').change( function () {stairTriggers(4);} ); $('#handrailCombo').change( function () {stairTriggers(1);} ); $('#treadMaterial').change( function () {stairTriggers(3);} ); $('#riserMaterial').change( function () {stairTriggers(2);} ); $('#assembledCombo').change( function () {stairTriggers(2);} ); $('#wallrailCombo').change( function () {stairTriggers(2);} ); $('#deliveryCombo').change( function () {stairTriggers(2);} ); $('#bubble').click( function () {stairTriggers(2);} ); $('#nextStep').click(function() {stepButtonClick('forward')}); $('#backStep').click(function() {stepButtonClick('back');}); $('select').change(function () {createStairCode('loftStair');}); $('#bubble').click(function () {createStairCode('loftStair');}); if(location.search){ setTimeout("drawStairsFromCode()",350); } });